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)
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)
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)
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)
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
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
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()
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
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()
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