def updpt(): """ Standard app POST call to update a Point. """ try: appuser, _ = util.authenticate() fields = [ "dsId", "dsType", "modified", "editors", "srctl", "source", "date", "text", "refs", "qtype", "communities", "regions", "categories", "tags", "srclang", "translations", "stats" ] ptdat = util.set_fields_from_reqargs(fields, {}) dbpt = verify_edit_authorization(appuser, ptdat) if dbpt: dbst = dbpt.get("srctl") if dbst and (dbst != ptdat.get("srctl")): raise ValueError("Source Timeline may not be changed.") util.fill_missing_fields(fields, dbpt, ptdat) else: # making a new instance for fld in ["srctl", "date", "text"]: if not ptdat.get(fld): # required point field value raise ValueError("Point " + fld + " value is required.") # date format validity checking is done client side remove_html_from_point_fields(ptdat) ptdat["lmuid"] = appuser["dsId"] pt = dbacc.write_entity(ptdat, ptdat.get("modified", "")) except ValueError as e: return util.serve_value_error(e) return util.respJSON(pt)
def updtl(): """ Standard app POST call to update a Timeline. """ try: appuser, _ = util.authenticate() tlfs = [ "dsId", "dsType", "modified", "editors", "name", "slug", "title", "subtitle", "featured", "lang", "comment", "about", "kwds", "ctype", "cids", "rempts", "svs" ] tldat = util.set_fields_from_reqargs(tlfs, {}) # logging.info("updtl received: " + json.dumps(tldat)) tldb = verify_edit_authorization(appuser, tldat) if tldb: util.fill_missing_fields(tlfs, tldb, tldat) util.set_fields_from_reqargs(tlfs, tldat) # for fields set to "" tldat["cname"] = canonize(tldat.get("name", "")) verify_unique_timeline_field(tldat, "cname", tldb) verify_unique_timeline_field(tldat, "slug", tldb) if tldat.get("featured") == "Promoted": if not tldb or (tldb.get("featured") != "Promoted"): raise ValueError("Promoted feature not authorized") update_prebuilt(tldat, tldb) tldat["lmuid"] = appuser["dsId"] tl = dbacc.write_entity(tldat, tldat.get("modified", "")) except ValueError as e: return util.serve_value_error(e) return util.respJSON(tl)
def fetchtl(): """ Return the requested timeline and note the fetch. """ try: tlid = dbacc.reqarg("tlid", "dbid") if tlid: tl = dbacc.cfbk("Timeline", "dsId", str(tlid), required=True) else: slug = dbacc.reqarg("slug", "string") if not slug: slug = "default" slug = slug.lower() # in case someone camelcased the url. tl = dbacc.cfbk("Timeline", "slug", slug, required=True) tls = contained_timelines(tl) # Note the timeline was fetched for daily stats tracking det = { "referer": flask.request.headers.get("Referer", ""), "useragent": flask.request.headers.get("User-Agent", ""), "tlid": tl["dsId"], "tlname": tl["name"], "uid": dbacc.reqarg("uid", "dbid") } dcd = { "dsType": "DayCount", "tstamp": dbacc.timestamp(), "rtype": "tlfetch", "detail": json.dumps(det) } dbacc.write_entity(dcd) except ValueError as e: return util.serve_value_error(e) return util.respJSON(tls)
def featured(): """ Return currently featured timelines to select from. """ try: where = [] for badval in ["Unlisted", "Archived", "Deleted"]: where.append("featured != \"" + badval + "\"") where = "WHERE " + " AND ".join(where) tls = dbacc.query_entity("Timeline", where) except ValueError as e: return util.serve_value_error(e) return util.respJSON(tls)
def findcomps(): """ Return completions from other people for the given timeline. """ try: appuser, _ = util.authenticate() tlid = dbacc.reqarg("tlid", "dbid", required=True) where = ("WHERE tlid = " + tlid + " AND userid != " + appuser["dsId"] + " ORDER BY modified DESC LIMIT 50") tlcs = dbacc.query_entity("TLComp", where) except ValueError as e: return util.serve_value_error(e) return util.respJSON(tlcs)
def fetchobj(): """ General purpose object retrieval, public info only. """ oj = "" try: dsType = dbacc.reqarg("dt", "string", required=True) keyfld = dbacc.reqarg("ak", "string") # alternate key if keyfld: fldval = dbacc.reqarg("kv", "string", required=True) else: keyfld = "dsId" fldval = dbacc.reqarg("di", "string", required=True) inst = dbacc.cfbk(dsType, keyfld, fldval) if not inst: raise ValueError(dsType + " " + keyfld + ": " + fldval + " not found") oj = util.safe_JSON(inst) except ValueError as e: return util.serve_value_error(e) return util.respJSON("[" + oj + "]")
def notecomp(): """ Note Timeline completion in TLComp instance. """ try: appuser, token = util.authenticate() tlc = { "dsType": "TLComp", "userid": appuser["dsId"], "username": appuser["name"] } tlc = util.set_fields_from_reqargs( ["tlid", "tlname", "tltitle", "tlsubtitle"], tlc) proginst = pop_proginst_from_started(appuser, tlc["tlid"]) tlc["data"] = json.dumps(proginst) tlc = dbacc.write_entity(tlc) push_or_update_completion(appuser, tlc, proginst) appuser = dbacc.write_entity(appuser, appuser["modified"]) dbacc.entcache.cache_put(appuser) # ensure cache has latest except ValueError as e: return util.serve_value_error(e) return util.respJSON([appuser, token], audience="private")
def notefs(): """ Note first save of Timeline progress. """ # normally called to make note of an anonymous user having reached the # first save point in a timeline. Shows someone interacted with the # timeline even if they don't create an account. try: det = { "useragent": flask.request.headers.get("User-Agent", ""), "tlid": dbacc.reqarg("tlid", "dbid"), "tlname": dbacc.reqarg("tlname", "string"), "uid": dbacc.reqarg("uid", "dbid") } dcd = { "dsType": "DayCount", "tstamp": dbacc.timestamp(), "rtype": "guestsave", "detail": json.dumps(det) } dbacc.write_entity(dcd) except ValueError as e: return util.serve_value_error(e) return util.respJSON("[]")