]> git.lizzy.rs Git - cheatdb.git/commitdiff
Add package soft deletion
authorrubenwardy <rw@rubenwardy.com>
Fri, 25 May 2018 17:28:24 +0000 (18:28 +0100)
committerrubenwardy <rw@rubenwardy.com>
Fri, 25 May 2018 17:28:24 +0000 (18:28 +0100)
12 files changed:
app/models.py
app/scss/components.scss
app/tasks/importtasks.py
app/templates/admin/list.html
app/templates/packages/delete.html [new file with mode: 0644]
app/templates/packages/view.html
app/utils.py
app/views/__init__.py
app/views/admin.py
app/views/packages/__init__.py
app/views/packages/todo.py
migrations/versions/c4152f4240ed_.py [new file with mode: 0644]

index c0c9a095dd9f58b1d6dab327c50989678f0fea2c..9118f78cbf6d6042e8815349db311743d597ef15 100644 (file)
@@ -261,6 +261,7 @@ class Package(db.Model):
        license_id   = db.Column(db.Integer, db.ForeignKey("license.id"))
 
        approved     = db.Column(db.Boolean, nullable=False, default=False)
+       soft_deleted = db.Column(db.Boolean, nullable=False, default=False)
 
        # Downloads
        repo         = db.Column(db.String(200), nullable=True)
@@ -329,6 +330,10 @@ class Package(db.Model):
                return url_for("approve_package_page",
                                author=self.author.username, name=self.name)
 
+       def getDeleteURL(self):
+               return url_for("delete_package_page",
+                               author=self.author.username, name=self.name)
+
        def getNewScreenshotURL(self):
                return url_for("create_screenshot_page",
                                author=self.author.username, name=self.name)
@@ -546,7 +551,7 @@ class EditRequestChange(db.Model):
                                if user is None:
                                        continue
 
-                               dep = Package.query.filter_by(author=user, name=value).first()
+                               dep = Package.query.filter_by(author=user, name=value, soft_deleted=False).first()
                                if dep is None:
                                        continue
 
index 3a145bc57cadef99eadccd64b4ee53fd1386b7b8..226ef6b24029c02c5251d4a42a2c043888ab0571 100644 (file)
@@ -301,9 +301,9 @@ select:not([multiple]) {
        color: #fff;
 }
 
