Exemple #1
0
 def test_attach_file_from_form(self):
     data = {
         "animalname": "Testio",
         "estimatedage": "1",
         "animaltype": "1",
         "entryreason": "1",
         "species": "1"
     }
     post = utils.PostedData(data, "en")
     nid, code = animal.insert_animal_from_form(base.get_dbo(), post, "test")
     f = open(base.PATH + "../src/media/reports/nopic.jpg", "rb")
     data = f.read()
     f.close()
     post = utils.PostedData({ "base64image": "data:" + base64.b64encode(data) }, "en")
     media.attach_file_from_form(base.get_dbo(), "test", media.ANIMAL, nid, post)
     animal.delete_animal(base.get_dbo(), "test", nid)
Exemple #2
0
 def test_attach_file_from_form(self):
     data = {
         "animalname": "Testio",
         "estimatedage": "1",
         "animaltype": "1",
         "entryreason": "1",
         "species": "1"
     }
     post = utils.PostedData(data, "en")
     nid, code = animal.insert_animal_from_form(base.get_dbo(), post,
                                                "test")
     f = open(base.PATH + "../src/media/reports/nopic.jpg", "rb")
     data = f.read()
     f.close()
     post = utils.PostedData(
         {
             "filename": "image.jpg",
             "filetype": "image/jpeg",
             "filedata": "data:image/jpeg;base64," + base64.b64encode(data)
         }, "en")
     media.attach_file_from_form(base.get_dbo(), "test", media.ANIMAL, nid,
                                 post)
     animal.delete_animal(base.get_dbo(), "test", nid)
Exemple #3
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")
    seq = post.integer("seq")
    title = post["title"]
    strip_personal = post.integer("sensitive") == 0

    cache_key = querystring.replace(" ", "")

    # Do we have a cached response for these parameters?
    cached_response = get_cached_response(cache_key)
    if cached_response is not None:
        al.debug("cache hit for %s" % (cache_key), "service.handler")
        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")

    dbo = db.get_database(account)

    if dbo.database in ("FAIL", "DISABLED", "WRONGSERVER"):
        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 configuration.service_enabled(dbo):
        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 dbupdate.check_for_updates(dbo):
        dbupdate.perform_updates(dbo)

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

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

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

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

    elif method == "animal_view":
        if utils.cint(animalid) == 0:
            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, "text/html", 86400, 120,
                publishers.html.get_animal_view(dbo, utils.cint(animalid)))

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

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

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

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

    elif method == "json_adoptable_animal":
        if utils.cint(animalid) == 0:
            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:
            users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                       users.VIEW_ANIMAL)
            rs = publishers.base.get_animal_data(
                dbo,
                None,
                utils.cint(animalid),
                include_additional_fields=True)
            return set_cached_response(cache_key, "application/json", 3600,
                                       3600, utils.json(rs))

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

    elif method == "html_adopted_animals":
        return set_cached_response(cache_key, "text/html", 10800, 1800, \
            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, "text/html", 10800, 1800, \
            publishers.html.get_deceased_animals(dbo, daysdeceased=post.integer("days"), style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid")))

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

    elif method == "json_adoptable_animals":
        users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                   users.VIEW_ANIMAL)
        rs = 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, "application/json", 3600, 3600,
                                   utils.json(rs))

    elif method == "jsonp_adoptable_animals":
        users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                   users.VIEW_ANIMAL)
        rs = 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"], utils.json(rs)))

    elif method == "xml_adoptable_animal":
        if utils.cint(animalid) == 0:
            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:
            users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                       users.VIEW_ANIMAL)
            rs = publishers.base.get_animal_data(
                dbo,
                None,
                utils.cint(animalid),
                include_additional_fields=True)
            return set_cached_response(cache_key, "application/xml", 3600,
                                       3600, html.xml(rs))

    elif method == "xml_adoptable_animals":
        users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                   users.VIEW_ANIMAL)
        rs = 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, "application/xml", 3600, 3600,
                                   html.xml(rs))

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    elif method == "sign_document":
        if formid == 0:
            raise utils.ASMError(
                "method sign_document requires a valid formid")
        if post["sig"] == "":
            return set_cached_response(cache_key, "text/html", 2, 2,
                                       sign_document_page(dbo, formid))
        else:
            media.sign_document(dbo, "service", formid, post["sig"],
                                post["signdate"])
            media.create_log(dbo, "service", formid, "ES02",
                             _("Document signed", l))
            return ("text/plain", 0, 0, "OK")

    else:
        al.error("invalid method '%s'" % method, "service.handler", dbo)
        raise utils.ASMError("Invalid method '%s'" % method)
