コード例 #1
0
ファイル: lostfound.py プロジェクト: luckyhuntproject/asm3
def match_report(dbo, username = "******", lostanimalid = 0, foundanimalid = 0, animalid = 0, limit = 0):
    """
    Generates the match report and returns it as a string
    """
    l = dbo.locale
    title = _("Match lost and found animals", l)
    h = []
    h.append(asm3.reports.get_report_header(dbo, title, username))
    if limit > 0:
        h.append("<p>(" + _("Limited to {0} matches", l).format(limit) + ")</p>")
    def p(s): 
        return "<p>%s</p>" % s
    def td(s): 
        return "<td>%s</td>" % s
    def hr(): 
        return "<hr />"
    lastid = 0
    matches = match(dbo, lostanimalid, foundanimalid, animalid, limit)
    if len(matches) > 0:
        for m in matches:
            if lastid != m.lid:
                if lastid != 0:
                    h.append("</tr></table>")
                    h.append(hr())
                h.append(p(_("{0} - {1} {2} ({3}), contact {4} ({5}) - lost in {6}, postcode {7}, on {8}", l).format( \
                    m.lid, "%s %s %s" % (m.lagegroup, m.lbasecolourname, m.lsexname), \
                    "%s/%s %s" % (m.lspeciesname, m.lbreedname, m.lmicrochip), \
                    m.ldistinguishingfeatures, m.lcontactname, m.lcontactnumber, m.larealost, m.lareapostcode,
                    python2display(l, m.ldatelost))))
                h.append("<table border=\"1\" width=\"100%\"><tr>")
                h.append("<th>%s</th>" % _("Reference", l))
                h.append("<th>%s</th>" % _("Description", l))
                h.append("<th>%s</th>" % _("Area Found", l))
                h.append("<th>%s</th>" % _("Area Postcode", l))
                h.append("<th>%s</th>" % _("Date Found", l))
                h.append("<th>%s</th>" % _("Contact", l))
                h.append("<th>%s</th>" % _("Number", l))
                h.append("<th>%s</th>" % _("Microchip", l))
                h.append("<th>%s</th>" % _("Match", l))
                h.append("</tr>")
                lastid = m.lid
            h.append("<tr>")
            h.append(td(str(m.fid)))
            h.append(td("%s %s %s %s %s" % (m.fagegroup, m.fbasecolourname, m.fsexname, m.fspeciesname, m.fbreedname)))
            h.append(td(m.fareafound))
            h.append(td(m.fareapostcode))
            h.append(td(python2display(l, m.fdatefound)))
            h.append(td(m.fcontactname))
            h.append(td(m.fcontactnumber))
            h.append(td(m.fmicrochip))
            h.append(td(str(m.matchpoints) + "%"))
            h.append("</tr>")
        h.append("</tr></table>")
    else:
        h.append(p(_("No matches found.", l)))
    h.append(asm3.reports.get_report_footer(dbo, title, username))
    return "\n".join(h)
コード例 #2
0
def insert_animalcontrol(dbo, username):
    """
    Creates a new animal control incident record and returns the id
    """
    l = dbo.locale
    d = {
        "incidentdate":     python2display(l, dbo.now()),
        "incidenttime":     format_time_now(dbo.timezone),
        "incidenttype":     asm3.configuration.default_incident(dbo),
        "calldate":         python2display(l, dbo.now()),
        "calltime":         format_time_now(dbo.timezone),
        "calltaker":        username
    }
    return insert_animalcontrol_from_form(dbo, asm3.utils.PostedData(d, dbo.locale), username)
コード例 #3
0
ファイル: additional.py プロジェクト: luckyhuntproject/asm3
def merge_values_for_link(dbo, post, linkid, linktype="animal"):
    """
    Saves incoming additional field values. Only updates the 
    additional fields that are present in the post object and leaves the rest alone. 
    It will only update a field if it has a value. This function is aimed
    at areas that merge into existing records, such as online forms and CSV imports.
    linkid: The link to the parent record
    linktype: The class of parent record
    Keys of either a.MANDATORY.ID can be used (ASM internal forms)
        or keys of the form additionalFIELDNAME (ASM online forms)
    """
    for f in get_field_definitions(dbo, linktype):

        key = "a.%s.%s" % (f.mandatory, f.id)
        key2 = "additional%s" % f.fieldname

        if key2 in post: key = key2
        if key in post:
            val = post[key]
            if val == "": continue
            if f.fieldtype == YESNO:
                val = str(post.boolean(key))
            elif f.fieldtype == MONEY:
                val = str(post.integer(key))
            elif f.fieldtype == DATE:
                val = python2display(dbo.locale, post.date(key))
            dbo.delete("additional",
                       "LinkID=%s AND AdditionalFieldID=%s" % (linkid, f.ID))
            insert_additional(dbo, f.LINKTYPE, linkid, f.ID, val)
