Integrate tags with api.js and improve sanity of tag endpoints.
This commit is contained in:
		
							parent
							
								
									af318414e2
								
							
						
					
					
						commit
						8cfa88e45d
					
				
					 3 changed files with 151 additions and 70 deletions
				
			
		|  | @ -46,6 +46,28 @@ def post_tag_edit(specific_tag): | ||||||
|     response = jsonify.make_json_response(response) |     response = jsonify.make_json_response(response) | ||||||
|     return response |     return response | ||||||
| 
 | 
 | ||||||
|  | @site.route('/tag/<tagname>/add_child', methods=['POST']) | ||||||
|  | @decorators.catch_etiquette_exception | ||||||
|  | @session_manager.give_token | ||||||
|  | @decorators.required_fields(['child_name'], forbid_whitespace=True) | ||||||
|  | def post_tag_add_child(tagname): | ||||||
|  |     parent = common.P_tag(tagname) | ||||||
|  |     child = common.P_tag(request.form['child_name']) | ||||||
|  |     parent.add_child(child) | ||||||
|  |     response = {'action': 'add_child', 'tagname': f'{parent.name}.{child.name}'} | ||||||
|  |     return jsonify.make_json_response(response) | ||||||
|  | 
 | ||||||
|  | @site.route('/tag/<tagname>/remove_child', methods=['POST']) | ||||||
|  | @decorators.catch_etiquette_exception | ||||||
|  | @session_manager.give_token | ||||||
|  | @decorators.required_fields(['child_name'], forbid_whitespace=True) | ||||||
|  | def post_tag_remove_child(tagname): | ||||||
|  |     parent = common.P_tag(tagname) | ||||||
|  |     child = common.P_tag(request.form['child_name']) | ||||||
|  |     parent.remove_child(child) | ||||||
|  |     response = {'action': 'remove_child', 'tagname': f'{parent.name}.{child.name}'} | ||||||
|  |     return jsonify.make_json_response(response) | ||||||
|  | 
 | ||||||
| # Tag listings ##################################################################################### | # Tag listings ##################################################################################### | ||||||
| 
 | 
 | ||||||
| @site.route('/all_tags.json') | @site.route('/all_tags.json') | ||||||
|  | @ -115,47 +137,44 @@ def get_tags_json(specific_tag_name=None): | ||||||
| @site.route('/tags/create_tag', methods=['POST']) | @site.route('/tags/create_tag', methods=['POST']) | ||||||
| @decorators.catch_etiquette_exception | @decorators.catch_etiquette_exception | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| @decorators.required_fields(['tagname'], forbid_whitespace=True) | @decorators.required_fields(['name'], forbid_whitespace=True) | ||||||
| def post_tag_create(): | def post_tag_create(): | ||||||
|     easybake_string = request.form['tagname'] |     name = request.form['name'] | ||||||
|     user = session_manager.get(request).user |     description = request.form.get('description', None) | ||||||
|     notes = common.P.easybake(easybake_string, author=user) | 
 | ||||||
|  |     tag = P.new_tag(name, description, author=session_manager.get(request).user) | ||||||
|  |     response = etiquette.jsonify.tag(tag) | ||||||
|  |     return jsonify.make_json_response(response) | ||||||
|  | 
 | ||||||
|  | @site.route('/tags/easybake', methods=['POST']) | ||||||
|  | @decorators.catch_etiquette_exception | ||||||
|  | @session_manager.give_token | ||||||
|  | @decorators.required_fields(['easybake_string'], forbid_whitespace=True) | ||||||
|  | def post_tag_easybake(): | ||||||
|  |     easybake_string = request.form['easybake_string'] | ||||||
|  | 
 | ||||||
|  |     notes = common.P.easybake(easybake_string, author=session_manager.get(request).user) | ||||||
|     notes = [{'action': action, 'tagname': tagname} for (action, tagname) in notes] |     notes = [{'action': action, 'tagname': tagname} for (action, tagname) in notes] | ||||||
|     return jsonify.make_json_response(notes) |     return jsonify.make_json_response(notes) | ||||||
| 
 | 
 | ||||||
