diff --git a/warehouse/migrations/versions/75dde92f5019_create_spam_models.py b/warehouse/migrations/versions/75dde92f5019_create_spam_models.py new file mode 100644 index 000000000000..fbc8a65502b1 --- /dev/null +++ b/warehouse/migrations/versions/75dde92f5019_create_spam_models.py @@ -0,0 +1,63 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +create spam models + +Revision ID: 75dde92f5019 +Revises: b75709859292 +Create Date: 2018-02-19 20:16:00.579309 +""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +revision = '75dde92f5019' +down_revision = 'b75709859292' + + +def upgrade(): + op.create_table( + 'spam_report', + sa.Column( + 'id', postgresql.UUID(as_uuid=True), + server_default=sa.text('gen_random_uuid()'), nullable=False + ), + sa.Column('release_name', sa.Text(), nullable=False), + sa.Column('release_version', sa.Text(), nullable=False), + sa.Column( + 'source', + postgresql.ENUM( + 'automation', 'user', + name='report_source_enum' + ), + nullable=False + ), + sa.Column('reporter_user_id', postgresql.UUID(), nullable=True), + sa.Column('result', sa.Boolean(), nullable=False), + sa.Column('comment', sa.Text(), nullable=True), + sa.Column('valid', sa.Boolean(), nullable=True), + sa.CheckConstraint( + "reporter_user_id IS NOT NULL OR source = 'automation'", + name='valid_reporter_user_id' + ), + sa.ForeignKeyConstraint( + ['release_name', 'release_version'], + ['releases.name', 'releases.version'], + onupdate='CASCADE', ondelete='CASCADE' + ), + sa.PrimaryKeyConstraint('id') + ) + + +def downgrade(): + op.drop_table('spam_report') diff --git a/warehouse/spam/__init__.py b/warehouse/spam/__init__.py new file mode 100644 index 000000000000..164f68b09175 --- /dev/null +++ b/warehouse/spam/__init__.py @@ -0,0 +1,11 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/warehouse/spam/models.py b/warehouse/spam/models.py new file mode 100644 index 000000000000..1d762ad70b08 --- /dev/null +++ b/warehouse/spam/models.py @@ -0,0 +1,54 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from sqlalchemy import ( + Boolean, + CheckConstraint, + Column, + ForeignKeyConstraint, + Text, +) +from sqlalchemy.dialects.postgresql import ENUM, UUID + +from warehouse import db + + +report_source = ENUM( + 'automation', + 'user', + name="report_source_enum", +) + + +class SpamReport(db.Model): + + __tablename__ = "spam_report" + __table_args__ = ( + ForeignKeyConstraint( + ["release_name", "release_version"], + ["releases.name", "releases.version"], + onupdate="CASCADE", + ondelete="CASCADE", + ), + CheckConstraint( + "reporter_user_id IS NOT NULL OR source = 'automation'", + name="valid_reporter_user_id", + ), + ) + + release_name = Column(Text, nullable=False) + release_version = Column(Text, nullable=False) + source = Column(report_source, nullable=False) + reporter_user_id = Column(UUID, nullable=True) + result = Column(Boolean, nullable=False) + comment = Column(Text, nullable=True) + valid = Column(Boolean, nullable=True) diff --git a/warehouse/spam/tasks.py b/warehouse/spam/tasks.py new file mode 100644 index 000000000000..eecf155eb167 --- /dev/null +++ b/warehouse/spam/tasks.py @@ -0,0 +1,21 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from warehouse import tasks + + +@tasks.task(bind=True, ignore_result=True, acks_late=True) +def analyze_upload(task, request): + try: + pass + except Exception as exc: + task.retry(exc=exc)