]> git.lizzy.rs Git - cheatdb.git/commitdiff
Add start of bulk tag editor
authorrubenwardy <rw@rubenwardy.com>
Tue, 14 Jul 2020 02:49:30 +0000 (03:49 +0100)
committerrubenwardy <rw@rubenwardy.com>
Tue, 14 Jul 2020 22:45:54 +0000 (23:45 +0100)
app/blueprints/packages/releases.py
app/blueprints/todo/__init__.py
app/public/static/tagselector.js
app/scss/components.scss
app/tasks/importtasks.py
app/templates/base.html
app/templates/todo/tags.html [new file with mode: 0644]

index cc209aa43dd7d1e01fda219044ded6593a2d8c24..1d11477fec9d8bcff2c53ec4cac2f3d86423dfe9 100644 (file)
@@ -22,7 +22,7 @@ from . import bp
 
 from app.rediscache import has_key, set_key, make_download_key
 from app.models import *
-from app.tasks.importtasks import makeVCSRelease, checkZipRelease
+from app.tasks.importtasks import makeVCSRelease, checkZipRelease, updateMetaFromRelease
 from app.utils import *
 
 from celery import uuid
@@ -111,6 +111,7 @@ def create_release(package):
                                db.session.commit()
 
                                checkZipRelease.apply_async((rel.id, uploadedPath), task_id=rel.task_id)
+                               updateMetaFromRelease.delay(rel.id, uploadedPath)
 
                                msg = "Release {} created".format(rel.title)
                                addNotification(package.maintainers, current_user, msg, rel.getEditURL(), package)
@@ -120,6 +121,7 @@ def create_release(package):
 
        return render_template("packages/release_new.html", package=package, form=form)
 
+
 @bp.route("/packages/<author>/<name>/releases/<id>/download/")
 @is_package_page
 def download_release(package, id):
@@ -149,6 +151,7 @@ def download_release(package, id):
 
        return redirect(release.url, code=300)
 
+
 @bp.route("/packages/<author>/<name>/releases/<id>/", methods=["GET", "POST"])
 @login_required
 @is_package_page
index 12b062222c486d1e0b103c886f69643d1d5f0198..89e24b88b535a8a20564714bf082b4c050a46898 100644 (file)
@@ -100,3 +100,12 @@ def topics():
                        topic_count=topic_count, query=qb.search, show_discarded=qb.show_discarded, \
                        next_url=next_url, prev_url=prev_url, page=page, page_max=query.pages, \
                        n=num, sort_by=qb.order_by)
