def search(dbo, session, q): """ Performs a database wide search for the term given. special tokens: a:term Only search animals for term ac:term Only search animal control incidents for term p:term Only search people for term la:term Only search lost animals for term li:num Only search licence numbers for term fa:term Only search found animals for term wl:term Only search waiting list entries for term sort:az Sort results alphabetically az sort:za Sort results alphabetically za sort:mr Sort results most recently changed first sort:lr Sort results least recently changed first -- update this list in header.js/bind_search/keywords activelost, activefound, onshelter/os, notforadoption, hold, holdtoday, quarantine, deceased, forpublish, people, vets, retailers, staff, fosterers, volunteers, shelters, aco, banned, homechecked, homecheckers, members, donors, drivers, reservenohomecheck, notmicrochipped returns a tuple of: results, timetaken, explain, sortname """ # ar (add results) inner method def ar(rlist, rtype, sortfield): # Return brief records to save bandwidth if rtype == "ANIMAL": rlist = animal.get_animals_brief(rlist) if rtype == "PERSON": pass # TODO: for r in rlist: r["RESULTTYPE"] = rtype if sortfield == "RELEVANCE": # How "relevant" is this record to what was searched for? # animal name and code weight higher than other elements. # Note that the code below modifies inbound var q, so by the # time we read it here, it should only contain the search term # itself. Weight everything else by last changed date so there # is some semblance of useful order for less relevant items qlow = q.lower() if rtype == "ANIMAL": r["SORTON"] = r["LASTCHANGEDDATE"] if r["SORTON"] is None: r["SORTON"] = THE_PAST if r["ANIMALNAME"].lower( ) == qlow or r["SHELTERCODE"].lower( ) == qlow or r["SHORTCODE"].lower() == qlow: r["SORTON"] = now() # Put matches where term present just behind direct matches elif r["ANIMALNAME"].lower().find( qlow) != -1 or r["SHELTERCODE"].lower().find( qlow) != -1 or r["SHORTCODE"].lower().find( qlow) != -1: r["SORTON"] = now() - datetime.timedelta(seconds=1) elif rtype == "PERSON": r["SORTON"] = r["LASTCHANGEDDATE"] if r["SORTON"] is None: r["SORTON"] = THE_PAST # Count how many of the keywords in the search were present # in the owner name field - if it's all of them then raise # the relevance. qw = qlow.split(" ") qm = 0 for w in qw: if r["OWNERNAME"].lower().find(w) != -1: qm += 1 if qm == len(qw): r["SORTON"] = now() # Put matches where term present just behind direct matches if r["OWNERSURNAME"].lower().find( qlow) or r["OWNERNAME"].lower().find(qlow): r["SORTON"] = now() - datetime.timedelta(seconds=1) elif rtype == "LICENCE": r["SORTON"] = r["ISSUEDATE"] if r["SORTON"] is None: r["SORTON"] = THE_PAST if r["LICENCENUMBER"].lower() == qlow: r["SORTON"] = now() else: r["SORTON"] = r["LASTCHANGEDDATE"] else: r["SORTON"] = r[sortfield] if r["SORTON"] is None and sortfield.endswith("DATE"): r["SORTON"] = THE_PAST results.append(r) l = dbo.locale # start the clock starttime = time.time() # The returned results results = [] # An i18n explanation of what was searched for explain = "" # Max records to be returned by search limit = configuration.record_search_limit(dbo) # Default sort for the search searchsort = configuration.search_sort(dbo) q = q.replace("'", "`") # Allow the sort to be overridden if q.find("sort:") != -1: if "sort:az" in q: searchsort = 0 q = q.replace("sort:az", "") elif "sort:za" in q: searchsort = 1 q = q.replace("sort:za", "") elif "sort:lr" in q: searchsort = 2 q = q.replace("sort:lr", "") elif "sort:mr" in q: searchsort = 3 q = q.replace("sort:mr", "") elif "sort:as" in q: searchsort = 4 q = q.replace("sort:as", "") elif "sort:sa" in q: searchsort = 5 q = q.replace("sort:sa", "") elif "sort:rel" in q: searchsort = 6 q = q.replace("sort:rel", "") q = q.strip() # Handle sorting =========================== animalsort = "" personsort = "" wlsort = "" acsort = "" lasort = "" lisort = "" fasort = "" sortdir = "a" sortname = "" # alphanumeric ascending if searchsort == 0: animalsort = "ANIMALNAME" personsort = "OWNERNAME" wlsort = "OWNERNAME" acsort = "OWNERNAME" lasort = "OWNERNAME" lisort = "OWNERNAME" fasort = "OWNERNAME" sortdir = "a" sortname = _("Alphabetically A-Z", l) # alphanumeric descending elif searchsort == 1: animalsort = "ANIMALNAME" personsort = "OWNERNAME" wlsort = "OWNERNAME" acsort = "OWNERNAME" lasort = "OWNERNAME" lisort = "OWNERNAME" fasort = "OWNERNAME" sortdir = "d" sortname = _("Alphabetically Z-A", l) # last changed ascending elif searchsort == 2: animalsort = "LASTCHANGEDDATE" personsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" acsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" lisort = "ISSUEDATE" fasort = "LASTCHANGEDDATE" sortdir = "a" sortname = _("Least recently changed", l) # last changed descending elif searchsort == 3: animalsort = "LASTCHANGEDDATE" personsort = "LASTCHANGEDDATE" acsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" lisort = "ISSUEDATE" fasort = "LASTCHANGEDDATE" sortdir = "d" sortname = _("Most recently changed", l) # species ascending elif searchsort == 4: animalsort = "SPECIESNAME" personsort = "OWNERNAME" acsort = "SPECIESNAME" wlsort = "SPECIESNAME" lasort = "SPECIESNAME" lisort = "COMMENTS" fasort = "SPECIESNAME" sortdir = "a" sortname = _("Species A-Z", l) elif searchsort == 5: animalsort = "SPECIESNAME" personsort = "OWNERNAME" acsort = "SPECIESNAME" wlsort = "SPECIESNAME" lasort = "SPECIESNAME" lisort = "COMMENTS" fasort = "SPECIESNAME" sortdir = "d" sortname = _("Species Z-A", l) elif searchsort == 6: animalsort = "RELEVANCE" personsort = "RELEVANCE" wlsort = "RELEVANCE" acsort = "RELEVANCE" lasort = "RELEVANCE" lisort = "RELEVANCE" fasort = "RELEVANCE" sortdir = "d" sortname = _("Most relevant", l) viewperson = users.check_permission_bool(session, users.VIEW_PERSON) viewanimal = users.check_permission_bool(session, users.VIEW_ANIMAL) viewstaff = users.check_permission_bool(session, users.VIEW_STAFF) viewvolunteer = users.check_permission_bool(session, users.VIEW_VOLUNTEER) user = session.user locationfilter = session.locationfilter siteid = session.siteid # Special token searches if q == "onshelter" or q == "os": explain = _("All animals on the shelter.", l) if viewanimal: ar( animal.get_animal_find_simple(dbo, "", limit=limit, locationfilter=locationfilter, siteid=siteid), "ANIMAL", animalsort) elif q == "notforadoption": explain = _("All animals who are flagged as not for adoption.", l) if viewanimal: ar(animal.get_animals_not_for_adoption(dbo), "ANIMAL", animalsort) elif q == "longterm": explain = _( "All animals who have been on the shelter longer than {0} months.", l).format(configuration.long_term_months(dbo)) if viewanimal: ar(animal.get_animals_long_term(dbo), "ANIMAL", animalsort) elif q == "notmicrochipped": explain = _("All animals who have not been microchipped", l) if viewanimal: ar(animal.get_animals_not_microchipped(dbo), "ANIMAL", animalsort) elif q == "hold": explain = _("All animals who are currently held in case of reclaim.", l) if viewanimal: ar(animal.get_animals_hold(dbo), "ANIMAL", animalsort) elif q == "holdtoday": explain = _("All animals where the hold ends today.", l) if viewanimal: ar(animal.get_animals_hold_today(dbo), "ANIMAL", animalsort) elif q == "quarantine": explain = _("All animals who are currently quarantined.", l) if viewanimal: ar(animal.get_animals_quarantine(dbo), "ANIMAL", animalsort) elif q == "deceased": explain = _("Recently deceased shelter animals (last 30 days).", l) if viewanimal: ar(animal.get_animals_recently_deceased(dbo), "ANIMAL", animalsort) elif q == "forpublish": explain = _("All animals matching current publishing options.", l) if viewanimal: ar(publishers.base.get_animal_data(dbo), "ANIMAL", animalsort) elif q == "people": ar( person.get_person_find_simple(dbo, "", user, classfilter="all", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) explain = _("All people on file.", l) elif q == "vets": explain = _("All vets on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="vet", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "retailers": explain = _("All retailers on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="retailer", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "staff": explain = _("All staff on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="staff", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "fosterers": explain = _("All fosterers on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="fosterer", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "volunteers": explain = _("All volunteers on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="volunteer", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "shelters": explain = _("All animal shelters on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="shelter", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "aco": explain = _("All animal care officers on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="aco", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "banned": explain = _("All banned owners on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="banned", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "homechecked": explain = _("All homechecked owners on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="homechecked", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "homecheckers": explain = _("All homecheckers on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="homechecker", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "members": explain = _("All members on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="member", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "donors": explain = _("All donors on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="donor", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "drivers": explain = _("All drivers on file.", l) if viewperson: ar( person.get_person_find_simple(dbo, "", user, classfilter="driver", includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q == "reservenohomecheck": explain = _( "People with active reservations, but no homecheck has been done.", l) if viewperson: ar(person.get_reserves_without_homechecks(dbo), "PERSON", personsort) elif q == "overduedonations": explain = _("People with overdue donations.", l) if viewperson: ar(person.get_overdue_donations(dbo), "PERSON", personsort) elif q == "activelost": explain = _("Lost animals reported in the last 30 days.", l) if users.check_permission_bool(session, users.VIEW_LOST_ANIMAL): ar( lostfound.get_lostanimal_find_simple(dbo, "", limit=limit, siteid=siteid), "LOSTANIMAL", lasort) elif q == "activefound": explain = _("Found animals reported in the last 30 days.", l) if users.check_permission_bool(session, users.VIEW_FOUND_ANIMAL): ar( lostfound.get_foundanimal_find_simple(dbo, "", limit=limit, siteid=siteid), "FOUNDANIMAL", fasort) elif q.startswith("a:") or q.startswith("animal:"): q = q[q.find(":") + 1:].strip() explain = _("Animals matching '{0}'.", l).format(q) if viewanimal: ar( animal.get_animal_find_simple(dbo, q, limit=limit, locationfilter=locationfilter, siteid=siteid), "ANIMAL", animalsort) elif q.startswith("ac:") or q.startswith("animalcontrol:"): q = q[q.find(":") + 1:].strip() explain = _("Animal control incidents matching '{0}'.", l).format(q) if users.check_permission_bool(session, users.VIEW_INCIDENT): ar( animalcontrol.get_animalcontrol_find_simple(dbo, q, user, limit=limit, siteid=siteid), "ANIMALCONTROL", acsort) elif q.startswith("p:") or q.startswith("person:"): q = q[q.find(":") + 1:].strip() explain = _("People matching '{0}'.", l).format(q) if viewperson: ar( person.get_person_find_simple(dbo, q, user, includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) elif q.startswith("wl:") or q.startswith("waitinglist:"): q = q[q.find(":") + 1:].strip() explain = _("Waiting list entries matching '{0}'.", l).format(q) if users.check_permission_bool(session, users.VIEW_WAITING_LIST): ar( waitinglist.get_waitinglist_find_simple(dbo, q, limit=limit, siteid=siteid), "WAITINGLIST", wlsort) elif q.startswith("la:") or q.startswith("lostanimal:"): q = q[q.find(":") + 1:].strip() explain = _("Lost animal entries matching '{0}'.", l).format(q) if users.check_permission_bool(session, users.VIEW_LOST_ANIMAL): ar( lostfound.get_lostanimal_find_simple(dbo, q, limit=limit, siteid=siteid), "LOSTANIMAL", lasort) elif q.startswith("fa:") or q.startswith("foundanimal:"): q = q[q.find(":") + 1:].strip() explain = _("Found animal entries matching '{0}'.", l).format(q) if users.check_permission_bool(session, users.VIEW_FOUND_ANIMAL): ar( lostfound.get_foundanimal_find_simple(dbo, q, limit=limit, siteid=siteid), "FOUNDANIMAL", fasort) elif q.startswith("li:") or q.startswith("license:"): q = q[q.find(":") + 1:].strip() explain = _("License numbers matching '{0}'.", l).format(q) if users.check_permission_bool(session, users.VIEW_LICENCE): ar(financial.get_licence_find_simple(dbo, q, limit), "LICENCE", lisort) # No special tokens, search everything and collate else: if viewanimal: ar( animal.get_animal_find_simple(dbo, q, limit=limit, locationfilter=locationfilter, siteid=siteid), "ANIMAL", animalsort) if users.check_permission_bool(session, users.VIEW_INCIDENT): ar( animalcontrol.get_animalcontrol_find_simple(dbo, q, user, limit=limit, siteid=siteid), "ANIMALCONTROL", acsort) if viewperson: ar( person.get_person_find_simple(dbo, q, user, includeStaff=viewstaff, includeVolunteers=viewvolunteer, limit=limit, siteid=siteid), "PERSON", personsort) if users.check_permission_bool(session, users.VIEW_WAITING_LIST): ar( waitinglist.get_waitinglist_find_simple(dbo, q, limit=limit, siteid=siteid), "WAITINGLIST", wlsort) if users.check_permission_bool(session, users.VIEW_LOST_ANIMAL): ar( lostfound.get_lostanimal_find_simple(dbo, q, limit=limit, siteid=siteid), "LOSTANIMAL", lasort) if users.check_permission_bool(session, users.VIEW_FOUND_ANIMAL): ar( lostfound.get_foundanimal_find_simple(dbo, q, limit=limit, siteid=siteid), "FOUNDANIMAL", fasort) if users.check_permission_bool(session, users.VIEW_LICENCE): ar(financial.get_licence_find_simple(dbo, q, limit), "LICENCE", lisort) explain = _("Results for '{0}'.", l).format(q) # Apply the sort to the results if sortdir == "a": sortresults = sorted(results, key=lambda k: k["SORTON"]) else: sortresults = sorted(results, reverse=True, key=lambda k: k["SORTON"]) # stop the clock timetaken = (time.time() - starttime) # Return our final set of values return sortresults, timetaken, explain, sortname
def test_get_animal_find_simple(self): assert len(animal.get_animal_find_simple(base.get_dbo(), "Testio")) > 0
def search(dbo, session, q): """ Performs a database wide search for the term given. special tokens: a:term Only search animals for term p:term Only search people for term wl:term Only search waiting list entries for term sort:az Sort results alphabetically az sort:za Sort results alphabetically za sort:mr Sort results most recently changed first sort:lr Sort results least recently changed first onshelter/os, notforadoption, hold, quarantine, deceased, forpublish people, vets, retailers, staff, fosterers, volunteers, shelters, aco, homechecked, homecheckers, members, donors, reservenohomecheck returns a tuple of: results, timetaken, explain, sortname """ # ar (add results) inner method def ar(rlist, rtype, sortfield): # Return brief records if rtype == "ANIMAL": rlist = animal.get_animals_brief(rlist) if rtype == "PERSON": pass # TODO: for r in rlist: r["RESULTTYPE"] = rtype if sortfield == "RELEVANCE": # How "relevant" is this record to what was searched for? # animal name and code weight higher than other elements. # Note that the code below modifies inbound var q, so by the # time we read it here, it should only contain the search term # itself. Weight everything else by last changed date so there # is some semblance of useful order for less relevant items r["SORTON"] = r["LASTCHANGEDDATE"] qlow = q.lower() if rtype == "ANIMAL": if r["ANIMALNAME"].lower( ) == qlow or r["SHELTERCODE"].lower( ) == qlow or r["SHORTCODE"].lower() == qlow: r["SORTON"] = now() # Put matches where term present just behind direct matches if r["ANIMALNAME"].lower().find( qlow) != -1 or r["SHELTERCODE"].lower().find( qlow) != -1 or r["SHORTCODE"].lower().find( qlow) != -1: r["SORTON"] = now() - datetime.timedelta(seconds=1) elif rtype == "PERSON": if r["OWNERSURNAME"].lower( ) == qlow or r["OWNERNAME"].lower() == qlow: r["SORTON"] = now() # Put matches where term present just behind direct matches if r["OWNERSURNAME"].lower().find( qlow) or r["OWNERNAME"].lower().find(qlow): r["SORTON"] = now() - datetime.timedelta(seconds=1) else: r["SORTON"] = r[sortfield] results.append(r) l = dbo.locale # start the clock starttime = time.time() # The returned results results = [] # An i18n explanation of what was searched for explain = "" # Max records to be returned by search limit = configuration.record_search_limit(dbo) # Default sort for the search searchsort = configuration.search_sort(dbo) q = q.replace("'", "`") # Allow the sort to be overridden if q.find("sort:") != -1: if "sort:az" in q: searchsort = 0 q = q.replace("sort:az", "") elif "sort:za" in q: searchsort = 1 q = q.replace("sort:za", "") elif "sort:lr" in q: searchsort = 2 q = q.replace("sort:lr", "") elif "sort:mr" in q: searchsort = 3 q = q.replace("sort:mr", "") elif "sort:as" in q: searchsort = 4 q = q.replace("sort:as", "") elif "sort:sa" in q: searchsort = 5 q = q.replace("sort:sa", "") elif "sort:rel" in q: searchsort = 6 q = q.replace("sort:rel", "") q = q.strip() # Only search indexed fields in larger databases indexed_only = dbo.is_large_db # Handle sorting =========================== animalsort = "" personsort = "" wlsort = "" lasort = "" fasort = "" sortdir = "a" sortname = "" # alphanumeric ascending if searchsort == 0: animalsort = "ANIMALNAME" personsort = "OWNERNAME" wlsort = "OWNERNAME" lasort = "OWNERNAME" fasort = "OWNERNAME" sortdir = "a" sortname = _("Alphabetically A-Z", l) # alphanumeric descending elif searchsort == 1: animalsort = "ANIMALNAME" personsort = "OWNERNAME" wlsort = "OWNERNAME" lasort = "OWNERNAME" fasort = "OWNERNAME" sortdir = "d" sortname = _("Alphabetically Z-A", l) # last changed ascending elif searchsort == 2: animalsort = "LASTCHANGEDDATE" personsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" fasort = "LASTCHANGEDDATE" sortdir = "a" sortname = _("Least recently changed", l) # last changed descending elif searchsort == 3: animalsort = "LASTCHANGEDDATE" personsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" fasort = "LASTCHANGEDDATE" sortdir = "d" sortname = _("Most recently changed", l) # species ascending elif searchsort == 4: animalsort = "SPECIESNAME" # This will look screwy if you ask for a species sort and there # are records other than animals in there personsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" fasort = "LASTCHANGEDDATE" sortdir = "a" sortname = _("Species A-Z", l) elif searchsort == 5: animalsort = "SPECIESNAME" # This will look screwy if you ask for a species sort and there # are records other than animals in there personsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" fasort = "LASTCHANGEDDATE" sortdir = "d" sortname = _("Species Z-A", l) elif searchsort == 6: animalsort = "RELEVANCE" personsort = "RELEVANCE" wlsort = "RELEVANCE" lasort = "RELEVANCE" fasort = "RELEVANCE" sortdir = "d" sortname = _("Most relevant", l) # Special token searches if q == "onshelter" or q == "os": ar(animal.get_animal_find_simple(dbo, "", "all", limit), "ANIMAL", animalsort) explain = _("All animals on the shelter.", l) elif q == "notforadoption": ar(animal.get_animals_not_for_adoption(dbo), "ANIMAL", animalsort) explain = _("All animals who are flagged as not for adoption.", l) elif q == "hold": ar(animal.get_animals_hold(dbo), "ANIMAL", animalsort) explain = _("All animals who are currently held in case of reclaim.", l) elif q == "quarantine": ar(animal.get_animals_quarantine(dbo), "ANIMAL", animalsort) explain = _("All animals who are currently quarantined.", l) elif q == "deceased": ar(animal.get_animals_recently_deceased(dbo), "ANIMAL", animalsort) explain = _("Recently deceased shelter animals (last 30 days).", l) elif q == "forpublish": pc = publish.PublishCriteria(configuration.publisher_presets(dbo)) ar(publish.get_animal_data(dbo, pc), "ANIMAL", animalsort) explain = _("All animals matching current publishing options.", l) elif q == "people": ar( person.get_person_find_simple( dbo, "", "all", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All people on file.", l) elif q == "vets": ar( person.get_person_find_simple( dbo, "", "vet", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All vets on file.", l) elif q == "retailers": ar( person.get_person_find_simple( dbo, "", "retailer", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All retailers on file.", l) elif q == "staff": ar( person.get_person_find_simple( dbo, "", "staff", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All staff on file.", l) elif q == "fosterers": ar( person.get_person_find_simple( dbo, "", "fosterer", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All fosterers on file.", l) elif q == "volunteers": ar( person.get_person_find_simple( dbo, "", "volunteer", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All volunteers on file.", l) elif q == "shelters": ar( person.get_person_find_simple( dbo, "", "shelter", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All animal shelters on file.", l) elif q == "aco": ar( person.get_person_find_simple( dbo, "", "aco", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All animal care officers on file.", l) elif q == "homechecked": ar( person.get_person_find_simple( dbo, "", "homechecked", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All homechecked owners on file.", l) elif q == "homecheckers": ar( person.get_person_find_simple( dbo, "", "homechecker", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All homecheckers on file.", l) elif q == "members": ar( person.get_person_find_simple( dbo, "", "member", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All members on file.", l) elif q == "donors": ar( person.get_person_find_simple( dbo, "", "donor", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All donors on file.", l) elif q == "reservenohomecheck": ar(person.get_reserves_without_homechecks(dbo), "PERSON", personsort) explain = _( "People with active reservations, but no homecheck has been done.", l) elif q == "overduedonations": ar(person.get_overdue_donations(dbo), "PERSON", personsort) explain = _("People with overdue donations.", l) elif q == "activelost": ar(lostfound.get_lostanimal_find_simple(dbo, ""), "LOSTANIMAL", lasort) explain = _("Lost animals reported in the last 30 days.", l) elif q == "activefound": ar(lostfound.get_foundanimal_find_simple(dbo, ""), "FOUNDANIMAL", fasort) explain = _("Found animals reported in the last 30 days.", l) elif q.startswith("a:") or q.startswith("animal:"): q = q[q.find(":") + 1:].strip() explain = _("Animals matching '{0}'.", l).format(q) ar(animal.get_animal_find_simple(dbo, q, "all", limit, indexed_only), "ANIMAL", animalsort) elif q.startswith("p:") or q.startswith("person:"): q = q[q.find(":") + 1:].strip() explain = _("People matching '{0}'.", l).format(q) ar( person.get_person_find_simple( dbo, q, "all", users.check_permission_bool(session, users.VIEW_STAFF), limit, indexed_only), "PERSON", personsort) elif q.startswith("wl:") or q.startswith("waitinglist:"): q = q[q.find(":") + 1:].strip() explain = _("Waiting list entries matching '{0}'.", l).format(q) ar( waitinglist.get_waitinglist_find_simple(dbo, q, limit, indexed_only), "WAITINGLIST", wlsort) elif q.startswith("la:") or q.startswith("lostanimal:"): q = q[q.find(":") + 1:].strip() explain = _("Lost animal entries matching '{0}'.", l).format(q) ar(lostfound.get_lostanimal_find_simple(dbo, q, limit, indexed_only), "LOSTANIMAL", lasort) elif q.startswith("fa:") or q.startswith("foundanimal:"): q = q[q.find(":") + 1:].strip() explain = _("Found animal entries matching '{0}'.", l).format(q) ar(lostfound.get_foundanimal_find_simple(dbo, q, limit, indexed_only), "FOUNDANIMAL", fasort) # No special tokens, search everything and collate else: ar(animal.get_animal_find_simple(dbo, q, "all", limit, indexed_only), "ANIMAL", animalsort) ar( person.get_person_find_simple( dbo, q, "all", users.check_permission_bool(session, users.VIEW_STAFF), limit, indexed_only), "PERSON", personsort) ar( waitinglist.get_waitinglist_find_simple(dbo, q, limit, indexed_only), "WAITINGLIST", wlsort) ar(lostfound.get_lostanimal_find_simple(dbo, q, limit, indexed_only), "LOSTANIMAL", lasort) ar(lostfound.get_foundanimal_find_simple(dbo, q, limit, indexed_only), "FOUNDANIMAL", fasort) explain = _("Results for '{0}'.", l).format(q) # Apply the sort to the results if sortdir == "a": sortresults = sorted(results, key=lambda k: k["SORTON"]) else: sortresults = sorted(results, reverse=True, key=lambda k: k["SORTON"]) # stop the clock timetaken = (time.time() - starttime) # Return our final set of values return sortresults, timetaken, explain, sortname
def handler(dbo, user, post): """ Handles posts from the frontend. Depending on the type we either return more HTML for the javascript to inject, or GO URL to have the controller redirect to URL """ l = dbo.locale homelink = "<a href='mobile' class='ui-btn-right' data-icon='home' data-theme='b'>%s</a>" % _( "Home", l) mode = post["posttype"] pid = post.integer("id") animalid = post.integer("animalid") if mode == "vacc": # We're vaccinating an animal a = animal.get_animal(dbo, animalid) medical.update_vaccination_today(dbo, user, pid) return jqm_page_header("", _("Vaccination Given", l), homelink) + \ jqm_p(_("Vaccination marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + \ jqm_button("mobile#vacc", _("More Vaccinations", l), "", "false") + \ jqm_page_footer() if mode == "test": # We're performing a test on an animal a = animal.get_animal(dbo, animalid) medical.update_test_today(dbo, user, pid, post.integer("resultid")) return jqm_page_header("", _("Test Performed", l), homelink) + \ jqm_p(_("Test marked as performed for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + \ jqm_button("mobile#test", _("More Tests", l), "", "false") + \ jqm_page_footer() elif mode == "med": # We're treating an animal a = animal.get_animal(dbo, animalid) medical.update_treatment_today(dbo, user, pid) return jqm_page_header("", _("Treatment Given", l), homelink) + \ jqm_p(_("Treatment marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + \ jqm_button("mobile#med", _("More Medications", l), "", "false") + \ jqm_page_footer() elif mode == "dia": # We're completing a diary task d = diary.get_diary(dbo, pid) if post["on"] == "0": diary.complete_diary_note(dbo, user, pid) return jqm_page_header("", _("Completed", l), homelink) + \ jqm_p(_("Diary note {0} marked completed", l).format(d["SUBJECT"])) + \ jqm_button("mobile#diary", _("More diary notes", l), "", "false") + \ jqm_page_footer() else: diary.rediarise_diary_note(dbo, user, pid, post.date("on")) return jqm_page_header("", _("Rediarised", l), homelink) + \ jqm_p(_("Diary note {0} rediarised for {1}", l).format(d["SUBJECT"], post["on"])) + \ jqm_button("mobile#diary", _("More diary notes", l), "", "false") + \ jqm_page_footer() elif mode == "dianew": # We're adding a diary note diary.insert_diary(dbo, user, 0, 0, post.date("diarydate"), post["diaryfor"], post["subject"], post["note"]) return "GO mobile" elif mode == "message": # We're adding a message lookups.add_message(dbo, user, post.boolean("email"), post["message"], post["forname"], post.integer("priority"), post.date("expires")) return "GO mobile" elif mode == "log": # We're adding a log to an animal a = animal.get_animal(dbo, animalid) log.add_log(dbo, user, log.ANIMAL, animalid, post.integer("logtypeid"), post["logtext"]) return "GO mobile" elif mode == "hc": # We're marking an owner homechecked person.update_pass_homecheck(dbo, user, post.integer("personid"), post["comments"]) return "GO mobile" elif mode == "vsa": # Return a list of the shelter animals h = [] alin = [] h.append(header(l)) h.append(jqm_page_header("", _("Shelter Animals", l), homelink)) an = animal.get_animal_find_simple(dbo, "", "all") for a in an: alin.append( jqm_listitem_link( "mobile_post?posttype=va&id=%d" % a["ID"], "%s - %s (%s %s %s) %s" % (a["CODE"], a["ANIMALNAME"], a["SEXNAME"], a["BREEDNAME"], a["SPECIESNAME"], a["IDENTICHIPNUMBER"]), "animal")) h.append(jqm_list("\n".join(alin), True)) h.append(jqm_page_footer()) h.append("</body></html>") return "\n".join(h) elif mode == "uai": # Upload an animal image media.attach_file_from_form(dbo, user, media.ANIMAL, animalid, post.data) return "GO mobile_post?posttype=va&id=%d&success=true" % animalid elif mode == "va": # Display a page containing the selected animal by id a = animal.get_animal(dbo, pid) af = additional.get_additional_fields(dbo, pid, "animal") return handler_viewanimal(l, a, af, homelink, post)
def handler(dbo, user, post): """ Handles posts from the frontend. Depending on the type we either return more HTML for the javascript to inject, or GO URL to have the controller redirect to URL """ l = dbo.locale homelink = "<a href='mobile' class='ui-btn-right' data-icon='home' data-theme='b'>%s</a>" % _("Home", l) mode = post["posttype"] pid = post.integer("id") animalid = post.integer("animalid") if mode == "vacc": # We're vaccinating an animal a = animal.get_animal(dbo, animalid) medical.update_vaccination_today(dbo, user, pid) return ( jqm_page_header("", _("Vaccination Given", l), homelink) + jqm_p(_("Vaccination marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + jqm_button("mobile#vacc", _("More Vaccinations", l), "", "false") + jqm_page_footer() ) if mode == "test": # We're performing a test on an animal a = animal.get_animal(dbo, animalid) medical.update_test_today(dbo, user, pid, post.integer("resultid")) return ( jqm_page_header("", _("Test Performed", l), homelink) + jqm_p(_("Test marked as performed for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + jqm_button("mobile#test", _("More Tests", l), "", "false") + jqm_page_footer() ) elif mode == "med": # We're treating an animal a = animal.get_animal(dbo, animalid) medical.update_treatment_today(dbo, user, pid) return ( jqm_page_header("", _("Treatment Given", l), homelink) + jqm_p(_("Treatment marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + jqm_button("mobile#med", _("More Medications", l), "", "false") + jqm_page_footer() ) elif mode == "dia": # We're completing a diary task d = diary.get_diary(dbo, pid) if post["on"] == "0": diary.complete_diary_note(dbo, user, pid) return ( jqm_page_header("", _("Completed", l), homelink) + jqm_p(_("Diary note {0} marked completed", l).format(d["SUBJECT"])) + jqm_button("mobile#diary", _("More diary notes", l), "", "false") + jqm_page_footer() ) else: diary.rediarise_diary_note(dbo, user, pid, post.date("on")) return ( jqm_page_header("", _("Rediarised", l), homelink) + jqm_p(_("Diary note {0} rediarised for {1}", l).format(d["SUBJECT"], post["on"])) + jqm_button("mobile#diary", _("More diary notes", l), "", "false") + jqm_page_footer() ) elif mode == "dianew": # We're adding a diary note diary.insert_diary(dbo, user, 0, 0, post.date("diarydate"), post["diaryfor"], post["subject"], post["note"]) return "GO mobile" elif mode == "message": # We're adding a message lookups.add_message( dbo, user, post.boolean("email"), post["message"], post["forname"], post.integer("priority"), post.date("expires"), ) return "GO mobile" elif mode == "log": # We're adding a log to an animal a = animal.get_animal(dbo, animalid) log.add_log(dbo, user, log.ANIMAL, animalid, post.integer("logtypeid"), post["logtext"]) return "GO mobile" elif mode == "hc": # We're marking an owner homechecked person.update_pass_homecheck(dbo, user, post.integer("personid"), post["comments"]) return "GO mobile" elif mode == "vsa": # Return a list of the shelter animals h = [] alin = [] h.append(header(l)) h.append(jqm_page_header("", _("Shelter Animals", l), homelink)) an = animal.get_animal_find_simple(dbo, "", "all") for a in an: alin.append( jqm_listitem_link( "mobile_post?posttype=va&id=%d" % a["ID"], "%s - %s (%s %s %s) %s" % ( a["CODE"], a["ANIMALNAME"], a["SEXNAME"], a["BREEDNAME"], a["SPECIESNAME"], a["IDENTICHIPNUMBER"], ), "animal", ) ) h.append(jqm_list("\n".join(alin), True)) h.append(jqm_page_footer()) h.append("</body></html>") return "\n".join(h) elif mode == "uai": # Upload an animal image media.attach_file_from_form(dbo, user, media.ANIMAL, animalid, post.data) return "GO mobile_post?posttype=va&id=%d&success=true" % animalid elif mode == "va": # Display a page containing the selected animal by id a = animal.get_animal(dbo, pid) af = additional.get_additional_fields(dbo, pid, "animal") return handler_viewanimal(l, a, af, homelink, post)
def search(dbo, session, q): """ Performs a database wide search for the term given. special tokens: a:term Only search animals for term ac:term Only search animal control incidents for term p:term Only search people for term la:term Only search lost animals for term li:num Only search licence numbers for term fa:term Only search found animals for term wl:term Only search waiting list entries for term sort:az Sort results alphabetically az sort:za Sort results alphabetically za sort:mr Sort results most recently changed first sort:lr Sort results least recently changed first -- update this list in header.js/bind_search/keywords activelost, activefound, onshelter/os, notforadoption, hold, holdtoday, quarantine, deceased, forpublish, people, vets, retailers, staff, fosterers, volunteers, shelters, aco, banned, homechecked, homecheckers, members, donors, drivers, reservenohomecheck, notmicrochipped returns a tuple of: results, timetaken, explain, sortname """ # ar (add results) inner method def ar(rlist, rtype, sortfield): # Return brief records to save bandwidth if rtype == "ANIMAL": rlist = animal.get_animals_brief(rlist) if rtype == "PERSON": pass # TODO: for r in rlist: r["RESULTTYPE"] = rtype if sortfield == "RELEVANCE": # How "relevant" is this record to what was searched for? # animal name and code weight higher than other elements. # Note that the code below modifies inbound var q, so by the # time we read it here, it should only contain the search term # itself. Weight everything else by last changed date so there # is some semblance of useful order for less relevant items qlow = q.lower() if rtype == "ANIMAL": r["SORTON"] = r["LASTCHANGEDDATE"] if r["ANIMALNAME"].lower() == qlow or r["SHELTERCODE"].lower() == qlow or r["SHORTCODE"].lower() == qlow: r["SORTON"] = now() # Put matches where term present just behind direct matches elif r["ANIMALNAME"].lower().find(qlow) != -1 or r["SHELTERCODE"].lower().find(qlow) != -1 or r["SHORTCODE"].lower().find(qlow) != -1: r["SORTON"] = now() - datetime.timedelta(seconds=1) elif rtype == "PERSON": r["SORTON"] = r["LASTCHANGEDDATE"] # Count how many of the keywords in the search were present # in the owner name field - if it's all of them then raise # the relevance. qw = qlow.split(" ") qm = 0 for w in qw: if r["OWNERNAME"].lower().find(w) != -1: qm += 1 if qm == len(qw): r["SORTON"] = now() # Put matches where term present just behind direct matches if r["OWNERSURNAME"].lower().find(qlow) or r["OWNERNAME"].lower().find(qlow): r["SORTON"] = now() - datetime.timedelta(seconds=1) elif rtype == "LICENCE": r["SORTON"] = r["ISSUEDATE"] if r["SORTON"] is None: r["SORTON"] = now() if r["LICENCENUMBER"].lower() == qlow: r["SORTON"] = now() else: r["SORTON"] = r["LASTCHANGEDDATE"] else: r["SORTON"] = r[sortfield] results.append(r) l = dbo.locale # start the clock starttime = time.time() # The returned results results = [] # An i18n explanation of what was searched for explain = "" # Max records to be returned by search limit = configuration.record_search_limit(dbo) # Default sort for the search searchsort = configuration.search_sort(dbo) q = q.replace("'", "`") # Allow the sort to be overridden if q.find("sort:") != -1: if "sort:az" in q: searchsort = 0 q = q.replace("sort:az", "") elif "sort:za" in q: searchsort = 1 q = q.replace("sort:za", "") elif "sort:lr" in q: searchsort = 2 q = q.replace("sort:lr", "") elif "sort:mr" in q: searchsort = 3 q = q.replace("sort:mr", "") elif "sort:as" in q: searchsort = 4 q = q.replace("sort:as", "") elif "sort:sa" in q: searchsort = 5 q = q.replace("sort:sa", "") elif "sort:rel" in q: searchsort = 6 q = q.replace("sort:rel", "") q = q.strip() # Handle sorting =========================== animalsort = "" personsort = "" wlsort = "" acsort = "" lasort = "" lisort = "" fasort = "" sortdir = "a" sortname = "" # alphanumeric ascending if searchsort == 0: animalsort = "ANIMALNAME" personsort = "OWNERNAME" wlsort = "OWNERNAME" acsort = "OWNERNAME" lasort = "OWNERNAME" lisort = "OWNERNAME" fasort = "OWNERNAME" sortdir = "a" sortname = _("Alphabetically A-Z", l) # alphanumeric descending elif searchsort == 1: animalsort = "ANIMALNAME" personsort = "OWNERNAME" wlsort = "OWNERNAME" acsort = "OWNERNAME" lasort = "OWNERNAME" lisort = "OWNERNAME" fasort = "OWNERNAME" sortdir = "d" sortname = _("Alphabetically Z-A", l) # last changed ascending elif searchsort == 2: animalsort = "LASTCHANGEDDATE" personsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" acsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" lisort = "ISSUEDATE" fasort = "LASTCHANGEDDATE" sortdir = "a" sortname = _("Least recently changed", l) # last changed descending elif searchsort == 3: animalsort = "LASTCHANGEDDATE" personsort = "LASTCHANGEDDATE" acsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" lisort = "ISSUEDATE" fasort = "LASTCHANGEDDATE" sortdir = "d" sortname = _("Most recently changed", l) # species ascending elif searchsort == 4: animalsort = "SPECIESNAME" personsort = "OWNERNAME" acsort = "SPECIESNAME" wlsort = "SPECIESNAME" lasort = "SPECIESNAME" lisort = "COMMENTS" fasort = "SPECIESNAME" sortdir = "a" sortname = _("Species A-Z", l) elif searchsort == 5: animalsort = "SPECIESNAME" personsort = "OWNERNAME" acsort = "SPECIESNAME" wlsort = "SPECIESNAME" lasort = "SPECIESNAME" lisort = "COMMENTS" fasort = "SPECIESNAME" sortdir = "d" sortname = _("Species Z-A", l) elif searchsort == 6: animalsort = "RELEVANCE" personsort = "RELEVANCE" wlsort = "RELEVANCE" acsort = "RELEVANCE" lasort = "RELEVANCE" lisort = "RELEVANCE" fasort = "RELEVANCE" sortdir = "d" sortname = _("Most relevant", l) viewperson = users.check_permission_bool(session, users.VIEW_PERSON) viewanimal = users.check_permission_bool(session, users.VIEW_ANIMAL) viewstaff = users.check_permission_bool(session, users.VIEW_STAFF) viewvolunteer = users.check_permission_bool(session, users.VIEW_VOLUNTEER) # Special token searches if q == "onshelter" or q == "os": explain = _("All animals on the shelter.", l) if viewanimal: ar(animal.get_animal_find_simple(dbo, "", "all", limit), "ANIMAL", animalsort) elif q == "notforadoption": explain = _("All animals who are flagged as not for adoption.", l) if viewanimal: ar(animal.get_animals_not_for_adoption(dbo), "ANIMAL", animalsort) elif q == "longterm": explain = _("All animals who have been on the shelter longer than {0} months.", l).format(configuration.long_term_months(dbo)) if viewanimal: ar(animal.get_animals_long_term(dbo), "ANIMAL", animalsort) elif q == "notmicrochipped": explain = _("All animals who have not been microchipped", l) if viewanimal: ar(animal.get_animals_not_microchipped(dbo), "ANIMAL", animalsort) elif q == "hold": explain = _("All animals who are currently held in case of reclaim.", l) if viewanimal: ar(animal.get_animals_hold(dbo), "ANIMAL", animalsort) elif q == "holdtoday": explain = _("All animals where the hold ends today.", l) if viewanimal: ar(animal.get_animals_hold_today(dbo), "ANIMAL", animalsort) elif q == "quarantine": explain = _("All animals who are currently quarantined.", l) if viewanimal: ar(animal.get_animals_quarantine(dbo), "ANIMAL", animalsort) elif q == "deceased": explain = _("Recently deceased shelter animals (last 30 days).", l) if viewanimal: ar(animal.get_animals_recently_deceased(dbo), "ANIMAL", animalsort) elif q == "forpublish": explain = _("All animals matching current publishing options.", l) if viewanimal: pc = publish.PublishCriteria(configuration.publisher_presets(dbo)) ar(publish.get_animal_data(dbo, pc), "ANIMAL", animalsort) elif q == "people": ar(person.get_person_find_simple(dbo, "", "all", viewstaff, viewvolunteer, limit), "PERSON", personsort) explain = _("All people on file.", l) elif q == "vets": explain = _("All vets on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "vet", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "retailers": explain = _("All retailers on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "retailer", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "staff": explain = _("All staff on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "staff", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "fosterers": explain = _("All fosterers on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "fosterer", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "volunteers": explain = _("All volunteers on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "volunteer", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "shelters": explain = _("All animal shelters on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "shelter", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "aco": explain = _("All animal care officers on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "aco", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "banned": explain = _("All banned owners on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "banned", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "homechecked": explain = _("All homechecked owners on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "homechecked", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "homecheckers": explain = _("All homecheckers on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "homechecker", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "members": explain = _("All members on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "member", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "donors": explain = _("All donors on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "donor", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "drivers": explain = _("All drivers on file.", l) if viewperson: ar(person.get_person_find_simple(dbo, "", "driver", viewstaff, viewvolunteer, limit), "PERSON", personsort) elif q == "reservenohomecheck": explain = _("People with active reservations, but no homecheck has been done.", l) if viewperson: ar(person.get_reserves_without_homechecks(dbo), "PERSON", personsort) elif q == "overduedonations": explain = _("People with overdue donations.", l) if viewperson: ar(person.get_overdue_donations(dbo), "PERSON", personsort) elif q == "activelost": explain = _("Lost animals reported in the last 30 days.", l) if users.check_permission_bool(session, users.VIEW_LOST_ANIMAL): ar(lostfound.get_lostanimal_find_simple(dbo, ""), "LOSTANIMAL", lasort) elif q == "activefound": explain = _("Found animals reported in the last 30 days.", l) if users.check_permission_bool(session, users.VIEW_FOUND_ANIMAL): ar(lostfound.get_foundanimal_find_simple(dbo, ""), "FOUNDANIMAL", fasort) elif q.startswith("a:") or q.startswith("animal:"): q = q[q.find(":")+1:].strip() explain = _("Animals matching '{0}'.", l).format(q) if viewanimal: ar( animal.get_animal_find_simple(dbo, q, "all", limit), "ANIMAL", animalsort ) elif q.startswith("ac:") or q.startswith("animalcontrol:"): q = q[q.find(":")+1:].strip() explain = _("Animal control incidents matching '{0}'.", l).format(q) if users.check_permission_bool(session, users.VIEW_INCIDENT): ar( animalcontrol.get_animalcontrol_find_simple(dbo, q, limit), "ANIMALCONTROL", acsort ) elif q.startswith("p:") or q.startswith("person:"): q = q[q.find(":")+1:].strip() explain = _("People matching '{0}'.", l).format(q) if viewperson: ar( person.get_person_find_simple(dbo, q, "all", viewstaff, viewvolunteer, limit), "PERSON", personsort ) elif q.startswith("wl:") or q.startswith("waitinglist:"): q = q[q.find(":")+1:].strip() explain = _("Waiting list entries matching '{0}'.", l).format(q) if users.check_permission_bool(session, users.VIEW_WAITING_LIST): ar( waitinglist.get_waitinglist_find_simple(dbo, q, limit), "WAITINGLIST", wlsort ) elif q.startswith("la:") or q.startswith("lostanimal:"): q = q[q.find(":")+1:].strip() explain = _("Lost animal entries matching '{0}'.", l).format(q) if users.check_permission_bool(session, users.VIEW_LOST_ANIMAL): ar( lostfound.get_lostanimal_find_simple(dbo, q, limit), "LOSTANIMAL", lasort ) elif q.startswith("fa:") or q.startswith("foundanimal:"): q = q[q.find(":")+1:].strip() explain = _("Found animal entries matching '{0}'.", l).format(q) if users.check_permission_bool(session, users.VIEW_FOUND_ANIMAL): ar( lostfound.get_foundanimal_find_simple(dbo, q, limit), "FOUNDANIMAL", fasort ) elif q.startswith("li:") or q.startswith("license:"): q = q[q.find(":")+1:].strip() explain = _("License numbers matching '{0}'.", l).format(q) if users.check_permission_bool(session, users.VIEW_LICENCE): ar( financial.get_licence_find_simple(dbo, q, limit), "LICENCE", lisort ) # No special tokens, search everything and collate else: if viewanimal: ar( animal.get_animal_find_simple(dbo, q, "all", limit), "ANIMAL", animalsort ) if users.check_permission_bool(session, users.VIEW_INCIDENT): ar( animalcontrol.get_animalcontrol_find_simple(dbo, q, limit), "ANIMALCONTROL", acsort ) if viewperson: ar( person.get_person_find_simple(dbo, q, "all", viewstaff, viewvolunteer, limit), "PERSON", personsort ) if users.check_permission_bool(session, users.VIEW_WAITING_LIST): ar( waitinglist.get_waitinglist_find_simple(dbo, q, limit), "WAITINGLIST", wlsort ) if users.check_permission_bool(session, users.VIEW_LOST_ANIMAL): ar( lostfound.get_lostanimal_find_simple(dbo, q, limit), "LOSTANIMAL", lasort ) if users.check_permission_bool(session, users.VIEW_FOUND_ANIMAL): ar( lostfound.get_foundanimal_find_simple(dbo, q, limit), "FOUNDANIMAL", fasort ) if users.check_permission_bool(session, users.VIEW_LICENCE): ar( financial.get_licence_find_simple(dbo, q, limit), "LICENCE", lisort ) explain = _("Results for '{0}'.", l).format(q) # Apply the sort to the results if sortdir == "a": sortresults = sorted(results, key=lambda k: k["SORTON"]) else: sortresults = sorted(results, reverse=True, key=lambda k: k["SORTON"]) # stop the clock timetaken = (time.time() - starttime) # Return our final set of values return sortresults, timetaken, explain, sortname
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 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 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)
def search(dbo, session, q): """ Performs a database wide search for the term given. special tokens: a:term Only search animals for term p:term Only search people for term wl:term Only search waiting list entries for term sort:az Sort results alphabetically az sort:za Sort results alphabetically za sort:mr Sort results most recently changed first sort:lr Sort results least recently changed first onshelter/os, notforadoption, hold, quarantine, deceased, forpublish people, vets, retailers, staff, fosterers, volunteers, shelters, aco, homechecked, homecheckers, members, donors, reservenohomecheck returns a tuple of: results, timetaken, explain, sortname """ # ar (add results) inner method def ar(rlist, rtype, sortfield): # Return brief records if rtype == "ANIMAL": rlist = animal.get_animals_brief(rlist) if rtype == "PERSON": pass # TODO: for r in rlist: r["RESULTTYPE"] = rtype if sortfield == "RELEVANCE": # How "relevant" is this record to what was searched for? # animal name and code weight higher than other elements. # Note that the code below modifies inbound var q, so by the # time we read it here, it should only contain the search term # itself. Weight everything else by last changed date so there # is some semblance of useful order for less relevant items r["SORTON"] = r["LASTCHANGEDDATE"] qlow = q.lower() if rtype == "ANIMAL": if r["ANIMALNAME"].lower() == qlow or r["SHELTERCODE"].lower() == qlow or r["SHORTCODE"].lower() == qlow: r["SORTON"] = now() # Put matches where term present just behind direct matches if r["ANIMALNAME"].lower().find(qlow) != -1 or r["SHELTERCODE"].lower().find(qlow) != -1 or r["SHORTCODE"].lower().find(qlow) != -1: r["SORTON"] = now() - datetime.timedelta(seconds=1) elif rtype == "PERSON": if r["OWNERSURNAME"].lower() == qlow or r["OWNERNAME"].lower() == qlow: r["SORTON"] = now() # Put matches where term present just behind direct matches if r["OWNERSURNAME"].lower().find(qlow) or r["OWNERNAME"].lower().find(qlow): r["SORTON"] = now() - datetime.timedelta(seconds=1) else: r["SORTON"] = r[sortfield] results.append(r) l = dbo.locale # start the clock starttime = time.time() # The returned results results = [] # An i18n explanation of what was searched for explain = "" # Max records to be returned by search limit = configuration.record_search_limit(dbo) # Default sort for the search searchsort = configuration.search_sort(dbo) q = q.replace("'", "`") # Allow the sort to be overridden if q.find("sort:") != -1: if "sort:az" in q: searchsort = 0 q = q.replace("sort:az", "") elif "sort:za" in q: searchsort = 1 q = q.replace("sort:za", "") elif "sort:lr" in q: searchsort = 2 q = q.replace("sort:lr", "") elif "sort:mr" in q: searchsort = 3 q = q.replace("sort:mr", "") elif "sort:as" in q: searchsort = 4 q = q.replace("sort:as", "") elif "sort:sa" in q: searchsort = 5 q = q.replace("sort:sa", "") elif "sort:rel" in q: searchsort = 6 q = q.replace("sort:rel", "") q = q.strip() # Only search indexed fields in larger databases indexed_only = dbo.is_large_db # Handle sorting =========================== animalsort = "" personsort = "" wlsort = "" lasort = "" fasort = "" sortdir = "a" sortname = "" # alphanumeric ascending if searchsort == 0: animalsort = "ANIMALNAME" personsort = "OWNERNAME" wlsort = "OWNERNAME" lasort = "OWNERNAME" fasort = "OWNERNAME" sortdir = "a" sortname = _("Alphabetically A-Z", l) # alphanumeric descending elif searchsort == 1: animalsort = "ANIMALNAME" personsort = "OWNERNAME" wlsort = "OWNERNAME" lasort = "OWNERNAME" fasort = "OWNERNAME" sortdir = "d" sortname = _("Alphabetically Z-A", l) # last changed ascending elif searchsort == 2: animalsort = "LASTCHANGEDDATE" personsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" fasort = "LASTCHANGEDDATE" sortdir = "a" sortname = _("Least recently changed", l) # last changed descending elif searchsort == 3: animalsort = "LASTCHANGEDDATE" personsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" fasort = "LASTCHANGEDDATE" sortdir = "d" sortname = _("Most recently changed", l) # species ascending elif searchsort == 4: animalsort = "SPECIESNAME" # This will look screwy if you ask for a species sort and there # are records other than animals in there personsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" fasort = "LASTCHANGEDDATE" sortdir = "a" sortname = _("Species A-Z", l) elif searchsort == 5: animalsort = "SPECIESNAME" # This will look screwy if you ask for a species sort and there # are records other than animals in there personsort = "LASTCHANGEDDATE" wlsort = "LASTCHANGEDDATE" lasort = "LASTCHANGEDDATE" fasort = "LASTCHANGEDDATE" sortdir = "d" sortname = _("Species Z-A", l) elif searchsort == 6: animalsort = "RELEVANCE" personsort = "RELEVANCE" wlsort = "RELEVANCE" lasort = "RELEVANCE" fasort = "RELEVANCE" sortdir = "d" sortname = _("Most relevant", l) # Special token searches if q == "onshelter" or q == "os": ar(animal.get_animal_find_simple(dbo, "", "all", limit), "ANIMAL", animalsort) explain = _("All animals on the shelter.", l) elif q == "notforadoption": ar(animal.get_animals_not_for_adoption(dbo), "ANIMAL", animalsort) explain = _("All animals who are flagged as not for adoption.", l) elif q == "hold": ar(animal.get_animals_hold(dbo), "ANIMAL", animalsort) explain = _("All animals who are currently held in case of reclaim.", l) elif q == "quarantine": ar(animal.get_animals_quarantine(dbo), "ANIMAL", animalsort) explain = _("All animals who are currently quarantined.", l) elif q == "deceased": ar(animal.get_animals_recently_deceased(dbo), "ANIMAL", animalsort) explain = _("Recently deceased shelter animals (last 30 days).", l) elif q == "forpublish": pc = publish.PublishCriteria(configuration.publisher_presets(dbo)) ar(publish.get_animal_data(dbo, pc), "ANIMAL", animalsort) explain = _("All animals matching current publishing options.", l) elif q == "people": ar(person.get_person_find_simple(dbo, "", "all", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All people on file.", l) elif q == "vets": ar(person.get_person_find_simple(dbo, "", "vet", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All vets on file.", l) elif q == "retailers": ar(person.get_person_find_simple(dbo, "", "retailer", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All retailers on file.", l) elif q == "staff": ar(person.get_person_find_simple(dbo, "", "staff", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All staff on file.", l) elif q == "fosterers": ar(person.get_person_find_simple(dbo, "", "fosterer", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All fosterers on file.", l) elif q == "volunteers": ar(person.get_person_find_simple(dbo, "", "volunteer", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All volunteers on file.", l) elif q == "shelters": ar(person.get_person_find_simple(dbo, "", "shelter", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All animal shelters on file.", l) elif q == "aco": ar(person.get_person_find_simple(dbo, "", "aco", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All animal care officers on file.", l) elif q == "homechecked": ar(person.get_person_find_simple(dbo, "", "homechecked", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All homechecked owners on file.", l) elif q == "homecheckers": ar(person.get_person_find_simple(dbo, "", "homechecker", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All homecheckers on file.", l) elif q == "members": ar(person.get_person_find_simple(dbo, "", "member", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All members on file.", l) elif q == "donors": ar(person.get_person_find_simple(dbo, "", "donor", users.check_permission_bool(session, users.VIEW_STAFF), limit), "PERSON", personsort) explain = _("All donors on file.", l) elif q == "reservenohomecheck": ar(person.get_reserves_without_homechecks(dbo), "PERSON", personsort) explain = _("People with active reservations, but no homecheck has been done.", l) elif q == "overduedonations": ar(person.get_overdue_donations(dbo), "PERSON", personsort) explain = _("People with overdue donations.", l) elif q == "activelost": ar(lostfound.get_lostanimal_find_simple(dbo, ""), "LOSTANIMAL", lasort) explain = _("Lost animals reported in the last 30 days.", l) elif q == "activefound": ar(lostfound.get_foundanimal_find_simple(dbo, ""), "FOUNDANIMAL", fasort) explain = _("Found animals reported in the last 30 days.", l) elif q.startswith("a:") or q.startswith("animal:"): q = q[q.find(":")+1:].strip() explain = _("Animals matching '{0}'.", l).format(q) ar( animal.get_animal_find_simple(dbo, q, "all", limit, indexed_only), "ANIMAL", animalsort ) elif q.startswith("p:") or q.startswith("person:"): q = q[q.find(":")+1:].strip() explain = _("People matching '{0}'.", l).format(q) ar( person.get_person_find_simple(dbo, q, "all", users.check_permission_bool(session, users.VIEW_STAFF), limit, indexed_only), "PERSON", personsort ) elif q.startswith("wl:") or q.startswith("waitinglist:"): q = q[q.find(":")+1:].strip() explain = _("Waiting list entries matching '{0}'.", l).format(q) ar( waitinglist.get_waitinglist_find_simple(dbo, q, limit, indexed_only), "WAITINGLIST", wlsort ) elif q.startswith("la:") or q.startswith("lostanimal:"): q = q[q.find(":")+1:].strip() explain = _("Lost animal entries matching '{0}'.", l).format(q) ar( lostfound.get_lostanimal_find_simple(dbo, q, limit, indexed_only), "LOSTANIMAL", lasort ) elif q.startswith("fa:") or q.startswith("foundanimal:"): q = q[q.find(":")+1:].strip() explain = _("Found animal entries matching '{0}'.", l).format(q) ar( lostfound.get_foundanimal_find_simple(dbo, q, limit, indexed_only), "FOUNDANIMAL", fasort ) # No special tokens, search everything and collate else: ar( animal.get_animal_find_simple(dbo, q, "all", limit, indexed_only), "ANIMAL", animalsort ) ar( person.get_person_find_simple(dbo, q, "all", users.check_permission_bool(session, users.VIEW_STAFF), limit, indexed_only), "PERSON", personsort ) ar( waitinglist.get_waitinglist_find_simple(dbo, q, limit, indexed_only), "WAITINGLIST", wlsort ) ar( lostfound.get_lostanimal_find_simple(dbo, q, limit, indexed_only), "LOSTANIMAL", lasort ) ar( lostfound.get_foundanimal_find_simple(dbo, q, limit, indexed_only), "FOUNDANIMAL", fasort ) explain = _("Results for '{0}'.", l).format(q) # Apply the sort to the results if sortdir == "a": sortresults = sorted(results, key=lambda k: k["SORTON"]) else: sortresults = sorted(results, reverse=True, key=lambda k: k["SORTON"]) # stop the clock timetaken = (time.time() - starttime) # Return our final set of values return sortresults, timetaken, explain, sortname