コード例 #4
0
ファイル: lostfound.py プロジェクト: luckyhuntproject/asm3
def create_animal_from_found(dbo, username, aid):
    """
    Creates an animal record from a found animal with the id given
    """
    a = dbo.first_row( dbo.query("SELECT * FROM animalfound WHERE ID = %d" % int(aid)) )
    l = dbo.locale
    data = {
        "animalname":           _("Found Animal {0}", l).format(aid),
        "markings":             str(a["DISTFEAT"]),
        "species":              str(a["ANIMALTYPEID"]),
        "comments":             str(a["COMMENTS"]),
        "broughtinby":          str(a["OWNERID"]),
        "originalowner":        str(a["OWNERID"]),
        "animaltype":           asm3.configuration.default_type(dbo),
        "breed1":               a["BREEDID"],
        "breed2":               a["BREEDID"],
        "basecolour":           str(a["BASECOLOURID"]),
        "microchipped":         asm3.utils.iif(a["MICROCHIPNUMBER"] is not None and a["MICROCHIPNUMBER"] != "", "1", "0"),
        "microchipnumber":      a["MICROCHIPNUMBER"],
        "size":                 asm3.configuration.default_size(dbo),
        "internallocation":     asm3.configuration.default_location(dbo),
        "dateofbirth":          python2display(l, subtract_years(now(dbo.timezone))),
        "estimateddob":         "1",
    }
    # If we're creating shelter codes manually, we need to put something unique
    # in there for now. Use the id
    if asm3.configuration.manual_codes(dbo):
        data["sheltercode"] = "FA" + str(aid)
        data["shortcode"] = "FA" + str(aid)
    nextid, dummy = asm3.animal.insert_animal_from_form(dbo, asm3.utils.PostedData(data, l), username)
    return nextid
コード例 #5
0
def save_values_for_link(dbo,
                         post,
                         username,
                         linkid,
                         linktype="animal",
                         setdefaults=False):
    """
    Saves incoming additional field values from a record.
    Clears existing additional field values before saving (this is because forms
        don't send blank values)
    linkid: The link to the parent record
    linktype: The class of parent record
    setdefaults: If True, will set default values for any keys not supplied
        (Should be True for calls from insert_X_from_form methods)
    Keys of either a.MANDATORY.ID can be used (ASM internal forms)
        or keys of the form additionalFIELDNAME (ASM online forms)
    """
    dbo.delete(
        "additional", "LinkType IN (%s) AND LinkID=%s" %
        (clause_for_linktype(linktype), linkid))
    audits = []

    for f in get_field_definitions(dbo, linktype):

        key = "a.%s.%s" % (f.mandatory, f.id)
        key2 = "additional%s" % f.fieldname

        if key not in post and key2 not in post:
            if setdefaults and f.DEFAULTVALUE and f.DEFAULTVALUE != "":
                insert_additional(dbo, f.LINKTYPE, linkid, f.ID,
                                  f.DEFAULTVALUE)
                audits.append("%s='%s'" % (f.FIELDNAME, f.DEFAULTVALUE))
            continue

        elif key not in post:
            key = key2

        val = post[key]
        if f.fieldtype == YESNO:
            val = str(post.boolean(key))
        elif f.fieldtype == MONEY:
            val = str(post.integer(key))
        elif f.fieldtype == DATE:
            val = python2display(dbo.locale, post.date(key))
        audits.append("%s='%s'" % (f.FIELDNAME, val))
        insert_additional(dbo, f.LINKTYPE, linkid, f.ID, val)

    if len(audits) > 0:
        asm3.audit.edit(dbo, username, "additional", 0,
                        "%s=%s " % (table_for_linktype(linktype), linkid),
                        ", ".join(audits))
コード例 #6
0
ファイル: stock.py プロジェクト: vijaydairyf/sheltermanager
def get_stock_items(dbo):
    """
    Returns a set of stock items.
    """
    rows = dbo.query("SELECT sv.*, sl.LocationName " \
        "FROM stocklevel sv " \
        "INNER JOIN stocklocation sl ON sl.ID = sv.StockLocationID " \
        "WHERE sv.Balance > 0 " \
        "ORDER BY sv.StockLocationID, sv.Name")
    for r in rows:
        r.ITEMNAME = "%s - %s %s %s (%g/%g)" % (
            r.LOCATIONNAME, r.NAME, r.BATCHNUMBER,
            python2display(dbo.locale, r.EXPIRY), r.BALANCE, r.TOTAL)
    return rows
