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 page(dbo, session, username): """ Generates the main mobile web page dbo: Database info """ l = dbo.locale nsa = animal.get_number_animals_on_shelter_now(dbo) osa = nsa > 0 ar = reports.get_available_reports(dbo, False) vacc = medical.get_vaccinations_outstanding(dbo) test = medical.get_tests_outstanding(dbo) med = medical.get_treatments_outstanding(dbo) dia = diary.get_uncompleted_upto_today(dbo, username) hck = person.get_reserves_without_homechecks(dbo) mess = lookups.get_messages(dbo, session.user, session.roles, session.superuser) testresults = lookups.get_test_results(dbo) homelink = jqm_link("mobile", _("Home", l), "home", "ui-btn-right", "b") h = [] h.append(header(l)) logoutlink = jqm_link("mobile_logout", _("Logout", l), "delete", "ui-btn-right", "b") h.append(jqm_page_header("home", _("ASM", l), logoutlink, False)) items = [] if configuration.smdb_locked(dbo): items.append( jqm_listitem( _( "This database is locked and in read-only mode. You cannot add, change or delete records.", l))) if len(mess) > 0: items.append( jqm_listitem_link("#messages", _("Messages", l), "message", len(mess))) if len(ar) > 0 and users.check_permission_bool(session, users.VIEW_REPORT): items.append( jqm_listitem_link("#reports", _("Generate Report", l), "report")) items.append(jqm_list_divider(_("Animal", l))) if osa and users.check_permission_bool(session, users.VIEW_ANIMAL): items.append( jqm_listitem_link("mobile_post?posttype=vsa", _("View Shelter Animals", l), "animal", nsa)) if len(vacc) > 0 and users.check_permission_bool(session, users.CHANGE_VACCINATION): items.append( jqm_listitem_link("#vacc", _("Vaccinate Animal", l), "vaccination", len(vacc))) if len(test) > 0 and users.check_permission_bool(session, users.CHANGE_TEST): items.append( jqm_listitem_link("#test", _("Test Animal", l), "test", len(test))) if len(med) > 0 and users.check_permission_bool(session, users.CHANGE_MEDICAL): items.append( jqm_listitem_link("#med", _("Medicate Animal", l), "medical", len(med))) if osa and users.check_permission_bool(session, users.ADD_LOG): items.append( jqm_listitem_link("#log", _("Add Log to Animal", l), "log", -1, "dialog")) items.append(jqm_list_divider(_("Diary", l))) items.append(jqm_listitem_link("#diaryadd", _("New Task", l), "diary")) if len(dia) > 0 and users.check_permission_bool(session, users.EDIT_MY_DIARY_NOTES): items.append( jqm_listitem_link("#diary", _("Complete Tasks", l), "diary", len(dia))) items.append(jqm_list_divider(_("Person", l))) if len(hck) > 0 and users.check_permission_bool(session, users.CHANGE_PERSON): items.append( jqm_listitem_link("#homecheck", _("Perform Homecheck", l), "person", -1, "dialog")) h.append(jqm_list("\n".join(items))) h.append(jqm_page_footer()) h += page_messages(l, homelink, mess) h += page_message_add(l, homelink, dbo) h += page_reports(l, homelink, ar) h += page_vaccinations(l, homelink, vacc) h += page_tests(l, homelink, test, testresults) h += page_medication(l, homelink, med) h += page_log_add(l, homelink, dbo) h += page_diary_add(l, homelink, dbo) h += page_diary(l, homelink, dia) h += page_homecheck(l, homelink, dbo) h.append("</body></html>") return "\n".join(h)
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 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 page(dbo, session, username): """ Generates the main mobile web page dbo: Database info """ l = dbo.locale nsa = animal.get_number_animals_on_shelter_now(dbo) osa = nsa > 0 ar = reports.get_available_reports(dbo, False) vacc = medical.get_vaccinations_outstanding(dbo) test = medical.get_tests_outstanding(dbo) med = medical.get_treatments_outstanding(dbo) dia = diary.get_uncompleted_upto_today(dbo, username) hck = person.get_reserves_without_homechecks(dbo) mess = lookups.get_messages(dbo, session.user, session.roles, session.superuser) testresults = lookups.get_test_results(dbo) homelink = jqm_link("mobile", _("Home", l), "home", "ui-btn-right", "b") h = [] h.append(header(l)) logoutlink = jqm_link("mobile_logout", _("Logout", l), "delete", "ui-btn-right", "b") h.append(jqm_page_header("home", _("ASM", l), logoutlink, False)) items = [] if configuration.smdb_locked(dbo): items.append( jqm_listitem( _("This database is locked and in read-only mode. You cannot add, change or delete records.", l) ) ) if len(mess) > 0: items.append(jqm_listitem_link("#messages", _("Messages", l), "message", len(mess))) if len(ar) > 0 and users.check_permission_bool(session, users.VIEW_REPORT): items.append(jqm_listitem_link("#reports", _("Generate Report", l), "report")) items.append(jqm_list_divider(_("Animal", l))) if osa and users.check_permission_bool(session, users.VIEW_ANIMAL): items.append(jqm_listitem_link("mobile_post?posttype=vsa", _("View Shelter Animals", l), "animal", nsa)) if len(vacc) > 0 and users.check_permission_bool(session, users.CHANGE_VACCINATION): items.append(jqm_listitem_link("#vacc", _("Vaccinate Animal", l), "vaccination", len(vacc))) if len(test) > 0 and users.check_permission_bool(session, users.CHANGE_TEST): items.append(jqm_listitem_link("#test", _("Test Animal", l), "test", len(test))) if len(med) > 0 and users.check_permission_bool(session, users.CHANGE_MEDICAL): items.append(jqm_listitem_link("#med", _("Medicate Animal", l), "medical", len(med))) if osa and users.check_permission_bool(session, users.ADD_LOG): items.append(jqm_listitem_link("#log", _("Add Log to Animal", l), "log", -1, "dialog")) items.append(jqm_list_divider(_("Diary", l))) items.append(jqm_listitem_link("#diaryadd", _("New Task", l), "diary")) if len(dia) > 0 and users.check_permission_bool(session, users.EDIT_MY_DIARY_NOTES): items.append(jqm_listitem_link("#diary", _("Complete Tasks", l), "diary", len(dia))) items.append(jqm_list_divider(_("Person", l))) if len(hck) > 0 and users.check_permission_bool(session, users.CHANGE_PERSON): items.append(jqm_listitem_link("#homecheck", _("Perform Homecheck", l), "person", -1, "dialog")) h.append(jqm_list("\n".join(items))) h.append(jqm_page_footer()) h += page_messages(l, homelink, mess) h += page_message_add(l, homelink, dbo) h += page_reports(l, homelink, ar) h += page_vaccinations(l, homelink, vacc) h += page_tests(l, homelink, test, testresults) h += page_medication(l, homelink, med) h += page_log_add(l, homelink, dbo) h += page_diary_add(l, homelink, dbo) h += page_diary(l, homelink, dia) h += page_homecheck(l, homelink, dbo) h.append("</body></html>") return "\n".join(h)
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