def sync() -> flask.Response: extension_version = flask.request.headers.get( "Quarchive-Extension-Version", "unknown" ) log.debug("extension version: %s", extension_version) user = get_current_user() use_jsonlines = flask.request.headers["Content-Type"] != "application/json" if not use_jsonlines: log.warning("sync request using deprecated single json object") body = flask.request.json recieved_bookmarks = (Bookmark.from_json(item) for item in body["bookmarks"]) else: log.info("sync request using jsonlines") recieved_bookmarks = ( Bookmark.from_json(json.loads(l)) for l in flask.request.stream.readlines() ) try: changed_bookmarks = merge_bookmarks( db.session, user.user_uuid, recieved_bookmarks ) except BadCanonicalisationException as e: log.error( "bad canonicalised url ('%s') from version %s, user %s", e.url_string, extension_version, user, ) db.session.rollback() flask.abort(400, "bad canonicalisation on url: %s" % e.url_string) db.session.commit() if "full" in flask.request.args: response_bookmarks = all_bookmarks(db.session, get_current_user().user_uuid) else: response_bookmarks = changed_bookmarks # If we got JSON, send json back if not use_jsonlines: return flask.json.jsonify( {"bookmarks": [b.to_json() for b in response_bookmarks]} ) else: def generator(): for b in response_bookmarks: yield json.dumps(b.to_json()) yield "\n" return flask.Response( flask.stream_with_context(generator()), mimetype="application/x-ndjson", )
def sync(current_user: User) -> Tuple[flask.Response, int]: start_time = datetime.utcnow() extension_version = flask.request.headers.get( "Quarchive-Extension-Version", "unknown" ) log.debug("extension version: %s", extension_version) user_uuid = current_user.user_uuid use_jsonlines = flask.request.headers["Content-Type"] != "application/json" if not use_jsonlines: log.warning("sync request using deprecated single json object") body = flask.request.json recieved_bookmarks = (Bookmark.from_json(item) for item in body["bookmarks"]) else: log.info("sync request using jsonlines") recieved_bookmarks = ( Bookmark.from_json(json.loads(l)) for l in flask.request.stream.readlines() ) try: merge_result = merge_bookmarks(db.session, user_uuid, recieved_bookmarks) except BadCanonicalisationException as e: log.error( "bad canonicalised url ('%s') from version %s, user %s", e.url_string, extension_version, current_user, ) db.session.rollback() flask.abort(400, "bad canonicalisation on url: %s" % e.url_string) db.session.commit() for added in merge_result.added: publish_message( message_lib.BookmarkCreated( user_uuid=user_uuid, url_uuid=added.url.url_uuid ), environ["QM_RABBITMQ_BG_WORKER_TOPIC"], ) is_full_sync = "full" in flask.request.args if is_full_sync: response_bookmarks = all_bookmarks(db.session, current_user.user_uuid) else: response_bookmarks = merge_result.changed # If we got JSON, send json back if not use_jsonlines: return flask.json.jsonify( {"bookmarks": [b.to_json() for b in response_bookmarks]} ) else: def generator(): for b in response_bookmarks: yield json.dumps(b.to_json()) yield "\n" if is_full_sync: duration = datetime.utcnow() - start_time log.info( "completed full sync for %s in %ds", current_user.username, duration.total_seconds(), ) return ( flask.Response( flask.stream_with_context(generator()), mimetype="application/x-ndjson", ), 200, )