-.alert-error {
-       background: #933;
-       border: 1px solid #c44;
+.alert-error, .button-danger {
+       background: #933 !important;
+       border: 1px solid #c44 !important;
 }
 
 .alert-warning {
index 352736e706f5737a6f20417860f307c4d54746b4..a20bbee8deda6353ac343ba403a673ddf1bd8d10 100644 (file)
@@ -231,7 +231,7 @@ def makeVCSRelease(id, branch):
 @celery.task()
 def importRepoScreenshot(id):
        package = Package.query.get(id)
-       if package is None:
+       if package is None or package.soft_deleted:
                raise Exception("Unexpected none package")
 
        # Get URL Maker
index 7b6645848a3fbbc47d3316181fb976b3ede646c2..373f18b52b5058a10bea1df74fc9ff8f40311b38 100644 (file)
                                <option value="importusers" selected>Create users from mod list</option>
                                <option value="importscreenshots">Import screenshots from VCS</option>
                        </select>
-                       <input type="submit" value="Start" />
+                       <input type="submit" value="Perform" />
+               </form>
+       </div>
+
+       <div class="box box_grey">
+               <h2>Restore Package</h2>
+
+               <form method="post" action="" class="box-body">
+                       <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
+                       <input type="hidden" name="action" value="restore" />
+                       <select name="package">
+                               {% for p in deleted_packages %}
+                                       <option value={{ p.id }}>{{ p.id}}) {{ p.title }} by {{ p.author.display_name }}</option>
+                               {% endfor %}
+                       </select>
+                       <input type="submit" value="Restore" />
                </form>
        </div>
 {% endblock %}
diff --git a/app/templates/packages/delete.html b/app/templates/packages/delete.html
new file mode 100644 (file)
index 0000000..95709c3
--- /dev/null
@@ -0,0 +1,18 @@
+{% extends "base.html" %}
+
+{% block title %}
+       Delete | {{ package.title }}
+{% endblock %}
+
+{% block content %}
+       <form method="POST" action="" class="box box_grey ">
+               <h3>Delete Package</h3>
+
+               <div class="box-body">
+                       <p>This action can be undone by the admin, but he'll be very annoyed!</p>
+
+                       <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
+                       <input type="submit" value="Delete" class="button-danger" />
+               </div>
+       </form>
+{% endblock %}
index c3dbb34b422361a0602c763fdbab185da0df695a..8d329ef74e1616e4b6159cb2578f817d80d0191e 100644 (file)
@@ -91,6 +91,9 @@
                                {% if package.checkPerm(current_user, "MAKE_RELEASE") %}
                                        <li><a href="{{ package.getCreateReleaseURL() }}">Create Release</a></li>
                                {% endif %}
+                               {% if package.checkPerm(current_user, "DELETE_PACKAGE") %}
+                                       <li><a href="{{ package.getDeleteURL() }}">Delete</a></li>
+                               {% endif %}
                        </ul>
                </div>
        </aside>
index e42c3cc06b50be55df5134dacdccb9632625046b..9be70d6c07b05fbaaf3073d4024015b5c71a5ca6 100644 (file)
@@ -116,7 +116,7 @@ def getPackageByInfo(author, name):
        if user is None:
                abort(404)
 
-       package = Package.query.filter_by(name=name, author_id=user.id).first()
+       package = Package.query.filter_by(name=name, author_id=user.id, soft_deleted=False).first()
        if package is None:
                abort(404)
 
index a296e5df9cece6268a42e5642ba53b9ce75582b8..abaacd719e9a3227d2723e86d2783394172eeda3 100644 (file)
@@ -38,7 +38,7 @@ def send_upload(path):
 @app.route("/")
 @menu.register_menu(app, ".", "Home")
 def home_page():
-       query = Package.query.filter_by(approved=True)
+       query = Package.query.filter_by(approved=True, soft_deleted=False)
        count = query.count()
        packages = query.order_by(db.desc(Package.created_at)).limit(15).all()
        return render_template("index.html", packages=packages, count=count)
index d0dcf733557168949a85570659e2844379990a90..6c8c4ef069da09e0ebfa4c91fe21b8c3a62c2ccf 100644 (file)
@@ -37,15 +37,25 @@ def admin_page():
                elif action == "importscreenshots":
                        packages = Package.query \
                                .outerjoin(PackageScreenshot, Package.id==PackageScreenshot.package_id) \
-                               .filter(PackageScreenshot.id==None).all()
+                               .filter(PackageScreenshot.id==None) \
+                               .filter_by(soft_deleted=False).all()
                        for package in packages:
                                importRepoScreenshot.delay(package.id)
 
                        return redirect(url_for("admin_page"))
+               elif action == "restore":
+                       package = Package.query.get(request.form["package"])
+                       if package is None:
+                               flash("Unknown package", "error")
+                       else:
+                               package.soft_deleted = False
+                               db.session.commit()
+                               return redirect(url_for("admin_page"))
                else:
                        flash("Unknown action: " + action, "error")
 
-       return render_template("admin/list.html")
+       deleted_packages = Package.query.filter_by(soft_deleted=True).all()
+       return render_template("admin/list.html", deleted_packages=deleted_packages)
 
 class SwitchUserForm(FlaskForm):
        username = StringField("Username")
index c28066655f84f4069063fd6957ff6f1be9fc45f8..340dab7aca32656aa77a649de7b1cde368c4776f 100644 (file)
@@ -43,7 +43,7 @@ def packages_page():
                type = PackageType[type.upper()]
 
        title = "Packages"
-       query = Package.query
+       query = Package.query.filter_by(soft_deleted=False)
 
        if type is not None:
                title = type.value + "s"
@@ -107,8 +107,8 @@ class PackageForm(FlaskForm):
        type          = SelectField("Type", [InputRequired()], choices=PackageType.choices(), coerce=PackageType.coerce, default=PackageType.MOD)
        license       = QuerySelectField("License", [InputRequired()], query_factory=lambda: License.query, get_pk=lambda a: a.id, get_label=lambda a: a.name)
        tags          = QuerySelectMultipleField('Tags', query_factory=lambda: Tag.query.order_by(db.asc(Tag.name)), get_pk=lambda a: a.id, get_label=lambda a: a.title)
-       harddeps      = QuerySelectMultipleField('Dependencies', query_factory=lambda: Package.query.join(User).order_by(db.asc(Package.title), db.asc(User.display_name)), get_pk=lambda a: a.id, get_label=lambda a: a.title + " by " + a.author.display_name)
-       softdeps      = QuerySelectMultipleField('Soft Dependencies', query_factory=lambda: Package.query.join(User).order_by(db.asc(Package.title), db.asc(User.display_name)), get_pk=lambda a: a.id, get_label=lambda a: a.title + " by " + a.author.display_name)
+       harddeps      = QuerySelectMultipleField('Dependencies', query_factory=lambda: Package.query.join(User).filter_by(soft_deleted=False,approved=True).order_by(db.asc(Package.title), db.asc(User.display_name)), get_pk=lambda a: a.id, get_label=lambda a: a.title + " by " + a.author.display_name)
+       softdeps      = QuerySelectMultipleField('Soft Dependencies', query_factory=lambda: Package.query.join(User).filter_by(soft_deleted=False,approved=True).order_by(db.asc(Package.title), db.asc(User.display_name)), get_pk=lambda a: a.id, get_label=lambda a: a.title + " by " + a.author.display_name)
        repo          = StringField("Repo URL", [Optional(), URL()])
        website       = StringField("Website URL", [Optional(), URL()])
        issueTracker  = StringField("Issue Tracker URL", [Optional(), URL()])
@@ -151,8 +151,11 @@ def create_edit_package_page(author=None, name=None):
                if not package:
                        package = Package.query.filter_by(name=form["name"].data, author_id=author.id).first()
                        if package is not None:
-                               flash("Package already exists!", "error")
-                               return redirect(url_for("create_edit_package_page"))
+                               if package.soft_deleted:
+                                       package.delete()
+                               else:
+                                       flash("Package already exists!", "error")
+                                       return redirect(url_for("create_edit_package_page"))
 
                        package = Package()
                        package.author = author
@@ -198,4 +201,26 @@ def approve_package_page(package):
 
        return redirect(package.getDetailsURL())
 
+
+@app.route("/packages/<author>/<name>/delete/", methods=["GET", "POST"])
+@login_required
+@is_package_page
+def delete_package_page(package):
+       if request.method == "GET":
+               return render_template("packages/delete.html", package=package)
+
+       if not package.checkPerm(current_user, Permission.DELETE_PACKAGE):
+               flash("You don't have permission to do that.", "error")
+
+       package.soft_deleted = True
+
+       url = url_for("user_profile_page", username=package.author.username)
+       triggerNotif(package.author, current_user,
+                       "{} deleted".format(package.title), url)
+       db.session.commit()
+
+       flash("Deleted package", "success")
+
+       return redirect(url)
+
 from . import todo, screenshots, editrequests, releases
index 53fec7370603a2ddf43f022f9056ddcb60f5f6c3..63f843b7df9e3253d0213e165f5673fbc42f1294 100644 (file)
@@ -29,7 +29,7 @@ def todo_page():
 
        packages = None
        if canApproveNew:
-               packages = Package.query.filter_by(approved=False).all()
+               packages = Package.query.filter_by(approved=False, soft_deleted=False).all()
 
        releases = None
        if canApproveRel:
diff --git a/migrations/versions/c4152f4240ed_.py b/migrations/versions/c4152f4240ed_.py
new file mode 100644 (file)
index 0000000..de729a8
--- /dev/null
@@ -0,0 +1,28 @@
+"""empty message
+
+Revision ID: c4152f4240ed
+Revises: 3f4d7cd8401f
+Create Date: 2018-05-25 18:27:16.953305
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = 'c4152f4240ed'
+down_revision = '3f4d7cd8401f'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.add_column('package', sa.Column('soft_deleted', sa.Boolean(), nullable=False))
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_column('package', 'soft_deleted')
+    # ### end Alembic commands ###