+
+
+@bp.route("/todo/tags/")
+@login_required
+def tags():
+       packages = Package.query.filter_by(approved=True, soft_deleted=False).all()
+       tags = Tag.query.order_by(db.asc(Tag.title)).all()
+
+       return render_template("todo/tags.html", packages=packages, tags=tags)
index 9bbb764d77fe303ba6b57b5f0cb10c63f2d207a4..f09941512713011d6f46cbe16f1d8b06159638a4 100644 (file)
 
        $.fn.selectSelector = function(source, select) {
                return this.each(function() {
-                               var selector = $(this),
-                                       input = $('input[type=text]', this);
+                       var selector = $(this),
+                               input = $('input[type=text]', this);
 
-                               selector.click(function() { input.focus(); })
-                                       .delegate('.badge a', 'click', function() {
-                                               var id = $(this).parent().data("id");
-                                               select.find("option[value=" + id + "]").attr("selected", false)
-                                               recreate();
-                                       });
+                       selector.click(function() { input.focus(); })
+                               .delegate('.badge a', 'click', function() {
+                                       var id = $(this).parent().data("id");
+                                       select.find("option[value=" + id + "]").attr("selected", false)
+                                       recreate();
+                               });
 
-                               function addTag(id, text) {
-                                       $('<span class="badge badge-pill badge-primary"/>')
-                                               .text(text + ' ')
-                                               .data("id", id)
-                                               .append('<a>x</a>')
-                                               .insertBefore(input);
-                                       input.attr("placeholder", null);
-                                       select.find("option[value='" + id + "']").attr("selected", "selected")
-                                       hide_error(input);
-                               }
+                       function addTag(id, text) {
+                               $('<span class="badge badge-pill badge-primary"/>')
+                                       .text(text + ' ')
+                                       .data("id", id)
+                                       .append('<a>x</a>')
+                                       .insertBefore(input);
+                               input.attr("placeholder", null);
+                               select.find("option[value='" + id + "']").attr("selected", "selected")
+                               hide_error(input);
+                       }
 
-                               function recreate() {
-                                       selector.find("span").remove();
-                                       select.find("option").each(function() {
-                                               if (this.hasAttribute("selected")) {
-                                                       addTag(this.getAttribute("value"), this.innerText);
-                                               }
-                                       });
+                       function recreate() {
+                               selector.find("span").remove();
+                               select.find("option").each(function() {
+                                       if (this.hasAttribute("selected")) {
+                                               addTag(this.getAttribute("value"), this.innerText);
+                                       }
+                               });
+                       }
+                       recreate();
+
+                       input.focusout(function(e) {
+                               var value = input.val().trim()
+                               if (value != "") {
+                                       show_error(input, "Please select an existing tag, it;s not possible to add custom ones.");
                                }
-                               recreate();
+                       })
 
-                               input.focusout(function(e) {
-                                       var value = input.val().trim()
-                                       if (value != "") {
-                                               show_error(input, "Please select an existing tag, it;s not possible to add custom ones.");
-                                       }
+                       input.keydown(function(e) {
+                                       if (e.keyCode === $.ui.keyCode.TAB && $(this).data('ui-autocomplete').menu.active)
+                                               e.preventDefault();
                                })
+                               .autocomplete({
+                                       minLength: 0,
+                                       source: source,
+                                       select: function(event, ui) {
+                                               addTag(ui.item.id, ui.item.toString());
+                                               input.val("");
+                                               return false;
+                                       }
+                               }).focus(function() {
+                                       // The following works only once.
+                                       // $(this).trigger('keydown.autocomplete');
+                                       // As suggested by digitalPBK, works multiple times
+                                       // $(this).data("autocomplete").search($(this).val());
+                                       // As noted by Jonny in his answer, with newer versions use uiAutocomplete
+                                       $(this).data("ui-autocomplete").search($(this).val());
+                               });
 
-                               input.keydown(function(e) {
-                                               if (e.keyCode === $.ui.keyCode.TAB && $(this).data('ui-autocomplete').menu.active)
-                                                       e.preventDefault();
-                                       })
-                                       .autocomplete({
-                                               minLength: 0,
-                                               source: source,
-                                               select: function(event, ui) {
-                                                       addTag(ui.item.id, ui.item.toString());
-                                                       input.val("");
-                                                       return false;
-                                               }
-                                       }).focus(function() {
-                                               // The following works only once.
-                                               // $(this).trigger('keydown.autocomplete');
-                                               // As suggested by digitalPBK, works multiple times
-                                               // $(this).data("autocomplete").search($(this).val());
-                                               // As noted by Jonny in his answer, with newer versions use uiAutocomplete
-                                               $(this).data("ui-autocomplete").search($(this).val());
-                                       });
-
-                               input.data('ui-autocomplete')._renderItem = function(ul, item) {
-                                               return $('<li/>')
-                                                       .data('item.autocomplete', item)
-                                                       .append($('<a/>').text(item.toString()))
-                                                       .appendTo(ul);
-                                       };
+                       input.data('ui-autocomplete')._renderItem = function(ul, item) {
+                                       return $('<li/>')
+                                               .data('item.autocomplete', item)
+                                               .append($('<a/>').text(item.toString()))
+                                               .appendTo(ul);
+                               };
 
-                               input.data('ui-autocomplete')._resizeMenu = function(ul, item) {
-                                               var ul = this.menu.element;
-                                               ul.outerWidth(Math.max(
-                                                       ul.width('').outerWidth(),
-                                                       selector.outerWidth()
-                                               ));
-                                       };
-                       });
+                       input.data('ui-autocomplete')._resizeMenu = function(ul, item) {
+                                       var ul = this.menu.element;
+                                       ul.outerWidth(Math.max(
+                                               ul.width('').outerWidth(),
+                                               selector.outerWidth()
+                                       ));
+                               };
+               });
        }
 
        $.fn.csvSelector = function(source, name, result, allowSlash) {
index 3f10ed4d6633b47d89419a46423fae681277b6e0..a9ce978b074127729da17204bdd088b8c055f8c6 100644 (file)
@@ -1,7 +1,7 @@
 .ui-autocomplete, ui-front {
        position:absolute;
        cursor:default;
-       z-index:1001 !important
+       z-index:1100 !important
 }
 
 .ui-autocomplete {
index e0b2308af89427807ebfb8a2520d451a512d428b..ff085cd4b1cc6270333bb55b6037e32e960901d7 100644 (file)
@@ -299,6 +299,8 @@ def makeVCSRelease(id, branch):
                release.approve(release.package.author)
                db.session.commit()
 
+               updateMetaFromRelease.delay(release.id, destPath)
+
                return release.url
        finally:
                shutil.rmtree(gitDir)
index b492ae95a20a2669b697fb5eeb8cc63b2193c162..67d83512a1793bb09e43dee44610e877a1ed9ff3 100644 (file)
@@ -7,7 +7,7 @@
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>{% block title %}title{% endblock %} - {{ config.USER_APP_NAME }}</title>
        <link rel="stylesheet" type="text/css" href="/static/bootstrap.css">
-       <link rel="stylesheet" type="text/css" href="/static/custom.css?v=12">
+       <link rel="stylesheet" type="text/css" href="/static/custom.css?v=13">
        <link rel="search" type="application/opensearchdescription+xml" href="/static/opensearch.xml" title="ContentDB" />
        <link rel="shortcut icon" href="/favicon-16.png" sizes="16x16">
        <link rel="icon" href="/favicon-128.png" sizes="128x128">
diff --git a/app/templates/todo/tags.html b/app/templates/todo/tags.html
new file mode 100644 (file)
index 0000000..e7675f8
--- /dev/null
@@ -0,0 +1,113 @@
+{% extends "base.html" %}
+
+{% block title %}
+       Tags
+{% endblock %}
+
+{% block content %}
+
+<style>
+       table {
+               width:auto;
+       }
+       td {
+               white-space:nowrap;
+       }
+       table td:last-child {
+               width: 100%;
+       }
+</style>
+
+<table class="table">
+       <tr>
+               <th>Package</th>
+               <th>Tags</th>
+       </tr>
+       {% for package in packages %}
+               <tr>
+                       <td>
+                               <a href="{{ package.getDetailsURL() }}">
+                                       {{ package.title }}
+                               </a>
+
+                               by {{ package.author.display_name }}
+                       </td>
+                       <td class="tags">
+                               {% for tag in package.tags %}
+                                       <span class="badge badge-primary mr-1">{{ tag.title }}</span>
+                               {% endfor %}
+                               <a class="badge badge-secondary add-btn px-2" href="#">
+                                       <i class="fas fa-plus"></i>
+                               </a>
+                       </td>
+               </tr>
+       {% endfor %}
+</table>
+
+<div class="modal">
+       <div class="modal-dialog" role="document">
+               <div class="modal-content">
+                       <div class="modal-header">
+                               <h5 class="modal-title">{{ _("Edit tags") }}</h5>
+                               <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                                       <span aria-hidden="true">&times;</span>
+                               </button>
+                       </div>
+                       <div class="modal-body">
+                               <select name="tags" multiple>
+                                       {% for tag in tags %}
+                                               <option value="{{ tag.name }}">{{ tag.title }}</option>
+                                       {% endfor %}
+                               </select>
+                       </div>
+                       <div class="modal-footer">
+                               <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
+                               <button type="button" class="btn btn-primary">Update</button>
+                       </div>
+               </div>
+       </div>
+</div>
+{% endblock %}
+
+{% from "macros/forms.html" import form_scripts %}
+
+{% block scriptextra %}
+{{ form_scripts() }}
+
+<script>
+       $(".add-btn").click(function() {
+               const row = $(this).parent().parent()
+
+               $(".modal select option").removeAttr("selected");
+               $(".multichoice_selector").remove();
+
+               $(".modal .modal-body").prepend(`
+                       <div class="multichoice_selector bulletselector form-control">
+                               <input type="text" placeholder="Start typing to see suggestions">
+                               <div class="clearboth"></div>
+                       </div>
+               `);
+
+               $(".modal").modal("show");
+               $(".modal input").focus();
+               $(".multichoice_selector").each(function() {
+                       var ele = $(this);
+                       var sel = ele.parent().find("select");
+                       sel.hide();
+
+                       var options = [];
+                       sel.find("option").each(function() {
+                               var text = $(this).text();
+                               options.push({
+                                       id: $(this).attr("value"),
+                                       value: text,
+                                       toString: function() { return text; },
+                               });
+                       });
+
+                       ele.selectSelector(options, sel);
+               });
+       });
+
+</script>
+{% endblock %}