mirror of
https://github.com/minetest/contentdb.git
synced 2024-12-23 06:22:24 +01:00
Add package soft deletion
This commit is contained in:
parent
f93394df75
commit
8cf5c7204f
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -19,7 +19,22 @@
|
||||
<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 %}
|
||||
|
18
app/templates/packages/delete.html
Normal file
18
app/templates/packages/delete.html
Normal file
@ -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 %}
|
@ -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>
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
|
@ -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,6 +151,9 @@ 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:
|
||||
if package.soft_deleted:
|
||||
package.delete()
|
||||
else:
|
||||
flash("Package already exists!", "error")
|
||||
return redirect(url_for("create_edit_package_page"))
|
||||
|
||||
@ -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
|
||||
|
@ -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:
|
||||
|
28
migrations/versions/c4152f4240ed_.py
Normal file
28
migrations/versions/c4152f4240ed_.py
Normal file
@ -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 ###
|
Loading…
Reference in New Issue
Block a user