Exemple #1
0
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
Exemple #2
0
 def test_get_animal_find_simple(self):
     assert len(animal.get_animal_find_simple(base.get_dbo(), "Testio")) > 0
Exemple #3
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
Exemple #4
0
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)
Exemple #5
0
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)
Exemple #6
0
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
Exemple #7
0
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)
Exemple #8
0
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)
Exemple #9
0
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)
Exemple #10
0
 def test_get_animal_find_simple(self):
     assert len(animal.get_animal_find_simple(base.get_dbo(), "Testio")) > 0
Exemple #11
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