Beispiel #1
0
    def GET(self, key, value, suffix=''):
        key = key.lower()

        if key == 'oclc':
            key = 'oclc_numbers'
        elif key == 'ia':
            key = 'ocaid'

        if key != 'ocaid':  # example: MN41558ucmf_6
            value = value.replace('_', ' ')

        if web.ctx.encoding and web.ctx.path.endswith('.' + web.ctx.encoding):
            ext = '.' + web.ctx.encoding
        else:
            ext = ''

        if web.ctx.env.get('QUERY_STRING'):
            ext += '?' + web.ctx.env['QUERY_STRING']

        q = {'type': '/type/edition', key: value}

        result = web.ctx.site.things(q)

        if result:
            return web.found(result[0] + ext)
        elif key == 'ocaid':
            # Try a range of ocaid alternatives:
            ocaid_alternatives = [
                {
                    'type': '/type/edition',
                    'source_records': 'ia:' + value
                },
                {
                    'type': '/type/volume',
                    'ia_id': value
                },
            ]
            for q in ocaid_alternatives:
                result = web.ctx.site.things(q)
                if result:
                    return web.found(result[0] + ext)

            # Perform import, if possible
            from openlibrary.plugins.importapi.code import ia_importapi, BookImportError
            from openlibrary import accounts

            with accounts.RunAs('ImportBot'):
                try:
                    ia_importapi.ia_import(value, require_marc=True)
                except BookImportError:
                    logger.exception('Unable to import ia record')

            # Go the the record created, or to the dummy ia-wrapper record
            return web.found('/books/ia:' + value + ext)

        web.ctx.status = '404 Not Found'
        return render.notfound(web.ctx.path, create=False)
Beispiel #2
0
def sync_completed_sponsored_books(dryrun=False):
    """Retrieves a list of all completed sponsored books from Archive.org
    so they can be synced with Open Library, which entails:

    - adding IA ocaid into openlibrary edition
    - alerting patrons (if possible) by email of completion
    - possibly marking archive.org item status as complete/synced

    XXX Note: This `search_items` query requires the `ia` tool (the
    one installed via virtualenv) to be configured with (scope:all)
    privileged s3 keys.
    """
    items = ia.search_items(
        'collection:openlibraryscanningteam AND collection:inlibrary',
        fields=['identifier', 'openlibrary_edition'],
        params={
            'page': 1,
            'rows': 1000,
            'scope': 'all'
        },
        config={'general': {
            'secure': False
        }},
    )
    books = web.ctx.site.get_many([
        '/books/%s' % i.get('openlibrary_edition') for i in items
        if i.get('openlibrary_edition')
    ])
    unsynced = [book for book in books if not book.ocaid]
    ocaid_lookup = {
        '/books/%s' % i.get('openlibrary_edition'): i.get('identifier')
        for i in items
    }
    fixed = []
    for book in unsynced:
        book.ocaid = ocaid_lookup[book.key]
        with accounts.RunAs('ImportBot'):
            if not dryrun:
                web.ctx.site.save(book.dict(),
                                  "Adding ocaid for completed sponsorship")
            fixed.append({'key': book.key, 'ocaid': book.ocaid})
            # TODO: send out an email?... Requires Civi.
            if book.ocaid.startswith("isbn_"):
                isbn = book.ocaid.split("_")[-1]
                sponsorship = get_sponsorship_by_isbn(isbn)
                contact = sponsorship and sponsorship.get("contact")
                email = contact and contact.get("email")
                if not dryrun and email:
                    email_sponsor(email, book)
    return json.dumps(fixed)
Beispiel #3
0
    def GET(self):
        user = accounts.get_current_user()
        if user:
            account = OpenLibraryAccount.get_by_email(user.email)
            ia_itemname = account.itemname if account else None
        if not user or not ia_itemname:
            web.setcookie(config.login_cookie_name, "", expires=-1)
            raise web.seeother("/account/login?redirect=/sponsorship/join")
        try:
            with accounts.RunAs('archive_support'):
                models.UserGroup.from_key('sponsors-waitlist').add_user(user.key)
        except KeyError as e:
            add_flash_message('error', 'Unable to join waitlist: %s' % e.message)

        raise web.seeother('/sponsorship')
Beispiel #4
0
def create_edition_from_amazon_metadata(id_, id_type='isbn'):
    """Fetches Amazon metadata by id from Amazon Product Advertising API, attempts to
    create OL edition from metadata, and returns the resulting edition
    key `/key/OL..M` if successful or None otherwise.

    :param str id_: The item id: isbn (10/13), or Amazon ASIN.
    :param str id_type: 'isbn' or 'asin'.
    :return: Edition key '/key/OL..M' or None
    :rtype: str or None
    """

    md = get_amazon_metadata(id_, id_type=id_type)

    if md and md.get('product_group') == 'Book':
        with accounts.RunAs('ImportBot') as account:
            reply = load(clean_amazon_metadata_for_load(md), account=account)
            if reply and reply.get('success'):
                return reply['edition'].get('key')