def update_org_recent_points(pt): # Rebuild org.recpre if empty or null, otherwise splice in pt. # Maintain max recpre size of 512k to stay within 1mb db obj limit. organization = org.Organization.get_by_id(int(pt.orgid)) preb = organization.recpre if preb and len(preb) > 3000: # save db quota, splice in pt ptid = str(pt.key().id()) preb = json.loads(preb) # remove existing instance from prebuilt if it exists upda = [x for x in preb if "instid" in x and x["instid"] != ptid] # prepend the modified point unless deleted if not is_deleted_point(pt): upda.insert(0, point_summary_dict(pt)) preb = json.dumps(upda) if len(preb) >= 512 * 1024: # exceeded total size, knock last off upda = upda[0:len(upda) - 1] preb = json.dumps(upda) else: # rebuild from database query vq = appuser.VizQuery(Point, "WHERE orgid=:1 ORDER BY modified DESC", pt.orgid) pts = vq.fetch(1000, read_policy=db.EVENTUAL_CONSISTENCY, deadline=20) preb = "" for pt in pts: if len(preb) >= 512 * 1024: break if is_deleted_point(pt): continue if preb: preb += "," preb += json.dumps(point_summary_dict(pt)) preb = "[" + preb + "]" organization.recpre = preb appuser.cached_put(None, organization)
def send_reminder_if_needed(acc, sched): remlog = "" acc.started = acc.started or "[]" started = json.loads(acc.started) for tlp in started: rdue = reminder_due(tlp, sched) if rdue: tlp["reminder"] = rdue remlog = rdue + " reminder " + acc.email + " tlid: " + tlp["tlid"] body = "As requested, this is your " + rdue + " reminder to finish the timeline you started. The best is yet to come. Here's the link to continue: https://pastkey.org/timeline/" + tlp[ "tlid"] + "?email=" + acc.email + "&authtok=" + appuser.token_for_user( acc) subj = rdue + " timeline reminder" try: appuser.mailgun_send(None, acc.email, subj, body) except Exception as e: logging.warn("send_reminder_if_needed failure: " + str(e) + "\n" + subj + "\n" + acc.email + "\n\n" + body) # Only send one reminder even if they have multiple started # timelines. If they have another it will be picked up tomorrow. break if remlog: acc.started = json.dumps(started) appuser.cached_put(acc.email, acc) return remlog
def get_service_info(svcname): qp = { "dboc": AppService, "where": "WHERE name=:1 LIMIT 1", "wags": svcname } svc = appuser.cached_get(svcname, qp) if not svc: # make an empty placeholder entry svc = AppService(name=svcname, ckey="unknown", csec="unknown", data="") appuser.cached_put(svcname, svc) return svc
def update_organization(org, params): for field in params: attr = field val = params[field] if attr.startswith("upd"): attr = attr[3:] if val: if val.lower() == "noval": val = "" setattr(org, attr, val) appuser.cached_put(str(org.key().id()), org) return org
def post(self): acc = appuser.authenticated(self.request) if not acc: return srverr(self, 401, "Authentication failed") params = appuser.read_params(self, [ "instid", "name", "ctype", "cids", "svs", "slug", "title", "subtitle", "featured", "lang", "comment", "about" ]) timeline = update_or_create_timeline(self, acc, params) if timeline: updated = update_timeline_list(acc.built, timeline) if updated != acc.built: acc.built = updated appuser.cached_put(acc.email, acc) appuser.return_json(self, [timeline, acc])
def post(self): if not appuser.verify_secure_comms(self): return acc = appuser.authenticated(self.request) if not acc: return srverr(self, 401, "Authentication failed") if not acc.orgid or acc.lev != 2: return appuser.srverr(self, 403, "Not an Administrator") params = appuser.read_params(self, ["membermail"]) mem = appuser.account_from_email(params["membermail"]) if not mem: return appuser.srverr(self, 404, "User not found") if mem.orgid: if mem.orgid == acc.orgid: return appuser.srverr(self, 400, "Already a member") else: return appuser.srverr(self, 403, "Member of other Org") mem.orgid = acc.orgid mem.lev = 0 appuser.cached_put(mem.email, mem) appuser.return_json(self, [public_member_record(mem)])
def fetch_timeline_by_slug(slug): logging.info("fetch_timeline_by_slug: " + slug) instid = memcache.get(slug) if instid: # if slug was a tlid, then we found the cached version and it should # be reconstituted. Otherwise we found the tlid try: tl = pickle.loads(instid) return tl except: return fetch_timeline_by_id(instid) # If slug is all numbers, look it up as a tlid if re.match(r'^[0-9]+$', slug): return fetch_timeline_by_id(slug) vq = appuser.VizQuery(Timeline, "WHERE slug=:1 LIMIT 1", slug) instances = vq.fetch(1, read_policy=db.EVENTUAL_CONSISTENCY, deadline=20) if len(instances) > 0: timeline = instances[0] memcache.set(slug, str(timeline.key().id())) appuser.cached_put(None, timeline) return timeline return None
def post(self): if not appuser.verify_secure_comms(self): return acc = appuser.authenticated(self.request) if not acc: return srverr(self, 401, "Authentication failed") params = appuser.read_params(self, ["orgid", "userid", "lev"]) if not params["orgid"] or int(params["orgid"]) != acc.orgid: return appuser.srverr(self, 403, "Not your Organization") orgid = int(params["orgid"]) userid = int(params["userid"]) lev = int(params["lev"]) if acc.key().id() != userid and acc.lev != 2: return appuser.srverr(self, 403, "Not an Administrator") if acc.key().id() == userid and lev > acc.lev: return appuser.srverr(self, 403, "Can't promote yourself") user = appuser.AppUser.get_by_id(userid) if lev < 0: user.orgid = 0 user.lev = 0 else: user.lev = lev appuser.cached_put(user.email, user) appuser.return_json(self, [])
def update_or_create_timeline(handler, acc, params): timeline = None now = appuser.nowISO() instid = params["instid"] or 0 cname = canonize(params["name"]) vq = appuser.VizQuery(Timeline, "WHERE cname=:1 LIMIT 1", cname) tls = vq.fetch(1, read_policy=db.EVENTUAL_CONSISTENCY, deadline=20) if len(tls) > 0: if int(instid) != tls[0].key().id(): return appuser.srverr(handler, 406, "Name already used") timeline = tls[0] if instid and not timeline: timeline = Timeline.get_by_id(int(instid)) if not timeline: return appuser.srverr(handler, 404, "No Timeline " + instid) if not may_edit_timeline(handler, acc, timeline): return if not timeline: # not found, create new timeline = Timeline(name=params["name"], created=now) timeline.name = params["name"] timeline.cname = canonize(timeline.name) timeline.slug = params["slug"] or "" timeline.title = params["title"] or "" timeline.subtitle = params["subtitle"] or "" timeline.featured = params["featured"] or "" timeline.lang = params["lang"] or "en-US" timeline.comment = params["comment"] or "" timeline.about = params["about"] or "" timeline.ctype = params["ctype"] timeline.cids = params["cids"] or "" timeline.svs = params["svs"] or "" timeline.preb = rebuild_prebuilt_timeline_points(timeline) timeline.orgid = timeline.orgid or acc.orgid timeline.modified = now appuser.cached_put(None, timeline) return timeline