Exemple #1
0
def get_held_animals(dbo, style="", speciesid=0, animaltypeid=0):
    """ Returns a page of currently held animals.
    style: The HTML publishing template to use
    speciesid: 0 for all species, or a specific one
    animaltypeid: 0 for all animal types or a specific one
    """
    animals = dbo.query(animal.get_animal_query(dbo) + \
        " WHERE a.IsHold = 1 AND a.Archived = 0 ORDER BY a.DateBroughtIn DESC")
    return animals_to_page(dbo,
                           animals,
                           style=style,
                           speciesid=speciesid,
                           animaltypeid=animaltypeid)
Exemple #2
0
def get_deceased_animals(dbo,
                         daysdeceased=0,
                         style="",
                         speciesid=0,
                         animaltypeid=0):
    """ Returns a page of deceased animals.
    daysdeceased: The number of days the animals have been deceased
    style: The HTML publishing template to use
    speciesid: 0 for all species, or a specific one
    animaltypeid: 0 for all animal types or a specific one
    """
    if daysdeceased == 0: daysdeceased = 30
    orderby = "a.DeceasedDate DESC"
    animals = dbo.query(animal.get_animal_query(dbo) + \
        " WHERE a.DeceasedDate Is Not Null AND a.DeceasedDate >= ? AND a.NonShelterAnimal = 0 AND a.DiedOffShelter = 0 "
        "ORDER BY %s" % orderby, [ dbo.today(daysdeceased * -1)] )
    return animals_to_page(dbo,
                           animals,
                           style=style,
                           speciesid=speciesid,
                           animaltypeid=animaltypeid)
Exemple #3
0
def get_adopted_animals(dbo,
                        daysadopted=0,
                        style="",
                        speciesid=0,
                        animaltypeid=0):
    """ Returns a page of adopted animals.
    daysadopted: The number of days the animals have been adopted
    style: The HTML publishing template to use
    speciesid: 0 for all species, or a specific one
    animaltypeid: 0 for all animal types or a specific one
    """
    if daysadopted == 0: daysadopted = 30
    orderby = "a.ActiveMovementDate DESC"
    animals = dbo.query(animal.get_animal_query(dbo) + \
        " WHERE a.IsNotAvailableForAdoption = 0 AND a.ActiveMovementType = 1 AND " \
        "a.ActiveMovementDate >= ? AND a.DeceasedDate Is Null AND a.NonShelterAnimal = 0 " \
        "ORDER BY %s" % orderby, [ dbo.today(daysadopted * -1)] )
    return animals_to_page(dbo,
                           animals,
                           style=style,
                           speciesid=speciesid,
                           animaltypeid=animaltypeid)
Exemple #4
0
    def executeDeceasedPage(self):
        """
        Generates and uploads the page of recently deceased animals
        """
        self.log("Generating deceased animals page...")

        user = self.user
        thisPage = ""
        thisPageName = "deceased.%s" % self.pc.extension
        totalAnimals = 0
        l = self.dbo.locale

        try:
            cutoff = i18n.subtract_days(i18n.now(self.dbo.timezone),
                                        self.pc.outputAdoptedDays)
            orderby = "a.AnimalName"
            if self.pc.order == 0: orderby = "a.DeceasedDate"
            elif self.pc.order == 1: orderby = "a.DeceasedDate DESC"
            elif self.pc.order == 2: orderby = "a.AnimalName"
            animals = self.dbo.query(animal.get_animal_query(self.dbo) + " WHERE a.DeceasedDate Is Not Null AND " \
                "a.DeceasedDate >= %s AND a.NonShelterAnimal = 0 AND a.DiedOffShelter = 0 " \
                "ORDER BY %s" % (self.dbo.sql_date(cutoff), orderby))
            totalAnimals = len(animals)
            header = self.substituteHFTag(self.getHeader(), -1, user,
                                          i18n._("Recently deceased", l))
            footer = self.substituteHFTag(self.getFooter(), -1, user,
                                          i18n._("Recently deceased", l))
            body = self.getBody()
            thisPage = header
        except Exception as err:
            self.setLastError("Error setting up deceased page: %s" % err)
            self.logError("Error setting up deceased page: %s" % err,
                          sys.exc_info())
            return

        anCount = 0
        for an in animals:
            try:
                anCount += 1
                self.log("Processing: %s: %s (%d of %d)" %
                         (an["SHELTERCODE"], an["ANIMALNAME"], anCount,
                          totalAnimals))
                self.updatePublisherProgress(
                    self.getProgress(anCount, len(animals)))

                # If the user cancelled, stop now
                if self.shouldStopPublishing():
                    self.log("User cancelled publish. Stopping.")
                    self.resetPublisherProgress()
                    self.cleanup()
                    return

                # upload images for this animal to our current FTP
                self.uploadImages(an, True)

                # Add to the page
                thisPage += self.substituteBodyTags(body, an)
                self.log("Finished processing: %s" % an["SHELTERCODE"])

            except Exception as err:
                self.logError(
                    "Failed processing animal: %s, %s" %
                    (str(an["SHELTERCODE"]), err), sys.exc_info())

        # Append the footer, flush and upload the page
        thisPage += footer
        self.log("Saving page to disk: %s (%d bytes)" %
                 (thisPageName, len(thisPage)))
        self.saveFile(os.path.join(self.publishDir, thisPageName), thisPage)
        self.log("Saved page to disk: %s" % thisPageName)
        if self.pc.uploadDirectly:
            self.log("Uploading page: %s" % thisPageName)
            self.upload(thisPageName)
            self.log("Uploaded page: %s" % thisPageName)