コード例 #7
0
ファイル: additional.py プロジェクト: luckyhuntproject/asm3
def save_values_for_link(dbo,
                         post,
                         linkid,
                         linktype="animal",
                         setdefaults=False):
    """
    Saves incoming additional field values from a record.
    Clears existing additional field values before saving (this is because forms
        don't send blank values)
    linkid: The link to the parent record
    linktype: The class of parent record
    setdefaults: If True, will set default values for any keys not supplied
        (Should be True for calls from insert_X_from_form methods)
    Keys of either a.MANDATORY.ID can be used (ASM internal forms)
        or keys of the form additionalFIELDNAME (ASM online forms)
    """
    l = dbo.locale

    dbo.delete(
        "additional", "LinkType IN (%s) AND LinkID=%s" %
        (clause_for_linktype(linktype), linkid))

    for f in get_field_definitions(dbo, linktype):

        key = "a.%s.%s" % (f.mandatory, f.id)
        key2 = "additional%s" % f.fieldname

        if key not in post and key2 not in post:
            if setdefaults and f.DEFAULTVALUE and f.DEFAULTVALUE != "":
                insert_additional(dbo, f.LINKTYPE, linkid, f.ID,
                                  f.DEFAULTVALUE)
            continue

        elif key not in post:
            key = key2

        val = post[key]
        if f.fieldtype == YESNO:
            val = str(post.boolean(key))
        elif f.fieldtype == MONEY:
            val = str(post.integer(key))
        elif f.fieldtype == DATE:
            if len(val.strip()) > 0 and post.date(key) is None:
                raise asm3.utils.ASMValidationError(
                    _("Additional date field '{0}' contains an invalid date.",
                      l).format(f.fieldname))
            val = python2display(dbo.locale, post.date(key))
        insert_additional(dbo, f.LINKTYPE, linkid, f.ID, val)
コード例 #8
0
ファイル: lostfound.py プロジェクト: luckyhuntproject/asm3
def create_waitinglist_from_found(dbo, username, aid):
    """
    Creates a waiting list entry from a found animal with the id given
    """
    a = dbo.first_row( dbo.query("SELECT * FROM animalfound WHERE ID = %d" % int(aid)) )
    l = dbo.locale
    data = {
        "dateputon":            python2display(l, now(dbo.timezone)),
        "description":          str(a["DISTFEAT"]),
        "species":              str(a["ANIMALTYPEID"]),
        "comments":             str(a["COMMENTS"]),
        "owner":                str(a["OWNERID"]),
        "breed1":               a["BREEDID"],
        "breed2":               a["BREEDID"],
        "basecolour":           str(a["BASECOLOURID"]),
        "urgency":              str(asm3.configuration.waiting_list_default_urgency(dbo))
    }
    nextid = asm3.waitinglist.insert_waitinglist_from_form(dbo, asm3.utils.PostedData(data, dbo.locale), username)
    return nextid
コード例 #9
0
ファイル: waitinglist.py プロジェクト: astridn74/asm3
def create_animal(dbo, username, wlid):
    """
    Creates an animal record from a waiting list entry with the id given
    """
    l = dbo.locale
    a = dbo.first_row(
        dbo.query("SELECT * FROM animalwaitinglist WHERE ID = ?", [wlid]))

    data = {
        "animalname": _("Waiting List {0}", l).format(wlid),
        "markings": str(a["ANIMALDESCRIPTION"]),
        "reasonforentry": str(a["REASONFORWANTINGTOPART"]),
        "species": str(a["SPECIESID"]),
        "hiddenanimaldetails": str(a["COMMENTS"]),
        "broughtinby": str(a["OWNERID"]),
        "originalowner": str(a["OWNERID"]),
        "animaltype": asm3.configuration.default_type(dbo),
        "entryreason": asm3.configuration.default_entry_reason(dbo),
        "breed1": asm3.configuration.default_breed(dbo),
        "breed2": asm3.configuration.default_breed(dbo),
        "basecolour": asm3.configuration.default_colour(dbo),
        "size": asm3.configuration.default_size(dbo),
        "internallocation": asm3.configuration.default_location(dbo),
        "dateofbirth": python2display(l, subtract_years(now(dbo.timezone))),
        "estimateddob": "1"
    }
    # If we aren't showing the time brought in, set it to midnight
    if not asm3.configuration.add_animals_show_time_brought_in(dbo):
        data["timebroughtin"] = "00:00:00"

    # If we're creating shelter codes manually, we need to put something unique
    # in there for now. Use the id
    if asm3.configuration.manual_codes(dbo):
        data["sheltercode"] = "WL" + str(wlid)
        data["shortcode"] = "WL" + str(wlid)
    nextid, code = asm3.animal.insert_animal_from_form(
        dbo, asm3.utils.PostedData(data, l), username)

    # Now that we've created our animal, we should remove this entry from the waiting list
    dbo.update(
        "animalwaitinglist", wlid, {
            "DateRemovedFromList": dbo.today(),
            "ReasonForRemoval": _("Moved to animal record {0}", l).format(code)
        }, username)

    # If there were any logs and media entries on the waiting list, create them on the animal

    # Media
    for me in dbo.query(
            "SELECT * FROM media WHERE LinkTypeID = ? AND LinkID = ?",
        (asm3.media.WAITINGLIST, wlid)):
        ext = me.medianame
        ext = ext[ext.rfind("."):].lower()
        mediaid = dbo.get_id("media")
        medianame = "%d%s" % (mediaid, ext)
        dbo.insert(
            "media",
            {
                "ID": mediaid,
                "DBFSID": 0,
                "MediaSize": 0,
                "MediaName": medianame,
                "MediaMimeType": asm3.media.mime_type(medianame),
                "MediaType": me.mediatype,
                "MediaNotes": me.medianotes,
                "WebsitePhoto": me.websitephoto,
                "WebsiteVideo": me.websitevideo,
                "DocPhoto": me.docphoto,
                "ExcludeFromPublish": me.excludefrompublish,
                # ASM2_COMPATIBILITY
                "NewSinceLastPublish": 1,
                "UpdatedSinceLastPublish": 0,
                # ASM2_COMPATIBILITY
                "LinkID": nextid,
                "LinkTypeID": asm3.media.ANIMAL,
                "Date": me.date,
                "CreatedDate": me.createddate,
                "RetainUntil": me.retainuntil
            },
            generateID=False)

        # Now clone the dbfs item pointed to by this media item if it's a file
        if me.mediatype == asm3.media.MEDIATYPE_FILE:
            filedata = asm3.dbfs.get_string(dbo, me.medianame)
            dbfsid = asm3.dbfs.put_string(dbo, medianame,
                                          "/animal/%d" % nextid, filedata)
            dbo.execute(
                "UPDATE media SET DBFSID = ?, MediaSize = ? WHERE ID = ?",
                (dbfsid, len(filedata), mediaid))

    # Logs
    for lo in dbo.query("SELECT * FROM log WHERE LinkType = ? AND LinkID = ?",
                        (asm3.log.WAITINGLIST, wlid)):
        dbo.insert(
            "log", {
                "LinkID": nextid,
                "LinkType": asm3.log.ANIMAL,
                "LogTypeID": lo.LOGTYPEID,
                "Date": lo.DATE,
                "Comments": lo.COMMENTS
            }, username)

    return nextid
