From 83c3ec1c0286cca93acf8d7728bfa3244031b8eb Mon Sep 17 00:00:00 2001 From: Jayden Teoh Date: Sat, 3 Jun 2023 15:07:55 +0800 Subject: [PATCH 01/10] drying of Tag functions and fixing Tag schema --- openlibrary/core/models.py | 38 +++++ openlibrary/core/schema.py | 2 + .../plugins/openlibrary/types/tag.type | 60 +++++++ openlibrary/plugins/upstream/addtag.py | 146 ++++++++++++++++++ openlibrary/plugins/upstream/code.py | 3 +- openlibrary/plugins/upstream/models.py | 7 + 6 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 openlibrary/plugins/openlibrary/types/tag.type create mode 100644 openlibrary/plugins/upstream/addtag.py diff --git a/openlibrary/core/models.py b/openlibrary/core/models.py index de72ec8b4b5..9092770b181 100644 --- a/openlibrary/core/models.py +++ b/openlibrary/core/models.py @@ -3,6 +3,7 @@ from datetime import datetime, timedelta import logging import web +import json import requests from typing import Any from collections import defaultdict @@ -1116,6 +1117,41 @@ def get_default_cover(self): return Image(web.ctx.site, "b", cover_id) +# TODO: expand on tag model +class Tag(Thing): + """Class to represent /type/tag objects in OL.""" + @classmethod + def get_tag(cls, tag_name, tag_type): + """Returns a Tag object for a given tag name and tag type.""" + q = {'type': '/type/tag', 'name': tag_name, 'tag_type': tag_type} + match = list(web.ctx.site.things(q)) + return match[0] if match else None + + @classmethod + def create_tag(cls, tag_name, tag_description, tag_type, tag_plugins): + """Creates a new Tag object.""" + key = web.ctx.site.new_key('/type/tag') + web.ctx.path = key + web.ctx.site.save( + { + 'key': key, + 'name': tag_name, + 'tag_description': tag_description, + 'tag_type': tag_type, + 'tag_plugins': json.loads(tag_plugins or "[]"), + 'type': dict(key='/type/tag'), + }, + comment='New Tag', + ) + return key + + def url(self, suffix="", **params): + return self.get_url(suffix, **params) + + def get_url_suffix(self): + return self.name or "unnamed" + + @dataclass class LoggedBooksData: """ @@ -1164,6 +1200,7 @@ def register_models(): client.register_thing_class('/type/user', User) client.register_thing_class('/type/list', List) client.register_thing_class('/type/usergroup', UserGroup) + client.register_thing_class('/type/tag', Tag) def register_types(): @@ -1174,6 +1211,7 @@ def register_types(): types.register_type('^/books/[^/]*$', '/type/edition') types.register_type('^/works/[^/]*$', '/type/work') types.register_type('^/languages/[^/]*$', '/type/language') + types.register_type('^/tags/[^/]*$', '/type/tag') types.register_type('^/usergroup/[^/]*$', '/type/usergroup') types.register_type('^/permission/[^/]*$', '/type/permission') diff --git a/openlibrary/core/schema.py b/openlibrary/core/schema.py index 51cc2804f2a..c15de883b8a 100644 --- a/openlibrary/core/schema.py +++ b/openlibrary/core/schema.py @@ -23,12 +23,14 @@ def get_schema(): schema.add_table_group('work', '/type/work', datatypes) schema.add_table_group('publisher', '/type/publisher', datatypes) schema.add_table_group('subject', '/type/subject', datatypes) + schema.add_table_group('tag', '/type/tag', datatypes) schema.add_seq('/type/edition', '/books/OL%dM') schema.add_seq('/type/author', '/authors/OL%dA') schema.add_seq('/type/work', '/works/OL%dW') schema.add_seq('/type/publisher', '/publishers/OL%dP') + schema.add_seq('/type/tag', '/tags/OL%dT') _sql = schema.sql diff --git a/openlibrary/plugins/openlibrary/types/tag.type b/openlibrary/plugins/openlibrary/types/tag.type new file mode 100644 index 00000000000..55861451979 --- /dev/null +++ b/openlibrary/plugins/openlibrary/types/tag.type @@ -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 +} diff --git a/openlibrary/plugins/upstream/addtag.py b/openlibrary/plugins/upstream/addtag.py new file mode 100644 index 00000000000..c756a023dd2 --- /dev/null +++ b/openlibrary/plugins/upstream/addtag.py @@ -0,0 +1,146 @@ +"""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 go back 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 diff --git a/openlibrary/plugins/upstream/code.py b/openlibrary/plugins/upstream/code.py index 0f7d9665620..ff58da2bca0 100644 --- a/openlibrary/plugins/upstream/code.py +++ b/openlibrary/plugins/upstream/code.py @@ -22,7 +22,7 @@ from openlibrary import accounts -from openlibrary.plugins.upstream import addbook, covers, models, utils +from openlibrary.plugins.upstream import addbook, addtag, covers, models, utils from openlibrary.plugins.upstream import spamcheck from openlibrary.plugins.upstream import merge_authors from openlibrary.plugins.upstream import edits @@ -384,6 +384,7 @@ def setup(): models.setup() utils.setup() addbook.setup() + addtag.setup() covers.setup() merge_authors.setup() # merge_works.setup() # ILE code diff --git a/openlibrary/plugins/upstream/models.py b/openlibrary/plugins/upstream/models.py index 3f7827f99f7..a9f893546e2 100644 --- a/openlibrary/plugins/upstream/models.py +++ b/openlibrary/plugins/upstream/models.py @@ -1007,6 +1007,12 @@ def get_seed(self, seed): return models.Seed(self.get_list(), seed) +class Tag(models.Tag): + """Class to represent /type/tag objects in Open Library.""" + + pass + + def setup(): models.register_models() @@ -1018,6 +1024,7 @@ def setup(): client.register_thing_class('/type/place', SubjectPlace) client.register_thing_class('/type/person', SubjectPerson) client.register_thing_class('/type/user', User) + client.register_thing_class('/type/tag', Tag) client.register_changeset_class(None, Changeset) # set the default class client.register_changeset_class('merge-authors', MergeAuthors) From c94708be83932e306fb3f294d50dde3b036c88c1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 3 Jun 2023 07:12:41 +0000 Subject: [PATCH 02/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- openlibrary/core/models.py | 3 ++- openlibrary/plugins/upstream/addtag.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/openlibrary/core/models.py b/openlibrary/core/models.py index 9092770b181..69a5719b0c8 100644 --- a/openlibrary/core/models.py +++ b/openlibrary/core/models.py @@ -1120,13 +1120,14 @@ def get_default_cover(self): # TODO: expand on tag model class Tag(Thing): """Class to represent /type/tag objects in OL.""" + @classmethod def get_tag(cls, tag_name, tag_type): """Returns a Tag object for a given tag name and tag type.""" q = {'type': '/type/tag', 'name': tag_name, 'tag_type': tag_type} match = list(web.ctx.site.things(q)) return match[0] if match else None - + @classmethod def create_tag(cls, tag_name, tag_description, tag_type, tag_plugins): """Creates a new Tag object.""" diff --git a/openlibrary/plugins/upstream/addtag.py b/openlibrary/plugins/upstream/addtag.py index c756a023dd2..32ca5afaa4c 100644 --- a/openlibrary/plugins/upstream/addtag.py +++ b/openlibrary/plugins/upstream/addtag.py @@ -93,6 +93,7 @@ def no_match(self, i: web.utils.Storage) -> NoReturn: 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" @@ -141,6 +142,7 @@ def process_input(self, i): tag = trim_doc(i) return tag + def setup(): """Do required setup.""" pass From ca4668d56c0dc819d28fb365cfdb51b99f29788e Mon Sep 17 00:00:00 2001 From: Mek Date: Wed, 7 Jun 2023 11:02:50 -0400 Subject: [PATCH 03/10] cleanup + fix querying --- openlibrary/core/models.py | 5 ++--- openlibrary/core/schema.py | 4 ++-- openlibrary/plugins/openlibrary/types/tag.type | 1 + openlibrary/plugins/upstream/addtag.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openlibrary/core/models.py b/openlibrary/core/models.py index 69a5719b0c8..f220b16c75e 100644 --- a/openlibrary/core/models.py +++ b/openlibrary/core/models.py @@ -1117,19 +1117,18 @@ def get_default_cover(self): return Image(web.ctx.site, "b", cover_id) -# TODO: expand on tag model class Tag(Thing): """Class to represent /type/tag objects in OL.""" @classmethod - def get_tag(cls, tag_name, tag_type): + def get(cls, tag_name, tag_type): """Returns a Tag object for a given tag name and tag type.""" q = {'type': '/type/tag', 'name': tag_name, 'tag_type': tag_type} match = list(web.ctx.site.things(q)) return match[0] if match else None @classmethod - def create_tag(cls, tag_name, tag_description, tag_type, tag_plugins): + def create(cls, tag_name, tag_description, tag_type, tag_plugins): """Creates a new Tag object.""" key = web.ctx.site.new_key('/type/tag') web.ctx.path = key diff --git a/openlibrary/core/schema.py b/openlibrary/core/schema.py index c15de883b8a..0079b95508e 100644 --- a/openlibrary/core/schema.py +++ b/openlibrary/core/schema.py @@ -23,14 +23,14 @@ def get_schema(): schema.add_table_group('work', '/type/work', datatypes) schema.add_table_group('publisher', '/type/publisher', datatypes) schema.add_table_group('subject', '/type/subject', datatypes) - schema.add_table_group('tag', '/type/tag', datatypes) + #schema.add_table_group('tag', '/type/tag', datatypes) schema.add_seq('/type/edition', '/books/OL%dM') schema.add_seq('/type/author', '/authors/OL%dA') schema.add_seq('/type/work', '/works/OL%dW') schema.add_seq('/type/publisher', '/publishers/OL%dP') - schema.add_seq('/type/tag', '/tags/OL%dT') + #schema.add_seq('/type/tag', '/tags/OL%dT') _sql = schema.sql diff --git a/openlibrary/plugins/openlibrary/types/tag.type b/openlibrary/plugins/openlibrary/types/tag.type index 55861451979..ccd6c52da00 100644 --- a/openlibrary/plugins/openlibrary/types/tag.type +++ b/openlibrary/plugins/openlibrary/types/tag.type @@ -1,6 +1,7 @@ { "name": "Tag", "key": "/type/tag", + "id": 121411342, "kind": "regular", "created": { "type": "/type/datetime", diff --git a/openlibrary/plugins/upstream/addtag.py b/openlibrary/plugins/upstream/addtag.py index 32ca5afaa4c..a9b33747346 100644 --- a/openlibrary/plugins/upstream/addtag.py +++ b/openlibrary/plugins/upstream/addtag.py @@ -74,7 +74,7 @@ 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) + return Tag.get(i.tag_name, i.tag_type) def tag_match(self, match: list) -> NoReturn: """ @@ -90,7 +90,7 @@ def no_match(self, i: web.utils.Storage) -> NoReturn: 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) + key = Tag.create(i.tag_name, i.tag_description, i.tag_type, i.tag_plugins) raise safe_seeother(key) From acfb1b83eec135162a7beb0a28dcec6051dc6fe1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 7 Jun 2023 15:03:30 +0000 Subject: [PATCH 04/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- openlibrary/core/schema.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlibrary/core/schema.py b/openlibrary/core/schema.py index 0079b95508e..88e337dc7b2 100644 --- a/openlibrary/core/schema.py +++ b/openlibrary/core/schema.py @@ -23,14 +23,14 @@ def get_schema(): schema.add_table_group('work', '/type/work', datatypes) schema.add_table_group('publisher', '/type/publisher', datatypes) schema.add_table_group('subject', '/type/subject', datatypes) - #schema.add_table_group('tag', '/type/tag', datatypes) + # schema.add_table_group('tag', '/type/tag', datatypes) schema.add_seq('/type/edition', '/books/OL%dM') schema.add_seq('/type/author', '/authors/OL%dA') schema.add_seq('/type/work', '/works/OL%dW') schema.add_seq('/type/publisher', '/publishers/OL%dP') - #schema.add_seq('/type/tag', '/tags/OL%dT') + # schema.add_seq('/type/tag', '/tags/OL%dT') _sql = schema.sql From a31e3c1a7d61eb720b0e483100f977a9026afa2c Mon Sep 17 00:00:00 2001 From: Jayden Teoh Date: Fri, 9 Jun 2023 21:47:58 +0800 Subject: [PATCH 05/10] remove addtag and add DDL for tags --- openlibrary/core/infobase_schema.sql | 38 +++++++ openlibrary/plugins/upstream/addtag.py | 148 ------------------------- openlibrary/plugins/upstream/code.py | 3 +- 3 files changed, 39 insertions(+), 150 deletions(-) delete mode 100644 openlibrary/plugins/upstream/addtag.py diff --git a/openlibrary/core/infobase_schema.sql b/openlibrary/core/infobase_schema.sql index 7fefeb0c15e..0830663e982 100644 --- a/openlibrary/core/infobase_schema.sql +++ b/openlibrary/core/infobase_schema.sql @@ -401,6 +401,42 @@ create table work_str ( create index work_str_idx ON work_str(key_id, value); create index work_str_thing_id_idx ON work_str(thing_id); +create table tag_boolean ( + thing_id int references thing, + key_id int references property, + value boolean, + ordering int default NULL +); +create index tag_boolean_idx ON tag_boolean(key_id, value); +create index tag_boolean_thing_id_idx ON tag_boolean(thing_id); + +create table tag_int ( + thing_id int references thing, + key_id int references property, + value int, + ordering int default NULL +); +create index tag_int_idx ON tag_int(key_id, value); +create index tag_int_thing_id_idx ON tag_int(thing_id); + +create table tag_ref ( + thing_id int references thing, + key_id int references property, + value int references thing, + ordering int default NULL +); +create index tag_ref_idx ON tag_ref(key_id, value); +create index tag_ref_thing_id_idx ON tag_ref(thing_id); + +create table tag_str ( + thing_id int references thing, + key_id int references property, + value varchar(2048), + ordering int default NULL +); +create index tag_str_idx ON tag_str(key_id, value); +create index tag_str_thing_id_idx ON tag_str(thing_id); + -- sequences -- CREATE SEQUENCE type_edition_seq; @@ -410,6 +446,8 @@ CREATE SEQUENCE type_work_seq; CREATE SEQUENCE type_publisher_seq; +CREATE SEQUENCE type_tag_seq; + create table store ( id serial primary key, key text unique, diff --git a/openlibrary/plugins/upstream/addtag.py b/openlibrary/plugins/upstream/addtag.py deleted file mode 100644 index a9b33747346..00000000000 --- a/openlibrary/plugins/upstream/addtag.py +++ /dev/null @@ -1,148 +0,0 @@ -"""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 go back 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(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(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 diff --git a/openlibrary/plugins/upstream/code.py b/openlibrary/plugins/upstream/code.py index ff58da2bca0..0f7d9665620 100644 --- a/openlibrary/plugins/upstream/code.py +++ b/openlibrary/plugins/upstream/code.py @@ -22,7 +22,7 @@ from openlibrary import accounts -from openlibrary.plugins.upstream import addbook, addtag, covers, models, utils +from openlibrary.plugins.upstream import addbook, covers, models, utils from openlibrary.plugins.upstream import spamcheck from openlibrary.plugins.upstream import merge_authors from openlibrary.plugins.upstream import edits @@ -384,7 +384,6 @@ def setup(): models.setup() utils.setup() addbook.setup() - addtag.setup() covers.setup() merge_authors.setup() # merge_works.setup() # ILE code From 5f312f3e47d1d0963b0c66a675a50a76082a720d Mon Sep 17 00:00:00 2001 From: Mek Date: Thu, 15 Jun 2023 08:55:29 -0700 Subject: [PATCH 06/10] fixes Tag.create and Tag.find --- openlibrary/core/models.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/openlibrary/core/models.py b/openlibrary/core/models.py index f220b16c75e..40e0d3f8bc4 100644 --- a/openlibrary/core/models.py +++ b/openlibrary/core/models.py @@ -1121,29 +1121,33 @@ class Tag(Thing): """Class to represent /type/tag objects in OL.""" @classmethod - def get(cls, tag_name, tag_type): + def find(cls, tag_name, tag_type): """Returns a Tag object for a given tag name and tag type.""" q = {'type': '/type/tag', 'name': tag_name, 'tag_type': tag_type} match = list(web.ctx.site.things(q)) return match[0] if match else None @classmethod - def create(cls, tag_name, tag_description, tag_type, tag_plugins): + def create(cls, tag_name, tag_description, tag_type, tag_plugins, ip='127.0.0.1', comment='New Tag'): """Creates a new Tag object.""" + current_user = web.ctx.site.get_user() + patron = current_user and current_user.username or 'ImportBot' key = web.ctx.site.new_key('/type/tag') - web.ctx.path = key - web.ctx.site.save( - { - 'key': key, - 'name': tag_name, - 'tag_description': tag_description, - 'tag_type': tag_type, - 'tag_plugins': json.loads(tag_plugins or "[]"), - 'type': dict(key='/type/tag'), - }, - comment='New Tag', - ) - return key + from openlibrary.accounts import RunAs + with RunAs(patron): + web.ctx.ip = web.ctx.ip or ip + web.ctx.site.save( + { + 'key': key, + 'name': tag_name, + 'tag_description': tag_description, + 'tag_type': tag_type, + 'tag_plugins': json.loads(tag_plugins or "[]"), + 'type': dict(key='/type/tag'), + }, + comment=comment, + ) + return key def url(self, suffix="", **params): return self.get_url(suffix, **params) From 5f250a3c1acf84ee36bd5e02005edca3bc4d7b3b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 15:58:01 +0000 Subject: [PATCH 07/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- openlibrary/core/models.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/openlibrary/core/models.py b/openlibrary/core/models.py index 40e0d3f8bc4..3ec320f838c 100644 --- a/openlibrary/core/models.py +++ b/openlibrary/core/models.py @@ -1128,12 +1128,21 @@ def find(cls, tag_name, tag_type): return match[0] if match else None @classmethod - def create(cls, tag_name, tag_description, tag_type, tag_plugins, ip='127.0.0.1', comment='New Tag'): + def create( + cls, + tag_name, + tag_description, + tag_type, + tag_plugins, + ip='127.0.0.1', + comment='New Tag', + ): """Creates a new Tag object.""" current_user = web.ctx.site.get_user() patron = current_user and current_user.username or 'ImportBot' key = web.ctx.site.new_key('/type/tag') from openlibrary.accounts import RunAs + with RunAs(patron): web.ctx.ip = web.ctx.ip or ip web.ctx.site.save( From 22de00f46b534132855e87346f4f88e10ff7c0c6 Mon Sep 17 00:00:00 2001 From: Jayden Teoh Date: Sat, 1 Jul 2023 23:21:29 +0800 Subject: [PATCH 08/10] remove duplicate thing class registering --- openlibrary/plugins/upstream/models.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/openlibrary/plugins/upstream/models.py b/openlibrary/plugins/upstream/models.py index a9f893546e2..f60e8f24932 100644 --- a/openlibrary/plugins/upstream/models.py +++ b/openlibrary/plugins/upstream/models.py @@ -1007,11 +1007,6 @@ def get_seed(self, seed): return models.Seed(self.get_list(), seed) -class Tag(models.Tag): - """Class to represent /type/tag objects in Open Library.""" - - pass - def setup(): models.register_models() @@ -1024,7 +1019,6 @@ def setup(): client.register_thing_class('/type/place', SubjectPlace) client.register_thing_class('/type/person', SubjectPerson) client.register_thing_class('/type/user', User) - client.register_thing_class('/type/tag', Tag) client.register_changeset_class(None, Changeset) # set the default class client.register_changeset_class('merge-authors', MergeAuthors) From 19eb71330ca040828a8a47a57253a4ac4d11974d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 15:22:12 +0000 Subject: [PATCH 09/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- openlibrary/plugins/upstream/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openlibrary/plugins/upstream/models.py b/openlibrary/plugins/upstream/models.py index f60e8f24932..3f7827f99f7 100644 --- a/openlibrary/plugins/upstream/models.py +++ b/openlibrary/plugins/upstream/models.py @@ -1007,7 +1007,6 @@ def get_seed(self, seed): return models.Seed(self.get_list(), seed) - def setup(): models.register_models() From 32c6aeb8e16ae5c8a89f1ab41d36887cd0e5c98e Mon Sep 17 00:00:00 2001 From: Mek Date: Mon, 3 Jul 2023 11:38:29 -0700 Subject: [PATCH 10/10] + schema add_seq --- openlibrary/core/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlibrary/core/schema.py b/openlibrary/core/schema.py index 88e337dc7b2..3aa4770425d 100644 --- a/openlibrary/core/schema.py +++ b/openlibrary/core/schema.py @@ -30,7 +30,7 @@ def get_schema(): schema.add_seq('/type/work', '/works/OL%dW') schema.add_seq('/type/publisher', '/publishers/OL%dP') - # schema.add_seq('/type/tag', '/tags/OL%dT') + schema.add_seq('/type/tag', '/tags/OL%dT') _sql = schema.sql