-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Tag type creation and crud functions #7928
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
mekarpeles
merged 10 commits into
internetarchive:master
from
JaydenTeoh:feature/tags-crud
Jul 3, 2023
Merged
Changes from 2 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
83c3ec1
drying of Tag functions and fixing Tag schema
JaydenTeoh c94708b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] ca4668d
cleanup + fix querying
mekarpeles acfb1b8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] a31e3c1
remove addtag and add DDL for tags
JaydenTeoh 5f312f3
fixes Tag.create and Tag.find
mekarpeles 5f250a3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 22de00f
remove duplicate thing class registering
JaydenTeoh 19eb713
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 32c6aeb
+ schema add_seq
mekarpeles File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| { | ||
| "name": "Tag", | ||
| "key": "/type/tag", | ||
| "kind": "regular", | ||
| "created": { | ||
| "type": "/type/datetime", | ||
| "value": "2023-04-05T22:27:36.162339" | ||
| }, | ||
| "last_modified": { | ||
| "type": "/type/datetime", | ||
| "value": "2023-04-05T22:37:06.504291" | ||
| }, | ||
| "latest_revision": 3, | ||
| "type": { | ||
| "key": "/type/type" | ||
| }, | ||
| "properties": [ | ||
| { | ||
| "expected_type": { | ||
| "key": "/type/string", | ||
| }, | ||
| "name": "name", | ||
| "type": { | ||
| "key": "/type/property" | ||
| }, | ||
| "unique": true | ||
| }, | ||
| { | ||
| "expected_type": { | ||
| "key": "/type/string", | ||
| }, | ||
| "name": "tag_description", | ||
| "type": { | ||
| "key": "/type/property" | ||
| }, | ||
| "unique": true | ||
| }, | ||
| { | ||
| "expected_type": { | ||
| "key": "/type/string", | ||
| }, | ||
| "name": "tag_plugins", | ||
| "type": { | ||
| "key": "/type/property" | ||
| }, | ||
| "unique": true | ||
| }, | ||
| { | ||
| "expected_type": { | ||
| "key": "/type/string", | ||
| }, | ||
| "name": "tag_type", | ||
| "type": { | ||
| "key": "/type/property" | ||
| }, | ||
| "unique": true | ||
| }, | ||
| ], | ||
| "revision": 3 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| """Handlers for adding and editing tags.""" | ||
|
|
||
| import web | ||
| import json | ||
|
|
||
| from typing import NoReturn | ||
|
|
||
| from infogami.core.db import ValidationException | ||
| from infogami.infobase import common | ||
| from infogami.utils.view import add_flash_message, public | ||
| from infogami.infobase.client import ClientException | ||
| from infogami.utils import delegate | ||
|
|
||
| from openlibrary.plugins.openlibrary.processors import urlsafe | ||
| from openlibrary.i18n import gettext as _ | ||
| import logging | ||
|
|
||
| from openlibrary.plugins.upstream import spamcheck, utils | ||
| from openlibrary.plugins.upstream.models import Tag | ||
| from openlibrary.plugins.upstream.addbook import get_recaptcha, safe_seeother, trim_doc | ||
| from openlibrary.plugins.upstream.utils import render_template | ||
|
|
||
| logger = logging.getLogger("openlibrary.tag") | ||
|
|
||
|
|
||
| class addtag(delegate.page): | ||
| path = '/tag/add' | ||
|
|
||
| def GET(self): | ||
| """Main user interface for adding a tag to Open Library.""" | ||
|
|
||
| if not self.has_permission(): | ||
| raise common.PermissionDenied(message='Permission denied to add tags') | ||
|
|
||
| return render_template('tag/add', recaptcha=get_recaptcha()) | ||
|
|
||
| def has_permission(self) -> bool: | ||
| """ | ||
| Can a tag be added? | ||
| """ | ||
| return web.ctx.user and ( | ||
| web.ctx.user.is_usergroup_member('/usergroup/super-librarians') | ||
| ) | ||
|
|
||
| def POST(self): | ||
| i = web.input( | ||
| tag_name="", | ||
| tag_type="", | ||
| tag_description="", | ||
| tag_plugins="", | ||
| ) | ||
|
|
||
| if spamcheck.is_spam(i, allow_privileged_edits=True): | ||
| return render_template( | ||
| "message.html", "Oops", 'Something went wrong. Please try again later.' | ||
| ) | ||
|
|
||
| if not web.ctx.site.get_user(): | ||
| recap = get_recaptcha() | ||
| if recap and not recap.validate(): | ||
| return render_template( | ||
| 'message.html', | ||
| 'Recaptcha solution was incorrect', | ||
| 'Please <a href="javascript:history.back()">go back</a> and try again.', | ||
| ) | ||
|
|
||
| i = utils.unflatten(i) | ||
| match = self.find_match(i) # returns None or Tag (if match found) | ||
|
|
||
| return self.tag_match(match) if match else self.no_match(i) | ||
|
|
||
| def find_match(self, i: web.utils.Storage): | ||
| """ | ||
| Tries to find an existing tag that matches the data provided by the user. | ||
| """ | ||
|
|
||
| return Tag.get_tag(i.tag_name, i.tag_type) | ||
|
|
||
| def tag_match(self, match: list) -> NoReturn: | ||
| """ | ||
| Action for when an existing tag has been found. | ||
| Redirect user to the found tag's edit page to add any missing details. | ||
| """ | ||
| tag = web.ctx.site.get(match) | ||
| raise safe_seeother(tag.key + "/edit") | ||
|
|
||
| def no_match(self, i: web.utils.Storage) -> NoReturn: | ||
| """ | ||
| Action to take when no tags are found. | ||
| Creates a new Tag. | ||
| Redirects the user to the tag's home page | ||
| """ | ||
| key = Tag.create_tag(i.tag_name, i.tag_description, i.tag_type, i.tag_plugins) | ||
| raise safe_seeother(key) | ||
|
|
||
|
|
||
| class tag_edit(delegate.page): | ||
| path = r"(/tags/OL\d+T)/edit" | ||
|
|
||
| def GET(self, key): | ||
| if not web.ctx.site.can_write(key): | ||
| return render_template( | ||
| "permission_denied", | ||
| web.ctx.fullpath, | ||
| "Permission denied to edit " + key + ".", | ||
| ) | ||
|
|
||
| tag = web.ctx.site.get(key) | ||
| if tag is None: | ||
| raise web.notfound() | ||
|
|
||
| return render_template('type/tag/edit', tag) | ||
|
|
||
| def POST(self, key): | ||
| tag = web.ctx.site.get(key) | ||
| if tag is None: | ||
| raise web.notfound() | ||
|
|
||
| i = web.input(_comment=None) | ||
| formdata = self.process_input(i) | ||
| try: | ||
| if not formdata: | ||
| raise web.badrequest() | ||
| elif "_delete" in i: | ||
| tag = web.ctx.site.new( | ||
| key, {"key": key, "type": {"key": "/type/delete"}} | ||
| ) | ||
| tag._save(comment=i._comment) | ||
| raise safe_seeother(key) | ||
| else: | ||
| tag.update(formdata) | ||
| tag._save(comment=i._comment) | ||
| raise safe_seeother(key) | ||
| except (ClientException, ValidationException) as e: | ||
| add_flash_message('error', str(e)) | ||
| return render_template("type/tag/edit", tag) | ||
|
|
||
| def process_input(self, i): | ||
| i = utils.unflatten(i) | ||
| if i.tag_plugins: | ||
| i.tag_plugins = json.loads(i.tag_plugins) | ||
| tag = trim_doc(i) | ||
| return tag | ||
|
|
||
|
|
||
| def setup(): | ||
| """Do required setup.""" | ||
| pass |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.