def get_editions_data(self, work, limit, offset): if limit > 1000: limit = 1000 keys = web.ctx.site.things({ "type": "/type/edition", "works": work.key, "limit": limit, "offset": offset }) editions = web.ctx.site.get_many(keys, raw=True) size = work.edition_count links = { "self": web.ctx.fullpath, "work": work.key, } if offset > 0: links['prev'] = web.changequery(offset=min(0, offset - limit)) if offset + len(editions) < size: links['next'] = web.changequery(offset=offset + limit) return {"links": links, "size": size, "entries": editions}
def GET(self, path): i = web.input(b=None, a=None) # default value of b is latest revision and default value of a is b-1 def get(path, revision): if revision == 0: page = web.ctx.site.new(path, { 'revision': 0, 'type': { 'key': '/type/object' }, 'key': path }) else: page = web.ctx.site.get(path, revision) return page def is_int(n): return n is None or safeint(n, None) is not None # if either or i.a or i.b is bad, then redirect to latest diff if not is_int(i.b) or not is_int(i.a): return web.redirect(web.changequery(b=None, a=None)) b = get(path, safeint(i.b, None)) # if the page is not there go to view page if b is None: raise web.seeother(web.changequery(query={})) a = get(path, max(1, safeint(i.a, b.revision - 1))) return render.diff(a, b)
def GET(self, path): i = web.input(b=None, a=None) # default value of b is latest revision and default value of a is b-1 def get(path, revision): if revision == 0: page = web.ctx.site.new(path, {'revision': 0, 'type': {'key': '/type/object'}, 'key': path}) else: page = web.ctx.site.get(path, revision) return page def is_int(n): return n is None or safeint(n, None) is not None # if either or i.a or i.b is bad, then redirect to latest diff if not is_int(i.b) or not is_int(i.a): return web.redirect(web.changequery(b=None, a=None)) b = get(path, safeint(i.b, None)) # if the page is not there go to view page if b is None: raise web.seeother(web.changequery(query={})) a = get(path, safeint(i.a, b.revision-1)) return render.diff(a, b)
def get_works_data(self, author, limit, offset): if limit > 1000: limit = 1000 keys = web.ctx.site.things({ "type": "/type/work", "authors": { "author": { "key": author.key } }, "limit": limit, "offset": offset }) works = web.ctx.site.get_many(keys, raw=True) size = author.get_work_count() links = { "self": web.ctx.fullpath, "author": author.key, } if offset > 0: links['prev'] = web.changequery(offset=min(0, offset - limit)) if offset + len(works) < size: links['next'] = web.changequery(offset=offset + limit) return {"links": links, "size": size, "entries": works}
def POST(self, key): i = web.input("v", _comment=None) v = i.v and safeint(i.v, None) if v is None: raise web.seeother(web.changequery({})) if not web.ctx.site.can_write(key) or not user_is_admin_or_librarian(): return render.permission_denied( web.ctx.fullpath, "Permission denied to edit " + key + ".") thing = web.ctx.site.get(key, i.v) if not thing: raise web.notfound() def revert(thing): if thing.type.key == "/type/delete" and thing.revision > 1: prev = web.ctx.site.get(thing.key, thing.revision - 1) if prev.type.key in ["/type/delete", "/type/redirect"]: return revert(prev) else: prev._save("revert to revision %d" % prev.revision) return prev elif thing.type.key == "/type/redirect": redirect = web.ctx.site.get(thing.location) if redirect and redirect.type.key not in [ "/type/delete", "/type/redirect", ]: return redirect else: # bad redirect. Try the previous revision prev = web.ctx.site.get(thing.key, thing.revision - 1) return revert(prev) else: return thing def process(value): if isinstance(value, list): return [process(v) for v in value] elif isinstance(value, client.Thing): if value.key: if value.type.key in ['/type/delete', '/type/revert']: return revert(value) else: return value else: for k in value: value[k] = process(value[k]) return value else: return value for k in thing: thing[k] = process(thing[k]) comment = i._comment or "reverted to revision %d" % v thing._save(comment) raise web.seeother(key)
def POST(self, path): i = web.input(_method='post') i = web.storage(helpers.unflatten(i)) i.key = path _ = web.storage((k, i.pop(k)) for k in i.keys() if k.startswith('_')) action = self.get_action(_) comment = _.get('_comment', None) for k, v in i.items(): i[k] = self.trim(v) p = web.ctx.site.get(path) or web.ctx.site.new(path, {}) p.update(i) if action == 'preview': p['comment_'] = comment return render.editpage(p, preview=True) elif action == 'save': try: p._save(comment) path = web.input(_method='GET', redirect=None).redirect or web.changequery(query={}) raise web.seeother(path) except (ClientException, db.ValidationException), e: add_flash_message('error', str(e)) p['comment_'] = comment return render.editpage(p)
def make_collection(size, entries, limit, offset): d = { "size": size, "entries": entries, "links": { "self": web.changequery(), } } if offset + len(entries) < size: d['links']['next'] = web.changequery(limit=limit, offset=offset+limit) if offset: d['links']['prev'] = web.changequery(limit=limit, offset=max(0, offset-limit)) return d
def redirect_if_needed(self, i): params = {} need_redirect = False for k, v in i.items(): if k in plurals: params[k] = None k = plurals[k] need_redirect = True if isinstance(v, list): if v == []: continue clean = [normalize('NFC', b.strip()) for b in v] if clean != v: need_redirect = True if len(clean) == 1 and clean[0] == u'': clean = None else: clean = normalize('NFC', v.strip()) if clean == '': need_redirect = True clean = None if clean != v: need_redirect = True params[k] = clean if need_redirect: raise web.seeother(web.changequery(**params))
def GET(self): i = web.input(author_key=[], language=[], first_publish_year=[], publisher_facet=[], subject_facet=[], person_facet=[], place_facet=[], time_facet=[]) params = {} need_redirect = False for k, v in i.items(): if isinstance(v, list): if v == []: continue clean = [b.strip() for b in v] if clean != v: need_redirect = True if len(clean) == 1 and clean[0] == u'': clean = None else: clean = v.strip() if clean == '': need_redirect = True clean = None if clean != v: need_redirect = True params[k] = clean if need_redirect: raise web.seeother(web.changequery(**params)) return render.work_search(i, do_search, get_doc)
def POST(self, path): if not self.is_scan_user(): return permission_denied('Permission denied.') book = web.ctx.site.get(path) i = web.input("scan_status", _comment=None) q = { 'key': '/scan_record' + path, 'scan_status': { 'connect': 'update', 'value': i.scan_status } } web.ctx.site.write(q, i._comment) def get_email(user): try: delegate.admin_login() return web.utf8(web.ctx.site.get_user_email(user.key).email) finally: web.ctx.headers = [] scan_record = get_scan_record(path) to = scan_record.sponsor and get_email(scan_record.sponsor) cc = getattr(config, 'scan_email_recipients', []) if to: if i.scan_status == 'SCAN_IN_PROGRESS': message = render.scan_inprogress_email(book, scan_record, i._comment) else: message = render.scan_book_notfound_email(book, scan_record, i._comment) web.sendmail(config.from_address, to, message.subject.strip(), str(message), cc=cc) raise web.seeother(web.changequery(query={}))
def redirect_if_needed(self, i): params = {} need_redirect = False for k, v in i.items(): if k in plurals: params[k] = None k = plurals[k] need_redirect = True if isinstance(v, list): if v == []: continue clean = [b.strip() for b in v] if clean != v: need_redirect = True if len(clean) == 1 and clean[0] == u'': clean = None else: clean = v.strip() if clean == '': need_redirect = True clean = None if clean != v: need_redirect = True params[k] = clean if need_redirect: raise web.seeother(web.changequery(**params))
def POST(self, path): p = db.get_version(path) if not p: raise web.seeother(path) i = web.input('permission.key', 'child_permission.key') q = { 'key': path, 'permission': { 'connect': 'update', 'key': i['permission.key'] or None, }, 'child_permission': { 'connect': 'update', 'key': i['child_permission.key'] or None, }, } try: web.ctx.site.write(q) except Exception as e: import traceback traceback.print_exc(e) add_flash_message('error', str(e)) return render.permission(p) raise web.seeother(web.changequery({}, m='permission'))
def POST(self, key): i = web.input("v", _comment=None) v = i.v and safeint(i.v, None) if v is None: raise web.seeother(web.changequery({})) user = accounts.get_current_user() is_admin = user and user.key in [m.key for m in web.ctx.site.get('/usergroup/admin').members] if not (is_admin and web.ctx.site.can_write(key)): return render.permission_denied(web.ctx.fullpath, "Permission denied to edit " + key + ".") thing = web.ctx.site.get(key, i.v) if not thing: raise web.notfound() def revert(thing): if thing.type.key == "/type/delete" and thing.revision > 1: prev = web.ctx.site.get(thing.key, thing.revision-1) if prev.type.key in ["/type/delete", "/type/redirect"]: return revert(prev) else: prev._save("revert to revision %d" % prev.revision) return prev elif thing.type.key == "/type/redirect": redirect = web.ctx.site.get(thing.location) if redirect and redirect.type.key not in ["/type/delete", "/type/redirect"]: return redirect else: # bad redirect. Try the previous revision prev = web.ctx.site.get(thing.key, thing.revision-1) return revert(prev) else: return thing def process(value): if isinstance(value, list): return [process(v) for v in value] elif isinstance(value, client.Thing): if value.key: if value.type.key in ['/type/delete', '/type/revert']: return revert(value) else: return value else: for k in value.keys(): value[k] = process(value[k]) return value else: return value for k in thing.keys(): thing[k] = process(thing[k]) comment = i._comment or "reverted to revision %d" % v thing._save(comment) raise web.seeother(key)
def POST(self, path): if not self.is_scan_user(): return permission_denied('Permission denied.') book = get_book(path, check_scanned=False, check_ocaid=False) i = web.input("ocaid", volumes=None, multivolume_work=None, _comment=None) q = [ { 'key': path, 'ocaid': { 'connect': 'update', 'value': i.ocaid } }, { 'key': '/scan_record' + path, 'scan_status': { 'connect': 'update', 'value': 'SCAN_COMPLETE' }, 'completion_date': { 'connect': 'update', 'value': datetime.datetime.utcnow().isoformat() } } ] if i.multivolume_work: def volume(index, ia_id): return { 'type': {'key': '/type/volume'}, 'volume_number': index, 'ia_id': ia_id } volumes = i.volumes and i.volumes.split() or [] q[0]['volumes'] = { 'connect': 'update_list', 'value': [volume(index+1, v) for index, v in enumerate(volumes)] } q[0]['ocaid'] = { 'connect': 'update', 'value': '' } web.ctx.site.write(q, i._comment) scan_record = get_scan_record(path) to = scan_record.sponsor and get_email(scan_record.sponsor) cc = getattr(config, 'scan_email_recipients', []) if to: message = render.scan_complete_email(book, scan_record, i._comment) web.sendmail(config.from_address, to, message.subject.strip(), str(message), cc=cc) raise web.seeother(web.changequery(query={}))
def POST(self, site, path): i = input() if i.c != core.db.get_version(site, path).revision: return render.parallel_modification() if i.a == i.b: return approve().POST(site, path) else: web.seeother(web.changequery(m='review', b=i.b-1))
def POST(self, site, path): i = input() if i.c != core.db.get_version(site, path).revision: return render.parallel_modification() if i.a == i.b: return approve().POST(site, path) else: web.seeother(web.changequery(m='review', b=i.b - 1))
def GET(self): i = web.input(status="WAITING_FOR_BOOK", p=None) options = ["NOT_SCANNED", "WAITING_FOR_BOOK", "BOOK_NOT_SCANNED", "SCAN_IN_PROGRESS", "SCAN_COMPLETE"] if i.status not in options: raise web.seeother(web.changequery({})) offset = safeint(i.p, 0) * 50 records = get_scan_queue(i.status, limit=50, offset=offset) return render.scan_queue(records)
def make_collection(size, entries, limit, offset, key=None): d = { "size": size, "start": offset, "end": offset + limit, "entries": entries, "links": { "self": web.changequery(), }, } if offset + len(entries) < size: d['links']['next'] = web.changequery(limit=limit, offset=offset + limit) if offset: d['links']['prev'] = web.changequery(limit=limit, offset=max(0, offset - limit)) if key: d['links']['list'] = key return d
def get_lists(self, doc, limit=50, offset=0): lists = doc.get_lists(limit=limit, offset=offset) size = len(lists) if offset or len(lists) == limit: # There could be more lists than len(lists) size = len(doc.get_lists(limit=1000)) d = { "links": {"self": web.ctx.path}, "size": size, "entries": [lst.preview() for lst in lists], } if offset + len(lists) < size: d['links']['next'] = web.changequery(limit=limit, offset=offset + limit) if offset: offset = max(0, offset - limit) d['links']['prev'] = web.changequery(limit=limit, offset=offset) return d
def POST(self, key): i = web.input("v", _comment=None) v = i.v and safeint(i.v, None) if v is None: raise web.seeother(web.changequery({})) thing = web.ctx.site.get(key, i.v) if not thing: raise web.notfound() def revert(thing): if thing.type.key == "/type/delete" and thing.revision > 1: prev = web.ctx.site.get(thing.key, thing.revision-1) if prev.type.key in ["/type/delete", "/type/redirect"]: return revert(prev) else: prev._save("revert to revision %d" % prev.revision) return prev elif thing.type.key == "/type/redirect": redirect = web.ctx.site.get(thing.location) if redirect and redirect.type.key not in ["/type/delete", "/type/redirect"]: return redirect else: # bad redirect. Try the previous revision prev = web.ctx.site.get(thing.key, thing.revision-1) return revert(prev) else: return thing def process(value): if isinstance(value, list): return [process(v) for v in value] elif isinstance(value, client.Thing): if value.key: if value.type.key in ['/type/delete', '/type/revert']: return revert(value) else: return value else: for k in value.keys(): value[k] = process(value[k]) return value else: return value for k in thing.keys(): thing[k] = process(thing[k]) comment = i._comment or "reverted to revision %d" % v thing._save(comment) raise web.seeother(key)
def GET(self): i = web.input(v=None) v = doc.md5() if v != i.v: raise web.seeother(web.changequery(v=v)) if web.modified(etag=v): oneyear = 365 * 24 * 3600 web.header("Content-Type", content_type) web.header("Cache-Control", "Public, max-age=%d" % oneyear) web.lastmodified(doc.last_modified) web.expires(oneyear) return delegate.RawText(doc.get_text())
def get_lists(self, doc, limit=50, offset=0): lists = doc.get_lists(limit=limit, offset=offset) size = len(lists) if offset or len(lists) == limit: # There could be more lists than len(lists) size = len(doc.get_lists(limit=1000)) d = { "links": { "self": web.ctx.path }, "size": size, "entries": [lst.preview() for lst in lists] } if offset + len(lists) < size: d['links']['next'] = web.changequery(limit=limit, offset=offset + limit) if offset: offset = max(0, offset-limit) d['links']['prev'] = web.changequery(limit=limit, offset=offset) return d
def get_works_data(self, author, limit, offset): if limit > 1000: limit = 1000 keys = web.ctx.site.things({"type": "/type/work", "authors": {"author": {"key": author.key}}, "limit": limit, "offset": offset}) works = web.ctx.site.get_many(keys, raw=True) size = author.get_work_count() links = { "self": web.ctx.fullpath, "author": author.key, } if offset > 0: links['prev'] = web.changequery(offset=min(0, offset-limit)) if offset + len(works) < size: links['next'] = web.changequery(offset=offset+limit) return { "links": links, "size": size, "entries": works }
def get_editions_data(self, work, limit, offset): if limit > 1000: limit = 1000 keys = web.ctx.site.things({"type": "/type/edition", "works": work.key, "limit": limit, "offset": offset}) editions = web.ctx.site.get_many(keys, raw=True) size = work.edition_count links = { "self": web.ctx.fullpath, "work": work.key, } if offset > 0: links['prev'] = web.changequery(offset=min(0, offset-limit)) if offset + len(editions) < size: links['next'] = web.changequery(offset=offset+limit) return { "links": links, "size": size, "entries": editions }
def delegate(): """Delegate the request to appropriate class.""" path = web.ctx.path method = web.ctx.method # look for special pages cls, args = find_page() if cls is None: cls, args = find_mode() if cls is None: raise web.seeother(web.changequery(m=None)) elif not hasattr(cls, method): raise web.nomethod(method) else: return getattr(cls(), method)(*args)
def POST(self, site, path): i = input() if i.c != core.db.get_version(site, path).revision: return render.parallel_modification() user = core.auth.get_user() if i.b != i.c: # user requested for some reverts before approving this db.revert(site, path, user.id, i.b) revision = i.c + 1 # one new version has been added by revert else: revision = i.b db.approve(site, user.id, path, revision) web.seeother(web.changequery(m=None, a=None, b=None, c=None))
def GET(self, path): i = web.input(v=None) if i.v is not None and safeint(i.v, None) is None: raise web.seeother(web.changequery(v=None)) p = db.get_version(path, i.v) if p is None: return notfound(path) elif p.type.key == '/type/delete': web.ctx.status = '404 Not Found' return render.viewpage(p) elif p.type.key == "/type/redirect": web.redirect(p.location) else: return render.viewpage(p)
def GET(self, path): i = web.input(v=None) if i.v is not None and safeint(i.v, None) is None: raise web.seeother(web.changequery(v=None)) p = db.get_version(path, i.v) if p is None: return notfound(path) elif p.type.key == '/type/delete': web.ctx.status = '404 Not Found' return render.viewpage(p) elif (p.type.key == "/type/redirect" and p.location and not p.location.startswith('http://') and not p.location.startswith('://')): web.redirect(p.location) else: return render.viewpage(p)
def GET(self, path): i = web.input(v=None, t=None) if not web.ctx.site.can_write(path): return render.permission_denied(web.ctx.fullpath, "Permission denied to edit " + path + ".") if i.v is not None and safeint(i.v, None) is None: raise web.seeother(web.changequery(v=None)) p = db.get_version(path, i.v) or db.new_version(path, types.guess_type(path)) if i.t: type = db.get_type(i.t) if type is None: add_flash_message('error', 'Unknown type: ' + i.t) else: p.type = type return render.editpage(p)
def GET(self, path): i = web.input(v=None, t=None) if not web.ctx.site.can_write(path): return render.permission_denied(path, "Permission denied to edit " + path + ".") if i.v is not None and safeint(i.v, None) is None: raise web.seeother(web.changequery(v=None)) p = db.get_version(path, i.v) or db.new_version(path, types.guess_type(path)) if i.t: type = db.get_type(i.t) if type is None: add_flash_message('error', 'Unknown type: ' + i.t) else: p.type = type return render.editpage(p)
def change_params(**kwargs): return re.sub('/.*?\?', '', web.changequery(**kwargs))
raise web.seeother(path) except (ClientException, db.ValidationException), e: add_flash_message('error', str(e)) p['comment_'] = comment return render.editpage(p) elif action == 'delete': q = dict(key=i['key'], type=dict(key='/type/delete')) try: web.ctx.site.save(q, comment) except (ClientException, db.ValidationException), e: add_flash_message('error', str(e)) p['comment_'] = comment return render.editpage(p) raise web.seeother(web.changequery(query={})) def get_action(self, i): """Finds the action from input.""" if '_save' in i: return 'save' elif '_preview' in i: return 'preview' elif '_delete' in i: return 'delete' else: return None class permission(delegate.mode): def GET(self, path): p = db.get_version(path) if not p: raise web.seeother(path) return render.permission(p)
def GET(self): return web.changequery(x=1)
def GET(self, key): raise web.seeother(web.changequery(m=None))