| @site.route('/tags/delete_synonym', methods=['POST']) | @site.route('/tag/<tagname>/delete', methods=['POST']) | ||||||
| @decorators.catch_etiquette_exception | @decorators.catch_etiquette_exception | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| @decorators.required_fields(['tagname'], forbid_whitespace=True) | def post_tag_delete(tagname): | ||||||
| def post_tag_delete_synonym(): |     tag = common.P_tag(tagname) | ||||||
|     synonym = request.form['tagname'] |     tag.delete() | ||||||
|     synonym = synonym.split('+')[-1].split('.')[-1] |     response = {'action': 'delete_tag', 'tagname': tag.name} | ||||||
| 
 |  | ||||||
|     try: |  | ||||||
|         master_tag = common.P.get_tag(name=synonym) |  | ||||||
|     except etiquette.exceptions.NoSuchTag as exc: |  | ||||||
|         raise etiquette.exceptions.NoSuchSynonym(*exc.given_args, **exc.given_kwargs) |  | ||||||
|     else: |  | ||||||
|         master_tag.remove_synonym(synonym) |  | ||||||
| 
 |  | ||||||
|     response = {'action':'delete_synonym', 'synonym': synonym} |  | ||||||
|     return jsonify.make_json_response(response) |     return jsonify.make_json_response(response) | ||||||
| 
 | 
 | ||||||
| @site.route('/tags/delete_tag', methods=['POST']) | @site.route('/tag/<tagname>/remove_synonym', methods=['POST']) | ||||||
| @decorators.catch_etiquette_exception | @decorators.catch_etiquette_exception | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| @decorators.required_fields(['tagname'], forbid_whitespace=True) | @decorators.required_fields(['syn_name'], forbid_whitespace=True) | ||||||
| def post_tag_delete(): | def post_tag_remove_synonym(tagname): | ||||||
|     tagname = request.form['tagname'] |     syn_name = request.form['syn_name'] | ||||||
|     tagname = tagname.split('+')[0] | 
 | ||||||
|     if '.' in tagname: |     master_tag = common.P_tag(tagname) | ||||||
|         (parentname, tagname) = tagname.rsplit('.', 1) |     master_tag.remove_synonym(syn_name) | ||||||
|         parent = common.P.get_tag(name=parentname) | 
 | ||||||
|         tag = common.P.get_tag(name=tagname) |     response = {'action':'delete_synonym', 'synonym': syn_name} | ||||||
|         parent.remove_child(tag) |  | ||||||
|         response = {'action': 'unlink_tag', 'tagname': f'{parent.name}.{tag.name}'} |  | ||||||
|     else: |  | ||||||
|         tag = common.P.get_tag(name=tagname) |  | ||||||
|         tag.delete() |  | ||||||
|         response = {'action': 'delete_tag', 'tagname': tag.name} |  | ||||||
|     return jsonify.make_json_response(response) |     return jsonify.make_json_response(response) | ||||||
|  |  | ||||||
|  | @ -177,5 +177,69 @@ function remove_tag(photo_id, tagname, callback) | ||||||
| /**************************************************************************************************/ | /**************************************************************************************************/ | ||||||
| api.tags = {}; | api.tags = {}; | ||||||
| 
 | 
 | ||||||