Exemple #5
0
def lookingfor_report(dbo, username="******"):
    """
    Generates the person looking for report
    """
    l = dbo.locale
    title = _("People Looking For", l)
    h = reports.get_report_header(dbo, title, username)

    def p(s):
        return "<p>%s</p>" % s

    def td(s):
        return "<td>%s</td>" % s

    def hr():
        return "<hr />"

    people = db.query(dbo, "SELECT owner.*, " \
        "(SELECT Size FROM lksize WHERE ID = owner.MatchSize) AS MatchSizeName, " \
        "(SELECT BaseColour FROM basecolour WHERE ID = owner.MatchColour) AS MatchColourName, " \
        "(SELECT Sex FROM lksex WHERE ID = owner.MatchSex) AS MatchSexName, " \
        "(SELECT BreedName FROM breed WHERE ID = owner.MatchBreed) AS MatchBreedName, " \
        "(SELECT AnimalType FROM animaltype WHERE ID = owner.MatchAnimalType) AS MatchAnimalTypeName, " \
        "(SELECT SpeciesName FROM species WHERE ID = owner.MatchSpecies) AS MatchSpeciesName " \
        "FROM owner WHERE MatchActive = 1 AND " \
        "(MatchExpires Is Null OR MatchExpires > %s)" \
        "ORDER BY OwnerName" % db.dd(now(dbo.timezone)))

    ah = hr()
    ah += "<table border=\"1\" width=\"100%\"><tr>"
    ah += "<th>%s</th>" % _("Code", l)
    ah += "<th>%s</th>" % _("Name", l)
    ah += "<th>%s</th>" % _("Age", l)
    ah += "<th>%s</th>" % _("Sex", l)
    ah += "<th>%s</th>" % _("Size", l)
    ah += "<th>%s</th>" % _("Color", l)
    ah += "<th>%s</th>" % _("Species", l)
    ah += "<th>%s</th>" % _("Breed", l)
    ah += "<th>%s</th>" % _("Good with cats", l)
    ah += "<th>%s</th>" % _("Good with dogs", l)
    ah += "<th>%s</th>" % _("Good with children", l)
    ah += "<th>%s</th>" % _("Housetrained", l)
    ah += "<th>%s</th>" % _("Comments", l)
    ah += "</tr>"

    totalmatches = 0
    for p in people:
        sql = ""
        if p["MATCHANIMALTYPE"] > 0:
            sql += " AND a.AnimalTypeID = %d" % int(p["MATCHANIMALTYPE"])
        if p["MATCHSPECIES"] > 0:
            sql += " AND a.SpeciesID = %d" % int(p["MATCHSPECIES"])
        if p["MATCHBREED"] > 0:
            sql += " AND (a.BreedID = %d OR a.Breed2ID = %d)" % (int(
                p["MATCHBREED"]), int(p["MATCHBREED"]))
        if p["MATCHSEX"] > -1: sql += " AND a.Sex = %d" % int(p["MATCHSEX"])
        if p["MATCHSIZE"] > -1: sql += " AND a.Size = %d" % int(p["MATCHSIZE"])
        if p["MATCHCOLOUR"] > -1:
            sql += " AND a.BaseColourID = %d" % int(p["MATCHCOLOUR"])
        if p["MATCHGOODWITHCHILDREN"] == 0:
            sql += " AND a.IsGoodWithChildren = 0"
        if p["MATCHGOODWITHCATS"] == 0: sql += " AND a.IsGoodWithCats = 0"
        if p["MATCHGOODWITHDOGS"] == 0: sql += " AND a.IsGoodWithDogs = 0"
        if p["MATCHHOUSETRAINED"] == 0: sql += " AND a.IsHouseTrained = 0"
        if p["MATCHAGEFROM"] >= 0 and p["MATCHAGETO"] > 0:
            sql += " AND a.DateOfBirth BETWEEN %s AND %s" % (db.dd(subtract_years(now(dbo.timezone), p["MATCHAGETO"])), \
                db.dd(subtract_years(now(dbo.timezone), p["MATCHAGEFROM"])))
        if p["MATCHCOMMENTSCONTAIN"] is not None and p[
                "MATCHCOMMENTSCONTAIN"] != "":
            for w in str(p["MATCHCOMMENTSCONTAIN"]).split(" "):
                sql += " AND a.AnimalComments Like '%%%s%%'" % w.replace(
                    "'", "`")
        sql = animal.get_animal_query(
        ) + " WHERE a.Archived=0 AND a.DeceasedDate Is Null" + sql
        animals = db.query(dbo, sql)

        h += "<h2>%s (%s) %s</h2>" % (p["OWNERNAME"], p["OWNERADDRESS"],
                                      p["HOMETELEPHONE"])
        c = []
        if p["MATCHSIZE"] != -1: c.append(p["MATCHSIZENAME"])
        if p["MATCHCOLOUR"] != -1: c.append(p["MATCHCOLOURNAME"])
        if p["MATCHSEX"] != -1: c.append(p["MATCHSEXNAME"])
        if p["MATCHBREED"] != -1: c.append(p["MATCHBREEDNAME"])
        if p["MATCHSPECIES"] != -1: c.append(p["MATCHSPECIESNAME"])
        if p["MATCHANIMALTYPE"] != -1: c.append(p["MATCHANIMALTYPENAME"])
        if p["MATCHGOODWITHCHILDREN"] == 0: c.append(_("Good with kids", l))
        if p["MATCHGOODWITHCATS"] == 0: c.append(_("Good with cats", l))
        if p["MATCHGOODWITHDOGS"] == 0: c.append(_("Good with dogs", l))
        if p["MATCHHOUSETRAINED"] == 0: c.append(_("Housetrained", l))
        if p["MATCHAGEFROM"] >= 0 and p["MATCHAGETO"] > 0:
            c.append(
                _("Age", l) + (" %0.2f - %0.2f" %
                               (p["MATCHAGEFROM"], p["MATCHAGETO"])))
        if p["MATCHCOMMENTSCONTAIN"] is not None and p[
                "MATCHCOMMENTSCONTAIN"] != "":
            c.append(
                _("Comments Contain", l) + ": " + p["MATCHCOMMENTSCONTAIN"])
        if len(c) > 0:
            h += "<p style='font-size: 8pt'>(%s: %s)</p>" % (_(
                "Looking for", l), ", ".join(c))

        outputheader = False
        for a in animals:
            if not outputheader:
                outputheader = True
                h += ah
            totalmatches += 1
            h += "<tr>"
            h += td(a["CODE"])
            h += td(a["ANIMALNAME"])
            h += td(a["ANIMALAGE"])
            h += td(a["SEXNAME"])
            h += td(a["SIZENAME"])
            h += td(a["COLOURNAME"])
            h += td(a["SPECIESNAME"])
            h += td(a["BREEDNAME"])
            h += td(a["ISGOODWITHCATSNAME"])
            h += td(a["ISGOODWITHDOGSNAME"])
            h += td(a["ISGOODWITHCHILDRENNAME"])
            h += td(a["ISHOUSETRAINEDNAME"])
            h += td(a["ANIMALCOMMENTS"])

        if outputheader:
            h += "</table>"
        h += hr()

    if len(people) == 0:
        h += p(_("No matches found.", l))

    h += "<!-- $AM%d^ animal matches -->" % totalmatches
    h += reports.get_report_footer(dbo, title, username)
    return h