コード例 #10
0
def handler(post, path, remoteip, referer, querystring):
    """ Handles the various service method types.
    post:        The GET/POST parameters
    path:        The current system path/code.PATH
    remoteip:    The IP of the caller
    referer:     The referer HTTP header
    querystring: The complete querystring
    return value is a tuple containing MIME type, max-age, content
    """
    # Get service parameters
    account = post["account"]
    username = post["username"]
    password = post["password"]
    method = post["method"]
    animalid = post.integer("animalid")
    formid = post.integer("formid")
    mediaid = post.integer("mediaid")
    seq = post.integer("seq")
    title = post["title"]
    strip_personal = post.integer("sensitive") == 0

    # If this method is in the cache protected list, only use
    # whitelisted parameters for the key to prevent callers
    # cache-busting by adding junk parameters
    cache_key = querystring.replace(" ", "")
    if method in CACHE_PROTECT_METHODS:
        cache_key = safe_cache_key(method, cache_key)

    # Do we have a cached response for these parameters?
    cached_response = get_cached_response(cache_key, account)
    if cached_response is not None:
        asm3.al.debug(
            "cache hit: %s (%d bytes)" % (cache_key, len(cached_response[3])),
            "service.handler", account)
        return cached_response

    # Are we dealing with multiple databases, but no account was specified?
    if account == "" and MULTIPLE_DATABASES:
        return ("text/plain", 0, 0, "ERROR: No database/alias specified")

    # Is flood protection activated for this method?
    if method in FLOOD_PROTECT_METHODS:
        flood_protect(method, remoteip)

    dbo = asm3.db.get_database(account)

    if dbo.database in asm3.db.ERROR_VALUES:
        asm3.al.error(
            "auth failed - invalid smaccount %s from %s (%s)" %
            (account, remoteip, dbo.database), "service.handler", dbo)
        return ("text/plain", 0, 0,
                "ERROR: Invalid database (%s)" % dbo.database)

    # If the database has disabled the service API, stop now
    if not asm3.configuration.service_enabled(dbo):
        asm3.al.error("Service API is disabled (%s)" % method,
                      "service.handler", dbo)
        return ("text/plain", 0, 0, "ERROR: Service API is disabled")

    # Do any database updates need doing in this db?
    dbo.installpath = path
    if asm3.dbupdate.check_for_updates(dbo):
        asm3.dbupdate.perform_updates(dbo)

    # Does the method require us to authenticate? If so, do it.
    user = None
    securitymap = ""
    if method in AUTH_METHODS:
        # If the database has authenticated service methods disabled, stop now
        if not asm3.configuration.service_auth_enabled(dbo):
            asm3.al.error(
                "Service API for auth methods is disabled (%s)" % method,
                "service.handler", dbo)
            return ("text/plain", 0, 0,
                    "ERROR: Service API for authenticated methods is disabled")
        user = asm3.users.authenticate(dbo, username, password)
        if user is None:
            asm3.al.error(
                "auth failed - %s/%s is not a valid username/password from %s"
                % (username, password, remoteip), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid username and password")
        securitymap = asm3.users.get_security_map(dbo, user["USERNAME"])

    # Get the preferred locale and timezone for the site
    l = asm3.configuration.locale(dbo)
    dbo.locale = l
    dbo.timezone = asm3.configuration.timezone(dbo)
    dbo.timezone_dst = asm3.configuration.timezone_dst(dbo)
    asm3.al.info("call @%s --> %s [%s]" % (username, method, querystring),
                 "service.handler", dbo)

    if method == "animal_image":
        hotlink_protect("animal_image", referer)
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error(
                "animal_image failed, %s is not an animalid" % str(animalid),
                "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            dummy, data = asm3.media.get_image_file_data(
                dbo, "animal", asm3.utils.cint(animalid), seq)
            if data == "NOPIC":
                dummy, data = asm3.media.get_image_file_data(dbo, "nopic", 0)
            return set_cached_response(cache_key, account, "image/jpeg", 86400,
                                       3600, data)

    elif method == "animal_thumbnail":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error(
                "animal_thumbnail failed, %s is not an animalid" %
                str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            dummy, data = asm3.media.get_image_file_data(
                dbo, "animalthumb", asm3.utils.cint(animalid), seq)
            if data == "NOPIC":
                dummy, data = asm3.media.get_image_file_data(dbo, "nopic", 0)
            return set_cached_response(cache_key, account, "image/jpeg", 86400,
                                       3600, data)

    elif method == "animal_view":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error(
                "animal_view failed, %s is not an animalid" % str(animalid),
                "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            return set_cached_response(
                cache_key, account, "text/html", 86400, 120,
                asm3.publishers.html.get_animal_view(
                    dbo, asm3.utils.cint(animalid)))

    elif method == "animal_view_adoptable_js":
        return set_cached_response(
            cache_key, account, "application/javascript", 10800, 600,
            asm3.publishers.html.get_animal_view_adoptable_js(dbo))

    elif method == "animal_view_adoptable_html":
        return set_cached_response(
            cache_key, account, "text/html", 86400, 120,
            asm3.publishers.html.get_animal_view_adoptable_html(dbo))

    elif method == "checkout":
        processor = asm3.financial.get_payment_processor(
            dbo, post["processor"])
        if not processor.validatePaymentReference(post["payref"]):
            return ("text/plain", 0, 0, "ERROR: Invalid payref")
        if processor.isPaymentReceived(post["payref"]):
            return ("text/plain", 0, 0, "ERROR: Expired payref")
        return_url = post["return"] or asm3.configuration.payment_return_url(
            dbo)
        return set_cached_response(
            cache_key, account, "text/html", 15, 15,
            processor.checkoutPage(post["payref"], return_url, title))

    elif method == "checkout_adoption":
        if post["token"] == "":
            raise asm3.utils.ASMError(
                "method checkout_adoption requires a valid token")
        elif post["sig"] == "":
            return set_cached_response(
                cache_key, account, "text/html", 120, 120,
                checkout_adoption_page(dbo, post["token"]))
        else:
            return ("text/plain", 0, 0, checkout_adoption_post(dbo, post))

    elif method == "dbfs_image":
        hotlink_protect("dbfs_image", referer)
        return set_cached_response(
            cache_key, account, "image/jpeg", 86400, 86400,
            asm3.utils.iif(title.startswith("/"),
                           asm3.dbfs.get_string_filepath(dbo, title),
                           asm3.dbfs.get_string(dbo, title)))

    elif method == "document_repository":
        return set_cached_response(
            cache_key, account,
            asm3.media.mime_type(asm3.dbfs.get_name_for_id(dbo, mediaid)),
            86400, 86400, asm3.dbfs.get_string_id(dbo, mediaid))

    elif method == "extra_image":
        hotlink_protect("extra_image", referer)
        return set_cached_response(
            cache_key, account, "image/jpeg", 86400, 86400,
            asm3.dbfs.get_string(dbo, title, "/reports"))

    elif method == "media_image":
        hotlink_protect("media_image", referer)
        return set_cached_response(
            cache_key, account, "image/jpeg", 86400, 86400,
            asm3.dbfs.get_string_id(
                dbo,
                dbo.query_int("select dbfsid from media where id = ?",
                              [mediaid])))

    elif method == "json_adoptable_animal":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error(
                "json_adoptable_animal failed, %s is not an animalid" %
                str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                            asm3.users.VIEW_ANIMAL)
            rs = asm3.publishers.base.get_animal_data(
                dbo,
                None,
                asm3.utils.cint(animalid),
                include_additional_fields=True)
            return set_cached_response(cache_key, account, "application/json",
                                       3600, 3600, asm3.utils.json(rs))

    elif method == "html_adoptable_animals":
        return set_cached_response(cache_key, account, "text/html", 600, 600, \
            asm3.publishers.html.get_adoptable_animals(dbo, style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid"), \
                locationid=post.integer("locationid"), underweeks=post.integer("underweeks"), \
                overweeks=post.integer("overweeks")))

    elif method == "html_adopted_animals":
        return set_cached_response(cache_key, account, "text/html", 10800, 1800, \
            asm3.publishers.html.get_adopted_animals(dbo, daysadopted=post.integer("days"), style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid")))

    elif method == "html_deceased_animals":
        return set_cached_response(cache_key, account, "text/html", 10800, 1800, \
            asm3.publishers.html.get_deceased_animals(dbo, daysdeceased=post.integer("days"), style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid")))

    elif method == "html_flagged_animals":
        if post["flag"] == "":
            asm3.al.error("html_flagged_animals requested with no flag.",
                          "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid flag")
        return set_cached_response(cache_key, account, "text/html", 1800, 1800, \
            asm3.publishers.html.get_flagged_animals(dbo, style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid"), flag=post["flag"], allanimals=post.integer("all")))

    elif method == "html_held_animals":
        return set_cached_response(cache_key, account, "text/html", 1800, 1800, \
            asm3.publishers.html.get_held_animals(dbo, style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid")))

    elif method == "json_adoptable_animals_xp":
        rs = strip_personal_data(
            asm3.publishers.base.get_animal_data(
                dbo, None, include_additional_fields=True))
        return set_cached_response(cache_key, account, "application/json", 600,
                                   600, asm3.utils.json(rs))

    elif method == "json_adoptable_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.publishers.base.get_animal_data(
            dbo, None, include_additional_fields=True)
        if strip_personal: rs = strip_personal_data(rs)
        return set_cached_response(cache_key, account, "application/json", 600,
                                   600, asm3.utils.json(rs))

    elif method == "jsonp_adoptable_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.publishers.base.get_animal_data(
            dbo, None, include_additional_fields=True)
        if strip_personal: rs = strip_personal_data(rs)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_adoptable_animal":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error(
                "xml_adoptable_animal failed, %s is not an animalid" %
                str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                            asm3.users.VIEW_ANIMAL)
            rs = asm3.publishers.base.get_animal_data(
                dbo,
                None,
                asm3.utils.cint(animalid),
                include_additional_fields=True)
            return set_cached_response(cache_key, account, "application/xml",
                                       600, 600, asm3.html.xml(rs))

    elif method == "xml_adoptable_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.publishers.base.get_animal_data(
            dbo, None, include_additional_fields=True)
        if strip_personal: rs = strip_personal_data(rs)
        return set_cached_response(cache_key, account, "application/xml", 600,
                                   600, asm3.html.xml(rs))

    elif method == "json_found_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_FOUND_ANIMAL)
        rs = asm3.lostfound.get_foundanimal_last_days(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(rs))

    elif method == "jsonp_found_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_FOUND_ANIMAL)
        rs = asm3.lostfound.get_foundanimal_last_days(dbo)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_found_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_FOUND_ANIMAL)
        rs = asm3.lostfound.get_foundanimal_last_days(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.html.xml(rs))

    elif method == "json_held_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.animal.get_animals_hold(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(rs))

    elif method == "xml_held_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.animal.get_animals_hold(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.html.xml(rs))

    elif method == "jsonp_held_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.animal.get_animals_hold(dbo)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "json_lost_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_LOST_ANIMAL)
        rs = asm3.lostfound.get_lostanimal_last_days(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(rs))

    elif method == "jsonp_lost_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_LOST_ANIMAL)
        rs = asm3.lostfound.get_lostanimal_last_days(dbo)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_lost_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_LOST_ANIMAL)
        rs = asm3.lostfound.get_lostanimal_last_days(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.html.xml(rs))

    elif method == "json_recent_adoptions":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.movement.get_recent_adoptions(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(rs))

    elif method == "jsonp_recent_adoptions":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.movement.get_recent_adoptions(dbo)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_recent_adoptions":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.movement.get_recent_adoptions(dbo)
        return set_cached_response(cache_key, account, "application/xml", 3600,
                                   3600, asm3.html.xml(rs))

    elif method == "html_report":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_REPORT)
        crid = asm3.reports.get_id(dbo, title)
        p = asm3.reports.get_criteria_params(dbo, crid, post)
        rhtml = asm3.reports.execute(dbo, crid, username, p)
        rhtml = asm3.utils.fix_relative_document_uris(dbo, rhtml)
        return set_cached_response(cache_key, account, "text/html", 600, 600,
                                   rhtml)

    elif method == "csv_mail" or method == "csv_report":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_REPORT)
        crid = asm3.reports.get_id(dbo, title)
        p = asm3.reports.get_criteria_params(dbo, crid, post)
        rows, cols = asm3.reports.execute_query(dbo, crid, username, p)
        mcsv = asm3.utils.csv(l, rows, cols, True)
        return set_cached_response(cache_key, account, "text/csv", 600, 600,
                                   mcsv)

    elif method == "json_report" or method == "json_mail":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_REPORT)
        crid = asm3.reports.get_id(dbo, title)
        p = asm3.reports.get_criteria_params(dbo, crid, post)
        rows, cols = asm3.reports.execute_query(dbo, crid, username, p)
        return set_cached_response(cache_key, account, "application/json", 600,
                                   600, asm3.utils.json(rows))

    elif method == "jsonp_report" or method == "jsonp_mail":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_REPORT)
        crid = asm3.reports.get_id(dbo, title)
        p = asm3.reports.get_criteria_params(dbo, crid, post)
        rows, cols = asm3.reports.execute_query(dbo, crid, username, p)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rows)))

    elif method == "jsonp_recent_changes":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_recent_changes(dbo)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(sa)))

    elif method == "json_recent_changes":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_recent_changes(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(sa))

    elif method == "xml_recent_changes":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_recent_changes(dbo)
        return set_cached_response(cache_key, account, "application/xml", 3600,
                                   3600, asm3.html.xml(sa))

    elif method == "jsonp_shelter_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_shelter_animals(dbo)
        if strip_personal: sa = strip_personal_data(sa)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(sa)))

    elif method == "json_shelter_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_shelter_animals(dbo)
        if strip_personal: sa = strip_personal_data(sa)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(sa))

    elif method == "xml_shelter_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_shelter_animals(dbo)
        if strip_personal: sa = strip_personal_data(sa)
        return set_cached_response(cache_key, account, "application/xml", 3600,
                                   3600, asm3.html.xml(sa))

    elif method == "rss_timeline":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        return set_cached_response(cache_key, account, "application/rss+xml",
                                   3600, 3600, asm3.html.timeline_rss(dbo))

    elif method == "upload_animal_image":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.ADD_MEDIA)
        asm3.media.attach_file_from_form(dbo, username, asm3.media.ANIMAL,
                                         int(animalid), post)
        return ("text/plain", 0, 0, "OK")

    elif method == "online_form_html":
        if formid == 0:
            raise asm3.utils.ASMError(
                "method online_form_html requires a valid formid")
        return set_cached_response(
            cache_key, account, "text/html; charset=utf-8", 120, 120,
            asm3.onlineform.get_onlineform_html(dbo, formid))

    elif method == "online_form_json":
        if formid == 0:
            raise asm3.utils.ASMError(
                "method online_form_json requires a valid formid")
        return set_cached_response(
            cache_key, account, "application/json; charset=utf-8", 30, 30,
            asm3.onlineform.get_onlineform_json(dbo, formid))

    elif method == "online_form_post":
        asm3.onlineform.insert_onlineformincoming_from_form(
            dbo, post, remoteip)
        redirect = post["redirect"]
        if redirect == "":
            redirect = BASE_URL + "/static/pages/form_submitted.html"
        return ("redirect", 0, 0, redirect)

    elif method == "sign_document":
        if formid == 0:
            raise asm3.utils.ASMError(
                "method sign_document requires a valid formid")
        if post["sig"] == "":
            m = asm3.media.get_media_by_id(dbo, formid)
            if m is None: raise asm3.utils.ASMError("invalid link")
            token = asm3.utils.md5_hash_hex("%s%s" % (m.ID, m.LINKID))
            if token != post["token"]:
                raise asm3.utils.ASMError("invalid token")
            return set_cached_response(
                cache_key, account, "text/html", 2, 2,
                sign_document_page(dbo, formid, post["email"]))
        else:
            signdate = "%s %s" % (python2display(
                l, dbo.now()), format_time(dbo.now()))
            asm3.media.sign_document(dbo, "service", formid, post["sig"],
                                     signdate, "signemail")
            asm3.media.create_log(dbo, "service", formid, "ES02",
                                  _("Document signed", l))
            if post.boolean("sendsigned"):
                m = asm3.media.get_media_by_id(dbo, formid)
                if m is None:
                    raise asm3.utils.ASMError("cannot find %s" % formid)
                content = asm3.utils.bytes2str(
                    asm3.dbfs.get_string(dbo, m.MEDIANAME))
                contentpdf = asm3.utils.html_to_pdf(dbo, content)
                attachments = [("%s.pdf" % m.ID, "application/pdf", contentpdf)
                               ]
                fromaddr = asm3.configuration.email(dbo)
                asm3.utils.send_email(dbo, fromaddr, post["email"], "", "",
                                      _("Signed Document", l), m.MEDIANOTES,
                                      "plain", attachments)
            return ("text/plain", 0, 0, "OK")

    else:
        asm3.al.error("invalid method '%s'" % method, "service.handler", dbo)
        raise asm3.utils.ASMError("Invalid method '%s'" % method)
