def mn(m, n, num_layers=2, overlay=False): assert num_layers >= 1 bases = [cint(m**(1. / num_layers))] * num_layers k = m result = [] for i in range(num_layers): layer = [] next_base = cint(bases[i] * ((n * 1. / k)**(1. / (num_layers - i)))) next_bases = bases[:i] + [next_base] + bases[i + 1:] for x in xrange(reduce(lambda x, y: x * y, bases, 1)): xseq = num_to_seq(x, bases) if not overlay: out = set([ seq_to_num(xseq[:i] + [j] + xseq[i + 1:], next_bases) for j in xrange(next_bases[i]) ]) else: out = set([ seq_to_num(xseq[:l] + [j] + xseq[l + 1:], next_bases) for l in xrange(num_layers) for j in xrange(next_bases[l]) ]) layer.append(list(out)) k = max_idx(layer) bases = next_bases result.append(layer) return result
def mn(m, n, stages=3, strict_nonblocking=False, augment=False): assert stages % 2 == 1 if stages == 1: # return mxn full connection return [[range(n)] * m] # otherwise, build the network recursively n1, n2 = _solve(m, n, strict_nonblocking) k = (n1 + n2 - 1) if strict_nonblocking else max(n1, n2) r1 = cint(m * 1. / n1) r2 = cint(n * 1. / n2) layers = [] # Build the first stage blocks = [[[range(k)] * n1]] * r1 layers.extend(stack(*blocks)) # Connect the first stage with the core switch network layers.append(_xlink(r1, k)) # Recursively build the core switch network blocks = [mn(r1, r2, stages - 2, strict_nonblocking)] * k layers.extend(stack(*blocks)) # Connect the core switch network with the last stage layers.append(_xlink(k, r2)) # Build the last stage blocks = [[[range(n2)] * k]] * r2 layers.extend(stack(*blocks)) return layers
def gkd(dbo, m, f, usetoday = False): """ reads field f from map m, returning a display date. string is empty if key not present or date is invalid. If usetoday is set to True, then today's date is returned if the date is blank. """ if not m.has_key(f): return "" lv = str(m[f]) # If there's a space, then I guess we have time info - throw it away if lv.find(" ") > 0: lv = lv[0:lv.find(" ")] # Now split it by either / or - b = lv.split("/") if lv.find("-") != -1: b = lv.split("-") # We should have three date bits now if len(b) != 3: # We don't have a valid date, if use today is on return that if usetoday: return i18n.python2display(dbo.locale, i18n.now(dbo.timezone)) else: return "" else: # Which of our 3 bits is the year? if utils.cint(b[0]) > 1900: # it's Y/M/D d = datetime.datetime(utils.cint(b[0]), utils.cint(b[1]), utils.cint(b[2])) elif dbo.locale == "en": # Assume it's M/D/Y for US d = datetime.datetime(utils.cint(b[2]), utils.cint(b[0]), utils.cint(b[1])) else: # Assume it's D/M/Y d = datetime.datetime(utils.cint(b[2]), utils.cint(b[1]), utils.cint(b[0])) return i18n.python2display(dbo.locale, d)
def parse_time(d, t): """ Parses the time t and combines it with python date d """ if d is None: return None tbits = t.split(":") hour = 0 minute = 0 second = 0 if len(tbits) > 0: hour = utils.cint(tbits[0]) if len(tbits) > 1: minute = utils.cint(tbits[1]) if len(tbits) > 2: second = utils.cint(tbits[2]) t = datetime.time(hour, minute, second) d = d.combine(d, t) return d
def get_animalcontrol_find_simple(dbo, query = "", limit = 0): """ Returns rows for simple animal control searches. query: The search criteria """ ors = [] query = query.replace("'", "`") def add(field): return utils.where_text_filter(dbo, field, query) # If no query has been given, show open animal control records # from the last 30 days if query == "": ors.append("ac.IncidentDateTime > %s AND ac.CompletedDate Is Null" % db.dd(subtract_days(now(dbo.timezone), 30))) else: if utils.is_numeric(query): ors.append("ac.ID = " + str(utils.cint(query))) ors.append(add("co.OwnerName")) ors.append(add("ti.IncidentName")) ors.append(add("ac.DispatchAddress")) ors.append(add("ac.DispatchPostcode")) ors.append(add("o1.OwnerName")) ors.append(add("o2.OwnerName")) ors.append(add("o3.OwnerName")) ors.append(add("vo.OwnerName")) ors.append(u"EXISTS(SELECT ad.Value FROM additional ad " \ "INNER JOIN additionalfield af ON af.ID = ad.AdditionalFieldID AND af.Searchable = 1 " \ "WHERE ad.LinkID=ac.ID AND ad.LinkType IN (%s) AND LOWER(ad.Value) LIKE '%%%s%%')" % (additional.INCIDENT_IN, query.lower())) if not dbo.is_large_db: ors.append(add("ac.CallNotes")) ors.append(add("ac.AnimalDescription")) sql = get_animalcontrol_query(dbo) + " WHERE " + " OR ".join(ors) if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
def get_foundanimal_find_simple(dbo, query = "", limit = 0): """ Returns rows for simple found animal searches. query: The search criteria """ ors = [] query = query.replace("'", "`") def add(field): return utils.where_text_filter(dbo, field, query) # If no query has been given, show unreturned found animal records # for the last 30 days if query == "": ors.append("a.DateFound > %s AND a.ReturnToOwnerDate Is Null" % db.dd(subtract_days(now(dbo.timezone), 30))) else: if utils.is_numeric(query): ors.append("a.ID = " + str(utils.cint(query))) ors.append(add("o.OwnerName")) ors.append(add("a.AreaFound")) ors.append(add("a.AreaPostcode")) ors.append(u"EXISTS(SELECT ad.Value FROM additional ad " \ "INNER JOIN additionalfield af ON af.ID = ad.AdditionalFieldID AND af.Searchable = 1 " \ "WHERE ad.LinkID=a.ID AND ad.LinkType IN (%s) AND LOWER(ad.Value) LIKE '%%%s%%')" % (additional.FOUNDANIMAL_IN, query.lower())) if not dbo.is_large_db: ors.append(add("x.Sex")) ors.append(add("b.BreedName")) ors.append(add("c.BaseColour")) ors.append(add("s.SpeciesName")) ors.append(add("a.AgeGroup")) ors.append(add("a.DistFeat")) ors.append(add("a.Comments")) sql = get_foundanimal_query(dbo) + " WHERE " + " OR ".join(ors) if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
def get_lostanimal_find_simple(dbo, query="", limit=0, onlyindexed=False): """ Returns rows for simple lost animal searches. query: The search criteria """ ors = [] query = query.replace("'", "`") def add(field): return utils.where_text_filter(dbo, field, query) # If no query has been given, show unfound lost animal records # for the last 30 days if query == "": ors.append("a.DateLost > %s AND a.DateFound Is Null" % db.dd(subtract_days(now(dbo.timezone), 30))) else: if utils.is_numeric(query): ors.append("a.ID = " + str(utils.cint(query))) ors.append(add("o.OwnerName")) ors.append(add("a.AreaLost")) ors.append(add("a.AreaPostcode")) if not onlyindexed: ors.append(add("x.Sex")) ors.append(add("b.BreedName")) ors.append(add("c.BaseColour")) ors.append(add("s.SpeciesName")) ors.append(add("a.AgeGroup")) ors.append(add("a.DistFeat")) ors.append(add("a.Comments")) sql = get_lostanimal_query(dbo) + " WHERE " + " OR ".join(ors) if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
def housenumber(s): # Return the full address if the first word is not numeric bits = s.strip().split(" ") houseno = s if len(bits) > 0 and utils.cint(bits[0]) > 0: houseno = bits[0] return houseno
def get_treatments_outstanding(dbo, offset="m31", locationfilter=""): """ Returns a recordset of shelter animals awaiting medical treatments: offset is m to go backwards, or p to go forwards with a number of days. ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, TREATMENTNAME, COST, COMMENTS, NAMEDFREQUENCY, NAMEDNUMBEROFTREATMENTS, NAMEDSTATUS, DOSAGE, STARTDATE, TREATMENTSGIVEN, TREATMENTSREMAINING, TIMINGRULE, TIMINGRULEFREQUENCY, TIMINGRULENOFREQUENCIES, TREATMENTRULE TOTALNUMBEROFTREATMENTS, DATEREQUIRED, DATEGIVEN, TREATMENTCOMMENTS, TREATMENTNUMBER, TOTALTREATMENTS, GIVENBY, REGIMENID, TREATMENTID """ ec = "" offsetdays = utils.cint(offset[1:]) if offset.startswith("m"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone))) if offset.startswith("p"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( now(dbo.timezone)), db.dd(add_days(now(dbo.timezone), offsetdays))) if locationfilter != "": locationfilter = " AND ShelterLocation IN (%s)" % locationfilter return embellish_regimen(dbo.locale, db.query(dbo, "SELECT * FROM v_animalmedicaltreatment " \ "WHERE DateRequired Is Not Null AND DateGiven Is Null " \ "AND Status = 0 " \ "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \ "ORDER BY DateRequired, AnimalName" % (ec, locationfilter)))
def get_lostanimal_find_simple(dbo, query = "", limit = 0, onlyindexed = False): """ Returns rows for simple lost animal searches. query: The search criteria """ ors = [] query = query.replace("'", "`") def add(field): return utils.where_text_filter(dbo, field, query) # If no query has been given, show unfound lost animal records # for the last 30 days if query == "": ors.append("a.DateLost > %s AND a.DateFound Is Null" % db.dd(subtract_days(now(dbo.timezone), 30))) else: if utils.is_numeric(query): ors.append("a.ID = " + str(utils.cint(query))) ors.append(add("OwnerName")) ors.append(add("AreaLost")) ors.append(add("AreaPostcode")) if not onlyindexed: ors.append(add("SexName")) ors.append(add("BreedName")) ors.append(add("BaseColourName")) ors.append(add("SpeciesName")) ors.append(add("AgeGroup")) ors.append(add("DistFeat")) ors.append(add("Comments")) sql = get_lostanimal_query() + " WHERE " + " OR ".join(ors) if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
def get_animalcontrol_find_simple(dbo, query="", limit=0, onlyindexed=False): """ Returns rows for simple animal control searches. query: The search criteria """ ors = [] query = query.replace("'", "`") def add(field): return utils.where_text_filter(dbo, field, query) # If no query has been given, show open animal control records # from the last 30 days if query == "": ors.append("ac.IncidentDateTime > %s AND ac.CompletedDate Is Null" % db.dd(subtract_days(now(dbo.timezone), 30))) else: if utils.is_numeric(query): ors.append("ac.ID = " + str(utils.cint(query))) ors.append(add("co.OwnerName")) ors.append(add("ti.IncidentName")) ors.append(add("ac.DispatchAddress")) ors.append(add("ac.DispatchPostcode")) ors.append(add("o1.OwnerName")) ors.append(add("o2.OwnerName")) ors.append(add("o3.OwnerName")) ors.append(add("vo.OwnerName")) if not onlyindexed: ors.append(add("ac.CallNotes")) ors.append(add("ac.AnimalDescription")) sql = get_animalcontrol_query(dbo) + " WHERE " + " OR ".join(ors) if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
def get_donations(dbo, offset="m31"): """ Returns a recordset of donations offset is m to go backwards, or p to go forwards with a number of days. ID, DONATIONTYPEID, DONATIONNAME, DATE, DATEDUE, DONATION, ISGIFTAID, FREQUENCY, FREQUENCYNAME, NEXTCREATED, COMMENTS, OWNERNAME, ANIMALNAME, SHELTERCODE, OWNERID, ANIMALID """ ec = "" order = "" offsetdays = utils.cint(offset[1:]) if offset.startswith("m"): ec = "Date >= %s AND Date <= %s" % (db.dd( i18n.subtract_days(i18n.now(dbo.timezone), offsetdays)), db.dd(i18n.now(dbo.timezone))) order = "Date DESC" elif offset.startswith("p"): ec = "Date Is Null AND DateDue >= %s AND DateDue <= %s" % ( db.dd(i18n.now(dbo.timezone)), db.dd(i18n.add_days(i18n.now(dbo.timezone), offsetdays))) order = "DateDue DESC" elif offset.startswith("d"): ec = "Date Is Null AND DateDue <= %s" % (db.dd(i18n.now(dbo.timezone))) order = "DateDue" return db.query(dbo, "SELECT * FROM v_ownerdonation " \ "WHERE %s " "ORDER BY %s" % (ec, order))
def get_foundanimal_find_simple(dbo, query = "", limit = 0, siteid = 0): """ Returns rows for simple found animal searches. query: The search criteria """ ss = utils.SimpleSearchBuilder(dbo, query) sitefilter = "" if siteid != 0: sitefilter = " AND (o.SiteID = 0 OR o.SiteID = %d)" % siteid # If no query has been given, show unfound lost animal records # for the last 30 days if query == "": ss.ors.append("a.DateFound > ? AND a.ReturnToOwnerDate Is Null %s" % sitefilter) ss.values.append(dbo.today(offset=-30)) else: if utils.is_numeric(query): ss.add_field_value("a.ID", utils.cint(query)) ss.add_fields([ "o.OwnerName", "a.AreaFound", "a.AreaPostcode" ]) ss.add_clause("EXISTS(SELECT ad.Value FROM additional ad " \ "INNER JOIN additionalfield af ON af.ID = ad.AdditionalFieldID AND af.Searchable = 1 " \ "WHERE ad.LinkID=a.ID AND ad.LinkType IN (%s) AND LOWER(ad.Value) LIKE ?)" % additional.FOUNDANIMAL_IN) ss.add_large_text_fields([ "b.BreedName", "a.DistFeat", "a.Comments" ]) sql = "%s WHERE a.ID > 0 %s AND (%s)" % (get_foundanimal_query(dbo), sitefilter, " OR ".join(ss.ors)) return dbo.query(sql, ss.values, limit=limit, distincton="ID")
def get_waitinglist_find_simple(dbo, query="", limit=0, siteid=0): """ Returns rows for simple waiting list searches. query: The search criteria """ ss = utils.SimpleSearchBuilder(dbo, query) sitefilter = "" if siteid != 0: sitefilter = " AND (o.SiteID = 0 OR o.SiteID = %d)" % siteid # If no query has been given, do a current waitinglist search if query == "": return get_waitinglist(dbo) if utils.is_numeric(query): ss.add_field_value("a.ID", utils.cint(query)) ss.add_field("o.OwnerName") ss.add_clause("EXISTS(SELECT ad.Value FROM additional ad " \ "INNER JOIN additionalfield af ON af.ID = ad.AdditionalFieldID AND af.Searchable = 1 " \ "WHERE ad.LinkID=a.ID AND ad.LinkType IN (%s) AND LOWER(ad.Value) LIKE ?)" % additional.WAITINGLIST_IN) ss.add_large_text_fields([ "a.AnimalDescription", "a.ReasonForWantingToPart", "a.ReasonForRemoval" ]) sql = "%s WHERE a.ID > 0 %s AND (%s) ORDER BY a.ID" % ( get_waitinglist_query(dbo), sitefilter, " OR ".join(ss.ors)) return dbo.query(sql, ss.values, limit=limit, distincton="ID")
def update_movement_donation(dbo, movementid): """ Goes through all donations attached to a particular movement and updates the denormalised movement total. """ if utils.cint(movementid) == 0: return dbo.execute("UPDATE adoption SET Donation = " \ "(SELECT SUM(Donation) FROM ownerdonation WHERE MovementID = ?) WHERE ID = ?", (movementid, movementid))
def now(self, timenow=True, offset=0, settime=""): """ Returns now as a Python date, adjusted for the database timezone. timenow: if True, includes the current time offset: Add this many days to now (negative values supported) settime: A time in HH:MM:SS format to set """ d = i18n.now(self.timezone) if not timenow: d = d.replace(hour = 0, minute = 0, second = 0, microsecond = 0) if offset > 0: d = i18n.add_days(d, offset) if offset < 0: d = i18n.subtract_days(d, abs(offset)) if settime != "": timebits = settime.split(":") d = d.replace(hour = utils.cint(timebits[0]), minute = utils.cint(timebits[1]), second = utils.cint(timebits[2]), microsecond = 0) return d
def mn(m, n, num_layers=2, direct=False, overlay=False, augment=False, exchange_func=pm2iplus0): assert num_layers >= 1 # num_layers == 1 means fully connected NN bases = [cint(m ** (1./num_layers))] * num_layers k = m result = [] for i in range(num_layers): next_base = cint(bases[-1] * ((n*1./k) ** (1./(num_layers-i)))) # print "[n%d][k%d][num_layers%d][i%d][next_base%d]" % (n, k, num_layers, i, next_base) # print "BASES: ", bases layer = _build_layer(k, bases, direct, overlay, augment, exchange_func, next_base) result.extend(layer) k = max_idx(layer[1]) bases = [next_base] + bases[:-1] return result
def lookingfor_last_match_count(dbo): """ Inspects the cached version of the looking for report and returns the number of animal matches. """ s = dbfs.get_string_filepath(dbo, "/reports/daily/lookingfor.html") sp = s.find("$AM") if sp == -1: return 0 return utils.cint(s[sp+3:s.find("^", sp)])
def update_movement_donation(dbo, movementid): """ Goes through all donations attached to a particular movement and updates the denormalised movement total. """ if utils.cint(movementid) == 0: return db.execute(dbo, "UPDATE adoption SET Donation = " \ "(SELECT SUM(Donation) FROM ownerdonation WHERE MovementID = %d) WHERE ID = %d" % \ (int(movementid), int(movementid)))
def lookingfor_last_match_count(dbo): """ Inspects the cached version of the looking for report and returns the number of animal matches. """ s = dbfs.get_string_filepath(dbo, "/reports/daily/lookingfor.html") sp = s.find("$AM") if sp == -1: return 0 return utils.cint(s[sp + 3:s.find("^", sp)])
def gkd(dbo, m, f, usetoday=False): """ reads field f from map m, returning a display date. string is empty if key not present or date is invalid. If usetoday is set to True, then today's date is returned if the date is blank. """ if f not in m: return "" lv = str(m[f]) # If there's a space, then I guess we have time info - throw it away if lv.find(" ") > 0: lv = lv[0:lv.find(" ")] # Now split it by either / or - b = lv.split("/") if lv.find("-") != -1: b = lv.split("-") # We should have three date bits now if len(b) != 3: # We don't have a valid date, if use today is on return that if usetoday: return i18n.python2display(dbo.locale, i18n.now(dbo.timezone)) else: return "" else: try: # Which of our 3 bits is the year? if utils.cint(b[0]) > 1900: # it's Y/M/D d = datetime.datetime(utils.cint(b[0]), utils.cint(b[1]), utils.cint(b[2])) elif dbo.locale == "en": # Assume it's M/D/Y for US d = datetime.datetime(utils.cint(b[2]), utils.cint(b[0]), utils.cint(b[1])) else: # Assume it's D/M/Y d = datetime.datetime(utils.cint(b[2]), utils.cint(b[1]), utils.cint(b[0])) return i18n.python2display(dbo.locale, d) except: # We've got an invalid date - return today if usetoday: return i18n.python2display(dbo.locale, i18n.now(dbo.timezone)) else: return ""
def insert_onlineformincoming_from_form(dbo, post, remoteip): """ Create onlineformincoming records from posted data. We create a row for every key/value pair in the posted data with a unique collation ID. """ IGNORE_FIELDS = [ "formname", "flags", "redirect", "account", "filechooser", "method" ] collationid = db.query_int(dbo, "SELECT MAX(CollationID) FROM onlineformincoming") + 1 formname = post["formname"] posteddate = i18n.now(dbo.timezone) flags = post["flags"] for k, v in post.data.iteritems(): if k not in IGNORE_FIELDS: label = "" displayindex = 0 fieldname = k # Form fields should have a _ONLINEFORMFIELD.ID suffix we can use to get the # original label and display position if k.find("_") != -1: fid = utils.cint(k[k.rfind("_")+1:]) fieldname = k[0:k.rfind("_")] if fid != 0: fld = db.query(dbo, "SELECT Label, DisplayIndex FROM onlineformfield WHERE ID = %d" % fid) if len(fld) > 0: label = fld[0]["LABEL"] displayindex = fld[0]["DISPLAYINDEX"] sql = db.make_insert_sql("onlineformincoming", ( ( "CollationID", db.di(collationid)), ( "FormName", db.ds(formname)), ( "PostedDate", db.ddt(posteddate)), ( "Flags", db.ds(flags)), ( "FieldName", db.ds(fieldname)), ( "Label", db.ds(label)), ( "DisplayIndex", db.di(displayindex)), ( "Host", db.ds(remoteip)), ( "Value", post.db_string(k)) )) db.execute(dbo, sql) # Sort out the preview of the first few fields fieldssofar = 0 preview = [] for fld in get_onlineformincoming_detail(dbo, collationid): if fieldssofar < 3: fieldssofar += 1 preview.append( fld["LABEL"] + ": " + fld["VALUE"] ) db.execute(dbo, "UPDATE onlineformincoming SET Preview = %s WHERE CollationID = %s" % ( db.ds(", ".join(preview)), db.di(collationid) )) # Did the original form specify some email addresses to send # incoming submissions to? email = db.query_string(dbo, "SELECT o.EmailAddress FROM onlineform o " \ "INNER JOIN onlineformincoming oi ON oi.FormName = o.Name " \ "WHERE oi.CollationID = %d" % int(collationid)) if email is not None and email.strip() != "": utils.send_email(dbo, configuration.email(dbo), email, "", "%s - %s" % (formname, ", ".join(preview)), get_onlineformincoming_plain(dbo, collationid)) return collationid
def insert_onlineformincoming_from_form(dbo, data, remoteip): """ Create onlineformincoming records from posted data. We create a row for every key/value pair in the posted data with a unique collation ID. """ IGNORE_FIELDS = [ "formname", "flags", "redirect", "account", "filechooser", "method" ] collationid = db.query_int( dbo, "SELECT MAX(CollationID) FROM onlineformincoming") + 1 formname = utils.df_ks(data, "formname") posteddate = i18n.now(dbo.timezone) flags = utils.df_ks(data, "flags") for k, v in data.iteritems(): if k not in IGNORE_FIELDS: label = "" displayindex = 0 fieldname = k # Form fields should have a _ONLINEFORMFIELD.ID suffix we can use to get the # original label and display position if k.find("_") != -1: fid = utils.cint(k[k.rfind("_") + 1:]) fieldname = k[0:k.rfind("_")] if fid != 0: fld = db.query( dbo, "SELECT Label, DisplayIndex FROM onlineformfield WHERE ID = %d" % fid) if len(fld) > 0: label = fld[0]["LABEL"] displayindex = fld[0]["DISPLAYINDEX"] sql = db.make_insert_sql( "onlineformincoming", (("CollationID", db.di(collationid)), ("FormName", db.ds(formname)), ("PostedDate", db.ddt(posteddate)), ("Flags", db.ds(flags)), ("FieldName", db.ds(fieldname)), ("Label", db.ds(label)), ("DisplayIndex", db.di(displayindex)), ("Host", db.ds(remoteip)), ("Value", db.ds(v)))) db.execute(dbo, sql) # Sort out the preview of the first few fields fieldssofar = 0 preview = [] for fld in get_onlineformincoming_detail(dbo, collationid): if fieldssofar < 3: fieldssofar += 1 preview.append(fld["LABEL"] + ": " + fld["VALUE"]) db.execute( dbo, "UPDATE onlineformincoming SET Preview = %s WHERE CollationID = %s" % (db.ds(", ".join(preview)), db.di(collationid))) return collationid
def update_appointment_total(dbo, appointmentid): """ Calculates the amount and VAT on an appointment/invoice """ a = get_appointment(dbo, appointmentid) total = dbo.query_int( "SELECT SUM(Amount) FROM clinicinvoiceitem WHERE ClinicAppointmentID = ? AND Amount Is Not Null AND Amount > 0", [appointmentid]) vatamount = 0 if a.ISVAT == 1 and a.VATRATE > 0: vatamount = utils.cint(total * (a.VATRATE / 100.0)) dbo.update("clinicappointment", appointmentid, { "Amount": total, "VATAmount": vatamount })
def insert_onlineformincoming_from_form(dbo, data, remoteip): """ Create onlineformincoming records from posted data. We create a row for every key/value pair in the posted data with a unique collation ID. """ IGNORE_FIELDS = [ "formname", "flags", "redirect", "account", "filechooser", "method" ] collationid = db.query_int(dbo, "SELECT MAX(CollationID) FROM onlineformincoming") + 1 formname = utils.df_ks(data, "formname") posteddate = i18n.now(dbo.timezone) flags = utils.df_ks(data, "flags") for k, v in data.iteritems(): if k not in IGNORE_FIELDS: label = "" displayindex = 0 fieldname = k # Form fields should have a _ONLINEFORMFIELD.ID suffix we can use to get the # original label and display position if k.find("_") != -1: fid = utils.cint(k[k.rfind("_")+1:]) fieldname = k[0:k.rfind("_")] if fid != 0: fld = db.query(dbo, "SELECT Label, DisplayIndex FROM onlineformfield WHERE ID = %d" % fid) if len(fld) > 0: label = fld[0]["LABEL"] displayindex = fld[0]["DISPLAYINDEX"] sql = db.make_insert_sql("onlineformincoming", ( ( "CollationID", db.di(collationid)), ( "FormName", db.ds(formname)), ( "PostedDate", db.ddt(posteddate)), ( "Flags", db.ds(flags)), ( "FieldName", db.ds(fieldname)), ( "Label", db.ds(label)), ( "DisplayIndex", db.di(displayindex)), ( "Host", db.ds(remoteip)), ( "Value", db.ds(v)) )) db.execute(dbo, sql) # Sort out the preview of the first few fields fieldssofar = 0 preview = [] for fld in get_onlineformincoming_detail(dbo, collationid): if fieldssofar < 3: fieldssofar += 1 preview.append( fld["LABEL"] + ": " + fld["VALUE"] ) db.execute(dbo, "UPDATE onlineformincoming SET Preview = %s WHERE CollationID = %s" % ( db.ds(", ".join(preview)), db.di(collationid) )) return collationid
def stock_take_from_mobile_form(dbo, username, post): """ Post should contain sl{ID} values for new balances. """ if post.integer("usagetype") == 0: raise utils.ASMValidationError("No usage type passed") for k in post.data.iterkeys(): if k.startswith("sl"): slid = utils.cint(k.replace("sl", "")) sl = get_stocklevel(dbo, slid) slb = utils.cfloat(sl["BALANCE"]) # balance sln = post.floating(k) # new balance # If the balance hasn't changed, do nothing if slb == sln: continue # Update the level db.execute(dbo, "UPDATE stocklevel SET Balance = %f WHERE ID = %d" % ( sln, slid )) # Write a stock usage record for the difference insert_stockusage(dbo, username, slid, sln - slb, now(dbo.timezone), post.integer("usagetype"), "")
def get_tests_outstanding(dbo, offset = "m31", locationfilter = ""): """ Returns a recordset of animals awaiting tests: offset is m to go backwards, or p to go forwards with a number of days. ID, ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, DATEREQUIRED, DATEOFTEST, COMMENTS, TESTNAME, RESULTNAME, TESTTYPEID """ ec = "" offsetdays = utils.cint(offset[1:]) if offset.startswith("m"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone))) if offset.startswith("p"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(now(dbo.timezone)), db.dd( add_days(now(dbo.timezone), offsetdays))) if locationfilter != "": locationfilter = " AND ShelterLocation IN (%s)" % locationfilter return db.query(dbo, "SELECT * FROM v_animaltest " \ "WHERE DateRequired Is Not Null AND DateOfTest Is Null " \ "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \ "ORDER BY DateRequired, AnimalName" % (ec, locationfilter))
def get_vaccinations_outstanding(dbo, offset = "m31", locationfilter = ""): """ Returns a recordset of animals awaiting vaccinations: offset is m to go backwards, or p to go forwards with a number of days. locationfilter is a comma separated list of internal locations to include animals in ID, ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, DATEREQUIRED, DATEOFVACCINATION, COMMENTS, VACCINATIONTYPE, VACCINATIONID """ ec = "" offsetdays = utils.cint(offset[1:]) if offset.startswith("m"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone))) if offset.startswith("p"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(now(dbo.timezone)), db.dd( add_days(now(dbo.timezone), offsetdays))) if locationfilter != "": locationfilter = " AND ShelterLocation IN (%s)" % locationfilter return db.query(dbo, "SELECT * FROM v_animalvaccination " \ "WHERE DateRequired Is Not Null AND DateOfVaccination Is Null " \ "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \ "ORDER BY DateRequired, AnimalName" % (ec, locationfilter))
def stock_take_from_mobile_form(dbo, username, post): """ Post should contain sl{ID} values for new balances. """ if post.integer("usagetype") == 0: raise utils.ASMValidationError("No usage type passed") for k in post.data.iterkeys(): if k.startswith("sl"): slid = utils.cint(k.replace("sl", "")) sl = get_stocklevel(dbo, slid) slb = utils.cfloat(sl.BALANCE) # balance sln = post.floating(k) # new balance # If the balance hasn't changed, do nothing if slb == sln: continue # Update the level dbo.update("stocklevel", slid, {"Balance": sln}) # Write a stock usage record for the difference insert_stockusage(dbo, username, slid, sln - slb, now(dbo.timezone), post.integer("usagetype"), "")
def get_waitinglist_find_simple(dbo, query = "", limit = 0, onlyindexed = False): """ Returns rows for simple waiting list searches. query: The search criteria """ # If no query has been given, do a current waitinglist search if query == "": return get_waitinglist(dbo) ors = [] add = lambda f: "LOWER(%s) LIKE '%%%s%%'" % (f, query.lower()) if utils.is_numeric(query): ors.append("a.ID = " + str(utils.cint(query))) ors.append(add("a.OwnerName")) ors.append(add("a.AnimalDescription")) if not onlyindexed: ors.append(add("a.ReasonForWantingToPart")) ors.append(add("a.ReasonForRemoval")) sql = get_waitinglist_query() + " WHERE " + " OR ".join(ors) if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
def get_waitinglist_find_simple(dbo, query="", limit=0, onlyindexed=False): """ Returns rows for simple waiting list searches. query: The search criteria """ # If no query has been given, do a current waitinglist search if query == "": return get_waitinglist(dbo) ors = [] add = lambda f: "LOWER(%s) LIKE '%%%s%%'" % (f, query.lower()) if utils.is_numeric(query): ors.append("a.ID = " + str(utils.cint(query))) ors.append(add("a.OwnerName")) ors.append(add("a.AnimalDescription")) if not onlyindexed: ors.append(add("a.ReasonForWantingToPart")) ors.append(add("a.ReasonForRemoval")) sql = get_waitinglist_query() + " WHERE " + " OR ".join(ors) if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
def get_tests_outstanding(dbo, offset="m31", locationfilter=""): """ Returns a recordset of animals awaiting tests: offset is m to go backwards, or p to go forwards with a number of days. ID, ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, DATEREQUIRED, DATEOFTEST, COMMENTS, TESTNAME, RESULTNAME, TESTTYPEID """ ec = "" offsetdays = utils.cint(offset[1:]) if offset.startswith("m"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone))) if offset.startswith("p"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( now(dbo.timezone)), db.dd(add_days(now(dbo.timezone), offsetdays))) if locationfilter != "": locationfilter = " AND ShelterLocation IN (%s)" % locationfilter return db.query(dbo, "SELECT * FROM v_animaltest " \ "WHERE DateRequired Is Not Null AND DateOfTest Is Null " \ "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \ "ORDER BY DateRequired, AnimalName" % (ec, locationfilter))
def get_vaccinations_outstanding(dbo, offset="m31", locationfilter=""): """ Returns a recordset of animals awaiting vaccinations: offset is m to go backwards, or p to go forwards with a number of days. locationfilter is a comma separated list of internal locations to include animals in ID, ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, DATEREQUIRED, DATEOFVACCINATION, COMMENTS, VACCINATIONTYPE, VACCINATIONID """ ec = "" offsetdays = utils.cint(offset[1:]) if offset.startswith("m"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone))) if offset.startswith("p"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( now(dbo.timezone)), db.dd(add_days(now(dbo.timezone), offsetdays))) if locationfilter != "": locationfilter = " AND ShelterLocation IN (%s)" % locationfilter return db.query(dbo, "SELECT * FROM v_animalvaccination " \ "WHERE DateRequired Is Not Null AND DateOfVaccination Is Null " \ "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \ "ORDER BY DateRequired, AnimalName" % (ec, locationfilter))
def get_animalcontrol_find_simple(dbo, query="", username="", limit=0, siteid=0): """ Returns rows for simple animal control searches. query: The search criteria """ ss = utils.SimpleSearchBuilder(dbo, query) sitefilter = "" if siteid != 0: sitefilter = " AND (ac.SiteID = 0 OR ac.SiteID = %d)" % siteid # If no query has been given, show open animal control records # from the last 30 days if query == "": ss.ors.append( "ac.IncidentDateTime > %s AND ac.CompletedDate Is Null %s" % (dbo.sql_date(dbo.today(offset=-30)), sitefilter)) else: if utils.is_numeric(query): ss.add_field_value("ac.ID", utils.cint(query)) ss.add_fields([ "co.OwnerName", "ti.IncidentName", "ac.DispatchAddress", "ac.DispatchPostcode", "o1.OwnerName", "o2.OwnerName", "o3.OwnerName", "vo.OwnerName" ]) ss.add_clause(u"EXISTS(SELECT ad.Value FROM additional ad " \ "INNER JOIN additionalfield af ON af.ID = ad.AdditionalFieldID AND af.Searchable = 1 " \ "WHERE ad.LinkID=ac.ID AND ad.LinkType IN (%s) AND LOWER(ad.Value) LIKE ?)" % (additional.INCIDENT_IN)) ss.add_large_text_fields(["ac.CallNotes", "ac.AnimalDescription"]) sql = "%s WHERE ac.ID > 0 %s AND (%s) ORDER BY ac.ID" % ( get_animalcontrol_query(dbo), sitefilter, " OR ".join(ss.ors)) return reduce_find_results( dbo, username, dbo.query(sql, ss.values, limit=limit, distincton="ID"))
def get_donations(dbo, offset = "m31"): """ Returns a recordset of donations offset is m to go backwards, or p to go forwards with a number of days. ID, DONATIONTYPEID, DONATIONNAME, DATE, DATEDUE, DONATION, ISGIFTAID, FREQUENCY, FREQUENCYNAME, NEXTCREATED, COMMENTS, OWNERNAME, ANIMALNAME, SHELTERCODE, OWNERID, ANIMALID """ ec = "" order = "" offsetdays = utils.cint(offset[1:]) if offset.startswith("m"): ec = "Date >= %s AND Date <= %s" % (db.dd( i18n.subtract_days(i18n.now(dbo.timezone), offsetdays)), db.dd(i18n.now(dbo.timezone))) order = "Date DESC" elif offset.startswith("p"): ec = "Date Is Null AND DateDue >= %s AND DateDue <= %s" % (db.dd(i18n.now(dbo.timezone)), db.dd(i18n.add_days(i18n.now(dbo.timezone), offsetdays))) order = "DateDue DESC" elif offset.startswith("d"): ec = "Date Is Null AND DateDue <= %s" % (db.dd(i18n.now(dbo.timezone))) order = "DateDue" return db.query(dbo, "SELECT * FROM v_ownerdonation " \ "WHERE %s " "ORDER BY %s" % (ec, order))
def get_onlineformincoming_html_print(dbo, ids): """ Returns a complete printable version of the online form (header/footer wrapped around the html call above) ids: A list of integer ids """ header = get_onlineform_header(dbo) headercontent = header[header.find("<body>")+6:] header = header[0:header.find("<body>")+6] footer = get_onlineform_footer(dbo) footercontent = footer[0:footer.find("</body>")] h = [] h.append(header) for collationid in ids: h.append(headercontent) formheader = get_onlineformincoming_formheader(dbo, collationid) h.append(formheader) h.append(get_onlineformincoming_html(dbo, utils.cint(collationid))) formfooter = get_onlineformincoming_formfooter(dbo, collationid) h.append(formfooter) h.append(footercontent) h.append('<div style="page-break-before: always;"></div>') h.append("</body></html>") return "\n".join(h)
def get_treatments_outstanding(dbo, offset = "m31", locationfilter = ""): """ Returns a recordset of shelter animals awaiting medical treatments: offset is m to go backwards, or p to go forwards with a number of days. ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, TREATMENTNAME, COST, COMMENTS, NAMEDFREQUENCY, NAMEDNUMBEROFTREATMENTS, NAMEDSTATUS, DOSAGE, STARTDATE, TREATMENTSGIVEN, TREATMENTSREMAINING, TIMINGRULE, TIMINGRULEFREQUENCY, TIMINGRULENOFREQUENCIES, TREATMENTRULE TOTALNUMBEROFTREATMENTS, DATEREQUIRED, DATEGIVEN, TREATMENTCOMMENTS, TREATMENTNUMBER, TOTALTREATMENTS, GIVENBY, REGIMENID, TREATMENTID """ ec = "" offsetdays = utils.cint(offset[1:]) if offset.startswith("m"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone))) if offset.startswith("p"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(now(dbo.timezone)), db.dd( add_days(now(dbo.timezone), offsetdays))) if locationfilter != "": locationfilter = " AND ShelterLocation IN (%s)" % locationfilter return embellish_regimen(dbo.locale, db.query(dbo, "SELECT * FROM v_animalmedicaltreatment " \ "WHERE DateRequired Is Not Null AND DateGiven Is Null " \ "AND Status = 0 " \ "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \ "ORDER BY DateRequired, AnimalName" % (ec, locationfilter)))
def get_foundanimal_find_advanced(dbo, criteria, limit = 0): """ Returns rows for advanced lost animal searches. criteria: A dictionary of criteria number - string partial pattern contact - string partial pattern area - string partial pattern postcode - string partial pattern features - string partial pattern agegroup - agegroup text to match sex - -1 for all or ID species - -1 for all or ID breed - -1 for all or ID colour - -1 for all or ID excludecomplete - 1 for yes datefrom - lost date from in current display locale format dateto - lost date to in current display locale format completefrom - returned date from in current display locale format completeto - returned date to in current display locale format """ c = [] l = dbo.locale post = utils.PostedData(criteria, l) def hk(cfield): return post[cfield] != "" def crit(cfield): return post[cfield] def addid(cfield, field): if hk(cfield) and int(crit(cfield)) != -1: c.append("%s = %s" % (field, crit(cfield))) def addstr(cfield, field): if hk(cfield) and crit(cfield) != "": c.append("LOWER(%s) LIKE '%%%s%%'" % ( field, crit(cfield).lower().replace("'", "`"))) def adddate(cfieldfrom, cfieldto, field): if hk(cfieldfrom) and hk(cfieldto): c.append("%s >= %s AND %s <= %s" % ( field, db.dd(display2python(l, crit(cfieldfrom))), field, db.dd(display2python(l, crit(cfieldto))))) c.append("a.ID > 0") if crit("number") != "": c.append("a.ID = %s" % utils.cint(crit("number"))) addstr("contact", "o.OwnerName") addstr("area", "a.AreaFound") addstr("postcode", "a.AreaPostcode") addstr("features", "a.DistFeat") if (crit("agegroup") != "-1"): addstr("agegroup", "a.AgeGroup") addid("sex", "a.Sex") addid("species", "a.AnimalTypeID") addid("breed", "a.BreedID") addid("colour", "a.BaseColourID") adddate("datefrom", "dateto", "a.DateFound") if crit("excludecomplete") == "1": c.append("a.ReturnToOwnerDate Is Null") elif crit("completefrom") != "" and crit("completeto") != "": adddate("completefrom", "completeto", "a.ReturnToOwnerDate") where = " WHERE " + " AND ".join(c) sql = get_foundanimal_query(dbo) + where + " ORDER BY a.ID" if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
def handler(post, path, remoteip, referer, querystring): """ Handles the various service method types. post: The GET/POST parameters path: The current system path/code.PATH remoteip: The IP of the caller referer: The referer HTTP header querystring: The complete querystring return value is a tuple containing MIME type, max-age, content """ # Get service parameters account = post["account"] username = post["username"] password = post["password"] method = post["method"] animalid = post.integer("animalid") formid = post.integer("formid") seq = post.integer("seq") title = post["title"] strip_personal = post.integer("sensitive") == 0 cache_key = querystring.replace(" ", "") # Do we have a cached response for these parameters? cached_response = get_cached_response(cache_key) if cached_response is not None: al.debug("cache hit for %s" % (cache_key), "service.handler") return cached_response # Are we dealing with multiple databases, but no account was specified? if account == "" and MULTIPLE_DATABASES: return ("text/plain", 0, 0, "ERROR: No database/alias specified") dbo = db.get_database(account) if dbo.database in ("FAIL", "DISABLED", "WRONGSERVER"): al.error( "auth failed - invalid smaccount %s from %s (%s)" % (account, remoteip, dbo.database), "service.handler", dbo) return ("text/plain", 0, 0, "ERROR: Invalid database (%s)" % dbo.database) # If the database has disabled the service API, stop now if not configuration.service_enabled(dbo): al.error("Service API is disabled (%s)" % method, "service.handler", dbo) return ("text/plain", 0, 0, "ERROR: Service API is disabled") # Do any database updates need doing in this db? dbo.installpath = path if dbupdate.check_for_updates(dbo): dbupdate.perform_updates(dbo) # Does the method require us to authenticate? If so, do it. user = None securitymap = "" if method in AUTH_METHODS: # If the database has authenticated service methods disabled, stop now if not configuration.service_auth_enabled(dbo): al.error("Service API for auth methods is disabled (%s)" % method, "service.handler", dbo) return ("text/plain", 0, 0, "ERROR: Service API for authenticated methods is disabled") user = users.authenticate(dbo, username, password) if user is None: al.error( "auth failed - %s/%s is not a valid username/password from %s" % (username, password, remoteip), "service.handler", dbo) return ("text/plain", 0, 0, "ERROR: Invalid username and password") securitymap = users.get_security_map(dbo, user["USERNAME"]) # Get the preferred locale and timezone for the site l = configuration.locale(dbo) dbo.locale = l dbo.timezone = configuration.timezone(dbo) al.info("call %s->%s [%s %s]" % (username, method, str(animalid), title), "service.handler", dbo) if method == "animal_image": hotlink_protect("animal_image", referer) if utils.cint(animalid) == 0: al.error( "animal_image failed, %s is not an animalid" % str(animalid), "service.handler", dbo) return ("text/plain", 0, 0, "ERROR: Invalid animalid") else: mediadate, data = media.get_image_file_data( dbo, "animal", utils.cint(animalid), seq) if data == "NOPIC": mediadate, data = media.get_image_file_data(dbo, "nopic", 0) return set_cached_response(cache_key, "image/jpeg", 86400, 3600, data) elif method == "animal_thumbnail": if utils.cint(animalid) == 0: al.error( "animal_thumbnail failed, %s is not an animalid" % str(animalid), "service.handler", dbo) return ("text/plain", 0, 0, "ERROR: Invalid animalid") else: mediadate, data = media.get_image_file_data( dbo, "animalthumb", utils.cint(animalid), seq) if data == "NOPIC": mediadate, data = media.get_image_file_data(dbo, "nopic", 0) return set_cached_response(cache_key, "image/jpeg", 86400, 86400, data) elif method == "animal_view": if utils.cint(animalid) == 0: al.error( "animal_view failed, %s is not an animalid" % str(animalid), "service.handler", dbo) return ("text/plain", 0, 0, "ERROR: Invalid animalid") else: return set_cached_response( cache_key, "text/html", 86400, 120, publishers.html.get_animal_view(dbo, utils.cint(animalid))) elif method == "animal_view_adoptable_js": return set_cached_response( cache_key, "application/javascript", 10800, 600, publishers.html.get_animal_view_adoptable_js(dbo)) elif method == "animal_view_adoptable_html": return set_cached_response( cache_key, "text/html", 86400, 120, publishers.html.get_animal_view_adoptable_html(dbo)) elif method == "dbfs_image": hotlink_protect("dbfs_image", referer) return set_cached_response( cache_key, "image/jpeg", 86400, 86400, utils.iif(title.startswith("/"), dbfs.get_string_filepath(dbo, title), dbfs.get_string(dbo, title))) elif method == "extra_image": hotlink_protect("extra_image", referer) return set_cached_response(cache_key, "image/jpeg", 86400, 86400, dbfs.get_string(dbo, title, "/reports")) elif method == "json_adoptable_animal": if utils.cint(animalid) == 0: al.error( "json_adoptable_animal failed, %s is not an animalid" % str(animalid), "service.handler", dbo) return ("text/plain", 0, 0, "ERROR: Invalid animalid") else: users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = publishers.base.get_animal_data( dbo, None, utils.cint(animalid), include_additional_fields=True) return set_cached_response(cache_key, "application/json", 3600, 3600, utils.json(rs)) elif method == "html_adoptable_animals": return set_cached_response(cache_key, "text/html", 10800, 1800, \ publishers.html.get_adoptable_animals(dbo, style=post["template"], \ speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid"), locationid=post.integer("locationid"))) elif method == "html_adopted_animals": return set_cached_response(cache_key, "text/html", 10800, 1800, \ publishers.html.get_adopted_animals(dbo, daysadopted=post.integer("days"), style=post["template"], \ speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid"))) elif method == "html_deceased_animals": return set_cached_response(cache_key, "text/html", 10800, 1800, \ publishers.html.get_deceased_animals(dbo, daysdeceased=post.integer("days"), style=post["template"], \ speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid"))) elif method == "html_held_animals": return set_cached_response(cache_key, "text/html", 10800, 1800, \ publishers.html.get_held_animals(dbo, style=post["template"], \ speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid"))) elif method == "json_adoptable_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = publishers.base.get_animal_data(dbo, None, include_additional_fields=True) if strip_personal: rs = strip_personal_data(rs) return set_cached_response(cache_key, "application/json", 3600, 3600, utils.json(rs)) elif method == "jsonp_adoptable_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = publishers.base.get_animal_data(dbo, None, include_additional_fields=True) if strip_personal: rs = strip_personal_data(rs) return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], utils.json(rs))) elif method == "xml_adoptable_animal": if utils.cint(animalid) == 0: al.error( "xml_adoptable_animal failed, %s is not an animalid" % str(animalid), "service.handler", dbo) return ("text/plain", 0, 0, "ERROR: Invalid animalid") else: users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = publishers.base.get_animal_data( dbo, None, utils.cint(animalid), include_additional_fields=True) return set_cached_response(cache_key, "application/xml", 3600, 3600, html.xml(rs)) elif method == "xml_adoptable_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = publishers.base.get_animal_data(dbo, None, include_additional_fields=True) if strip_personal: rs = strip_personal_data(rs) return set_cached_response(cache_key, "application/xml", 3600, 3600, html.xml(rs)) elif method == "json_found_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_FOUND_ANIMAL) rs = lostfound.get_foundanimal_last_days(dbo) return set_cached_response(cache_key, "application/json", 3600, 3600, utils.json(rs)) elif method == "jsonp_found_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_FOUND_ANIMAL) rs = lostfound.get_foundanimal_last_days(dbo) return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], utils.json(rs))) elif method == "xml_found_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_FOUND_ANIMAL) rs = lostfound.get_foundanimal_last_days(dbo) return set_cached_response(cache_key, "application/json", 3600, 3600, html.xml(rs)) elif method == "json_lost_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_LOST_ANIMAL) rs = lostfound.get_lostanimal_last_days(dbo) return set_cached_response(cache_key, "application/json", 3600, 3600, utils.json(rs)) elif method == "jsonp_lost_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_LOST_ANIMAL) rs = lostfound.get_lostanimal_last_days(dbo) return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], utils.json(rs))) elif method == "xml_lost_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_LOST_ANIMAL) rs = lostfound.get_lostanimal_last_days(dbo) return set_cached_response(cache_key, "application/json", 3600, 3600, html.xml(rs)) elif method == "json_recent_adoptions": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = movement.get_recent_adoptions(dbo) return set_cached_response(cache_key, "application/json", 3600, 3600, utils.json(rs)) elif method == "jsonp_recent_adoptions": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = movement.get_recent_adoptions(dbo) return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], utils.json(rs))) elif method == "xml_recent_adoptions": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = movement.get_recent_adoptions(dbo) return set_cached_response(cache_key, "application/xml", 3600, 3600, html.xml(rs)) elif method == "html_report": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_REPORT) crid = reports.get_id(dbo, title) p = reports.get_criteria_params(dbo, crid, post) rhtml = reports.execute(dbo, crid, username, p) return set_cached_response(cache_key, "text/html", 600, 600, rhtml) elif method == "csv_mail" or method == "csv_report": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_REPORT) crid = reports.get_id(dbo, title) p = reports.get_criteria_params(dbo, crid, post) rows, cols = reports.execute_query(dbo, crid, username, p) mcsv = utils.csv(l, rows, cols, True) return set_cached_response(cache_key, "text/csv", 600, 600, mcsv) elif method == "jsonp_recent_changes": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) sa = animal.get_recent_changes(dbo) return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], utils.json(sa))) elif method == "json_recent_changes": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) sa = animal.get_recent_changes(dbo) return set_cached_response(cache_key, "application/json", 3600, 3600, utils.json(sa)) elif method == "xml_recent_changes": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) sa = animal.get_recent_changes(dbo) return set_cached_response(cache_key, "application/xml", 3600, 3600, html.xml(sa)) elif method == "jsonp_shelter_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) sa = animal.get_shelter_animals(dbo) if strip_personal: sa = strip_personal_data(sa) return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], utils.json(sa))) elif method == "json_shelter_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) sa = animal.get_shelter_animals(dbo) if strip_personal: sa = strip_personal_data(sa) return set_cached_response(cache_key, "application/json", 3600, 3600, utils.json(sa)) elif method == "xml_shelter_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) sa = animal.get_shelter_animals(dbo) if strip_personal: sa = strip_personal_data(sa) return set_cached_response(cache_key, "application/xml", 3600, 3600, html.xml(sa)) elif method == "rss_timeline": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) return set_cached_response(cache_key, "application/rss+xml", 3600, 3600, html.timeline_rss(dbo)) elif method == "upload_animal_image": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.ADD_MEDIA) media.attach_file_from_form(dbo, username, media.ANIMAL, int(animalid), post) return ("text/plain", 0, 0, "OK") elif method == "online_form_html": if formid == 0: raise utils.ASMError( "method online_form_html requires a valid formid") return set_cached_response(cache_key, "text/html; charset=utf-8", 120, 120, onlineform.get_onlineform_html(dbo, formid)) elif method == "online_form_json": if formid == 0: raise utils.ASMError( "method online_form_json requires a valid formid") return set_cached_response(cache_key, "application/json; charset=utf-8", 30, 30, onlineform.get_onlineform_json(dbo, formid)) elif method == "online_form_post": flood_protect("online_form_post", remoteip, 15) onlineform.insert_onlineformincoming_from_form(dbo, post, remoteip) redirect = post["redirect"] if redirect == "": redirect = BASE_URL + "/static/pages/form_submitted.html" return ("redirect", 0, 0, redirect) elif method == "sign_document": if formid == 0: raise utils.ASMError( "method sign_document requires a valid formid") if post["sig"] == "": return set_cached_response(cache_key, "text/html", 2, 2, sign_document_page(dbo, formid)) else: media.sign_document(dbo, "service", formid, post["sig"], post["signdate"]) media.create_log(dbo, "service", formid, "ES02", _("Document signed", l)) return ("text/plain", 0, 0, "OK") else: al.error("invalid method '%s'" % method, "service.handler", dbo) raise utils.ASMError("Invalid method '%s'" % method)
def handler(post, remoteip, referer): """ Handles the various service method types. data: The GET/POST parameters return value is a tuple containing MIME type, max-age, content """ # Database info dbo = db.DatabaseInfo() # Get service parameters account = post["account"] username = post["username"] password = post["password"] method = post["method"] animalid = post.integer("animalid") formid = post.integer("formid") seq = post.integer("seq") title = post["title"] cache_key = "a" + account + "u" + username + "p" + password + "m" + method + \ "i" + str(animalid) + "s" + str(seq) + "f" + str(formid) + "t" + title # cache keys aren't allowed spaces cache_key = cache_key.replace(" ", "") # Do we have a cached response for these parameters? cached_response = get_cached_response(cache_key) if cached_response is not None: al.debug("cache hit for %s/%s/%s/%s" % (account, method, animalid, title), "service.handler") return cached_response # Are we dealing with multiple databases, but no account was specified? if account == "" and MULTIPLE_DATABASES: return ("text/plan", 0, "ERROR: No database/alias specified") # Are we dealing with multiple databases and an account was specified? if account != "": if MULTIPLE_DATABASES: if MULTIPLE_DATABASES_TYPE == "smcom": # Is this sheltermanager.com? If so, we need to get the # database connection info (dbo) before we can login. dbo = smcom.get_database_info(account) else: # Look up the database info from our map dbo = db.get_multiple_database_info(account) if dbo.database == "FAIL" or dbo.database == "DISABLED": al.error("auth failed - invalid smaccount %s from %s" % (account, remoteip), "service.handler", dbo) return ("text/plain", 0, "ERROR: Invalid database") # If the database has disabled the service API, stop now if not configuration.service_enabled(dbo): al.error("Service API is disabled (%s)" % method, "service.handler", dbo) return ("text/plain", 0, "ERROR: Service API is disabled") # Do any database updates need doing in this db? if dbupdate.check_for_updates(dbo): dbupdate.perform_updates(dbo) # Does the method require us to authenticate? If so, do it. user = None securitymap = "" if method in AUTH_METHODS: # If the database has authenticated service methods disabled, stop now if not configuration.service_auth_enabled(dbo): al.error("Service API for auth methods is disabled (%s)" % method, "service.handler", dbo) return ("text/plain", 0, "ERROR: Service API for authenticated methods is disabled") user = users.authenticate(dbo, username, password) if user is None: al.error("auth failed - %s/%s is not a valid username/password from %s" % (username, password, remoteip), "service.handler", dbo) return ("text/plain", 0, "ERROR: Invalid username and password") securitymap = users.get_security_map(dbo, user["USERNAME"]) # Get the preferred locale and timezone for the site l = configuration.locale(dbo) dbo.locale = l dbo.timezone = configuration.timezone(dbo) al.info("call %s->%s [%s %s]" % (username, method, str(animalid), title), "service.handler", dbo) if method =="animal_image": hotlink_protect("animal_image", referer) if animalid == "" or utils.cint(animalid) == 0: al.error("animal_image failed, %s is not an animalid" % str(animalid), "service.handler", dbo) return ("text/plain", 0, "ERROR: Invalid animalid") else: if seq == 0: seq = 1 mm = media.get_media_by_seq(dbo, media.ANIMAL, utils.cint(animalid), seq) if len(mm) == 0: return set_cached_response(cache_key, "image/jpeg", 86400, 120, dbfs.get_string(dbo, "nopic.jpg", "/reports")) else: return set_cached_response(cache_key, "image/jpeg", 86400, 120, dbfs.get_string(dbo, mm[0]["MEDIANAME"])) elif method == "animal_view": if animalid == "" or utils.cint(animalid) == 0: al.error("animal_view failed, %s is not an animalid" % str(animalid), "service.handler", dbo) return ("text/plain", 0, "ERROR: Invalid animalid") else: return set_cached_response(cache_key, "text/html", 120, 120, publish.get_animal_view(dbo, int(animalid))) elif method =="dbfs_image": hotlink_protect("dbfs_image", referer) return set_cached_response(cache_key, "image/jpeg", 86400, 120, dbfs.get_string_filepath(dbo, title)) elif method =="extra_image": hotlink_protect("extra_image", referer) return set_cached_response(cache_key, "image/jpeg", 86400, 120, dbfs.get_string(dbo, title, "/reports")) elif method == "json_adoptable_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) pc = publish.PublishCriteria(configuration.publisher_presets(dbo)) rs = publish.get_animal_data(dbo, pc, True) return set_cached_response(cache_key, "application/json", 3600, 3600, html.json(rs)) elif method == "jsonp_adoptable_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) pc = publish.PublishCriteria(configuration.publisher_presets(dbo)) rs = publish.get_animal_data(dbo, pc, True) return ("application/javascript", 0, "%s(%s);" % (post["callback"], html.json(rs))) elif method == "xml_adoptable_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) pc = publish.PublishCriteria(configuration.publisher_presets(dbo)) rs = publish.get_animal_data(dbo, pc, True) return set_cached_response(cache_key, "application/xml", 3600, 3600, html.xml(rs)) elif method == "json_recent_adoptions": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = movement.get_recent_adoptions(dbo) return set_cached_response(cache_key, "application/json", 3600, 3600, html.json(rs)) elif method == "jsonp_recent_adoptions": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = movement.get_recent_adoptions(dbo) return ("application/javascript", 0, "%s(%s);" % (post["callback"], html.json(rs))) elif method == "xml_recent_adoptions": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) rs = movement.get_recent_adoptions(dbo) return set_cached_response(cache_key, "application/xml", 3600, 3600, html.xml(rs)) elif method == "html_report": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_REPORT) crid = reports.get_id(dbo, title) p = reports.get_criteria_params(dbo, crid, post) rhtml = reports.execute(dbo, crid, username, p) return set_cached_response(cache_key, "text/html", 3600, 3600, rhtml) elif method == "csv_mail" or method == "csv_report": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_REPORT) crid = reports.get_id(dbo, title) p = reports.get_criteria_params(dbo, crid, post) rows, cols = reports.execute_query(dbo, crid, username, p) mcsv = utils.csv(l, rows, cols, True) return set_cached_response(cache_key, "text/csv", 3600, 3600, mcsv) elif method == "jsonp_shelter_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) sa = animal.get_animal_find_simple(dbo, "", "shelter") return ("application/javascript", 0, "%s(%s);" % (post["callback"], html.json(sa))) elif method == "json_shelter_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) sa = animal.get_animal_find_simple(dbo, "", "shelter") return set_cached_response(cache_key, "application/json", 3600, 3600, html.json(sa)) elif method == "xml_shelter_animals": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) sa = animal.get_animal_find_simple(dbo, "", "shelter") return set_cached_response(cache_key, "application/xml", 3600, 3600, html.xml(sa)) elif method == "rss_timeline": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL) return set_cached_response(cache_key, "application/rss+xml", 3600, 3600, html.timeline_rss(dbo)) elif method == "upload_animal_image": users.check_permission_map(l, user["SUPERUSER"], securitymap, users.ADD_MEDIA) media.attach_file_from_form(dbo, username, media.ANIMAL, int(animalid), post) return ("text/plain", 0, "OK") elif method == "online_form_html": if formid == 0: raise utils.ASMError("method online_form_html requires a valid formid") return set_cached_response(cache_key, "text/html; charset=utf-8", 120, 120, onlineform.get_onlineform_html(dbo, formid)) elif method == "online_form_json": if formid == 0: raise utils.ASMError("method online_form_json requires a valid formid") return set_cached_response(cache_key, "text/json; charset=utf-8", 30, 30, onlineform.get_onlineform_json(dbo, formid)) elif method == "online_form_post": flood_protect("online_form_post", remoteip, 15) onlineform.insert_onlineformincoming_from_form(dbo, post, remoteip) redirect = post["redirect"] if redirect == "": redirect = BASE_URL + "/static/pages/form_submitted.html" return ("redirect", 0, redirect) elif method == "sign_document": if formid == 0: raise utils.ASMError("method sign_document requires a valid formid") if post["sig"] == "": return set_cached_response(cache_key, "text/html", 2, 2, sign_document_page(dbo, formid)) else: media.sign_document(dbo, "service", formid, post["sig"], post["signdate"]) return ("text/plain", 0, "OK") else: al.error("invalid method '%s'" % method, "service.handler", dbo) raise utils.ASMError("Invalid method '%s'" % method)
print " maint_db_dump_dbfs - produce a dump of INSERT statements to recreate the dbfs" print " maint_db_dump_animalcsv - produce a CSV of animal/adoption/owner data" print " maint_db_dump_personcsv - produce a CSV of person data" print " maint_db_dump_smcom - produce an SQL dump for import into sheltermanager.com" print " maint_db_install - install structure/data into a new empty database" print " maint_db_reinstall - wipe the db and reinstall default data" print " maint_recode_all - regenerate all animal codes" print " maint_recode_shelter - regenerate animals codes for all shelter animals" print " maint_reinstall_default_media - re-adds default document/publishing templates" print " maint_scale_animal_images - re-scales all the animal images in the database" print " maint_variable_data - calculate variable data for the day" if __name__ == "__main__": if len(sys.argv) == 2 and not MULTIPLE_DATABASES: # mode argument given and we have a single database run_default_database(sys.argv[1]) elif len(sys.argv) == 2 and MULTIPLE_DATABASES and MULTIPLE_DATABASES_TYPE == "map": # mode argument given and we have multiple map databases run_all_map_databases(sys.argv[1]) elif len(sys.argv) == 3 and MULTIPLE_DATABASES: # mode and alias given run_alias(sys.argv[1], sys.argv[2]) elif len(sys.argv) == 9: # mode and database information given run_override_database(sys.argv[1], sys.argv[2], sys.argv[3], utils.cint(sys.argv[4]), sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8]) else: # We didn't get a valid combination of args print_usage() sys.exit(1)
def get_animalcontrol_find_advanced(dbo, criteria, limit = 0): """ Returns rows for advanced animal control searches. criteria: A dictionary of criteria number - string partial pattern callername - string partial pattern victimname - string partial pattern callerphone - string partial pattern incidenttype - -1 for all or ID dispatchedaco - string partial pattern completedtype - -1 for all or ID citationtype - -1 for all or ID address - string partial pattern city - string partial pattern postcode - string partial pattern pickuplocation - -1 for all or ID description - string partial pattern agegroup - agegroup text to match sex - -1 for all or ID species - -1 for all or ID filter - unpaid, incomplete, undispatched, requirefollowup incidentfrom - incident date from in current display locale format incidentto - incident date to in current display locale format dispatchfrom - dispatch date from in current display locale format dispatchto - dispatch date from in current display locale format respondedfrom - responded date from in current display locale format respondedto - responded date to in current display locale format followupfrom - follow up date from in current display locale format followupto - follow up date to in current display locale format completedfrom - completed date from in current display locale format completedto - completed date to in current display locale format """ c = [] l = dbo.locale post = utils.PostedData(criteria, l) def hk(cfield): return post[cfield] != "" def crit(cfield): return post[cfield] def addid(cfield, field): if hk(cfield) and int(crit(cfield)) != -1: c.append("%s = %s" % (field, crit(cfield))) def addstr(cfield, field): if hk(cfield) and crit(cfield) != "": c.append("LOWER(%s) LIKE '%%%s%%'" % ( field, crit(cfield).lower().replace("'", "`"))) def adddate(cfieldfrom, cfieldto, field): if hk(cfieldfrom) and hk(cfieldto): post.data["dayend"] = "23:59:59" c.append("%s >= %s AND %s <= %s" % ( field, post.db_date(cfieldfrom), field, post.db_datetime(cfieldto, "dayend"))) def addcomp(cfield, value, condition): if hk(cfield) and crit(cfield) == value: c.append(condition) c.append("ac.ID > 0") if crit("number") != "": c.append("ac.ID = " + str(utils.cint(crit("number")))) addstr("callername", "co.OwnerName") addstr("victimname", "vo.OwnerName") addstr("callerphone", "co.HomeTelephone") addid("incidenttype", "ac.IncidentTypeID") addid("pickuplocation", "ac.PickupLocationID") if (crit("dispatchedaco") != "-1"): addstr("dispatchedaco", "ac.DispatchedACO") adddate("incidentfrom", "incidentto", "ac.IncidentDateTime") adddate("dispatchfrom", "dispatchto", "ac.DispatchDateTime") adddate("respondedfrom", "respondedto", "ac.RespondedDateTime") adddate("followupfrom", "followupto", "ac.FollwupDateTime") adddate("completedfrom", "completedto", "ac.CompletedDate") addid("completedtype", "ac.IncidentCompletedID") addid("citationtype", "ac.CitationTypeID") addstr("address", "ac.DispatchAddress") addstr("city", "ac.DispatchTown") addstr("postcode", "ac.DispatchPostcode") addstr("callnotes", "ac.CallNotes") addstr("description", "ac.AnimalDescription") if (crit("agegroup") != "-1"): addstr("agegroup", "ac.AgeGroup") addid("sex", "ac.Sex") addid("species", "ac.SpeciesID") addcomp("filter", "incomplete", "ac.CompletedDate Is Null") addcomp("filter", "undispatched", "ac.CompletedDate Is Null AND ac.CallDateTime Is Not Null AND ac.DispatchDateTime Is Null") addcomp("filter", "requirefollowup", "(" \ "(ac.FollowupDateTime Is Not Null AND ac.FollowupDateTime <= %(now)s AND NOT ac.FollowupComplete = 1) OR " \ "(ac.FollowupDateTime2 Is Not Null AND ac.FollowupDateTime2 <= %(now)s AND NOT ac.FollowupComplete2 = 1) OR " \ "(ac.FollowupDateTime3 Is Not Null AND ac.FollowupDateTime3 <= %(now)s AND NOT ac.FollowupComplete3 = 1) " \ ")" % { "now": db.dd(now(dbo.timezone))} ) where = "" if len(c) > 0: where = " WHERE " + " AND ".join(c) sql = get_animalcontrol_query(dbo) + where + " ORDER BY ac.ID" if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
if page_name != "" and page_id == "": raise utils.ASMValidationError("Could not find page '%s' in Facebook user accounts list (%s)" % (page_name, accounts_list)) # If we're posting as the page, we can only post to the page. # switch us to post using the page's access token if post_as == "page": post_to = page_id access_token = page_access_token # If we're posting as us, but to a page, post to the page # but stick with the user's access_token if page_name != "": post_to = page_id # Grab the animal details a = animal.get_animal(dbo, utils.cint(oauth_state[1:])) # Bail out if we have a problem if a is None: raise utils.ASMValidationError("Facebook response did not contain a valid animal ID (got %s)" % oauth_state[1:]) # Generate the body of the post from our facebook template tags = wordprocessor.animal_tags(dbo, a) template = configuration.facebook_template(dbo) posttext = wordprocessor.substitute_tags(template, tags, False, "$$", "$$") # Post on the wall try: l = dbo.locale fb_url = "https://graph.facebook.com/%s/photos?access_token=%s" % (post_to, access_token)
def web_login(post, session, remoteip, path): """ Performs a login and sets up the user's session. Returns the username on successful login, or: FAIL - problem with user/pass/account/ip DISABLED - The database is disabled WRONGSERVER - The database is not on this server """ dbo = db.DatabaseInfo() database = post["database"] username = post["username"] password = post["password"] mobileapp = post["mobile"] == "true" nologconnection = post["nologconnection"] if len(username) > 100: username = username[0:100] # Do we have multiple databases? if MULTIPLE_DATABASES: if MULTIPLE_DATABASES_TYPE == "smcom": # Is this sheltermanager.com? If so, we need to get the # database connection info (dbo) before we can login. # If a database hasn't been supplied, let's bail out now # since we can't do anything if str(database).strip() == "": return "FAIL" else: dbo = smcom.get_database_info(database) # Bail out if there was a problem with the database if dbo.database in ("FAIL", "DISABLED", "WRONGSERVER"): return dbo.database else: # Look up the database info from our map dbo = db.get_multiple_database_info(database) if dbo.database == "FAIL": return dbo.database # Connect to the database and authenticate the username and password user = authenticate(dbo, username, password) if user is not None and not authenticate_ip(user, remoteip): al.error("user %s with ip %s failed ip restriction check '%s'" % (username, remoteip, user["IPRESTRICTION"]), "users.web_login", dbo) return "FAIL" if user is not None: al.info("%s successfully authenticated from %s" % (username, remoteip), "users.web_login", dbo) try: dbo.locked = configuration.smdb_locked(dbo) dbo.timezone = configuration.timezone(dbo) dbo.installpath = path session.locale = configuration.locale(dbo) dbo.locale = session.locale session.dbo = dbo session.user = user["USERNAME"] session.superuser = user["SUPERUSER"] session.passchange = (password == "password") session.mobileapp = mobileapp update_session(session) except: al.error("failed setting up session: %s" % str(sys.exc_info()[0]), "users.web_login", dbo, sys.exc_info()) return "FAIL" try: session.securitymap = get_security_map(dbo, user["USERNAME"]) except: # This is a pre-3002 login where the securitymap is with # the user (the error occurs because there's no role table) al.debug("role table does not exist, using securitymap from user", "users.web_login", dbo) session.securitymap = user["SECURITYMAP"] try: ur = get_users(dbo, user["USERNAME"])[0] session.roles = ur["ROLES"] session.roleids = ur["ROLEIDS"] session.siteid = utils.cint(user["SITEID"]) session.locationfilter = utils.nulltostr(user["LOCATIONFILTER"]) except: # Users coming from v2 won't have the # IPRestriction or EmailAddress fields necessary for get_users - we can't # help them right now so just give them an empty set of # roles and locationfilter until they login again after the db update session.roles = "" session.roleids = "" session.locationfilter = "" session.siteid = 0 try: # If it's a sheltermanager.com database, try and update the # last time the user connected to today if smcom.active() and database != "" and nologconnection == "": smcom.set_last_connected(dbo) except: pass try: # Mark the user logged in audit.login(dbo, username) # Check to see if any updates need performing on this database if dbupdate.check_for_updates(dbo): dbupdate.perform_updates(dbo) # We did some updates, better reload just in case config/reports/etc changed update_session(session) # Check to see if our views and sequences are out of date and need reloading if dbupdate.check_for_view_seq_changes(dbo): dbupdate.install_db_views(dbo) dbupdate.install_db_sequences(dbo) except: al.error("failed updating database: %s" % str(sys.exc_info()[0]), "users.web_login", dbo, sys.exc_info()) try: al.info("%s logged in" % user["USERNAME"], "users.login", dbo) update_user_activity(dbo, user["USERNAME"]) except: al.error("failed updating user activity: %s" % str(sys.exc_info()[0]), "users.web_login", dbo, sys.exc_info()) return "FAIL" else: al.error("database:%s username:%s password:%s failed authentication from %s" % (database, username, password, remoteip), "users.web_login", dbo) return "FAIL" return user["USERNAME"]
print " maint_scale_animal_images - re-scales all the animal images in the database" print " maint_variable_data - calculate variable data for the day" if __name__ == "__main__": if len(sys.argv) == 2 and not MULTIPLE_DATABASES: # mode argument given and we have a single database run_default_database(sys.argv[1]) elif len(sys.argv) == 2 and MULTIPLE_DATABASES and MULTIPLE_DATABASES_TYPE == "map": # mode argument given and we have multiple map databases run_all_map_databases(sys.argv[1]) elif len(sys.argv) == 3 and MULTIPLE_DATABASES: # mode and alias given run_alias(sys.argv[1], sys.argv[2]) elif len(sys.argv) == 9: # mode and database information given run_override_database( sys.argv[1], sys.argv[2], sys.argv[3], utils.cint(sys.argv[4]), sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8], ) else: # We didn't get a valid combination of args print_usage() sys.exit(1)
print " maint_db_dump_smcom - produce an SQL dump for import into sheltermanager.com" print " maint_db_install - install structure/data into a new empty database" print " maint_db_reinstall - wipe the db and reinstall default data" print " maint_deduplicate_people - automatically merge duplicate people records" print " maint_recode_all - regenerate all animal codes" print " maint_recode_shelter - regenerate animals codes for all shelter animals" print " maint_reinstall_default_media - re-adds default document/publishing templates" print " maint_scale_animal_images - re-scales all the animal images in the database" print " maint_scale_odts - re-scales all odt files attached to records (remove images)" print " maint_scale_pdfs - re-scales all the PDFs in the database" print " maint_variable_data - recalculate all variable data for all animals" if __name__ == "__main__": if len(sys.argv) == 2 and not MULTIPLE_DATABASES: # mode argument given and we have a single database run_default_database(sys.argv[1]) elif len(sys.argv) == 2 and MULTIPLE_DATABASES and MULTIPLE_DATABASES_TYPE == "map": # mode argument given and we have multiple map databases run_all_map_databases(sys.argv[1]) elif len(sys.argv) == 3 and MULTIPLE_DATABASES: # mode and alias given run_alias(sys.argv[1], sys.argv[2]) elif len(sys.argv) == 9: # mode and database information given run_override_database(sys.argv[1], sys.argv[2], sys.argv[3], utils.cint(sys.argv[4]), sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8]) else: # We didn't get a valid combination of args print_usage() sys.exit(1)
print " maint_db_install - install structure/data into a new empty database" print " maint_db_reinstall - wipe the db and reinstall default data" print " maint_recode_all - regenerate all animal codes" print " maint_recode_shelter - regenerate animals codes for all shelter animals" print " maint_reinstall_default_media - re-adds default document/publishing templates" print " maint_scale_animal_images - re-scales all the animal images in the database" print " maint_variable_data - calculate variable data for the day" if __name__ == "__main__": if len(sys.argv) == 2 and not MULTIPLE_DATABASES: # mode argument given and we have a single database run_default_database(sys.argv[1]) elif len( sys.argv ) == 2 and MULTIPLE_DATABASES and MULTIPLE_DATABASES_TYPE == "map": # mode argument given and we have multiple map databases run_all_map_databases(sys.argv[1]) elif len(sys.argv) == 3 and MULTIPLE_DATABASES: # mode and alias given run_alias(sys.argv[1], sys.argv[2]) elif len(sys.argv) == 9: # mode and database information given run_override_database(sys.argv[1], sys.argv[2], sys.argv[3], utils.cint(sys.argv[4]), sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8]) else: # We didn't get a valid combination of args print_usage() sys.exit(1)
"Could not find page '%s' in Facebook user accounts list (%s)" % (page_name, accounts_list)) # If we're posting as the page, we can only post to the page. # switch us to post using the page's access token if post_as == "page": post_to = page_id access_token = page_access_token # If we're posting as us, but to a page, post to the page # but stick with the user's access_token if page_name != "": post_to = page_id # Grab the animal details a = animal.get_animal(dbo, utils.cint(oauth_state[1:])) # Bail out if we have a problem if a is None: raise utils.ASMValidationError( "Facebook response did not contain a valid animal ID (got %s)" % oauth_state[1:]) # Generate the body of the post from our facebook template tags = wordprocessor.animal_tags(dbo, a) template = configuration.facebook_template(dbo) posttext = wordprocessor.substitute_tags(template, tags, False, "$$", "$$") # Post on the wall try:
def handler(data, remoteip, referer): """ Handles the various service method types. data: The GET/POST parameters return value is a tuple containing MIME type, max-age, content """ # Database info dbo = db.DatabaseInfo() # Get service parameters account = utils.df_ks(data, "account") username = utils.df_ks(data, "username") password = utils.df_ks(data, "password") method = utils.df_ks(data, "method") animalid = utils.df_ki(data, "animalid") formid = utils.df_ki(data, "formid") title = utils.df_ks(data, "title") cache_key = "a" + account + "u" + username + "p" + password + "m" + method + "a" + str(animalid) + "f" + str(formid) + "t" + title # cache keys aren't allowed spaces cache_key = cache_key.replace(" ", "") # Do we have a cached response for these parameters? cached_response = get_cached_response(cache_key) if cached_response is not None: al.debug("cache hit for %s/%s/%s/%s" % (account, method, animalid, title), "service.handler") return cached_response # Are we dealing with multiple databases, but no account was specified? if account == "" and MULTIPLE_DATABASES: return ("text/plan", 0, "ERROR: No database/alias specified") # Are we dealing with multiple databases and an account was specified? if account != "": if MULTIPLE_DATABASES: if MULTIPLE_DATABASES_TYPE == "smcom": # Is this sheltermanager.com? If so, we need to get the # database connection info (dbo) before we can login. dbo = smcom.get_database_info(account) else: # Look up the database info from our map dbo = db.get_multiple_database_info(account) if dbo.database == "FAIL" or dbo.database == "DISABLED": al.error("auth failed - invalid smaccount %s from %s" % (account, remoteip), "service.handler", dbo) return ("text/plain", 0, "ERROR: Invalid database") # Does the method require us to authenticate? If so, do it. user = None if method in AUTH_METHODS: user = users.authenticate(dbo, username, password) if user is None: al.error("auth failed - %s/%s is not a valid username/password from %s" % (username, password, remoteip), "service.handler", dbo) return ("text/plain", 0, "ERROR: Invalid username and password") # Get the preferred locale for the site dbo.locale = configuration.locale(dbo) al.info("call %s->%s [%s %s]" % (username, method, str(animalid), title), "service.handler", dbo) if method =="animal_image": # If we have a hotlinking restriction, enforce it if referer != "" and IMAGE_HOTLINKING_ONLY_FROM_DOMAIN != "" and referer.find(IMAGE_HOTLINKING_ONLY_FROM_DOMAIN) == -1: raise utils.ASMPermissionError("Image hotlinking is forbidden.") if animalid == "" or utils.cint(animalid) == 0: al.error("animal_image failed, %s is not an animalid" % str(animalid), "service.handler", dbo) return ("text/plain", 0, "ERROR: Invalid animalid") # If the option is on, forbid hotlinking else: seq = utils.df_ki(data, "seq") if seq == 0: seq = 1 mm = media.get_media_by_seq(dbo, media.ANIMAL, utils.cint(animalid), seq) if len(mm) == 0: return ("image/jpeg", 86400, dbfs.get_string(dbo, "nopic.jpg", "/reports")) else: return ("image/jpeg", 86400, dbfs.get_string(dbo, mm[0]["MEDIANAME"])) elif method =="extra_image": return ("image/jpeg", 86400, dbfs.get_string(dbo, title, "/reports")) elif method == "json_adoptable_animals": pc = publish.PublishCriteria(configuration.publisher_presets(dbo)) rs = publish.get_animal_data(dbo, pc, True) return set_cached_response(cache_key, "application/json", 3600, html.json(rs)) elif method == "xml_adoptable_animals": pc = publish.PublishCriteria(configuration.publisher_presets(dbo)) rs = publish.get_animal_data(dbo, pc, True) return set_cached_response(cache_key, "application/xml", 3600, html.xml(rs)) elif method == "json_recent_adoptions": rs = movement.get_recent_adoptions(dbo) return set_cached_response(cache_key, "application/json", 3600, html.json(rs)) elif method == "xml_recent_adoptions": rs = movement.get_recent_adoptions(dbo) return set_cached_response(cache_key, "application/xml", 3600, html.xml(rs)) elif method == "html_report": crid = reports.get_id(dbo, title) p = reports.get_criteria_params(dbo, crid, data) rhtml = reports.execute(dbo, crid, username, p) return set_cached_response(cache_key, "text/html", 3600, rhtml) elif method == "jsonp_shelter_animals": sa = animal.get_animal_find_simple(dbo, "", "shelter") return set_cached_response(cache_key, "application/javascript", 3600, str(utils.df_ks(data, "callback")) + "(" + html.json(sa) + ")") elif method == "json_shelter_animals": sa = animal.get_animal_find_simple(dbo, "", "shelter") return set_cached_response(cache_key, "application/json", 3600, html.json(sa)) elif method == "xml_shelter_animals": sa = animal.get_animal_find_simple(dbo, "", "shelter") return set_cached_response(cache_key, "application/xml", 3600, html.json(sa)) elif method == "upload_animal_image": media.attach_file_from_form(dbo, username, media.ANIMAL, int(animalid), data) return ("text/plain", 0, "OK") elif method == "online_form_html": if formid == 0: raise utils.ASMError("method online_form_html requires a valid formid") return set_cached_response(cache_key, "text/html", 120, onlineform.get_onlineform_html(dbo, formid)) elif method == "online_form_post": onlineform.insert_onlineformincoming_from_form(dbo, data, remoteip) redirect = utils.df_ks(data, "redirect") if redirect == "": redirect = BASE_URL + "/static/pages/form_submitted.html" return ("redirect", 0, redirect) else: al.error("invalid method '%s'" % method, "service.handler", dbo) raise utils.ASMError("Invalid method '%s'" % method)
def are_emails_muted(): from utils import cint return flags.mute_emails or cint(conf.get("mute_emails") or 0) or False
def web_login(post, session, remoteip, path): """ Performs a login and sets up the user's session. Returns the username on successful login, or: FAIL - problem with user/pass/account/ip DISABLED - The database is disabled WRONGSERVER - The database is not on this server """ database = post["database"] username = post["username"] password = post["password"] mobileapp = post["mobile"] == "true" nologconnection = post["nologconnection"] == "true" if len(username) > 100: username = username[0:100] dbo = db.get_database(database) if dbo.database in ("FAIL", "DISABLED", "WRONGSERVER"): return dbo.database # Connect to the database and authenticate the username and password user = authenticate(dbo, username, password) if user is not None and not authenticate_ip(user, remoteip): al.error( "user %s with ip %s failed ip restriction check '%s'" % (username, remoteip, user.IPRESTRICTION), "users.web_login", dbo) return "FAIL" if user is not None and "DISABLELOGIN" in user and user.DISABLELOGIN == 1: al.error( "user %s with ip %s failed as account has logins disabled" % (username, remoteip), "users.web_login", dbo) return "FAIL" if user is not None: al.info("%s successfully authenticated from %s" % (username, remoteip), "users.web_login", dbo) try: dbo.locked = configuration.smdb_locked(dbo) dbo.timezone = configuration.timezone(dbo) dbo.installpath = path session.locale = configuration.locale(dbo) dbo.locale = session.locale session.dbo = dbo session.user = user.USERNAME session.superuser = user.SUPERUSER session.mobileapp = mobileapp update_session(session) except: al.error("failed setting up session: %s" % str(sys.exc_info()[0]), "users.web_login", dbo, sys.exc_info()) return "FAIL" try: session.securitymap = get_security_map(dbo, user.USERNAME) except: # This is a pre-3002 login where the securitymap is with # the user (the error occurs because there's no role table) al.debug("role table does not exist, using securitymap from user", "users.web_login", dbo) session.securitymap = user.SECURITYMAP try: ur = get_users(dbo, user.USERNAME)[0] session.roles = ur.ROLES session.roleids = ur.ROLEIDS session.siteid = utils.cint(user.SITEID) session.locationfilter = utils.nulltostr(user.LOCATIONFILTER) except: # Users coming from v2 won't have the # IPRestriction or EmailAddress fields necessary for get_users - we can't # help them right now so just give them an empty set of # roles and locationfilter until they login again after the db update session.roles = "" session.roleids = "" session.locationfilter = "" session.siteid = 0 try: # Mark the user logged in if not nologconnection: audit.login(dbo, username, remoteip) # Check to see if any updates need performing on this database if dbupdate.check_for_updates(dbo): dbupdate.perform_updates(dbo) # We did some updates, better reload just in case config/reports/etc changed update_session(session) # Check to see if our views and sequences are out of date and need reloading if dbupdate.check_for_view_seq_changes(dbo): dbupdate.install_db_views(dbo) dbupdate.install_db_sequences(dbo) except: al.error("failed updating database: %s" % str(sys.exc_info()[0]), "users.web_login", dbo, sys.exc_info()) try: al.info("%s logged in" % user.USERNAME, "users.login", dbo) update_user_activity(dbo, user.USERNAME) except: al.error( "failed updating user activity: %s" % str(sys.exc_info()[0]), "users.web_login", dbo, sys.exc_info()) return "FAIL" else: al.error( "database:%s username:%s password:%s failed authentication from %s" % (database, username, password, remoteip), "users.web_login", dbo) return "FAIL" return user.USERNAME