diff options
Diffstat (limited to 'python/fatcat/sql.py')
-rw-r--r-- | python/fatcat/sql.py | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/python/fatcat/sql.py b/python/fatcat/sql.py new file mode 100644 index 00000000..9b1922ba --- /dev/null +++ b/python/fatcat/sql.py @@ -0,0 +1,150 @@ + +import json +import time +import random +import hashlib +from sqlalchemy.orm.session import make_transient +from fatcat import db +import fatcat.api +from fatcat.models import * + +def populate_db(): + admin_editor = Editor(id=1, username="admin", is_admin=True) + db.session.add(admin_editor) + db.session.commit() + +def add_crossref_via_model(meta): + + title = meta['title'][0] + + # authors + author_revs = [] + author_ids = [] + for am in meta['author']: + ar = CreatorRev( + name="{} {}".format(am['given'], am['family']), + sortname="{}, {}".format(am['family'], am['given']), + orcid=None) + author_revs.append(ar) + author_ids.append(CreatorIdent(rev=ar)) + + # container + container = ContainerRev( + issn=meta['ISSN'][0], + name=meta['container-title'][0], + #container_id=None, + publisher=meta['publisher'], + sortname=meta['short-container-title'][0]) + container_id = ContainerIdent(rev=container) + + # work and release + work = WorkRev(title=title) + work_id = WorkIdent(rev=work) + release = ReleaseRev( + title=title, + creators=[ReleaseContrib(creator=a) for a in author_ids], + # XXX: work=work, + container=container_id, + release_type=meta['type'], + doi=meta['DOI'], + date=meta['created']['date-time'], + license=meta.get('license', [dict(URL=None)])[0]['URL'] or None, + issue=meta.get('issue', None), + volume=meta.get('volume', None), + pages=meta.get('page', None)) + release_id = ReleaseIdent(rev=release) + work.primary_release = release_id + release.extra_json = json.dumps({ + 'crossref': { + 'links': meta.get('link', []), + 'subject': meta['subject'], + 'type': meta['type'], + 'alternative-id': meta.get('alternative-id', []), + } + }, indent=None).encode('utf-8') + + # references + for i, rm in enumerate(meta.get('reference', [])): + ref = ReleaseRef( + release_rev=release, + doi=rm.get("DOI", None), + index=i+1, + # TODO: how to generate a proper stub here from k/v metadata? + stub="| ".join(rm.values())) + release.refs.append(ref) + + db.session.add_all([work, work_id, release, release_id, container, + container_id]) + db.session.add_all(author_revs) + db.session.add_all(author_ids) + db.session.commit() + +def accept_editgroup(eg): + + # check if already accepted + # XXX: add a test for this + assert ChangelogEntry.query.filter(ChangelogEntry.editgroup_id==eg.id).count() == 0 + + # start transaction (TODO: explicitly?) + + # for each entity type: + for cls in (WorkEdit, ReleaseEdit, CreatorEdit, ContainerEdit, FileEdit): + edits = cls.query.filter(cls.editgroup_id==eg.id).all() + # for each entity edit->ident: + for edit in edits: + # update entity ident state (activate, redirect, delete) + edit.ident.is_live = True + edit.ident.rev_id = edit.rev_id + edit.ident.redirect_id = edit.redirect_id + db.session.add(edit.ident) + + # append log/changelog row + cle = ChangelogEntry( + editgroup_id=eg.id, + # TODO: is this UTC? + timestamp=int(time.time())) + db.session.add(cle) + + # update edit group state + db.session.add(eg) + + # no longer "active" + eg.editor.active_editgroup = None + db.session.add(eg.editor) + + db.session.commit() + +def merge_works(left_id, right_id, editgroup=None): + """Helper to merge two works together.""" + left = WorkIdent.query.get_or_404(left_id) + right = WorkIdent.query.get_or_404(right_id) + assert left.is_live and right.is_live + assert left.rev and right.rev + assert (left.redirect_id is None) and (right.redirect_id is None) + + if editgroup is None: + editgroup = fatcat.api.get_or_create_editgroup() + + releases = ReleaseIdent.query\ + .join(ReleaseIdent.rev)\ + .filter(ReleaseRev.work_ident_id==right_id)\ + .filter(ReleaseIdent.is_live==True)\ + .all() + + # update all right releases to point to left + for release_ident in releases: + rev = release_ident.rev + old_id = rev.id + db.session.expunge(rev) + make_transient(rev) + rev.id = None + rev.parent = old_id + rev.work_ident_id = left.id + re = ReleaseEdit(editgroup=editgroup, ident=release_ident, rev=rev) + db.session.add_all([rev, re]) + + # redirect right id to left (via editgroup) + neww = WorkEdit(editgroup=editgroup, ident=right, + rev=left.rev, redirect_id=left.id) + + db.session.add_all([neww]) |