コード例 #11
0
def checkout_adoption_post(dbo, post):
    """
    Called by the adoption checkout frontend with the document signature and donation amount.
    Handles the document signing, triggers creation of the payment records, etc.
    Returns the URL needed to redirect to the payment processor to complete payment.
    """
    l = dbo.locale
    co = asm3.cachedisk.get(post["token"], dbo.database)
    if co is None:
        raise asm3.utils.ASMError("invalid token")
    mediaid = co["mediaid"]
    donationamt = post.integer("donationamt") * 100
    # Sign the docs if they haven't been done already
    if not asm3.media.has_signature(dbo, mediaid):
        signdate = "%s %s" % (python2display(
            l, dbo.now()), format_time(dbo.now()))
        asm3.media.sign_document(dbo, "service", mediaid, post["sig"],
                                 signdate, "signemail")
        if post.boolean("sendsigned"):
            m = asm3.media.get_media_by_id(dbo, mediaid)
            if m is None: raise asm3.utils.ASMError("cannot find %s" % mediaid)
            content = asm3.utils.bytes2str(
                asm3.dbfs.get_string(dbo, m.MEDIANAME))
            contentpdf = asm3.utils.html_to_pdf(dbo, content)
            attachments = [("%s.pdf" % m.ID, "application/pdf", contentpdf)]
            asm3.utils.send_email(dbo, asm3.configuration.email(dbo),
                                  co["email"], "", "", _("Signed Document", l),
                                  m.MEDIANOTES, "plain", attachments)
    # Create the due payment records if they haven't been done already, along with a receipt/payref
    if co["paymentfeeid"] == 0:
        co["paymentprocessor"] = asm3.configuration.adoption_checkout_processor(
            dbo)
        co["receiptnumber"] = asm3.financial.get_next_receipt_number(
            dbo)  # Both go on the same receipt
        co["payref"] = "%s-%s" % (co["personcode"], co["receiptnumber"])
        # Adoption Fee
        co["paymentfeeid"] = asm3.financial.insert_donation_from_form(
            dbo, "checkout",
            asm3.utils.PostedData(
                {
                    "person":
                    str(co["personid"]),
                    "animal":
                    str(co["animalid"]),
                    "movement":
                    str(co["movementid"]),
                    "type":
                    asm3.configuration.adoption_checkout_feeid(dbo),
                    "payment":
                    asm3.configuration.adoption_checkout_payment_method(dbo),
                    "amount":
                    co["fee"],
                    "due":
                    python2display(l, dbo.now()),
                    "receiptnumber":
                    co["receiptnumber"],
                    "giftaid":
                    str(co["giftaid"])
                }, l))
        # Donation (not linked to movement on purpose to avoid showing on adoption fee reports)
        if donationamt > 0:
            co["paymentdonid"] = asm3.financial.insert_donation_from_form(
                dbo, "checkout",
                asm3.utils.PostedData(
                    {
                        "person":
                        str(co["personid"]),
                        "animal":
                        str(co["animalid"]),
                        "type":
                        str(
                            asm3.configuration.adoption_checkout_donationid(
                                dbo)),
                        "payment":
                        str(
                            asm3.configuration.
                            adoption_checkout_payment_method(dbo)),
                        "amount":
                        str(donationamt),
                        "due":
                        python2display(l, dbo.now()),
                        "receiptnumber":
                        co["receiptnumber"],
                        "giftaid":
                        str(co["giftaid"])
                    }, l))
        # Update the cache entry
        asm3.cachedisk.put(post["token"], dbo.database, co, 86400 * 2)
    elif co["paymentdonid"] > 0 and donationamt > 0:
        # payments have already been created, must be a user revisiting the checkout.
        # update their donation amount in case they made a different choice this time.
        dbo.update("ownerdonation", co["paymentdonid"],
                   {"Donation": donationamt}, "checkout")
    elif co["paymentdonid"] > 0 and donationamt == 0:
        # The user has changed their voluntary donation amount to 0 - delete it
        dbo.delete("ownerdonation", co["paymentdonid"], "checkout")
    # Construct the payment checkout URL
    params = {
        "account":
        dbo.database,
        "method":
        "checkout",
        "processor":
        co["paymentprocessor"],
        "payref":
        co["payref"],
        "title":
        _("{0}: Adoption fee") +
        asm3.utils.iif(co["paymentdonid"] != "0", _(" + donation"), "")
    }
    url = "%s?%s" % (SERVICE_URL, asm3.utils.urlencode(params))
    return url