def get_ia_carousel_books(query=None, subject=None, work_id=None, sorts=None, _type=None, limit=None): if 'env' not in web.ctx: delegate.fakeload() elif query in CAROUSELS_PRESETS: query = CAROUSELS_PRESETS[query] limit = limit or lending.DEFAULT_IA_RESULTS books = lending.get_available( limit=limit, subject=subject, work_id=work_id, _type=_type, sorts=sorts, query=query, ) formatted_books = [ format_book_data(book) for book in books if book != 'error' ] return formatted_books
def _get_recent_changes2(): """New recent changes for around the library. This function returns the message to display for each change. The message is get by calling `recentchanges/$kind/message.html` template. If `$var ignore=True` is set by the message template, the change is ignored. """ if 'env' not in web.ctx: delegate.fakeload() q = {"bot": False, "limit": 100} changes = web.ctx.site.recentchanges(q) def render(c): t = get_template("recentchanges/" + c.kind + "/message" ) or get_template("recentchanges/default/message") return t(c) # Gio: c.kind!='update' allow us to ignore update recent changes on people messages = [render(c) for c in changes if c.kind != 'update'] messages = [ m for m in messages if str(m.get("ignore", "false")).lower() != "true" ] return messages
def _get_recent_changes2(): """New recent changes for around the library. This function returns the message to display for each change. The message is get by calling `recentchanges/$kind/message.html` template. If `$var ignore=True` is set by the message template, the change is ignored. """ if 'env' not in web.ctx: delegate.fakeload() q = {"bot": False, "limit": 100} changes = web.ctx.site.recentchanges(q) def is_ignored(c): return ( # c.kind=='update' allow us to ignore update recent changes on people c.kind == 'update' or # ignore change if author has been deleted (e.g. spammer) (c.author and c.author.type.key == '/type/delete')) def render(c): t = get_template("recentchanges/" + c.kind + "/message" ) or get_template("recentchanges/default/message") return t(c) messages = [render(c) for c in changes if not is_ignored(c)] messages = [ m for m in messages if str(m.get("ignore", "false")).lower() != "true" ] return messages
def _get_recent_changes2(): """New recent changes for around the library. This function returns the message to display for each change. The message is get by calling `recentchanges/$kind/message.html` template. If `$var ignore=True` is set by the message template, the change is ignored. """ if 'env' not in web.ctx: delegate.fakeload() q = {"bot": False, "limit": 100} changes = web.ctx.site.recentchanges(q) def is_ignored(c): return ( # c.kind=='update' allow us to ignore update recent changes on people c.kind == 'update' or # ignore change if author has been deleted (e.g. spammer) (c.author and c.author.type.key == '/type/delete')) def render(c): t = get_template("recentchanges/" + c.kind + "/message") or get_template("recentchanges/default/message") return t(c) messages = [render(c) for c in changes if not is_ignored(c)] messages = [m for m in messages if str(m.get("ignore", "false")).lower() != "true"] return messages
def setup_module(mod): delegate.fakeload() # models module imports openlibrary.code, which imports ol_infobase and that expects db_parameters. web.config.db_parameters = dict(dbn="sqlite", db=":memory:") from .. import models models.setup()
def setup(): delegate.fakeload() from infogami.utils import types types.register_type('/i18n(/.*)?/strings.[^/]*', '/type/i18n') for site in db.get_all_sites(): load_strings(site)
def readinglog_stats(limit=limit): if 'env' not in web.ctx: delegate.fakeload() most_read = Bookshelves.most_logged_books( Bookshelves.PRESET_BOOKSHELVES['Already Read'], limit=limit) most_wanted = Bookshelves.most_logged_books( Bookshelves.PRESET_BOOKSHELVES['Want to Read'], limit=limit) return { 'total_books_logged': { 'total': Bookshelves.total_books_logged(), 'month': Bookshelves.total_books_logged(since=ONE_MONTH_DATE) }, 'total_users_logged': { 'total': Bookshelves.total_unique_users(), 'month': Bookshelves.total_unique_users(since=ONE_MONTH_DATE) }, 'total_books_starred': { 'total': Ratings.total_num_books_rated(), 'unique': Ratings.total_num_unique_raters(), 'month': Ratings.total_num_books_rated(since=ONE_MONTH_DATE) }, 'leaderboard': { 'most_read': most_read, 'most_wanted': most_wanted } }
def shell(*args): """Interactive Shell""" if "--ipython" in args: """IPython Interactive Shell - IPython must be installed to use.""" # remove an argument that confuses ipython sys.argv.pop(sys.argv.index("--ipython")) from IPython.Shell import IPShellEmbed import infogami # noqa: F401 from infogami.utils import delegate from infogami.core import db # noqa: F401 from infogami.utils.context import context as ctx # noqa: F401 delegate.fakeload() ipshell = IPShellEmbed() ipshell() else: from code import InteractiveConsole console = InteractiveConsole() console.push("import infogami") console.push("from infogami.utils import delegate") console.push("from infogami.core import db") console.push("from infogami.utils.context import context as ctx") console.push("delegate.fakeload()") console.interact()
def get_recently_modified_lists(limit, offset=0): """Returns the most recently modified lists as list of dictionaries. This function is memoized for better performance. """ # this function is memozied with background=True option. # web.ctx must be initialized as it won't be avaiable to the background thread. if 'env' not in web.ctx: delegate.fakeload() keys = web.ctx.site.things({ "type": "/type/list", "sort": "-last_modified", "limit": limit, "offset": offset }) lists = web.ctx.site.get_many(keys) # XXX-Anand, March 2014: This is not required any more. We switched to using solr # instead of relying on this data from couch. # # Cache seed_summary, so that it can be reused later without recomputing. #for list in lists: # list.seed_summary_cached = list.seed_summary return [list.dict() for list in lists]
def __init__( self, site: Site = None, db: DB = None, ia_db: DB = None, ): LegacyDataProvider.__init__(self) # cache for documents self.cache: Dict[str, dict] = {} self.metadata_cache: Dict[str, Optional[dict]] = {} # cache for redirects self.redirect_cache: Dict[str, List[str]] = {} self.edition_keys_of_works_cache: Dict[str, List[str]] = {} import infogami from infogami.utils import delegate # web.ctx might not be defined at this time -_- self.get_site = lambda: site or web.ctx.site if not db: infogami._setup() delegate.fakeload() from openlibrary.solr.process_stats import get_db self.db: DB = get_db() else: self.db = db # self.ia_db = get_ia_db # Ignore mypy because it can't find ia_database for some reason :/ self.ia_db: DB = ia_db or ia_database # type: ignore
def get_featured_subjects(): # web.ctx must be initialized as it won't be available to the background thread. if 'env' not in web.ctx: delegate.fakeload() FEATURED_SUBJECTS = [ {'key': '/subjects/art', 'presentable_name': _('Art')}, {'key': '/subjects/science_fiction', 'presentable_name': _('Science Fiction')}, {'key': '/subjects/fantasy', 'presentable_name': _('Fantasy')}, {'key': '/subjects/biographies', 'presentable_name': _('Biographies')}, {'key': '/subjects/recipes', 'presentable_name': _('Recipes')}, {'key': '/subjects/romance', 'presentable_name': _('Romance')}, {'key': '/subjects/textbooks', 'presentable_name': _('Textbooks')}, {'key': '/subjects/children', 'presentable_name': _('Children')}, {'key': '/subjects/history', 'presentable_name': _('History')}, {'key': '/subjects/medicine', 'presentable_name': _('Medicine')}, {'key': '/subjects/religion', 'presentable_name': _('Religion')}, { 'key': '/subjects/mystery_and_detective_stories', 'presentable_name': _('Mystery and Detective Stories'), }, {'key': '/subjects/plays', 'presentable_name': _('Plays')}, {'key': '/subjects/music', 'presentable_name': _('Music')}, {'key': '/subjects/science', 'presentable_name': _('Science')}, ] return [ {**subject, **(subjects.get_subject(subject['key'], limit=0) or {})} for subject in FEATURED_SUBJECTS ]
def get_work_authors_and_related_subjects(work_id): if 'env' not in web.ctx: delegate.fakeload() work = web.ctx.site.get(work_id) return { 'authors': work.get_author_names(blacklist=['anonymous']) if work else [], 'subjects': work.get_related_books_subjects() if work else [] }
def reading_log_summary(): # enable to work w/ cached if 'env' not in web.ctx: delegate.fakeload() stats = Bookshelves.summary() stats.update(Ratings.summary()) return stats
def get_returncart(limit): if 'env' not in web.ctx: delegate.fakeload() items = web.ctx.site.store.items(type='ebook', name='borrowed', value='false', limit=limit) keys = [doc['book_key'] for k, doc in items if 'book_key' in doc] books = web.ctx.site.get_many(keys) return [format_book_data(book) for book in books if book.type.key == '/type/edition']
def get_returncart(limit): if "env" not in web.ctx: delegate.fakeload() items = web.ctx.site.store.items(type="ebook", name="borrowed", value="false", limit=limit) keys = [doc["book_key"] for k, doc in items if "book_key" in doc] books = web.ctx.site.get_many(keys) return [format_book_data(book) for book in books if book.type.key == "/type/edition"]
def setup(): delegate.fakeload() load_all() from infogami.utils import types types.register_type(r'/templates/.*\.tmpl$', '/type/template') types.register_type('^/type/[^/]*$', '/type/type') types.register_type('/macros/.*$', '/type/macro')
def setup(): delegate.fakeload() load_all() from infogami.utils import types types.register_type('/templates/.*\.tmpl$', '/type/template') types.register_type('^/type/[^/]*$', '/type/type') types.register_type('/macros/.*$', '/type/macro')
def get_returncart(limit): if 'env' not in web.ctx: delegate.fakeload() items = web.ctx.site.store.items(type='ebook', name='borrowed', value='false', limit=limit) identifiers = [doc['identifier'] for k, doc in items if 'identifier' in doc] keys = web.ctx.site.things({"type": "/type/edition", "ocaid": identifiers}) books = web.ctx.site.get_many(keys) return [format_book_data(book) for book in books if book.type.key == '/type/edition']
def _get_changes_v2_raw(query, revision=None): """Returns the raw recentchanges response. Revision is taken as argument to make sure a new cache entry is used when a new revision of the page is created. """ if 'env' not in web.ctx: delegate.fakeload() changes = web.ctx.site.recentchanges(query) return [c.dict() for c in changes]
def _get_libraries(site=None): """Returns all the libraries each as a dict.""" if 'env' not in web.ctx: delegate.fakeload() site = site or web.ctx.site keys = site.things(query={"type": "/type/library", "limit": 1000, "status": "approved"}) libraries = site.get_many(keys) return [lib.dict() for lib in libraries]
def get_returncart(limit): if 'env' not in web.ctx: delegate.fakeload() items = web.ctx.site.store.items(type='ebook', name='borrowed', value='false', limit=limit) keys = [doc['book_key'] for k, doc in items if 'book_key' in doc] books = web.ctx.site.get_many(keys) return [format_book_data(book) for book in books]
def install(): """Setup everything.""" from infogami.utils import delegate delegate.fakeload() if not web.ctx.site.exists(): web.ctx.site.create() delegate.admin_login() for a in _install_hooks: print >> web.debug, a.__name__ a()
def GET(self): if 'env' not in web.ctx: delegate.fakeload() i = web.input(q='', offset='0', limit='10') keys = web.ctx.site.things({ "type": "/type/list", "name~": i.q, "limit": int(i.limit), "offset": int(i.offset) }) lists = web.ctx.site.get_many(keys) return render_template('search/lists.tmpl', q=i.q, lists=lists)
def get_featured_subjects(): # web.ctx must be initialized as it won't be available to the background thread. if 'env' not in web.ctx: delegate.fakeload() FEATURED_SUBJECTS = [ 'art', 'science_fiction', 'fantasy', 'biographies', 'recipes', 'romance', 'textbooks', 'children', 'history', 'medicine', 'religion', 'mystery_and_detective_stories', 'plays', 'music', 'science' ] return dict([(subject_name, subjects.get_subject('/subjects/' + subject_name, sort='edition_count')) for subject_name in FEATURED_SUBJECTS])
def get_results(self, q, offset=0, limit=100): if 'env' not in web.ctx: delegate.fakeload() keys = web.ctx.site.things({ "type": "/type/list", "name~": q, "limit": int(limit), "offset": int(offset) }) return web.ctx.site.get_many(keys)
def get_ia_carousel_books(query=None, subject=None, work_id=None, sorts=None, _type=None, limit=None): if 'env' not in web.ctx: delegate.fakeload() elif query in CAROUSELS_PRESETS: query = CAROUSELS_PRESETS[query] limit = limit or lending.DEFAULT_IA_RESULTS books = lending.get_available(limit=limit, subject=subject, work_id=work_id, _type=_type, sorts=sorts, query=query) formatted_books = [format_book_data(book) for book in books if book != 'error'] return formatted_books
def load_infogami(config_file): import web import infogami from infogami import config from infogami.utils import delegate config.plugin_path += ['openlibrary.plugins'] config.site = "openlibrary.org" infogami.load_config(config_file) setup_infobase_config(config_file) infogami._setup() delegate.fakeload()
def _get_recently_modified_lists(limit, offset=0): """Returns the most recently modified lists as list of dictionaries. This function is memoized for better performance. """ # this function is memozied with background=True option. # web.ctx must be initialized as it won't be avaiable to the background thread. if 'env' not in web.ctx: delegate.fakeload() keys = web.ctx.site.things({"type": "/type/list", "sort": "-last_modified", "limit": limit, "offset": offset}) lists = web.ctx.site.get_many(keys) return [lst.dict() for lst in lists]
def get_recently_modified_lists(limit, offset=0): """Returns the most recently modified lists as list of dictionaries. This function is memoized for better performance. """ # this function is memozied with background=True option. # web.ctx must be initialized as it won't be avaiable to the background thread. if 'env' not in web.ctx: delegate.fakeload() keys = web.ctx.site.things({"type": "/type/list", "sort": "-last_modified", "limit": limit, "offset": offset}) lists = web.ctx.site.get_many(keys) return [lst.dict() for lst in lists]
def get_homepage(): if 'env' not in web.ctx: delegate.fakeload() try: stats = admin.get_stats() except Exception: logger.error("Error in getting stats", exc_info=True) stats = None blog_posts = get_blog_feeds() # render tempalte should be setting ctx.bodyid # but because get_homepage is cached, this doesn't happen # during subsequent called page = render_template("home/index", stats=stats, blog_posts=blog_posts) return dict(page)
def install(): """Setup everything.""" # set debug=False to avoid reload magic. web.config.debug = False from infogami.utils import delegate delegate.fakeload() if not web.ctx.site.exists(): web.ctx.site.create() delegate.admin_login() for a in _install_hooks: print >> web.debug, a.__name__ a()
def get_featured_subjects(): # this function is memozied with background=True option. # web.ctx must be initialized as it won't be avaiable to the background thread. if 'env' not in web.ctx: delegate.fakeload() subjects = {} FEATURED_SUBJECTS = [ 'art', 'science_fiction', 'fantasy', 'biographies', 'recipes', 'romance', 'textbooks', 'children', 'history', 'medicine', 'religion', 'mystery_and_detective_stories', 'plays', 'music', 'science' ] for subject in FEATURED_SUBJECTS: subjects[subject] = get_subject('/subjects/' + subject, sort='edition_count') return subjects
def get_cachable_trending_books(shelf_id=None, since_days=1, limit=20, page=1): # enable to work w/ cached if 'env' not in web.ctx: delegate.fakeload() # Return as dict to enable cache serialization return [ dict(book) for book in Bookshelves.most_logged_books( shelf_id=shelf_id, since=dateutil.date_n_days_ago(since_days), limit=limit, page=page) ]
def get_most_logged_books(shelf_id=None, since_days=1, limit=20): """ shelf_id: Bookshelves.PRESET_BOOKSHELVES['Want to Read'|'Already Read'|'Currently Reading'] since: DATE_ONE_YEAR_AGO, DATE_ONE_MONTH_AGO, DATE_ONE_WEEK_AGO, DATE_ONE_DAY_AGO """ # enable to work w/ cached if 'env' not in web.ctx: delegate.fakeload() # Return as dict to enable cache serialization return [ dict(book) for book in Bookshelves.most_logged_books( shelf_id=shelf_id, since=dateutil.date_n_days_ago(since_days), limit=limit) ]
def get_returncart(limit): if 'env' not in web.ctx: delegate.fakeload() items = web.ctx.site.store.items(type='ebook', name='borrowed', value='false', limit=limit) identifiers = [ doc['identifier'] for k, doc in items if 'identifier' in doc ] keys = web.ctx.site.things({"type": "/type/edition", "ocaid": identifiers}) books = web.ctx.site.get_many(keys) return [ format_book_data(book) for book in books if book.type.key == '/type/edition' ]
def _setup(): #if config.db_parameters is None: # raise Exception('infogami.config.db_parameters is not specified') if config.site is None: raise Exception('infogami.config.site is not specified') if config.bugfixer: web.webapi.internalerror = web.emailerrors(config.bugfixer, web.debugerror) web.internalerror = web.webapi.internalerror web.config.db_parameters = config.db_parameters web.config.db_printing = config.db_printing from infogami.utils import delegate delegate._load() # setup context etc. delegate.fakeload()
def _get_changes_v1_raw(query, revision=None): """Returns the raw versions response. Revision is taken as argument to make sure a new cache entry is used when a new revision of the page is created. """ if 'env' not in web.ctx: delegate.fakeload() versions = web.ctx.site.versions(query) for v in versions: v.created = v.created.isoformat() v.author = v.author and v.author.key # XXX-Anand: hack to avoid too big data to be stored in memcache. # v.changes is not used and it contrinutes to memcache bloat in a big way. v.changes = '[]' return versions
def reading_log_leaderboard(limit=None): # enable to work w/ cached if 'env' not in web.ctx: delegate.fakeload() most_read = Bookshelves.most_logged_books( Bookshelves.PRESET_BOOKSHELVES['Already Read'], limit=limit) most_wanted_all = Bookshelves.most_logged_books( Bookshelves.PRESET_BOOKSHELVES['Want to Read'], limit=limit) most_wanted_month = Bookshelves.most_logged_books( Bookshelves.PRESET_BOOKSHELVES['Want to Read'], limit=limit, since=dateutil.DATE_ONE_MONTH_AGO) return { 'leaderboard': { 'most_read': most_read, 'most_wanted_all': most_wanted_all, 'most_wanted_month': most_wanted_month, 'most_rated_all': Ratings.most_rated_books() } }
def __init__(self): LegacyDataProvider.__init__(self) # cache for documents self.cache = {} self.metadata_cache = {} # cache for redirects self.redirect_cache = {} self.edition_keys_of_works_cache = {} import infogami from infogami.utils import delegate infogami._setup() delegate.fakeload() from openlibrary.solr.process_stats import get_ia_db, get_db self.db = get_db() self.ia_db = get_ia_db()
def _get_recent_changes2(): """New recent changes for around the library. This function returns the message to display for each change. The message is get by calling `recentchanges/$kind/message.html` template. If `$var ignore=True` is set by the message template, the change is ignored. """ if 'env' not in web.ctx: delegate.fakeload() q = {"bot": False, "limit": 100} changes = web.ctx.site.recentchanges(q) def render(c): t = get_template("recentchanges/" + c.kind + "/message") or get_template("recentchanges/default/message") return t(c) messages = [render(c) for c in changes] messages = [m for m in messages if str(m.get("ignore", "false")).lower() != "true"] return messages
def get_recently_modified_lists(limit, offset=0): """Returns the most recently modified lists as list of dictionaries. This function is memoized for better performance. """ # this function is memozied with background=True option. # web.ctx must be initialized as it won't be avaiable to the background thread. if 'env' not in web.ctx: delegate.fakeload() keys = web.ctx.site.things({"type": "/type/list", "sort": "-last_modified", "limit": limit, "offset": offset}) lists = web.ctx.site.get_many(keys) # XXX-Anand, March 2014: This is not required any more. We switched to using solr # instead of relying on this data from couch. # # Cache seed_summary, so that it can be reused later without recomputing. #for list in lists: # list.seed_summary_cached = list.seed_summary return [list.dict() for list in lists]
def _setup(): #if config.db_parameters is None: # raise Exception('infogami.config.db_parameters is not specified') if config.site is None: raise Exception('infogami.config.site is not specified') if config.bugfixer: web.webapi.internalerror = web.emailerrors(config.bugfixer, web.debugerror) web.internalerror = web.webapi.internalerror web.config.db_parameters = config.db_parameters web.config.db_printing = config.db_printing if config.get("debug", None) is not None: web.config.debug = config.debug from infogami.utils import delegate delegate._load() # setup context etc. delegate.fakeload()
def readinglog_stats(limit=limit): if 'env' not in web.ctx: delegate.fakeload() most_read = Bookshelves.most_logged_books( Bookshelves.PRESET_BOOKSHELVES['Already Read'], limit=limit) most_wanted = Bookshelves.most_logged_books( Bookshelves.PRESET_BOOKSHELVES['Want to Read'], limit=limit) return { 'total_books_logged': { 'total': Bookshelves.total_books_logged(), 'month': Bookshelves.total_books_logged(since=ONE_MONTH_DATE) }, 'total_users_logged': { 'total': Bookshelves.total_unique_users(), 'month': Bookshelves.total_unique_users(since=ONE_MONTH_DATE) }, 'leaderboard': { 'most_read': most_read, 'most_wanted': most_wanted } }
def format_list_editions(key): """Formats the editions of the list suitable for display in carousel. """ if 'env' not in web.ctx: delegate.fakeload() list = web.ctx.site.get(key) if not list: return [] editions = {} for seed in list.seeds: if not isinstance(seed, basestring): if seed.type.key == "/type/edition": editions[seed.key] = seed else: try: e = pick_best_edition(seed) except StopIteration: continue editions[e.key] = e return [format_book_data(e) for e in editions.values()]
def shell(*args): """Interactive Shell""" if not "--ipython" in args: from code import InteractiveConsole console = InteractiveConsole() console.push("import infogami") console.push("from infogami.utils import delegate") console.push("from infogami.core import db") console.push("from infogami.utils.context import context as ctx") console.push("delegate.fakeload()") console.interact() else: """IPython Interactive Shell - IPython must be installed to use.""" # remove an argument that confuses ipython sys.argv.pop(sys.argv.index("--ipython")) from IPython.Shell import IPShellEmbed import infogami from infogami.utils import delegate from infogami.core import db from infogami.utils.context import context as ctx delegate.fakeload() ipshell = IPShellEmbed() ipshell()
def _get_active_lists_in_random(limit=20, preload=True): if 'env' not in web.ctx: delegate.fakeload() lists = [] offset = 0 while len(lists) < limit: result = get_cached_recently_modified_lists(limit*5, offset=offset) if not result: break offset += len(result) # ignore lists with 4 or less seeds lists += [xlist for xlist in result if len(xlist.get("seeds", [])) > 4] if len(lists) > limit: lists = random.sample(lists, limit) if preload: _preload_lists(lists) return lists