Exemple #4
0
def handler(dbo, user, post):
    """
    Handles posts from the frontend. Depending on the type we either
    return more HTML for the javascript to inject, or GO URL to have
    the controller redirect to URL
    """
    l = dbo.locale
    homelink = "<a href='mobile' class='ui-btn-right' data-icon='home' data-theme='b'>%s</a>" % _(
        "Home", l)
    mode = post["posttype"]
    pid = post.integer("id")
    animalid = post.integer("animalid")

    if mode == "vacc":
        # We're vaccinating an animal
        a = animal.get_animal(dbo, animalid)
        medical.update_vaccination_today(dbo, user, pid)
        return jqm_page_header("", _("Vaccination Given", l), homelink) + \
            jqm_p(_("Vaccination marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + \
            jqm_button("mobile#vacc", _("More Vaccinations", l), "", "false") + \
            jqm_page_footer()

    if mode == "test":
        # We're performing a test on an animal
        a = animal.get_animal(dbo, animalid)
        medical.update_test_today(dbo, user, pid, post.integer("resultid"))
        return jqm_page_header("", _("Test Performed", l), homelink) + \
            jqm_p(_("Test marked as performed for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + \
            jqm_button("mobile#test", _("More Tests", l), "", "false") + \
            jqm_page_footer()

    elif mode == "med":
        # We're treating an animal
        a = animal.get_animal(dbo, animalid)
        medical.update_treatment_today(dbo, user, pid)
        return jqm_page_header("", _("Treatment Given", l), homelink) + \
            jqm_p(_("Treatment marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + \
            jqm_button("mobile#med", _("More Medications", l), "", "false") + \
            jqm_page_footer()

    elif mode == "dia":
        # We're completing a diary task
        d = diary.get_diary(dbo, pid)
        if post["on"] == "0":
            diary.complete_diary_note(dbo, user, pid)
            return jqm_page_header("", _("Completed", l), homelink) + \
                jqm_p(_("Diary note {0} marked completed", l).format(d["SUBJECT"])) + \
                jqm_button("mobile#diary", _("More diary notes", l), "", "false") + \
                jqm_page_footer()
        else:
            diary.rediarise_diary_note(dbo, user, pid, post.date("on"))
            return jqm_page_header("", _("Rediarised", l), homelink) + \
                jqm_p(_("Diary note {0} rediarised for {1}", l).format(d["SUBJECT"], post["on"])) + \
                jqm_button("mobile#diary", _("More diary notes", l), "", "false") + \
                jqm_page_footer()

    elif mode == "dianew":
        # We're adding a diary note
        diary.insert_diary(dbo, user, 0, 0, post.date("diarydate"),
                           post["diaryfor"], post["subject"], post["note"])
        return "GO mobile"

    elif mode == "message":
        # We're adding a message
        lookups.add_message(dbo, user, post.boolean("email"), post["message"],
                            post["forname"], post.integer("priority"),
                            post.date("expires"))
        return "GO mobile"

    elif mode == "log":
        # We're adding a log to an animal
        a = animal.get_animal(dbo, animalid)
        log.add_log(dbo, user, log.ANIMAL, animalid, post.integer("logtypeid"),
                    post["logtext"])
        return "GO mobile"

    elif mode == "hc":
        # We're marking an owner homechecked
        person.update_pass_homecheck(dbo, user, post.integer("personid"),
                                     post["comments"])
        return "GO mobile"

    elif mode == "vsa":
        # Return a list of the shelter animals
        h = []
        alin = []
        h.append(header(l))
        h.append(jqm_page_header("", _("Shelter Animals", l), homelink))
        an = animal.get_animal_find_simple(dbo, "", "all")
        for a in an:
            alin.append(
                jqm_listitem_link(
                    "mobile_post?posttype=va&id=%d" % a["ID"],
                    "%s - %s (%s %s %s) %s" %
                    (a["CODE"], a["ANIMALNAME"], a["SEXNAME"], a["BREEDNAME"],
                     a["SPECIESNAME"], a["IDENTICHIPNUMBER"]), "animal"))
        h.append(jqm_list("\n".join(alin), True))
        h.append(jqm_page_footer())
        h.append("</body></html>")
        return "\n".join(h)

    elif mode == "uai":
        # Upload an animal image
        media.attach_file_from_form(dbo, user, media.ANIMAL, animalid,
                                    post.data)
        return "GO mobile_post?posttype=va&id=%d&success=true" % animalid

    elif mode == "va":
        # Display a page containing the selected animal by id
        a = animal.get_animal(dbo, pid)
        af = additional.get_additional_fields(dbo, pid, "animal")
        return handler_viewanimal(l, a, af, homelink, post)
Exemple #5
0
def handler(dbo, user, post):
    """
    Handles posts from the frontend. Depending on the type we either
    return more HTML for the javascript to inject, or GO URL to have
    the controller redirect to URL
    """
    l = dbo.locale
    homelink = "<a href='mobile' class='ui-btn-right' data-icon='home' data-theme='b'>%s</a>" % _("Home", l)
    mode = post["posttype"]
    pid = post.integer("id")
    animalid = post.integer("animalid")

    if mode == "vacc":
        # We're vaccinating an animal
        a = animal.get_animal(dbo, animalid)
        medical.update_vaccination_today(dbo, user, pid)
        return (
            jqm_page_header("", _("Vaccination Given", l), homelink)
            + jqm_p(_("Vaccination marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"]))
            + jqm_button("mobile#vacc", _("More Vaccinations", l), "", "false")
            + jqm_page_footer()
        )

    if mode == "test":
        # We're performing a test on an animal
        a = animal.get_animal(dbo, animalid)
        medical.update_test_today(dbo, user, pid, post.integer("resultid"))
        return (
            jqm_page_header("", _("Test Performed", l), homelink)
            + jqm_p(_("Test marked as performed for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"]))
            + jqm_button("mobile#test", _("More Tests", l), "", "false")
            + jqm_page_footer()
        )

    elif mode == "med":
        # We're treating an animal
        a = animal.get_animal(dbo, animalid)
        medical.update_treatment_today(dbo, user, pid)
        return (
            jqm_page_header("", _("Treatment Given", l), homelink)
            + jqm_p(_("Treatment marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"]))
            + jqm_button("mobile#med", _("More Medications", l), "", "false")
            + jqm_page_footer()
        )

    elif mode == "dia":
        # We're completing a diary task
        d = diary.get_diary(dbo, pid)
        if post["on"] == "0":
            diary.complete_diary_note(dbo, user, pid)
            return (
                jqm_page_header("", _("Completed", l), homelink)
                + jqm_p(_("Diary note {0} marked completed", l).format(d["SUBJECT"]))
                + jqm_button("mobile#diary", _("More diary notes", l), "", "false")
                + jqm_page_footer()
            )
        else:
            diary.rediarise_diary_note(dbo, user, pid, post.date("on"))
            return (
                jqm_page_header("", _("Rediarised", l), homelink)
                + jqm_p(_("Diary note {0} rediarised for {1}", l).format(d["SUBJECT"], post["on"]))
                + jqm_button("mobile#diary", _("More diary notes", l), "", "false")
                + jqm_page_footer()
            )

    elif mode == "dianew":
        # We're adding a diary note
        diary.insert_diary(dbo, user, 0, 0, post.date("diarydate"), post["diaryfor"], post["subject"], post["note"])
        return "GO mobile"

    elif mode == "message":
        # We're adding a message
        lookups.add_message(
            dbo,
            user,
            post.boolean("email"),
            post["message"],
            post["forname"],
            post.integer("priority"),
            post.date("expires"),
        )
        return "GO mobile"

    elif mode == "log":
        # We're adding a log to an animal
        a = animal.get_animal(dbo, animalid)
        log.add_log(dbo, user, log.ANIMAL, animalid, post.integer("logtypeid"), post["logtext"])
        return "GO mobile"

    elif mode == "hc":
        # We're marking an owner homechecked
        person.update_pass_homecheck(dbo, user, post.integer("personid"), post["comments"])
        return "GO mobile"

    elif mode == "vsa":
        # Return a list of the shelter animals
        h = []
        alin = []
        h.append(header(l))
        h.append(jqm_page_header("", _("Shelter Animals", l), homelink))
        an = animal.get_animal_find_simple(dbo, "", "all")
        for a in an:
            alin.append(
                jqm_listitem_link(
                    "mobile_post?posttype=va&id=%d" % a["ID"],
                    "%s - %s (%s %s %s) %s"
                    % (
                        a["CODE"],
                        a["ANIMALNAME"],
                        a["SEXNAME"],
                        a["BREEDNAME"],
                        a["SPECIESNAME"],
                        a["IDENTICHIPNUMBER"],
                    ),
                    "animal",
                )
            )
        h.append(jqm_list("\n".join(alin), True))
        h.append(jqm_page_footer())
        h.append("</body></html>")
        return "\n".join(h)

    elif mode == "uai":
        # Upload an animal image
        media.attach_file_from_form(dbo, user, media.ANIMAL, animalid, post.data)
        return "GO mobile_post?posttype=va&id=%d&success=true" % animalid

    elif mode == "va":
        # Display a page containing the selected animal by id
        a = animal.get_animal(dbo, pid)
        af = additional.get_additional_fields(dbo, pid, "animal")
        return handler_viewanimal(l, a, af, homelink, post)
Exemple #6
0
def csvimport(dbo, csvdata, encoding = "utf8", user = "", createmissinglookups = False, cleartables = False, checkduplicates = False):
    """
    Imports the csvdata.
    createmissinglookups: If a lookup value is given that's not in our data, add it
    cleartables: Clear down the animal, owner and adoption tables before import
    """

    # Convert line endings to standard unix lf to prevent
    # the Python CSV importer barfing.
    csvdata = csvdata.replace("\r\n", "\n")
    csvdata = csvdata.replace("\r", "\n")

    if user == "":
        user = "******"
    else:
        user = "******" % user

    reader = None
    if encoding == "utf8":
        reader = utils.UnicodeCSVReader(StringIO(csvdata))
    else:
        reader = utils.UnicodeCSVReader(StringIO(csvdata), encoding=encoding)

    # Make sure we have a valid header
    cols = None
    for row in reader:
        cols = row
        break
    if cols is None:
        asynctask.set_last_error(dbo, "Your CSV file is empty")
        return

    onevalid = False
    hasanimal = False
    hasanimalname = False
    hasmed = False
    hasvacc = False
    hasperson = False
    haspersonlastname = False
    haspersonname = False
    haslicence = False
    haslicencenumber = False
    hasmovement = False
    hasmovementdate = False
    hasdonation = False
    hasdonationamount = False
    hasoriginalowner = False
    hasoriginalownerlastname = False
    for col in cols:
        if col in VALID_FIELDS: onevalid = True
        if col.startswith("ANIMAL"): hasanimal = True
        if col == "ANIMALNAME": hasanimalname = True
        if col.startswith("ORIGINALOWNER"): hasoriginalowner = True
        if col.startswith("VACCINATION"): hasvacc = True
        if col.startswith("MEDICAL"): hasmed = True
        if col.startswith("LICENSE"): haslicence = True
        if col == "LICENSENUMBER": haslicencenumber = True
        if col == "ORIGINALOWNERLASTNAME": hasoriginalownerlastname = True
        if col.startswith("PERSON"): hasperson = True
        if col == "PERSONLASTNAME": haspersonlastname = True
        if col == "PERSONNAME": haspersonname = True
        if col.startswith("MOVEMENT"): hasmovement = True
        if col == "MOVEMENTDATE": hasmovementdate = True
        if col.startswith("DONATION"): hasdonation = True
        if col == "DONATIONAMOUNT": hasdonationamount = True

    # Any valid fields?
    if not onevalid:
        asynctask.set_last_error(dbo, "Your CSV file did not contain any fields that ASM recognises")
        return

    # If we have any animal fields, make sure at least ANIMALNAME is supplied
    if hasanimal and not hasanimalname:
        asynctask.set_last_error(dbo, "Your CSV file has animal fields, but no ANIMALNAME column")
        return

    # If we have any person fields, make sure at least PERSONLASTNAME or PERSONNAME is supplied
    if hasperson and not haspersonlastname and not haspersonname:
        asynctask.set_last_error(dbo, "Your CSV file has person fields, but no PERSONNAME or PERSONLASTNAME column")
        return

    # If we have any original owner fields, make sure at least ORIGINALOWNERLASTNAME is supplied
    if hasoriginalowner and not hasoriginalownerlastname:
        asynctask.set_last_error(dbo, "Your CSV file has original owner fields, but no ORIGINALOWNERLASTNAME column")
        return

    # If we have any movement fields, make sure MOVEMENTDATE is supplied
    if hasmovement and not hasmovementdate:
        asynctask.set_last_error(dbo, "Your CSV file has movement fields, but no MOVEMENTDATE column")
        return

    # If we have any donation fields, we need an amount
    if hasdonation and not hasdonationamount:
        asynctask.set_last_error(dbo, "Your CSV file has donation fields, but no DONATIONAMOUNT column")
        return

    # We also need a valid person
    if hasdonation and not (haspersonlastname or haspersonname):
        asynctask.set_last_error(dbo, "Your CSV file has donation fields, but no person to apply the donation to")
        return

    # If we have any med fields, we need an animal
    if hasmed and not hasanimal:
        asynctask.set_last_error(dbo, "Your CSV file has medical fields, but no animal to apply them to")
        return

    # If we have any vacc fields, we need an animal
    if hasvacc and not hasanimal:
        asynctask.set_last_error(dbo, "Your CSV file has vaccination fields, but no animal to apply them to")
        return

    # If we have licence fields, we need a number
    if haslicence and not haslicencenumber:
        asynctask.set_last_error(dbo, "Your CSV file has license fields, but no LICENSENUMBER column")
        return

    # We also need a valid person
    if haslicence and not (haspersonlastname or haspersonname):
        asynctask.set_last_error(dbo, "Your CSV file has license fields, but no person to apply the license to")

    # Read the whole CSV file into a list of maps. Note, the
    # reader has a cursor at the second row already because
    # we read the header in the first row above
    data = []
    for row in reader:
        currow = {}
        for i, col in enumerate(row):
            if i >= len(cols): continue # skip if we run out of cols
            currow[cols[i]] = col
        data.append(currow)

    al.debug("reading CSV data, found %d rows" % len(data), "csvimport.csvimport", dbo)

    # If we're clearing down tables first, do it now
    if cleartables:
        al.warn("Resetting the database by removing all non-lookup data", "csvimport.csvimport", dbo)
        dbupdate.reset_db(dbo)

    # Now that we've read them in, go through all the rows
    # and start importing.
    errors = []
    rowno = 1
    asynctask.set_progress_max(dbo, len(data))
    for row in data:

        al.debug("import csv: row %d of %d" % (rowno, len(data)), "csvimport.csvimport", dbo)
        asynctask.increment_progress_value(dbo)

        # Should we stop?
        if asynctask.get_cancel(dbo): break

        # Do we have animal data to read?
        animalid = 0
        if hasanimal and gks(row, "ANIMALNAME") != "":
            a = {}
            a["animalname"] = gks(row, "ANIMALNAME")
            a["sheltercode"] = gks(row, "ANIMALCODE")
            a["shortcode"] = gks(row, "ANIMALCODE")
            if gks(row, "ANIMALSEX") == "": 
                a["sex"] = "2" # Default unknown if not set
            else:
                a["sex"] = gks(row, "ANIMALSEX").lower().startswith("m") and "1" or "0"
            a["basecolour"] = gkl(dbo, row, "ANIMALCOLOR", "basecolour", "BaseColour", createmissinglookups)
            if a["basecolour"] == "0":
                a["basecolour"] = str(configuration.default_colour(dbo))
            a["species"] = gkl(dbo, row, "ANIMALSPECIES", "species", "SpeciesName", createmissinglookups)
            if a["species"] == "0":
                a["species"] = str(configuration.default_species(dbo))
            a["animaltype"] = gkl(dbo, row, "ANIMALTYPE", "animaltype", "AnimalType", createmissinglookups)
            if a["animaltype"] == "0":
                a["animaltype"] = str(configuration.default_type(dbo))
            a["breed1"] = gkbr(dbo, row, "ANIMALBREED1", a["species"], createmissinglookups)
            if a["breed1"] == "0":
                a["breed1"] = str(configuration.default_breed(dbo))
            a["breed2"] = gkbr(dbo, row, "ANIMALBREED2", a["species"], createmissinglookups)
            if a["breed2"] != "0" and a["breed2"] != a["breed1"]:
                a["crossbreed"] = "on"
            a["size"] = gkl(dbo, row, "ANIMALSIZE", "lksize", "Size", False)
            if gks(row, "ANIMALSIZE") == "": 
                a["size"] = str(configuration.default_size(dbo))
            a["internallocation"] = gkl(dbo, row, "ANIMALLOCATION", "internallocation", "LocationName", createmissinglookups)
            if a["internallocation"] == "0":
                a["internallocation"] = str(configuration.default_location(dbo))
            a["unit"] = gks(row, "ANIMALUNIT")
            a["comments"] = gks(row, "ANIMALCOMMENTS")
            a["markings"] = gks(row, "ANIMALMARKINGS")
            a["hiddenanimaldetails"] = gks(row, "ANIMALHIDDENDETAILS")
            a["healthproblems"] = gks(row, "ANIMALHEALTHPROBLEMS")
            a["notforadoption"] = gkbi(row, "ANIMALNOTFORADOPTION")
            a["nonshelter"] = gkbi(row, "ANIMALNONSHELTER")
            a["housetrained"] = gkynu(row, "ANIMALHOUSETRAINED")
            a["goodwithcats"] = gkynu(row, "ANIMALGOODWITHCATS")
            a["goodwithdogs"] = gkynu(row, "ANIMALGOODWITHDOGS")
            a["goodwithkids"] = gkynu(row, "ANIMALGOODWITHKIDS")
            a["reasonforentry"] = gks(row, "ANIMALREASONFORENTRY")
            a["estimatedage"] = gks(row, "ANIMALAGE")
            a["dateofbirth"] = gkd(dbo, row, "ANIMALDOB", True)
            if gks(row, "ANIMALDOB") == "" and a["estimatedage"] != "":
                a["dateofbirth"] = "" # if we had an age and dob was blank, prefer the age
            a["datebroughtin"] = gkd(dbo, row, "ANIMALENTRYDATE", True)
            a["deceaseddate"] = gkd(dbo, row, "ANIMALDECEASEDDATE")
            a["neutered"] = gkbc(row, "ANIMALNEUTERED")
            a["neutereddate"] = gkd(dbo, row, "ANIMALNEUTEREDDATE")
            if a["neutereddate"] != "": a["neutered"] = "on"
            a["microchipnumber"] = gks(row, "ANIMALMICROCHIP")
            if a["microchipnumber"] != "": a["microchipped"] = "on"
            a["microchipdate"] = gkd(dbo, row, "ANIMALMICROCHIPDATE")
            # image data if any was supplied
            imagedata = gks(row, "ANIMALIMAGE")
            if imagedata.startswith("http"):
                # It's a URL, get the image from the remote server
                r = utils.get_image_url(imagedata, timeout=5000)
                if r["status"] == 200:
                    al.debug("retrieved image from %s (%s bytes)" % (imagedata, len(r["response"])), "csvimport.csvimport", dbo)
                    imagedata = "data:image/jpeg;base64,%s" % base64.b64encode(r["response"])
                else:
                    row_error(errors, "animal", rowno, row, "error reading image from '%s': %s" % (imagedata, r), dbo, sys.exc_info())
                    continue
            elif imagedata.startswith("data:image"):
                # It's a base64 encoded data URI - do nothing as attach_file requires it
                pass
            else:
                # We don't know what it is, don't try and do anything with it
                imagedata = ""
            # If an original owner is specified, create a person record
            # for them and attach it to the animal as original owner
            if gks(row, "ORIGINALOWNERLASTNAME") != "":
                p = {}
                p["title"] = gks(row, "ORIGINALOWNERTITLE")
                p["initials"] = gks(row, "ORIGINALOWNERINITIALS")
                p["forenames"] = gks(row, "ORIGINALOWNERFIRSTNAME")
                p["surname"] = gks(row, "ORIGINALOWNERLASTNAME")
                p["address"] = gks(row, "ORIGINALOWNERADDRESS")
                p["town"] = gks(row, "ORIGINALOWNERCITY")
                p["county"] = gks(row, "ORIGINALOWNERSTATE")
                p["postcode"] = gks(row, "ORIGINALOWNERZIPCODE")
                p["jurisdiction"] = gkl(dbo, row, "ORIGINALOWNERJURISDICTION", "jurisdiction", "JurisdictionName", createmissinglookups)
                p["hometelephone"] = gks(row, "ORIGINALOWNERHOMEPHONE")
                p["worktelephone"] = gks(row, "ORIGINALOWNERWORKPHONE")
                p["mobiletelephone"] = gks(row, "ORIGINALOWNERCELLPHONE")
                p["emailaddress"] = gks(row, "ORIGINALOWNEREMAIL")
                try:
                    if checkduplicates:
                        dups = person.get_person_similar(dbo, p["emailaddress"], p["surname"], p["forenames"], p["address"])
                        if len(dups) > 0:
                            a["originalowner"] = str(dups[0]["ID"])
                    if "originalowner" not in a:
                        ooid = person.insert_person_from_form(dbo, utils.PostedData(p, dbo.locale), user, geocode=False)
                        a["originalowner"] = str(ooid)
                        # Identify an ORIGINALOWNERADDITIONAL additional fields and create them
                        create_additional_fields(dbo, row, errors, rowno, "ORIGINALOWNERADDITIONAL", "person", ooid)
                except Exception as e:
                    row_error(errors, "originalowner", rowno, row, e, dbo, sys.exc_info())
            try:
                if checkduplicates:
                    dup = animal.get_animal_sheltercode(dbo, a["sheltercode"])
                    if dup is not None:
                        animalid = dup["ID"]
                if animalid == 0:
                    animalid, newcode = animal.insert_animal_from_form(dbo, utils.PostedData(a, dbo.locale), user)
                    # Identify any ANIMALADDITIONAL additional fields and create them
                    create_additional_fields(dbo, row, errors, rowno, "ANIMALADDITIONAL", "animal", animalid)
                # If we have some image data, add it to the animal
                if len(imagedata) > 0:
                    imagepost = utils.PostedData({ "filename": "image.jpg", "filetype": "image/jpeg", "filedata": imagedata }, dbo.locale)
                    media.attach_file_from_form(dbo, user, media.ANIMAL, animalid, imagepost)
            except Exception as e:
                row_error(errors, "animal", rowno, row, e, dbo, sys.exc_info())

        # Person data?
        personid = 0
        if hasperson and (gks(row, "PERSONLASTNAME") != "" or gks(row, "PERSONNAME") != ""):
            p = {}
            p["ownertype"] = gks(row, "PERSONCLASS")
            if p["ownertype"] != "1" and p["ownertype"] != "2": 
                p["ownertype"] = "1"
            p["title"] = gks(row, "PERSONTITLE")
            p["initials"] = gks(row, "PERSONINITIALS")
            p["forenames"] = gks(row, "PERSONFIRSTNAME")
            p["surname"] = gks(row, "PERSONLASTNAME")
            # If we have a person name, all upto the last space is first names,
            # everything after the last name
            if gks(row, "PERSONNAME") != "":
                pname = gks(row, "PERSONNAME")
                if pname.find(" ") != -1:
                    p["forenames"] = pname[0:pname.rfind(" ")]
                    p["surname"] = pname[pname.rfind(" ")+1:]
                else:
                    p["surname"] = pname
            p["address"] = gks(row, "PERSONADDRESS")
            p["town"] = gks(row, "PERSONCITY")
            p["county"] = gks(row, "PERSONSTATE")
            p["postcode"] = gks(row, "PERSONZIPCODE")
            p["jurisdiction"] = gkl(dbo, row, "PERSONJURISDICTION", "jurisdiction", "JurisdictionName", createmissinglookups)
            p["hometelephone"] = gks(row, "PERSONHOMEPHONE")
            p["worktelephone"] = gks(row, "PERSONWORKPHONE")
            p["mobiletelephone"] = gks(row, "PERSONCELLPHONE")
            p["emailaddress"] = gks(row, "PERSONEMAIL")
            p["gdprcontactoptin"] = gks(row, "PERSONGDPRCONTACTOPTIN")
            flags = gks(row, "PERSONFLAGS")
            if gkb(row, "PERSONFOSTERER"): flags += ",fosterer"
            if gkb(row, "PERSONMEMBER"): flags += ",member"
            if gkb(row, "PERSONDONOR"): flags += ",donor"
            p["flags"] = flags
            p["comments"] = gks(row, "PERSONCOMMENTS")
            p["membershipnumber"] = gks(row, "PERSONMEMBERSHIPNUMBER")
            p["membershipexpires"] = gkd(dbo, row, "PERSONMEMBERSHIPEXPIRY")
            p["matchactive"] = gkbi(row, "PERSONMATCHACTIVE")
            if p["matchactive"] == "1":
                if "PERSONMATCHADDED" in cols: p["matchadded"] = gkd(dbo, row, "PERSONMATCHADDED")
                if "PERSONMATCHEXPIRES" in cols: p["matchexpires"] = gkd(dbo, row, "PERSONMATCHEXPIRES")
                if "PERSONMATCHSEX" in cols: p["matchsex"] = gks(row, "PERSONMATCHSEX").lower().startswith("m") and "1" or "0"
                if "PERSONMATCHSIZE" in cols: p["matchsize"] = gkl(dbo, row, "PERSONMATCHSIZE", "lksize", "Size", False)
                if "PERSONMATCHCOLOR" in cols: p["matchcolour"] = gkl(dbo, row, "PERSONMATCHCOLOR", "basecolour", "BaseColour", createmissinglookups)
                if "PERSONMATCHAGEFROM" in cols: p["matchagefrom"] = gks(row, "PERSONMATCHAGEFROM")
                if "PERSONMATCHAGETO" in cols: p["matchageto"] = gks(row, "PERSONMATCHAGETO")
                if "PERSONMATCHTYPE" in cols: p["matchanimaltype"] = gkl(dbo, row, "PERSONMATCHTYPE", "animaltype", "AnimalType", createmissinglookups)
                if "PERSONMATCHSPECIES" in cols: p["matchspecies"] = gkl(dbo, row, "PERSONMATCHSPECIES", "species", "SpeciesName", createmissinglookups)
                if "PERSONMATCHBREED1" in cols: p["matchbreed"] = gkbr(dbo, row, "PERSONMATCHBREED1", p["matchspecies"], createmissinglookups)
                if "PERSONMATCHBREED2" in cols: p["matchbreed2"] = gkbr(dbo, row, "PERSONMATCHBREED2", p["matchspecies"], createmissinglookups)
                if "PERSONMATCHGOODWITHCATS" in cols: p["matchgoodwithcats"] = gkynu(row, "PERSONMATCHGOODWITHCATS")
                if "PERSONMATCHGOODWITHDOGS" in cols: p["matchgoodwithdogs"] = gkynu(row, "PERSONMATCHGOODWITHDOGS")
                if "PERSONMATCHGOODWITHCHILDREN" in cols: p["matchgoodwithchildren"] = gkynu(row, "PERSONMATCHGOODWITHCHILDREN")
                if "PERSONMATCHHOUSETRAINED" in cols: p["matchhousetrained"] = gkynu(row, "PERSONMATCHHOUSETRAINED")
                if "PERSONMATCHCOMMENTSCONTAIN" in cols: p["matchcommentscontain"] = gks(row, "PERSONMATCHCOMMENTSCONTAIN")
            try:
                if checkduplicates:
                    dups = person.get_person_similar(dbo, p["emailaddress"], p["surname"], p["forenames"], p["address"])
                    if len(dups) > 0:
                        personid = dups[0].ID
                        # Merge flags and any extra details
                        person.merge_flags(dbo, user, personid, flags)
                        person.merge_gdpr_flags(dbo, user, personid, p["gdprcontactoptin"])
                        # If we deduplicated on the email address, and address details are
                        # present, assume that they are newer than the ones we had and update them
                        # (we do this by setting force=True parameter to merge_person_details,
                        # otherwise we do a regular merge which only fills in any blanks)
                        person.merge_person_details(dbo, user, personid, p, force=dups[0].EMAILADDRESS == p["emailaddress"])
                if personid == 0:
                    personid = person.insert_person_from_form(dbo, utils.PostedData(p, dbo.locale), user, geocode=False)
                    # Identify any PERSONADDITIONAL additional fields and create them
                    create_additional_fields(dbo, row, errors, rowno, "PERSONADDITIONAL", "person", personid)
            except Exception as e:
                row_error(errors, "person", rowno, row, e, dbo, sys.exc_info())

        # Movement to tie animal/person together?
        movementid = 0
        if hasmovement and personid != 0 and animalid != 0 and gks(row, "MOVEMENTDATE") != "":
            m = {}
            m["person"] = str(personid)
            m["animal"] = str(animalid)
            movetype = gks(row, "MOVEMENTTYPE")
            if movetype == "": movetype = "1" # Default to adoption if not supplied
            m["type"] = str(movetype)
            m["movementdate"] = gkd(dbo, row, "MOVEMENTDATE", True)
            m["returndate"] = gkd(dbo, row, "MOVEMENTRETURNDATE")
            m["comments"] = gks(row, "MOVEMENTCOMMENTS")
            m["returncategory"] = str(configuration.default_entry_reason(dbo))
            try:
                movementid = movement.insert_movement_from_form(dbo, user, utils.PostedData(m, dbo.locale))
            except Exception as e:
                row_error(errors, "movement", rowno, row, e, dbo, sys.exc_info())

        # Donation?
        if hasdonation and personid != 0 and gkc(row, "DONATIONAMOUNT") != 0:
            d = {}
            d["person"] = str(personid)
            d["animal"] = str(animalid)
            d["movement"] = str(movementid)
            d["amount"] = str(gkc(row, "DONATIONAMOUNT"))
            d["fee"] = str(gkc(row, "DONATIONFEE"))
            d["comments"] = gks(row, "DONATIONCOMMENTS")
            d["received"] = gkd(dbo, row, "DONATIONDATE", True)
            d["chequenumber"] = gks(row, "DONATIONCHECKNUMBER")
            d["type"] = gkl(dbo, row, "DONATIONTYPE", "donationtype", "DonationName", createmissinglookups)
            if d["type"] == "0":
                d["type"] = str(configuration.default_donation_type(dbo))
            d["payment"] = gkl(dbo, row, "DONATIONPAYMENT", "donationpayment", "PaymentName", createmissinglookups)
            if d["payment"] == "0":
                d["payment"] = "1"
            try:
                financial.insert_donation_from_form(dbo, user, utils.PostedData(d, dbo.locale))
            except Exception as e:
                row_error(errors, "payment", rowno, row, e, dbo, sys.exc_info())
            if movementid != 0: movement.update_movement_donation(dbo, movementid)

        # Vaccination?
        if hasvacc and animalid != 0 and gks(row, "VACCINATIONDUEDATE") != "":
            v = {}
            v["animal"] = str(animalid)
            v["type"] = gkl(dbo, row, "VACCINATIONTYPE", "vaccinationtype", "VaccinationType", createmissinglookups)
            if v["type"] == "0":
                v["type"] = str(configuration.default_vaccination_type(dbo))
            v["required"] = gkd(dbo, row, "VACCINATIONDUEDATE", True)
            v["given"] = gkd(dbo, row, "VACCINATIONGIVENDATE")
            v["expires"] = gkd(dbo, row, "VACCINATIONEXPIRESDATE")
            v["batchnumber"] = gks(row, "VACCINATIONBATCHNUMBER")
            v["manufacturer"] = gks(row, "VACCINATIONMANUFACTURER")
            v["comments"] = gks(row, "VACCINATIONCOMMENTS")
            try:
                medical.insert_vaccination_from_form(dbo, user, utils.PostedData(v, dbo.locale))
            except Exception as e:
                row_error(errors, "vaccination", rowno, row, e, dbo, sys.exc_info())

        # Medical?
        if hasmed and animalid != 0 and gks(row, "MEDICALGIVENDATE") != "" and gks(row, "MEDICALNAME") != "":
            m = {}
            m["animal"] = str(animalid)
            m["treatmentname"] = gks(row, "MEDICALNAME")
            m["dosage"] = gks(row, "MEDICALDOSAGE")
            m["startdate"] = gkd(dbo, row, "MEDICALGIVENDATE")
            m["comments"] = gks(row, "MEDICALCOMMENTS")
            m["singlemulti"] = "0" # single treatment
            m["status"] = "2" # completed
            try:
                medical.insert_regimen_from_form(dbo, user, utils.PostedData(m, dbo.locale))
            except Exception as e:
                row_error(errors, "medical", rowno, row, e, dbo, sys.exc_info())

        # License?
        if haslicence and personid != 0 and gks(row, "LICENSENUMBER") != "":
            l = {}
            l["person"] = str(personid)
            l["animal"] = str(animalid)
            l["type"] = gkl(dbo, row, "LICENSETYPE", "licencetype", "LicenceTypeName", createmissinglookups)
            if l["type"] == "0": l["type"] = 1
            l["number"] = gks(row, "LICENSENUMBER")
            l["fee"] = str(gkc(row, "LICENSEFEE"))
            l["issuedate"] = gkd(dbo, row, "LICENSEISSUEDATE")
            l["expirydate"] = gkd(dbo, row, "LICENSEEXPIRESDATE")
            l["comments"] = gks(row, "LICENSECOMMENTS")
            try:
                financial.insert_licence_from_form(dbo, user, utils.PostedData(l, dbo.locale))
            except Exception as e:
                row_error(errors, "license", rowno, row, e, dbo, sys.exc_info())

        rowno += 1

    h = [ "<p>%d success, %d errors</p><table>" % (len(data) - len(errors), len(errors)) ]
    for rowno, row, err in errors:
        h.append("<tr><td>%s</td><td>%s</td><td>%s</td></tr>" % (rowno, row, err))
    h.append("</table>")
    return "".join(h)
Exemple #7
0
def handler(data, remoteip, referer):
    """
    Handles the various service method types.
    data: The GET/POST parameters 
    return value is a tuple containing MIME type, max-age, content
    """
    # Database info
    dbo = db.DatabaseInfo()

    # Get service parameters
    account = utils.df_ks(data, "account")
    username = utils.df_ks(data, "username")
    password = utils.df_ks(data, "password")
    method = utils.df_ks(data, "method")
    animalid = utils.df_ki(data, "animalid")
    formid = utils.df_ki(data, "formid")
    title = utils.df_ks(data, "title")
    cache_key = "a" + account + "u" + username + "p" + password + "m" + method + "a" + str(
        animalid) + "f" + str(formid) + "t" + title

    # cache keys aren't allowed spaces
    cache_key = cache_key.replace(" ", "")

    # Do we have a cached response for these parameters?
    cached_response = get_cached_response(cache_key)
    if cached_response is not None:
        al.debug(
            "cache hit for %s/%s/%s/%s" % (account, method, animalid, title),
            "service.handler")
        return cached_response

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

    # Are we dealing with multiple databases and an account was specified?
    if account != "":
        if MULTIPLE_DATABASES:
            if MULTIPLE_DATABASES_TYPE == "smcom":
                # Is this sheltermanager.com? If so, we need to get the
                # database connection info (dbo) before we can login.
                dbo = smcom.get_database_info(account)
            else:
                # Look up the database info from our map
                dbo = db.get_multiple_database_info(account)
            if dbo.database == "FAIL" or dbo.database == "DISABLED":
                al.error(
                    "auth failed - invalid smaccount %s from %s" %
                    (account, remoteip), "service.handler", dbo)
                return ("text/plain", 0, "ERROR: Invalid database")

    # Does the method require us to authenticate? If so, do it.
    user = None
    if method in AUTH_METHODS:
        user = users.authenticate(dbo, username, password)
        if user is None:
            al.error(
                "auth failed - %s/%s is not a valid username/password from %s"
                % (username, password, remoteip), "service.handler", dbo)
            return ("text/plain", 0, "ERROR: Invalid username and password")

    # Get the preferred locale for the site
    dbo.locale = configuration.locale(dbo)
    al.info("call %s->%s [%s %s]" % (username, method, str(animalid), title),
            "service.handler", dbo)

    if method == "animal_image":
        # If we have a hotlinking restriction, enforce it
        if referer != "" and IMAGE_HOTLINKING_ONLY_FROM_DOMAIN != "" and referer.find(
                IMAGE_HOTLINKING_ONLY_FROM_DOMAIN) == -1:
            raise utils.ASMPermissionError("Image hotlinking is forbidden.")
        if animalid == "" or utils.cint(animalid) == 0:
            al.error(
                "animal_image failed, %s is not an animalid" % str(animalid),
                "service.handler", dbo)
            return ("text/plain", 0, "ERROR: Invalid animalid")
        # If the option is on, forbid hotlinking
        else:
            seq = utils.df_ki(data, "seq")
            if seq == 0: seq = 1
            mm = media.get_media_by_seq(dbo, media.ANIMAL,
                                        utils.cint(animalid), seq)
            if len(mm) == 0:
                return ("image/jpeg", 86400,
                        dbfs.get_string(dbo, "nopic.jpg", "/reports"))
            else:
                return ("image/jpeg", 86400,
                        dbfs.get_string(dbo, mm[0]["MEDIANAME"]))

    elif method == "extra_image":
        return ("image/jpeg", 86400, dbfs.get_string(dbo, title, "/reports"))

    elif method == "json_adoptable_animals":
        pc = publish.PublishCriteria(configuration.publisher_presets(dbo))
        rs = publish.get_animal_data(dbo, pc, True)
        return set_cached_response(cache_key, "application/json", 3600,
                                   html.json(rs))

    elif method == "xml_adoptable_animals":
        pc = publish.PublishCriteria(configuration.publisher_presets(dbo))
        rs = publish.get_animal_data(dbo, pc, True)
        return set_cached_response(cache_key, "application/xml", 3600,
                                   html.xml(rs))

    elif method == "json_recent_adoptions":
        rs = movement.get_recent_adoptions(dbo)
        return set_cached_response(cache_key, "application/json", 3600,
                                   html.json(rs))

    elif method == "xml_recent_adoptions":
        rs = movement.get_recent_adoptions(dbo)
        return set_cached_response(cache_key, "application/xml", 3600,
                                   html.xml(rs))

    elif method == "html_report":
        crid = reports.get_id(dbo, title)
        p = reports.get_criteria_params(dbo, crid, data)
        rhtml = reports.execute(dbo, crid, username, p)
        return set_cached_response(cache_key, "text/html", 3600, rhtml)

    elif method == "jsonp_shelter_animals":
        sa = animal.get_animal_find_simple(dbo, "", "shelter")
        return set_cached_response(
            cache_key, "application/javascript", 3600,
            str(utils.df_ks(data, "callback")) + "(" + html.json(sa) + ")")

    elif method == "json_shelter_animals":
        sa = animal.get_animal_find_simple(dbo, "", "shelter")
        return set_cached_response(cache_key, "application/json", 3600,
                                   html.json(sa))

    elif method == "xml_shelter_animals":
        sa = animal.get_animal_find_simple(dbo, "", "shelter")
        return set_cached_response(cache_key, "application/xml", 3600,
                                   html.json(sa))

    elif method == "upload_animal_image":
        media.attach_file_from_form(dbo, username, media.ANIMAL, int(animalid),
                                    data)
        return ("text/plain", 0, "OK")

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

    elif method == "online_form_post":
        onlineform.insert_onlineformincoming_from_form(dbo, data, remoteip)
        redirect = utils.df_ks(data, "redirect")
        if redirect == "":
            redirect = BASE_URL + "/static/pages/form_submitted.html"
        return ("redirect", 0, redirect)

    else:
        al.error("invalid method '%s'" % method, "service.handler", dbo)
        raise utils.ASMError("Invalid method '%s'" % method)
Exemple #8
0
def handler(data, remoteip, referer):
    """
    Handles the various service method types.
    data: The GET/POST parameters 
    return value is a tuple containing MIME type, max-age, content
    """
    # Database info
    dbo = db.DatabaseInfo()

    # Get service parameters
    account = utils.df_ks(data, "account")
    username = utils.df_ks(data, "username")
    password = utils.df_ks(data, "password")
    method = utils.df_ks(data, "method")
    animalid = utils.df_ki(data, "animalid")
    formid = utils.df_ki(data, "formid")
    title = utils.df_ks(data, "title")
    cache_key = "a" + account + "u" + username + "p" + password + "m" + method + "a" + str(animalid) + "f" + str(formid) + "t" + title
    
    # cache keys aren't allowed spaces
    cache_key = cache_key.replace(" ", "")

    # Do we have a cached response for these parameters?
    cached_response = get_cached_response(cache_key)
    if cached_response is not None:
        al.debug("cache hit for %s/%s/%s/%s" % (account, method, animalid, title), "service.handler")
        return cached_response

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

    # Are we dealing with multiple databases and an account was specified?
    if account != "":
        if MULTIPLE_DATABASES:
            if MULTIPLE_DATABASES_TYPE == "smcom":
                # Is this sheltermanager.com? If so, we need to get the 
                # database connection info (dbo) before we can login.
                dbo = smcom.get_database_info(account)
            else:
                # Look up the database info from our map
                dbo  = db.get_multiple_database_info(account)
            if dbo.database == "FAIL" or dbo.database == "DISABLED": 
                al.error("auth failed - invalid smaccount %s from %s" % (account, remoteip), "service.handler", dbo)
                return ("text/plain", 0, "ERROR: Invalid database")

    # Does the method require us to authenticate? If so, do it.
    user = None
    if method in AUTH_METHODS:
        user = users.authenticate(dbo, username, password)
        if user is None:
            al.error("auth failed - %s/%s is not a valid username/password from %s" % (username, password, remoteip), "service.handler", dbo)
            return ("text/plain", 0, "ERROR: Invalid username and password")

    # Get the preferred locale for the site
    dbo.locale = configuration.locale(dbo)
    al.info("call %s->%s [%s %s]" % (username, method, str(animalid), title), "service.handler", dbo)

    if method =="animal_image":
        # If we have a hotlinking restriction, enforce it
        if referer != "" and IMAGE_HOTLINKING_ONLY_FROM_DOMAIN != "" and referer.find(IMAGE_HOTLINKING_ONLY_FROM_DOMAIN) == -1:
            raise utils.ASMPermissionError("Image hotlinking is forbidden.")
        if animalid == "" or utils.cint(animalid) == 0:
            al.error("animal_image failed, %s is not an animalid" % str(animalid), "service.handler", dbo)
            return ("text/plain", 0, "ERROR: Invalid animalid")
        # If the option is on, forbid hotlinking
        else:
            seq = utils.df_ki(data, "seq")
            if seq == 0: seq = 1
            mm = media.get_media_by_seq(dbo, media.ANIMAL, utils.cint(animalid), seq)
            if len(mm) == 0:
                return ("image/jpeg", 86400, dbfs.get_string(dbo, "nopic.jpg", "/reports"))
            else:
                return ("image/jpeg", 86400, dbfs.get_string(dbo, mm[0]["MEDIANAME"]))

    elif method =="extra_image":
        return ("image/jpeg", 86400, dbfs.get_string(dbo, title, "/reports"))

    elif method == "json_adoptable_animals":
        pc = publish.PublishCriteria(configuration.publisher_presets(dbo))
        rs = publish.get_animal_data(dbo, pc, True)
        return set_cached_response(cache_key, "application/json", 3600, html.json(rs))

    elif method == "xml_adoptable_animals":
        pc = publish.PublishCriteria(configuration.publisher_presets(dbo))
        rs = publish.get_animal_data(dbo, pc, True)
        return set_cached_response(cache_key, "application/xml", 3600, html.xml(rs))

    elif method == "json_recent_adoptions":
        rs = movement.get_recent_adoptions(dbo)
        return set_cached_response(cache_key, "application/json", 3600, html.json(rs))

    elif method == "xml_recent_adoptions":
        rs = movement.get_recent_adoptions(dbo)
        return set_cached_response(cache_key, "application/xml", 3600, html.xml(rs))

    elif method == "html_report":
        crid = reports.get_id(dbo, title)
        p = reports.get_criteria_params(dbo, crid, data)
        rhtml = reports.execute(dbo, crid, username, p)
        return set_cached_response(cache_key, "text/html", 3600, rhtml)

    elif method == "jsonp_shelter_animals":
        sa = animal.get_animal_find_simple(dbo, "", "shelter")
        return set_cached_response(cache_key, "application/javascript", 3600, str(utils.df_ks(data, "callback")) + "(" + html.json(sa) + ")")

    elif method == "json_shelter_animals":
        sa = animal.get_animal_find_simple(dbo, "", "shelter")
        return set_cached_response(cache_key, "application/json", 3600, html.json(sa))

    elif method == "xml_shelter_animals":
        sa = animal.get_animal_find_simple(dbo, "", "shelter")
        return set_cached_response(cache_key, "application/xml", 3600, html.json(sa))

    elif method == "upload_animal_image":
        media.attach_file_from_form(dbo, username, media.ANIMAL, int(animalid), data)
        return ("text/plain", 0, "OK")

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

    elif method == "online_form_post":
        onlineform.insert_onlineformincoming_from_form(dbo, data, remoteip)
        redirect = utils.df_ks(data, "redirect")
        if redirect == "":
            redirect = BASE_URL + "/static/pages/form_submitted.html"
        return ("redirect", 0, redirect)

    else:
        al.error("invalid method '%s'" % method, "service.handler", dbo)
        raise utils.ASMError("Invalid method '%s'" % method)
Exemple #9
0
def handler(post, remoteip, referer):
    """
    Handles the various service method types.
    data: The GET/POST parameters 
    return value is a tuple containing MIME type, max-age, content
    """
    # Database info
    dbo = db.DatabaseInfo()

    # Get service parameters
    account = post["account"]
    username = post["username"]
    password = post["password"]
    method = post["method"]
    animalid = post.integer("animalid")
    formid = post.integer("formid")
    seq = post.integer("seq")
    title = post["title"]
    cache_key = "a" + account + "u" + username + "p" + password + "m" + method + \
        "i" + str(animalid) + "s" + str(seq) + "f" + str(formid) + "t" + title
    
    # cache keys aren't allowed spaces
    cache_key = cache_key.replace(" ", "")

    # Do we have a cached response for these parameters?
    cached_response = get_cached_response(cache_key)
    if cached_response is not None:
        al.debug("cache hit for %s/%s/%s/%s" % (account, method, animalid, title), "service.handler")
        return cached_response

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

    # Are we dealing with multiple databases and an account was specified?
    if account != "":
        if MULTIPLE_DATABASES:
            if MULTIPLE_DATABASES_TYPE == "smcom":
                # Is this sheltermanager.com? If so, we need to get the 
                # database connection info (dbo) before we can login.
                dbo = smcom.get_database_info(account)
            else:
                # Look up the database info from our map
                dbo  = db.get_multiple_database_info(account)
            if dbo.database == "FAIL" or dbo.database == "DISABLED": 
                al.error("auth failed - invalid smaccount %s from %s" % (account, remoteip), "service.handler", dbo)
                return ("text/plain", 0, "ERROR: Invalid database")

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

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

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

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

    if method =="animal_image":
        hotlink_protect("animal_image", referer)
        if animalid == "" or utils.cint(animalid) == 0:
            al.error("animal_image failed, %s is not an animalid" % str(animalid), "service.handler", dbo)
            return ("text/plain", 0, "ERROR: Invalid animalid")
        else:
            if seq == 0: seq = 1
            mm = media.get_media_by_seq(dbo, media.ANIMAL, utils.cint(animalid), seq)
            if len(mm) == 0:
                return set_cached_response(cache_key, "image/jpeg", 86400, 120, dbfs.get_string(dbo, "nopic.jpg", "/reports"))
            else:
                return set_cached_response(cache_key, "image/jpeg", 86400, 120, dbfs.get_string(dbo, mm[0]["MEDIANAME"]))

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

    elif method =="dbfs_image":
        hotlink_protect("dbfs_image", referer)
        return set_cached_response(cache_key, "image/jpeg", 86400, 120, dbfs.get_string_filepath(dbo, title))

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

    elif method == "json_adoptable_animals":
        users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL)
        pc = publish.PublishCriteria(configuration.publisher_presets(dbo))
        rs = publish.get_animal_data(dbo, pc, True)
        return set_cached_response(cache_key, "application/json", 3600, 3600, html.json(rs))

    elif method == "jsonp_adoptable_animals":
        users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL)
        pc = publish.PublishCriteria(configuration.publisher_presets(dbo))
        rs = publish.get_animal_data(dbo, pc, True)
        return ("application/javascript", 0, "%s(%s);" % (post["callback"], html.json(rs)))

    elif method == "xml_adoptable_animals":
        users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL)
        pc = publish.PublishCriteria(configuration.publisher_presets(dbo))
        rs = publish.get_animal_data(dbo, pc, True)
        return set_cached_response(cache_key, "application/xml", 3600, 3600, html.xml(rs))

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

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

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

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

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

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

    elif method == "json_shelter_animals":
        users.check_permission_map(l, user["SUPERUSER"], securitymap, users.VIEW_ANIMAL)
        sa = animal.get_animal_find_simple(dbo, "", "shelter")
        return set_cached_response(cache_key, "application/json", 3600, 3600, html.json(sa))

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

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

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

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

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

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

    elif method == "sign_document":
        if formid == 0:
            raise utils.ASMError("method sign_document requires a valid formid")
        if post["sig"] == "":
            return set_cached_response(cache_key, "text/html", 2, 2, sign_document_page(dbo, formid))
        else:
            media.sign_document(dbo, "service", formid, post["sig"], post["signdate"])
            return ("text/plain", 0, "OK")

    else:
        al.error("invalid method '%s'" % method, "service.handler", dbo)
        raise utils.ASMError("Invalid method '%s'" % method)