Exemple #6
0
def match(dbo, lostanimalid = 0, foundanimalid = 0, animalid = 0):
    """
    Performs a lost and found match by going through all lost animals
    lostanimalid:   Compare this lost animal against all found animals
    foundanimalid:  Compare all lost animals against this found animal
    animalid:       Compare all lost animals against this shelter animal
    returns a list LostFoundMatch objects
    """
    l = dbo.locale
    matches = []
    matchspecies = configuration.match_species(dbo)
    matchbreed = configuration.match_breed(dbo)
    matchage = configuration.match_age(dbo)
    matchsex = configuration.match_sex(dbo)
    matcharealost = configuration.match_area_lost(dbo)
    matchfeatures = configuration.match_features(dbo)
    matchpostcode = configuration.match_postcode(dbo)
    matchcolour = configuration.match_colour(dbo)
    matchdatewithin2weeks = configuration.match_within2weeks(dbo)
    matchmax = matchspecies + matchbreed + matchage + matchsex + \
        matcharealost + matchfeatures + matchpostcode + matchcolour + \
        matchdatewithin2weeks
    matchpointfloor = configuration.match_point_floor(dbo)
    includeshelter = configuration.match_include_shelter(dbo)
    # Ignore records older than 6 months to keep things useful
    giveup = subtract_days(now(dbo.timezone), 180)

    # Get our set of lost animals
    lostanimals = None
    if lostanimalid == 0:
        lostanimals = db.query(dbo, get_lostanimal_query() + \
            " WHERE a.DateFound Is Null AND a.DateLost > %s ORDER BY a.DateLost" % db.dd(giveup))
    else:
        lostanimals = db.query(dbo, get_lostanimal_query() + \
            " WHERE a.ID = %d" % lostanimalid)

    oldestdate = giveup
    if len(lostanimals) > 0:
        oldestdate = lostanimals[0]["DATELOST"]

    # Get the set of found animals for comparison
    foundanimals = None
    if foundanimalid == 0:
        foundanimals = db.query(dbo, get_foundanimal_query() + \
            " WHERE a.ReturnToOwnerDate Is Null" \
            " AND a.DateFound >= %s " % db.dd(oldestdate))
    else:
        foundanimals = db.query(dbo, get_foundanimal_query() + " WHERE a.ID = %d" % foundanimalid)

    # Get the set of shelter animals for comparison
    shelteranimals = None
    if includeshelter:
        if animalid == 0:
            shelteranimals = db.query(dbo, animal.get_animal_query() + " WHERE " + \
                "a.DateBroughtIn > %s" % db.dd(oldestdate))
        else:
            shelteranimals = db.query(dbo, animal.get_animal_query() + " WHERE a.ID = %d" % animalid)

    for la in lostanimals:
        # Found animals (if an animal id has been given don't
        # check found animals)
        if animalid == 0:
            for fa in foundanimals:
                matchpoints = 0
                if la["ANIMALTYPEID"] == fa["ANIMALTYPEID"]: matchpoints += matchspecies
                if la["BREEDID"] == fa["BREEDID"]: matchpoints += matchbreed
                if la["AGEGROUP"] == fa["AGEGROUP"]: matchpoints += matchage
                if la["SEX"] == fa["SEX"]: matchpoints += matchsex
                matchpoints += words(la["AREALOST"], fa["AREAFOUND"], matcharealost)
                matchpoints += words(la["DISTFEAT"], fa["DISTFEAT"], matchfeatures)
                if la["AREAPOSTCODE"] == fa["AREAPOSTCODE"]: matchpoints += matchpostcode
                if la["BASECOLOURID"] == fa["BASECOLOURID"]: matchpoints += matchcolour
                if date_diff_days(la["DATELOST"], fa["DATEFOUND"]) <= 14: matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch()
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = str(fa["ID"])
                    m.fcontactname = fa["OWNERNAME"]
                    m.fcontactnumber = fa["HOMETELEPHONE"]
                    m.fareafound = fa["AREAFOUND"]
                    m.fareapostcode = fa["AREAPOSTCODE"]
                    m.fagegroup = fa["AGEGROUP"]
                    m.fsexname = fa["SEXNAME"]
                    m.fspeciesname = fa["SPECIESNAME"]
                    m.fbreedname = fa["BREEDNAME"]
                    m.fdistinguishingfeatures = fa["DISTFEAT"]
                    m.fbasecolourname = fa["BASECOLOURNAME"]
                    m.fdatefound = fa["DATEFOUND"]
                    m.matchpoints = int((float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)

        # Shelter animals
        if includeshelter:
            for a in shelteranimals:
                matchpoints = 0
                if la["ANIMALTYPEID"] == a["SPECIESID"]: matchpoints += matchspecies
                if la["BREEDID"] == a["BREEDID"] or la["BREEDID"] == a["BREED2ID"]: matchpoints += matchbreed
                if la["BASECOLOURID"] == a["BASECOLOURID"]: matchpoints += matchcolour
                if la["AGEGROUP"] == a["AGEGROUP"]: matchpoints += matchage
                if la["SEX"] == a["SEX"]: matchpoints += matchsex
                matchpoints += words(la["AREALOST"], a["ORIGINALOWNERADDRESS"], matcharealost)
                matchpoints += words(la["DISTFEAT"], a["MARKINGS"], matchfeatures)
                if str(a["ORIGINALOWNERPOSTCODE"]).find(la["AREAPOSTCODE"]): matchpoints += matchpostcode
                if date_diff_days(la["DATELOST"], a["DATEBROUGHTIN"]) <= 14: matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch()
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = a["CODE"]
                    m.fcontactname = _("Shelter animal {0} '{1}'", l).format(a["CODE"], a["ANIMALNAME"])
                    m.fcontactnumber = a["SPECIESNAME"]
                    m.fareafound = _("On Shelter", l)
                    m.fareapostcode = a["ORIGINALOWNERPOSTCODE"]
                    m.fagegroup = a["AGEGROUP"]
                    m.fsexname = a["SEXNAME"]
                    m.fspeciesname = a["SPECIESNAME"]
                    m.fbreedname = a["BREEDNAME"]
                    m.fdistinguishingfeatures = a["MARKINGS"]
                    m.fbasecolourname = a["BASECOLOURNAME"]
                    m.fdatefound = a["DATEBROUGHTIN"]
                    m.matchpoints = int((float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)
    return matches
Exemple #7
0
    def run(self):

        self.log("Maddies Fund Publisher starting...")

        BATCH_SIZE = 250  # How many animals to send in one POST
        PERIOD = 214  # How many days to go back when checking for fosters and adoptions (7 months * 30.5 = 214 days)

        if self.isPublisherExecuting(): return
        self.updatePublisherProgress(0)
        self.setLastError("")
        self.setStartPublishing()

        username = configuration.maddies_fund_username(self.dbo)
        password = configuration.maddies_fund_password(self.dbo)
        organisation = configuration.organisation(self.dbo)

        if username == "" or password == "":
            self.setLastError(
                "username and password all need to be set for Maddies Fund Publisher"
            )
            self.cleanup()
            return

        # Send all fosters and adoptions for the period that haven't been sent since they last had a change.
        # (we use lastchangeddate instead of sent date because MPA want an update when a number of key
        #  animal fields change, such as neuter status, microchip info, rabies tag, etc)
        cutoff = i18n.subtract_days(i18n.now(self.dbo.timezone), PERIOD)
        sql = "%s WHERE a.ActiveMovementType IN (1,2) " \
            "AND a.ActiveMovementDate >= ? AND a.DeceasedDate Is Null AND a.NonShelterAnimal = 0 " \
            "AND NOT EXISTS(SELECT AnimalID FROM animalpublished WHERE AnimalID = a.ID AND PublishedTo = 'maddiesfund' AND SentDate >= %s) " \
            "ORDER BY a.ID" % (animal.get_animal_query(self.dbo), self.dbo.sql_greatest(["a.ActiveMovementDate", "a.LastChangedDate"]))
        animals = self.dbo.query(sql, [cutoff], distincton="ID")

        # Now find animals who have been sent previously and are now deceased (using sent date against deceased to prevent re-sends)
        sql = "%s WHERE a.DeceasedDate Is Not Null AND a.DeceasedDate >= ? AND " \
            "EXISTS(SELECT AnimalID FROM animalpublished WHERE AnimalID = a.ID AND " \
            "PublishedTo = 'maddiesfund' AND SentDate < a.DeceasedDate)" % animal.get_animal_query(self.dbo)
        animals += self.dbo.query(sql, [cutoff], distincton="ID")

        # Now find shelter animals who have been sent previously and are back (using sent date against return to prevent re-sends)
        sql = "%s WHERE a.Archived = 0 AND " \
            "EXISTS(SELECT AnimalID FROM animalpublished WHERE AnimalID = a.ID AND " \
            "PublishedTo = 'maddiesfund' AND SentDate < " \
            "(SELECT MAX(ReturnDate) FROM adoption WHERE AnimalID = a.ID AND MovementType IN (1,2) AND ReturnDate Is Not Null))" % animal.get_animal_query(self.dbo)
        animals += self.dbo.query(sql, distincton="ID")

        # Now find animals who have been sent previously and have a new/changed vaccination since then
        sql = "%s WHERE a.Archived = 0 AND " \
            "EXISTS(SELECT p.AnimalID FROM animalpublished p INNER JOIN animalvaccination av ON av.AnimalID = a.ID WHERE p.AnimalID = a.ID AND " \
            "p.PublishedTo = 'maddiesfund' AND (p.SentDate < av.CreatedDate OR p.SentDate < av.LastChangedDate))" % animal.get_animal_query(self.dbo)
        animals += self.dbo.query(sql, [cutoff], distincton="ID")

        if len(animals) == 0:
            self.setLastError("No animals found to publish.")
            return

        # Get an authentication token
        token = ""
        try:
            fields = {
                "username": username,
                "password": password,
                "grant_type": "password"
            }
            r = utils.post_form(MADDIES_FUND_TOKEN_URL, fields)
            token = utils.json_parse(r["response"])["access_token"]
            self.log("got access token: %s (%s)" % (token, r["response"]))
        except Exception as err:
            self.setLastError(
                "failed to get access token: %s (request: '%s') (response: '%s')"
                % (err, r["requestbody"], r["response"]))
            self.cleanup()
            return

        anCount = 0
        thisbatch = []
        processed = []
        for an in animals:
            try:
                anCount += 1
                self.log("Processing: %s: %s (%d of %d)" %
                         (an["SHELTERCODE"], an["ANIMALNAME"], anCount,
                          len(animals)))
                self.updatePublisherProgress(
                    self.getProgress(anCount, len(animals)))

                # If the user cancelled, stop now
                if self.shouldStopPublishing():
                    self.log("User cancelled publish. Stopping.")
                    self.resetPublisherProgress()
                    return

                # Build an adoption JSON object containing the adopter and animal
                a = {
                    "PetID":
                    an["ID"],
                    "PetCode":
                    an["SHELTERCODE"],
                    "Site":
                    organisation,
                    "PetName":
                    an["ANIMALNAME"],
                    "PetStatus":
                    self.getPetStatus(an),
                    "PetLitterID":
                    an["ACCEPTANCENUMBER"],
                    "GroupType":
                    utils.iif(
                        utils.nulltostr(an["ACCEPTANCENUMBER"]) != "",
                        "Litter", ""),
                    "PetSpecies":
                    an["SPECIESNAME"],
                    "PetSex":
                    an["SEXNAME"],
                    "DateofBirth":
                    self.getDate(an["DATEOFBIRTH"]),
                    "SpayNeuterStatus":
                    utils.iif(an["NEUTERED"] == 1, "Spayed/Neutered", ""),
                    "Breed":
                    an["BREEDNAME"],
                    "Color":
                    an["BASECOLOURNAME"],
                    "SecondaryColor":
                    "",
                    "Pattern":
                    "",
                    "HealthStatus":
                    an["ASILOMARINTAKECATEGORY"] +
                    1,  # We're zero based, they use 1-base
                    "PetBiography":
                    an["ANIMALCOMMENTS"],
                    "Photo":
                    "%s?method=animal_image&account=%s&animalid=%s" %
                    (SERVICE_URL, self.dbo.database, an["ID"]),
                    "Microchip":
                    an["IDENTICHIPNUMBER"],
                    "MicrochipIssuer":
                    lookups.get_microchip_manufacturer(self.dbo.locale,
                                                       an["IDENTICHIPNUMBER"]),
                    "RelationshipType":
                    self.getRelationshipType(an),
                    "FosterCareDate":
                    self.getDate(an["ACTIVEMOVEMENTDATE"]),
                    "FosterEndDate":
                    "",
                    "RabiesTag":
                    an["RABIESTAG"],
                    "ID":
                    an["CURRENTOWNERID"],
                    "Firstname":
                    an["CURRENTOWNERFORENAMES"],
                    "Lastname":
                    an["CURRENTOWNERSURNAME"],
                    "EmailAddress":
                    self.getEmail(an["CURRENTOWNEREMAILADDRESS"]),
                    "Street":
                    an["CURRENTOWNERADDRESS"],
                    "Apartment":
                    "",
                    "City":
                    an["CURRENTOWNERTOWN"],
                    "State":
                    an["CURRENTOWNERCOUNTY"],
                    "Zipcode":
                    an["CURRENTOWNERPOSTCODE"],
                    "ContactNumber":
                    an["CURRENTOWNERHOMETELEPHONE"],
                    "Organization":
                    organisation,
                }

                # Build a list of intake histories - use the initial one first
                ph = [{
                    "IntakeType": an["ENTRYREASONNAME"],
                    "IntakeDate": self.getDate(an["DATEBROUGHTIN"]),
                    "City": utils.nulltostr(an["BROUGHTINBYOWNERTOWN"]),
                    "State": utils.nulltostr(an["BROUGHTINBYOWNERCOUNTY"]),
                    "LengthOwned": ""
                }]
                # Then any exit movements where the animal was returned
                for ra in movement.get_animal_movements(self.dbo, an["ID"]):
                    if ra["MOVEMENTTYPE"] > 0 and ra["MOVEMENTTYPE"] not in (
                            2, 8) and ra["RETURNDATE"] is not None:
                        ph.append({
                            "IntakeType": ra["RETURNEDREASONNAME"],
                            "IntakeDate": self.getDate(ra["RETURNDATE"]),
                            "City": utils.nulltostr(ra["OWNERTOWN"]),
                            "State": utils.nulltostr(ra["OWNERCOUNTY"]),
                            "LengthOwned": ""  # We don't have this info
                        })
                a["PetHistoryDetails"] = ph

                # Next add vaccination histories
                vh = []
                for v in medical.get_vaccinations(self.dbo, an["ID"]):
                    vh.append({
                        "VaccinationRecordNumber":
                        str(v["ID"]),
                        "VaccinationStatus":
                        utils.iif(v["DATEOFVACCINATION"] is not None,
                                  "Completed", "Scheduled"),
                        "VaccinationStatusDateTime":
                        self.getDate(v["DATEREQUIRED"]),
                        "Vaccine":
                        v["VACCINATIONTYPE"],
                        "Type":
                        "",  # Live/Killed - we don't keep this info yet, see issue #281
                        "Manufacturer":
                        utils.nulltostr(v["MANUFACTURER"]),
                        "VaccineLot":
                        utils.nulltostr(v["BATCHNUMBER"]),
                        "VaccinationNotes":
                        v["COMMENTS"],
                        "Length":
                        "",  # Not sure what this value is for - advised to ignore by MPA devs
                        "RevaccinationDate":
                        self.getDate(v["DATEEXPIRES"])
                    })
                a["PetVaccinationDetails"] = vh

                thisbatch.append(a)
                processed.append(an)
                self.logSuccess("Processed: %s: %s (%d of %d)" %
                                (an["SHELTERCODE"], an["ANIMALNAME"], anCount,
                                 len(animals)))

                # If we have hit our batch size, or this is the
                # last animal then send what we have.
                if len(thisbatch) == BATCH_SIZE or anCount == len(animals):
                    j = utils.json({"Animals": thisbatch})
                    headers = {"Authorization": "Bearer %s" % token}
                    self.log(
                        "HTTP POST request %s: headers: '%s', body: '%s'" %
                        (MADDIES_FUND_UPLOAD_URL, headers, j))
                    r = utils.post_json(MADDIES_FUND_UPLOAD_URL, j, headers)
                    if r["status"] != 200:
                        self.logError("HTTP %d response: %s" %
                                      (r["status"], r["response"]))
                    else:
                        self.log("HTTP %d response: %s" %
                                 (r["status"], r["response"]))
                        self.markAnimalsPublished(processed)
                    # start counting again
                    thisbatch = []
                    processed = []

            except Exception as err:
                self.logError(
                    "Failed processing animal: %s, %s" %
                    (an["SHELTERCODE"], err), sys.exc_info())

        self.cleanup()
Exemple #8
0
def match(dbo, lostanimalid = 0, foundanimalid = 0, animalid = 0, limit = 0):
    """
    Performs a lost and found match by going through all lost animals
    lostanimalid:   Compare this lost animal against all found animals
    foundanimalid:  Compare all lost animals against this found animal
    animalid:       Compare all lost animals against this shelter animal
    limit:          Stop when we hit this many matches (or 0 for all)
    returns a list of LostFoundMatch objects
    """
    l = dbo.locale
    batch = []
    matches = []
    matchspecies = configuration.match_species(dbo)
    matchbreed = configuration.match_breed(dbo)
    matchage = configuration.match_age(dbo)
    matchsex = configuration.match_sex(dbo)
    matcharealost = configuration.match_area_lost(dbo)
    matchfeatures = configuration.match_features(dbo)
    matchpostcode = configuration.match_postcode(dbo)
    matchcolour = configuration.match_colour(dbo)
    matchdatewithin2weeks = configuration.match_within2weeks(dbo)
    matchmax = matchspecies + matchbreed + matchage + matchsex + \
        matcharealost + matchfeatures + matchpostcode + matchcolour + \
        matchdatewithin2weeks
    matchpointfloor = configuration.match_point_floor(dbo)
    includeshelter = configuration.match_include_shelter(dbo)
    fullmatch = animalid == 0 and lostanimalid == 0 and foundanimalid == 0
    # Ignore records older than 6 months to keep things useful
    giveup = dbo.today(offset=-182)

    # Get our set of lost animals
    lostanimals = None
    if lostanimalid == 0:
        lostanimals = dbo.query(get_lostanimal_query(dbo) + \
            " WHERE a.DateFound Is Null AND a.DateLost > ? ORDER BY a.DateLost", [giveup])
    else:
        lostanimals = dbo.query(get_lostanimal_query(dbo) + \
            " WHERE a.ID = ?", [lostanimalid])

    oldestdate = giveup
    if len(lostanimals) > 0:
        oldestdate = lostanimals[0].DATELOST

    # Get the set of found animals for comparison
    foundanimals = None
    if foundanimalid == 0:
        foundanimals = dbo.query(get_foundanimal_query(dbo) + \
            " WHERE a.ReturnToOwnerDate Is Null" \
            " AND a.DateFound >= ? ", [oldestdate])
    else:
        foundanimals = dbo.query(get_foundanimal_query(dbo) + " WHERE a.ID = ?", [foundanimalid])

    # Get the set of shelter animals for comparison - anything brought in recently
    # that's 1. still on shelter or 2. was released to wild, transferred or escaped
    shelteranimals = None
    if includeshelter:
        if animalid == 0:
            shelteranimals = dbo.query(animal.get_animal_query(dbo) + " WHERE " + \
                "(a.Archived = 0 OR a.ActiveMovementType IN (3,4,7)) " \
                "AND a.DateBroughtIn > ?", [oldestdate])
        else:
            shelteranimals = dbo.query(animal.get_animal_query(dbo) + " WHERE a.ID = ?", [animalid])

    asynctask.set_progress_max(dbo, len(lostanimals))
    for la in lostanimals:
        asynctask.increment_progress_value(dbo)
        # Stop if we've hit our limit
        if limit > 0 and len(matches) >= limit:
            break
        # Found animals (if an animal id has been given don't
        # check found animals)
        if animalid == 0:
            for fa in foundanimals:
                matchpoints = 0
                if la["ANIMALTYPEID"] == fa["ANIMALTYPEID"]: matchpoints += matchspecies
                if la["BREEDID"] == fa["BREEDID"]: matchpoints += matchbreed
                if la["AGEGROUP"] == fa["AGEGROUP"]: matchpoints += matchage
                if la["SEX"] == fa["SEX"]: matchpoints += matchsex
                matchpoints += words(la["AREALOST"], fa["AREAFOUND"], matcharealost)
                matchpoints += words(la["DISTFEAT"], fa["DISTFEAT"], matchfeatures)
                if la["AREAPOSTCODE"] == fa["AREAPOSTCODE"]: matchpoints += matchpostcode
                if la["BASECOLOURID"] == fa["BASECOLOURID"]: matchpoints += matchcolour
                if date_diff_days(la["DATELOST"], fa["DATEFOUND"]) <= 14: matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch(dbo)
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexid = la["SEX"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesid = la["ANIMALTYPEID"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedid = la["BREEDID"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourid = la["BASECOLOURID"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = fa["ID"]
                    m.fanimalid = 0
                    m.fcontactname = fa["OWNERNAME"]
                    m.fcontactnumber = fa["HOMETELEPHONE"]
                    m.fareafound = fa["AREAFOUND"]
                    m.fareapostcode = fa["AREAPOSTCODE"]
                    m.fagegroup = fa["AGEGROUP"]
                    m.fsexid = fa["SEX"]
                    m.fsexname = fa["SEXNAME"]
                    m.fspeciesid = fa["ANIMALTYPEID"]
                    m.fspeciesname = fa["SPECIESNAME"]
                    m.fbreedid = fa["BREEDID"]
                    m.fbreedname = fa["BREEDNAME"]
                    m.fdistinguishingfeatures = fa["DISTFEAT"]
                    m.fbasecolourid = fa["BASECOLOURID"]
                    m.fbasecolourname = fa["BASECOLOURNAME"]
                    m.fdatefound = fa["DATEFOUND"]
                    m.matchpoints = int((float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)
                    if fullmatch: 
                        batch.append(m.toParams())
                    if limit > 0 and len(matches) >= limit:
                        break

        # Shelter animals
        if includeshelter:
            for a in shelteranimals:
                matchpoints = 0
                if la["ANIMALTYPEID"] == a["SPECIESID"]: matchpoints += matchspecies
                if la["BREEDID"] == a["BREEDID"] or la["BREEDID"] == a["BREED2ID"]: matchpoints += matchbreed
                if la["BASECOLOURID"] == a["BASECOLOURID"]: matchpoints += matchcolour
                if la["AGEGROUP"] == a["AGEGROUP"]: matchpoints += matchage
                if la["SEX"] == a["SEX"]: matchpoints += matchsex
                matchpoints += words(la["AREALOST"], a["ORIGINALOWNERADDRESS"], matcharealost)
                matchpoints += words(la["DISTFEAT"], a["MARKINGS"], matchfeatures)
                if utils.nulltostr(a["ORIGINALOWNERPOSTCODE"]).find(la["AREAPOSTCODE"]) != -1: matchpoints += matchpostcode
                if date_diff_days(la["DATELOST"], a["DATEBROUGHTIN"]) <= 14: matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch(dbo)
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexid = la["SEX"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesid = la["ANIMALTYPEID"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedid = la["BREEDID"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourid = la["BASECOLOURID"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = 0
                    m.fanimalid = a["ID"]
                    m.fcontactname = _("Shelter animal {0} '{1}'", l).format(a["CODE"], a["ANIMALNAME"])
                    m.fcontactnumber = a["SPECIESNAME"]
                    m.fareafound = _("On Shelter", l)
                    m.fareapostcode = a["ORIGINALOWNERPOSTCODE"]
                    m.fagegroup = a["AGEGROUP"]
                    m.fsexid = a["SEX"]
                    m.fsexname = a["SEXNAME"]
                    m.fspeciesid = a["SPECIESID"]
                    m.fspeciesname = a["SPECIESNAME"]
                    m.fbreedid = a["BREEDID"]
                    m.fbreedname = a["BREEDNAME"]
                    m.fdistinguishingfeatures = a["MARKINGS"]
                    m.fbasecolourid = a["BASECOLOURID"]
                    m.fbasecolourname = a["BASECOLOURNAME"]
                    m.fdatefound = a["DATEBROUGHTIN"]
                    m.matchpoints = int((float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)
                    if fullmatch:
                        batch.append(m.toParams())
                    if limit > 0 and len(matches) >= limit:
                        break

    if fullmatch:
        dbo.execute("DELETE FROM animallostfoundmatch")
        sql = "INSERT INTO animallostfoundmatch (AnimalLostID, AnimalFoundID, AnimalID, LostContactName, LostContactNumber, " \
            "LostArea, LostPostcode, LostAgeGroup, LostSex, LostSpeciesID, LostBreedID, LostFeatures, LostBaseColourID, LostDate, " \
            "FoundContactName, FoundContactNumber, FoundArea, FoundPostcode, FoundAgeGroup, FoundSex, FoundSpeciesID, FoundBreedID, " \
            "FoundFeatures, FoundBaseColourID, FoundDate, MatchPoints) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
        if len(batch) > 0:
            dbo.execute_many(sql, batch)

    return matches
def match(dbo, lostanimalid=0, foundanimalid=0, animalid=0):
    """
    Performs a lost and found match by going through all lost animals
    lostanimalid:   Compare this lost animal against all found animals
    foundanimalid:  Compare all lost animals against this found animal
    animalid:       Compare all lost animals against this shelter animal
    returns a list LostFoundMatch objects
    """
    l = dbo.locale
    matches = []
    matchspecies = configuration.match_species(dbo)
    matchbreed = configuration.match_breed(dbo)
    matchage = configuration.match_age(dbo)
    matchsex = configuration.match_sex(dbo)
    matcharealost = configuration.match_area_lost(dbo)
    matchfeatures = configuration.match_features(dbo)
    matchpostcode = configuration.match_postcode(dbo)
    matchcolour = configuration.match_colour(dbo)
    matchdatewithin2weeks = configuration.match_within2weeks(dbo)
    matchmax = matchspecies + matchbreed + matchage + matchsex + \
        matcharealost + matchfeatures + matchpostcode + matchcolour + \
        matchdatewithin2weeks
    matchpointfloor = configuration.match_point_floor(dbo)
    includeshelter = configuration.match_include_shelter(dbo)
    # Ignore records older than 6 months to keep things useful
    giveup = subtract_days(now(dbo.timezone), 180)

    # Get our set of lost animals
    lostanimals = None
    if lostanimalid == 0:
        lostanimals = db.query(dbo, get_lostanimal_query(dbo) + \
            " WHERE a.DateFound Is Null AND a.DateLost > %s ORDER BY a.DateLost" % db.dd(giveup))
    else:
        lostanimals = db.query(dbo, get_lostanimal_query(dbo) + \
            " WHERE a.ID = %d" % lostanimalid)

    oldestdate = giveup
    if len(lostanimals) > 0:
        oldestdate = lostanimals[0]["DATELOST"]

    # Get the set of found animals for comparison
    foundanimals = None
    if foundanimalid == 0:
        foundanimals = db.query(dbo, get_foundanimal_query(dbo) + \
            " WHERE a.ReturnToOwnerDate Is Null" \
            " AND a.DateFound >= %s " % db.dd(oldestdate))
    else:
        foundanimals = db.query(
            dbo,
            get_foundanimal_query(dbo) + " WHERE a.ID = %d" % foundanimalid)

    # Get the set of shelter animals for comparison
    shelteranimals = None
    if includeshelter:
        if animalid == 0:
            shelteranimals = db.query(dbo, animal.get_animal_query(dbo) + " WHERE " + \
                "a.DateBroughtIn > %s" % db.dd(oldestdate))
        else:
            shelteranimals = db.query(
                dbo,
                animal.get_animal_query(dbo) + " WHERE a.ID = %d" % animalid)

    for la in lostanimals:
        # Found animals (if an animal id has been given don't
        # check found animals)
        if animalid == 0:
            for fa in foundanimals:
                matchpoints = 0
                if la["ANIMALTYPEID"] == fa["ANIMALTYPEID"]:
                    matchpoints += matchspecies
                if la["BREEDID"] == fa["BREEDID"]: matchpoints += matchbreed
                if la["AGEGROUP"] == fa["AGEGROUP"]: matchpoints += matchage
                if la["SEX"] == fa["SEX"]: matchpoints += matchsex
                matchpoints += words(la["AREALOST"], fa["AREAFOUND"],
                                     matcharealost)
                matchpoints += words(la["DISTFEAT"], fa["DISTFEAT"],
                                     matchfeatures)
                if la["AREAPOSTCODE"] == fa["AREAPOSTCODE"]:
                    matchpoints += matchpostcode
                if la["BASECOLOURID"] == fa["BASECOLOURID"]:
                    matchpoints += matchcolour
                if date_diff_days(la["DATELOST"], fa["DATEFOUND"]) <= 14:
                    matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch()
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = str(fa["ID"])
                    m.fcontactname = fa["OWNERNAME"]
                    m.fcontactnumber = fa["HOMETELEPHONE"]
                    m.fareafound = fa["AREAFOUND"]
                    m.fareapostcode = fa["AREAPOSTCODE"]
                    m.fagegroup = fa["AGEGROUP"]
                    m.fsexname = fa["SEXNAME"]
                    m.fspeciesname = fa["SPECIESNAME"]
                    m.fbreedname = fa["BREEDNAME"]
                    m.fdistinguishingfeatures = fa["DISTFEAT"]
                    m.fbasecolourname = fa["BASECOLOURNAME"]
                    m.fdatefound = fa["DATEFOUND"]
                    m.matchpoints = int(
                        (float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)

        # Shelter animals
        if includeshelter:
            for a in shelteranimals:
                matchpoints = 0
                if la["ANIMALTYPEID"] == a["SPECIESID"]:
                    matchpoints += matchspecies
                if la["BREEDID"] == a["BREEDID"] or la["BREEDID"] == a[
                        "BREED2ID"]:
                    matchpoints += matchbreed
                if la["BASECOLOURID"] == a["BASECOLOURID"]:
                    matchpoints += matchcolour
                if la["AGEGROUP"] == a["AGEGROUP"]: matchpoints += matchage
                if la["SEX"] == a["SEX"]: matchpoints += matchsex
                matchpoints += words(la["AREALOST"], a["ORIGINALOWNERADDRESS"],
                                     matcharealost)
                matchpoints += words(la["DISTFEAT"], a["MARKINGS"],
                                     matchfeatures)
                if str(a["ORIGINALOWNERPOSTCODE"]).find(la["AREAPOSTCODE"]):
                    matchpoints += matchpostcode
                if date_diff_days(la["DATELOST"], a["DATEBROUGHTIN"]) <= 14:
                    matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch()
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = a["CODE"]
                    m.fcontactname = _("Shelter animal {0} '{1}'",
                                       l).format(a["CODE"], a["ANIMALNAME"])
                    m.fcontactnumber = a["SPECIESNAME"]
                    m.fareafound = _("On Shelter", l)
                    m.fareapostcode = a["ORIGINALOWNERPOSTCODE"]
                    m.fagegroup = a["AGEGROUP"]
                    m.fsexname = a["SEXNAME"]
                    m.fspeciesname = a["SPECIESNAME"]
                    m.fbreedname = a["BREEDNAME"]
                    m.fdistinguishingfeatures = a["MARKINGS"]
                    m.fbasecolourname = a["BASECOLOURNAME"]
                    m.fdatefound = a["DATEBROUGHTIN"]
                    m.matchpoints = int(
                        (float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)
    return matches
Exemple #10
0
    def run(self):

        if self.isPublisherExecuting(): return
        self.updatePublisherProgress(0)
        self.setLastError("")
        self.setStartPublishing()

        customerid = configuration.petslocated_customerid(self.dbo)
        if customerid == "":
            self.setLastError("No petslocated.com customer ID has been set.")
            return

        if not self.checkMappedSpecies():
            self.setLastError("Not all species have been mapped.")
            self.cleanup()
            return
        if not self.checkMappedBreeds():
            self.setLastError("Not all breeds have been mapped.")
            self.cleanup()
            return
        if self.pc.includeColours and not self.checkMappedColours():
            self.setLastError(
                "Not all colours have been mapped and sending colours is enabled"
            )
            self.cleanup()
            return

        includelost = False  # Don't publish lost animals - losers pay 12 pounds to post for 12 months
        includeshelter = configuration.petslocated_includeshelter(self.dbo)
        shelterwithflag = configuration.petslocated_animalflag(self.dbo)

        if shelterwithflag == "" and includeshelter:
            self.setLastError(
                "Include shelter animals set, but no flag chosen")
            self.cleanup()
            return

        lostanimals = lostfound.get_lostanimal_find_advanced(self.dbo, {})
        foundanimals = lostfound.get_foundanimal_last_days(self.dbo, 90)
        animals = []

        if includeshelter:
            animals = self.dbo.query(animal.get_animal_query(self.dbo) + " WHERE a.Archived = 0 AND " \
                "a.AdditionalFlags LIKE ?", ["%%%s|%%" % shelterwithflag])

        if len(animals) == 0 and len(foundanimals) == 0 and len(
                lostanimals) == 0:
            self.setLastError("No animals found to publish.")
            self.cleanup()
            return

        if not self.openFTPSocket():
            self.setLastError("Failed opening FTP socket.")
            if self.logSearch("530 Login") != -1:
                self.log(
                    "Found 530 Login incorrect: disabling PetsLocated UK publisher."
                )
                configuration.publishers_enabled_disable(self.dbo, "pcuk")
            self.cleanup()
            return

        csv = []
        header = "customerurn,importkey,lostfound,pettype,breed,sexofpet,neutered,petname,internalref,petage,hairtype,petcoloursall,chipchecked,chipno,petfeatures,lastlocationst,lastlocation,locationpostcode,datelostfound,otherdetails,privatenotes,showonsite,rawpettype,rawbreed,rawcolour,rawcoat,rawageyears\n"

        # Lost Animals
        if includelost:
            anCount = 0
            for an in lostanimals:
                try:
                    line = []
                    anCount += 1
                    self.log(
                        "Processing Lost Animal: %d: %s (%d of %d)" %
                        (an["ID"], an["COMMENTS"], anCount, len(foundanimals)))

                    # If the user cancelled, stop now
                    if self.shouldStopPublishing():
                        self.log("User cancelled publish. Stopping.")
                        self.resetPublisherProgress()
                        return

                    # customerurn
                    line.append("\"%s\"" % customerid)
                    # importkey
                    line.append("\"L%s\"" % an["ID"])
                    # lostfound
                    line.append("\"L\"")
                    # pettype
                    line.append(
                        "\"%s\"" %
                        self.plcSpecies(an["SPECIESNAME"], an["SPECIESNAME"]))
                    # breed
                    line.append("\"%s\"" % an["BREEDNAME"])
                    # sexofpet
                    line.append("\"%s\"" % self.plcSex(an["SEX"]))
                    # neutered
                    line.append("\"%s\"" % (self.plcNeutered(an["DISTFEAT"])))
                    # petname
                    line.append("\"\"")
                    # internalref
                    line.append("\"L%s\"" % an["ID"])
                    # petage
                    line.append("\"%s\"" % self.plcAge(an["AGEGROUP"]))
                    # hairtype
                    line.append("\"%s\"" % self.plcHairType(an))
                    # petcoloursall
                    line.append("\"%s\"" %
                                self.plcColour(an["ADOPTAPETCOLOUR"]))
                    # chipchecked
                    line.append("\"1\"")
                    # chipno
                    line.append("\"\"")
                    # petfeatures
                    line.append("\"%s\"" % an["DISTFEAT"])
                    # lastlocationst
                    line.append("\"\"")
                    # lastlocation
                    line.append("\"%s\"" % an["AREALOST"])
                    # locationpostcode
                    line.append("\"%s\"" % self.plcPostcode(
                        an["AREAPOSTCODE"], an["OWNERPOSTCODE"]))
                    # datelostfound
                    line.append(
                        "\"%s\"" %
                        i18n.python2display(self.locale, an["DATELOST"]))
                    # otherdetails
                    line.append("\"\"")
                    # privatenotes
                    line.append("\"%s\"" % an["COMMENTS"])
                    # showonsite
                    line.append("\"1\"")
                    # rawpettype
                    line.append("\"%s\"" % an["SPECIESNAME"])
                    # rawbreed
                    line.append("\"%s\"" % an["BREEDNAME"])
                    # rawcolour
                    line.append("\"%s\"" % an["BASECOLOURNAME"])
                    # rawcoat
                    line.append("\"\"")
                    # rawageyears
                    line.append("\"%s\"" %
                                self.plcAgeYears(agegroup=an["AGEGROUP"]))
                    # Add to our CSV file
                    csv.append(",".join(line))
                    # Mark success in the log
                    self.logSuccess(
                        "Processed Lost Animal: %d: %s (%d of %d)" %
                        (an["ID"], an["COMMENTS"], anCount, len(foundanimals)))
                except Exception as err:
                    self.logError(
                        "Failed processing lost animal: %s, %s" %
                        (str(an["ID"]), err), sys.exc_info())

        # Found Animals
        anCount = 0
        for an in foundanimals:
            try:
                line = []
                anCount += 1
                self.log(
                    "Processing Found Animal: %d: %s (%d of %d)" %
                    (an["ID"], an["COMMENTS"], anCount, len(foundanimals)))

                # If the user cancelled, stop now
                if self.shouldStopPublishing():
                    self.log("User cancelled publish. Stopping.")
                    self.resetPublisherProgress()
                    return

                # customerurn
                line.append("\"%s\"" % customerid)
                # importkey
                line.append("\"F%s\"" % an["ID"])
                # lostfound
                line.append("\"F\"")
                # pettype
                line.append(
                    "\"%s\"" %
                    self.plcSpecies(an["SPECIESNAME"], an["SPECIESNAME"]))
                # breed
                line.append("\"%s\"" % an["BREEDNAME"])
                # sexofpet
                line.append("\"%s\"" % self.plcSex(an["SEX"]))
                # neutered
                line.append("\"%s\"" % (self.plcNeutered(an["DISTFEAT"])))
                # petname
                line.append("\"\"")
                # internalref
                line.append("\"F%s\"" % an["ID"])
                # petage
                line.append("\"%s\"" % self.plcAge(an["AGEGROUP"]))
                # hairtype
                line.append("\"%s\"" % self.plcHairType(an))
                # petcoloursall
                line.append("\"%s\"" % self.plcColour(an["ADOPTAPETCOLOUR"]))
                # chipchecked
                line.append("\"1\"")
                # chipno
                line.append("\"\"")
                # petfeatures
                line.append("\"%s\"" % an["DISTFEAT"])
                # lastlocationst
                line.append("\"\"")
                # lastlocation
                line.append("\"%s\"" % an["AREAFOUND"])
                # locationpostcode
                line.append(
                    "\"%s\"" %
                    self.plcPostcode(an["AREAPOSTCODE"], an["OWNERPOSTCODE"]))
                # datelostfound
                line.append("\"%s\"" %
                            i18n.python2display(self.locale, an["DATEFOUND"]))
                # otherdetails
                line.append("\"\"")
                # privatenotes
                line.append("\"%s\"" % an["COMMENTS"])
                # showonsite
                line.append("\"1\"")
                # rawpettype
                line.append("\"%s\"" % an["SPECIESNAME"])
                # rawbreed
                line.append("\"%s\"" % an["BREEDNAME"])
                # rawcolour
                line.append("\"%s\"" % an["BASECOLOURNAME"])
                # rawcoat
                line.append("\"\"")
                # rawageyears
                line.append("\"%s\"" %
                            self.plcAgeYears(agegroup=an["AGEGROUP"]))
                # Add to our CSV file
                csv.append(",".join(line))
                # Mark success in the log
                self.logSuccess(
                    "Processed Found Animal: %d: %s (%d of %d)" %
                    (an["ID"], an["COMMENTS"], anCount, len(foundanimals)))
            except Exception as err:
                self.logError(
                    "Failed processing found animal: %s, %s" %
                    (str(an["ID"]), err), sys.exc_info())

        # Shelter animals
        if includeshelter:
            anCount = 0
            for an in animals:
                try:
                    line = []
                    anCount += 1
                    self.log("Processing: %s: %s (%d of %d)" %
                             (an["SHELTERCODE"], an["ANIMALNAME"], anCount,
                              len(animals)))
                    self.updatePublisherProgress(
                        self.getProgress(anCount, len(animals)))

                    # If the user cancelled, stop now
                    if self.shouldStopPublishing():
                        self.log("User cancelled publish. Stopping.")
                        self.resetPublisherProgress()
                        return

                    # Upload one image for this animal
                    # self.uploadImage(an, an["WEBSITEMEDIANAME"], an["SHELTERCODE"] + ".jpg")

                    # customerurn
                    line.append("\"%s\"" % customerid)
                    # importkey
                    line.append("\"A%s\"" % an["ID"])
                    # lostfound
                    line.append("\"F\"")
                    # pettype
                    line.append("\"%s\"" % self.plcSpecies(
                        an["SPECIESNAME"], an["PETFINDERSPECIES"]))
                    # breed
                    line.append("\"%s\"" % an["BREEDNAME"])
                    # sexofpet
                    line.append("\"%s\"" % self.plcSex(an["SEX"]))
                    # neutered
                    line.append("\"%s\"" % self.plcNeutered(an["NEUTERED"]))
                    # petname
                    line.append("\"%s\"" % an["ANIMALNAME"])
                    # internalref
                    line.append("\"A%s\"" % an["ID"])
                    # petage
                    line.append("\"%s\"" % self.plcAge(an["AGEGROUP"]))
                    # hairtype
                    line.append("\"%s\"" % self.plcHairType(an))
                    # petcoloursall
                    line.append("\"%s\"" %
                                self.plcColour(an["ADOPTAPETCOLOUR"]))
                    # chipchecked
                    line.append("\"%d\"" %
                                self.plcChipChecked(an["IDENTICHIPPED"]))
                    # chipno
                    line.append("\"%s\"" % an["IDENTICHIPNUMBER"])
                    # petfeatures
                    line.append("\"%s\"" % an["MARKINGS"])
                    # lastlocationst
                    line.append("\"\"")
                    # lastlocation
                    line.append("\"\"")
                    # locationpostcode
                    line.append("\"%s\"" %
                                self.plcPostcode(an["ORIGINALOWNERPOSTCODE"]))
                    # datelostfound
                    line.append(
                        "\"%s\"" %
                        i18n.python2display(self.locale, an["DATEBROUGHTIN"]))
                    # otherdetails
                    line.append("\"%s\"" % an["ANIMALCOMMENTS"])
                    # privatenotes
                    line.append("\"%s\"" % an["HIDDENANIMALDETAILS"])
                    # showonsite
                    line.append("\"1\"")
                    # rawpettype
                    line.append("\"%s\"" % an["SPECIESNAME"])
                    # rawbreed
                    line.append("\"%s\"" % an["BREEDNAME"])
                    # rawcolour
                    line.append("\"%s\"" % an["BASECOLOURNAME"])
                    # rawcoat
                    line.append("\"%s\"" % an["COATTYPENAME"])
                    # rawageyears
                    line.append("\"%s\"" %
                                self.plcAgeYears(dob=an["DATEOFBIRTH"]))
                    # Add to our CSV file
                    csv.append(",".join(line))
                    # Mark success in the log
                    self.logSuccess("Processed: %s: %s (%d of %d)" %
                                    (an["SHELTERCODE"], an["ANIMALNAME"],
                                     anCount, len(animals)))
                except Exception as err:
                    self.logError(
                        "Failed processing animal: %s, %s" %
                        (str(an["SHELTERCODE"]), err), sys.exc_info())

            # Mark published
            self.markAnimalsPublished(animals, first=True)

        filename = "%s_%s.csv" % (customerid, self.dbo.database)
        self.saveFile(os.path.join(self.publishDir, filename),
                      header + "\n".join(csv))
        self.log("Uploading datafile %s" % filename)
        self.upload(filename)
        self.log("Uploaded %s" % filename)
        self.log("-- FILE DATA --")
        self.log(header + "\n".join(csv))
        # Clean up
        self.closeFTPSocket()
        self.deletePublishDirectory()
        self.saveLog()
        self.setPublisherComplete()
Exemple #11
0
def lookingfor_report(dbo, username = "******"):
    """
    Generates the person looking for report
    """
    l = dbo.locale
    title = _("People Looking For", l)
    h = reports.get_report_header(dbo, title, username)
    def p(s): return "<p>%s</p>" % s
    def td(s): return "<td>%s</td>" % s
    def hr(): return "<hr />"
  
    people = db.query(dbo, "SELECT owner.*, " \
        "(SELECT Size FROM lksize WHERE ID = owner.MatchSize) AS MatchSizeName, " \
        "(SELECT BaseColour FROM basecolour WHERE ID = owner.MatchColour) AS MatchColourName, " \
        "(SELECT Sex FROM lksex WHERE ID = owner.MatchSex) AS MatchSexName, " \
        "(SELECT BreedName FROM breed WHERE ID = owner.MatchBreed) AS MatchBreedName, " \
        "(SELECT AnimalType FROM animaltype WHERE ID = owner.MatchAnimalType) AS MatchAnimalTypeName, " \
        "(SELECT SpeciesName FROM species WHERE ID = owner.MatchSpecies) AS MatchSpeciesName " \
        "FROM owner WHERE MatchActive = 1 AND " \
        "(MatchExpires Is Null OR MatchExpires > %s)" \
        "ORDER BY OwnerName" % db.dd(now(dbo.timezone)))

    ah = hr()
    ah += "<table border=\"1\" width=\"100%\"><tr>"
    ah += "<th>%s</th>" % _("Code", l)
    ah += "<th>%s</th>" % _("Name", l)
    ah += "<th>%s</th>" % _("Age", l)
    ah += "<th>%s</th>" % _("Sex", l)
    ah += "<th>%s</th>" % _("Size", l)
    ah += "<th>%s</th>" % _("Color", l)
    ah += "<th>%s</th>" % _("Species", l)
    ah += "<th>%s</th>" % _("Breed", l)
    ah += "<th>%s</th>" % _("Good with cats", l)
    ah += "<th>%s</th>" % _("Good with dogs", l)
    ah += "<th>%s</th>" % _("Good with children", l)
    ah += "<th>%s</th>" % _("Housetrained", l)
    ah += "<th>%s</th>" % _("Comments", l)
    ah += "</tr>"

    totalmatches = 0
    for p in people:
        sql = ""
        if p["MATCHANIMALTYPE"] > 0: sql += " AND a.AnimalTypeID = %d" % int(p["MATCHANIMALTYPE"])
        if p["MATCHSPECIES"] > 0: sql += " AND a.SpeciesID = %d" % int(p["MATCHSPECIES"])
        if p["MATCHBREED"] > 0: sql += " AND (a.BreedID = %d OR a.Breed2ID = %d)" % (int(p["MATCHBREED"]), int(p["MATCHBREED"]))
        if p["MATCHSEX"] > -1: sql += " AND a.Sex = %d" % int(p["MATCHSEX"])
        if p["MATCHSIZE"] > -1: sql += " AND a.Size = %d" % int(p["MATCHSIZE"])
        if p["MATCHCOLOUR"] > -1: sql += " AND a.BaseColourID = %d" % int(p["MATCHCOLOUR"])
        if p["MATCHGOODWITHCHILDREN"] == 0: sql += " AND a.IsGoodWithChildren = 0"
        if p["MATCHGOODWITHCATS"] == 0: sql += " AND a.IsGoodWithCats = 0"
        if p["MATCHGOODWITHDOGS"] == 0: sql += " AND a.IsGoodWithDogs = 0"
        if p["MATCHHOUSETRAINED"] == 0: sql += " AND a.IsHouseTrained = 0"
        if p["MATCHAGEFROM"] >= 0 and p["MATCHAGETO"] > 0: 
            sql += " AND a.DateOfBirth BETWEEN %s AND %s" % (db.dd(subtract_years(now(dbo.timezone), p["MATCHAGETO"])), \
                db.dd(subtract_years(now(dbo.timezone), p["MATCHAGEFROM"])))
        if p["MATCHCOMMENTSCONTAIN"] is not None and p["MATCHCOMMENTSCONTAIN"] != "":
            for w in str(p["MATCHCOMMENTSCONTAIN"]).split(" "):
                sql += " AND a.AnimalComments Like '%%%s%%'" % w.replace("'", "`")
        sql = animal.get_animal_query() + " WHERE a.Archived=0 AND a.DeceasedDate Is Null" + sql
        animals = db.query(dbo, sql)

        h += "<h2>%s (%s) %s</h2>" % (p["OWNERNAME"], p["OWNERADDRESS"], p["HOMETELEPHONE"])
        c = []
        if p["MATCHSIZE"] != -1: c.append(p["MATCHSIZENAME"])
        if p["MATCHCOLOUR"] != -1: c.append(p["MATCHCOLOURNAME"])
        if p["MATCHSEX"] != -1: c.append(p["MATCHSEXNAME"])
        if p["MATCHBREED"] != -1: c.append(p["MATCHBREEDNAME"])
        if p["MATCHSPECIES"] != -1: c.append(p["MATCHSPECIESNAME"])
        if p["MATCHANIMALTYPE"] != -1: c.append(p["MATCHANIMALTYPENAME"])
        if p["MATCHGOODWITHCHILDREN"] == 0: c.append(_("Good with kids", l))
        if p["MATCHGOODWITHCATS"] == 0: c.append(_("Good with cats", l))
        if p["MATCHGOODWITHDOGS"] == 0: c.append(_("Good with dogs", l))
        if p["MATCHHOUSETRAINED"] == 0: c.append(_("Housetrained", l))
        if p["MATCHAGEFROM"] >= 0 and p["MATCHAGETO"] > 0: c.append(_("Age", l) + (" %0.2f - %0.2f" % (p["MATCHAGEFROM"], p["MATCHAGETO"])))
        if p["MATCHCOMMENTSCONTAIN"] is not None and p["MATCHCOMMENTSCONTAIN"] != "": c.append(_("Comments Contain", l) + ": " + p["MATCHCOMMENTSCONTAIN"])
        if len(c) > 0:
            h += "<p style='font-size: 8pt'>(%s: %s)</p>" % (_("Looking for", l), ", ".join(c))

        outputheader = False
        for a in animals:
            if not outputheader:
                outputheader = True
                h += ah
            totalmatches += 1
            h += "<tr>"
            h += td(a["CODE"])
            h += td(a["ANIMALNAME"])
            h += td(a["ANIMALAGE"])
            h += td(a["SEXNAME"])
            h += td(a["SIZENAME"])
            h += td(a["COLOURNAME"])
            h += td(a["SPECIESNAME"])
            h += td(a["BREEDNAME"])
            h += td(a["ISGOODWITHCATSNAME"])
            h += td(a["ISGOODWITHDOGSNAME"])
            h += td(a["ISGOODWITHCHILDRENNAME"])
            h += td(a["ISHOUSETRAINEDNAME"])
            h += td(a["ANIMALCOMMENTS"])

        if outputheader:
            h += "</table>"
        h += hr()

    if len(people) == 0:
        h += p(_("No matches found.", l))

    h += "<!-- $AM%d^ animal matches -->" % totalmatches
    h += reports.get_report_footer(dbo, title, username)
    return h