|  | api.tags.add_child = | ||||||
|  | function add_child(tag_name, child_name, callback) | ||||||
|  | { | ||||||
|  |     var url = `/tag/${tag_name}/add_child`; | ||||||
|  |     var data = new FormData(); | ||||||
|  |     data.append("child_name", child_name); | ||||||
|  |     common.post(url, data, callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | api.tags.create = | ||||||
|  | function create(name, description, callback) | ||||||
|  | { | ||||||
|  |     var url = `/tags/create_tag`; | ||||||
|  |     var data = new FormData(); | ||||||
|  |     data.append("name", name); | ||||||
|  |     data.append("description", description); | ||||||
|  |     common.post(url, data, callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | api.tags.delete = | ||||||
|  | function _delete(tag_name, callback) | ||||||
|  | { | ||||||
|  |     var url = `/tag/${tag_name}/delete`; | ||||||
|  |     common.post(url, null, callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | api.tags.easybake = | ||||||
|  | function easybake(easybake_string, callback) | ||||||
|  | { | ||||||
|  |     var url = "/tags/easybake"; | ||||||
|  |     var data = new FormData(); | ||||||
|  |     data.append("easybake_string", easybake_string); | ||||||
|  |     common.post(url, data, callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | api.tags.edit = | ||||||
|  | function edit(tag_name, name, description, callback) | ||||||
|  | { | ||||||
|  |     var url = `/tag/${tag_name}/edit`; | ||||||
|  |     var data = new FormData(); | ||||||
|  |     data.append("name", name); | ||||||
|  |     data.append("description", description); | ||||||
|  |     common.post(url, data, callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | api.tags.remove_child = | ||||||
|  | function remove_child(tag_name, child_name, callback) | ||||||
|  | { | ||||||
|  |     var url = `/tag/${tag_name}/remove_child`; | ||||||
|  |     var data = new FormData(); | ||||||
|  |     data.append("child_name", child_name); | ||||||
|  |     common.post(url, data, callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | api.tags.remove_synonym = | ||||||
|  | function remove_synonym(tag_name, syn_name, callback) | ||||||
|  | { | ||||||
|  |     var url = `/tag/${tag_name}/remove_synonym`; | ||||||
|  |     var data = new FormData(); | ||||||
|  |     data.append("syn_name", syn_name); | ||||||
|  |     common.post(url, data, callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /**************************************************************************************************/ | /**************************************************************************************************/ | ||||||
| api.users = {}; | api.users = {}; | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"/> |     <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | ||||||
|     <link rel="stylesheet" href="/static/css/common.css"> |     <link rel="stylesheet" href="/static/css/common.css"> | ||||||
|     <script src="/static/js/common.js"></script> |     <script src="/static/js/common.js"></script> | ||||||
|  |     <script src="/static/js/api.js"></script> | ||||||
|     <script src="/static/js/editor.js"></script> |     <script src="/static/js/editor.js"></script> | ||||||
| 
 | 
 | ||||||
| <style> | <style> | ||||||
|  | @ -143,13 +144,13 @@ | ||||||
|                     {{tag_object.tag_object(tag, link='search', innertext=qualified_name, with_alt_description=True)-}} |                     {{tag_object.tag_object(tag, link='search', innertext=qualified_name, with_alt_description=True)-}} | ||||||
|                     <button |                     <button | ||||||
|                     class="remove_tag_button red_button button_with_confirm" |                     class="remove_tag_button red_button button_with_confirm" | ||||||
|                     data-onclick="delete_tag('{{qualified_name}}', receive_callback);" |                     data-onclick="remove_child_form('{{qualified_name.split('.')[-2]}}', '{{tag.name}}');" | ||||||
|                     data-prompt="Unlink Tags?" |                     data-prompt="Unlink Tags?" | ||||||
|                     data-confirm="Unlink" |                     data-confirm="Unlink" | ||||||
|                     data-confirm-class="remove_tag_button_perm red_button" |                     data-confirm-class="remove_tag_button_perm red_button" | ||||||
|                     data-cancel-class="remove_tag_button_perm gray_button" |                     data-cancel-class="remove_tag_button_perm gray_button" | ||||||
|                     > |                     > | ||||||
|                     unlink |                     Unlink | ||||||
|                     </button> |                     </button> | ||||||
|                 </li> |                 </li> | ||||||
|                 {% else %} |                 {% else %} | ||||||
|  | @ -158,13 +159,13 @@ | ||||||
|                     {{tag_object.tag_object(tag, link='search', innertext=qualified_name, with_alt_description=True)-}} |                     {{tag_object.tag_object(tag, link='search', innertext=qualified_name, with_alt_description=True)-}} | ||||||
|                     <button |                     <button | ||||||
|                     class="remove_tag_button red_button button_with_confirm" |                     class="remove_tag_button red_button button_with_confirm" | ||||||
|                     data-onclick="delete_tag('{{qualified_name}}', receive_callback);" |                     data-onclick="delete_tag_form('{{qualified_name}}');" | ||||||
|                     data-prompt="Delete Tag?" |                     data-prompt="Delete Tag?" | ||||||
|                     data-confirm="Delete" |                     data-confirm="Delete" | ||||||
|                     data-confirm-class="remove_tag_button_perm red_button" |                     data-confirm-class="remove_tag_button_perm red_button" | ||||||
|                     data-cancel-class="remove_tag_button_perm gray_button" |                     data-cancel-class="remove_tag_button_perm gray_button" | ||||||
|                     > |                     > | ||||||
|                     delete |                     Delete | ||||||
|                     </button> |                     </button> | ||||||
|                 </li> |                 </li> | ||||||
|                 {% endif %} |                 {% endif %} | ||||||
|  | @ -176,13 +177,13 @@ | ||||||
|                     {{tag_object.tag_object(tag, link='search', innertext=qualified_name + '+' + synonym)-}} |                     {{tag_object.tag_object(tag, link='search', innertext=qualified_name + '+' + synonym)-}} | ||||||
|                     <button |                     <button | ||||||
|                     class="remove_tag_button red_button button_with_confirm" |                     class="remove_tag_button red_button button_with_confirm" | ||||||
|                     data-onclick="delete_tag_synonym('{{synonym}}', receive_callback);" |                     data-onclick="remove_synonym_form('{{tag.name}}', '{{synonym}}');" | ||||||
|                     data-prompt="Remove Synonym?" |                     data-prompt="Remove Synonym?" | ||||||
|                     data-confirm="Remove" |                     data-confirm="Remove" | ||||||
|                     data-confirm-class="remove_tag_button_perm red_button" |                     data-confirm-class="remove_tag_button_perm red_button" | ||||||
|                     data-cancel-class="remove_tag_button_perm gray_button" |                     data-cancel-class="remove_tag_button_perm gray_button" | ||||||
|                     > |                     > | ||||||
|                     remove |                     Remove | ||||||
|                     </button> |                     </button> | ||||||
|                 </li> |                 </li> | ||||||
|                 {% endfor %} |                 {% endfor %} | ||||||
|  | @ -193,7 +194,7 @@ | ||||||
|     <div id="right"> |     <div id="right"> | ||||||
|         <div id="editor_area"> |         <div id="editor_area"> | ||||||
|             <input type="text" id="add_tag_textbox" autofocus> |             <input type="text" id="add_tag_textbox" autofocus> | ||||||
|             <button class="add_tag_button green_button" id="add_tag_button" onclick="submit_tag(receive_callback);">add</button> |             <button class="add_tag_button green_button" id="add_tag_button" onclick="easybake_form();">add</button> | ||||||
|         </div> |         </div> | ||||||
|         <div id="message_area"> |         <div id="message_area"> | ||||||
|         </div> |         </div> | ||||||
|  | @ -209,30 +210,27 @@ var message_area = document.getElementById('message_area'); | ||||||
| box.addEventListener("keyup", common.entry_with_history_hook); | box.addEventListener("keyup", common.entry_with_history_hook); | ||||||
| common.bind_box_to_button(box, button, false); | common.bind_box_to_button(box, button, false); | ||||||
| 
 | 
 | ||||||
| function submit_tag(callback) | function delete_tag_form(tag_name) | ||||||
| { | { | ||||||
|     create_tag(box.value, callback); |     api.tags.delete(tag_name, receive_callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function easybake_form() | ||||||
|  | { | ||||||
|  |     var box = document.getElementById('add_tag_textbox'); | ||||||
|  |     var easybake_string = box.value; | ||||||
|  |     api.tags.easybake(easybake_string, receive_callback); | ||||||
|     box.value = ""; |     box.value = ""; | ||||||
| } | } | ||||||
| function edit_tags(action, tagname, callback) | 
 | ||||||
|  | function remove_child_form(tag_name, child_name) | ||||||
| { | { | ||||||
|     if (tagname === ""){return} |     api.tags.remove_child(tag_name, child_name, receive_callback); | ||||||
|     var url = "/tags/" + action; |  | ||||||
|     data = new FormData(); |  | ||||||
|     data.append("tagname", tagname); |  | ||||||
|     return common.post(url, data, callback); |  | ||||||
| } | } | ||||||
| function delete_tag_synonym(tagname, callback) | 
 | ||||||
|  | function remove_synonym_form(tag_name, syn_name) | ||||||
| { | { | ||||||
|     return edit_tags("delete_synonym", tagname, callback); |     api.tags.remove_synonym(tag_name, syn_name, receive_callback); | ||||||
| } |  | ||||||
| function delete_tag(tagname, callback) |  | ||||||
| { |  | ||||||
|     return edit_tags("delete_tag", tagname, callback); |  | ||||||
| } |  | ||||||
| function create_tag(tagname, callback) |  | ||||||
| { |  | ||||||
|     return edit_tags("create_tag", tagname, callback); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function receive_callback(response) | function receive_callback(response) | ||||||
|  | @ -278,7 +276,7 @@ function receive_callback(response) | ||||||
|             else if (action == "delete_synonym") |             else if (action == "delete_synonym") | ||||||
|             {message_text = `Deleted synonym ${response["synonym"]}`;} |             {message_text = `Deleted synonym ${response["synonym"]}`;} | ||||||
| 
 | 
 | ||||||
|             else if (action == "unlink_tag") |             else if (action == "remove_child") | ||||||
|             {message_text = `Unlinked tags ${tagname}`;} |             {message_text = `Unlinked tags ${tagname}`;} | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
|  | @ -295,12 +293,6 @@ function on_open(ed, edit_element_map) | ||||||
| 
 | 
 | ||||||
| function on_save(ed, edit_element_map, display_element_map) | function on_save(ed, edit_element_map, display_element_map) | ||||||
| { | { | ||||||
|     var name_display = display_element_map["name"]; |  | ||||||
|     var name_editor = edit_element_map["name"]; |  | ||||||
|     var description_display = display_element_map["description"]; |  | ||||||
|     var description_editor = edit_element_map["description"]; |  | ||||||
| 
 |  | ||||||
|     ed.show_spinner(); |  | ||||||
|     function callback(response) |     function callback(response) | ||||||
|     { |     { | ||||||
|         console.log(response); |         console.log(response); | ||||||
|  | @ -321,11 +313,17 @@ function on_save(ed, edit_element_map, display_element_map) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     var url = "/tag/" + name_display.innerText + "/edit"; |     var name_display = display_element_map["name"]; | ||||||
|     var data = new FormData(); |     var name_editor = edit_element_map["name"]; | ||||||
|     data.append("name", name_editor.value); |     var description_display = display_element_map["description"]; | ||||||
|     data.append("description", description_editor.value); |     var description_editor = edit_element_map["description"]; | ||||||
|     common.post(url, data, callback); | 
 | ||||||
|  |     var tag_name = name_display.innerText; | ||||||
|  |     var name = name_editor.value; | ||||||
|  |     var description = description_editor.value; | ||||||
|  | 
 | ||||||
|  |     ed.show_spinner(); | ||||||
|  |     api.tags.edit(tag_name, name, description, callback) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function on_cancel(ed, edit_element_map, display_element_map) | function on_cancel(ed, edit_element_map, display_element_map) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue