From 7c898b3153c22a03d39bcb9e649c8d130ea1b92e Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Mon, 27 May 2019 18:42:07 +0200 Subject: upgrade/fix config logic --- talersurvey/talerconfig.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'talersurvey') diff --git a/talersurvey/talerconfig.py b/talersurvey/talerconfig.py index 69d06a8..4a44c97 100644 --- a/talersurvey/talerconfig.py +++ b/talersurvey/talerconfig.py @@ -344,6 +344,7 @@ class TalerConfig: filename = os.path.join(xdg, "taler.conf") else: filename = os.path.expanduser("~/.config/taler.conf") + print("Loading default config: (%s)" % filename) if load_defaults: cfg.load_defaults() cfg.load_file(os.path.expanduser(filename)) @@ -496,7 +497,8 @@ class TalerConfig: value=value, filename=filename, lineno=lineno) sections[current_section][key] = entry except FileNotFoundError: - LOGGER.error("Configuration file (%s) not found", filename) + # not logging here, as this interests the final user mostly. + print("Configuration file (%s) not found" % filename) sys.exit(3) ## -- cgit v1.2.3 From 141e949fa9f09e5f54acdfa90f609895236a8ac0 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 29 Aug 2019 23:08:26 +0200 Subject: make pretty --- .style.yapf | 5 ++ bin/taler-merchant-survey | 48 ++++++++++--------- setup.py | 58 +++++++++++----------- talersurvey/survey/survey.py | 102 ++++++++++++++++++++++++++------------- talersurvey/talerconfig.py | 112 ++++++++++++++++++++++++++++++------------- talersurvey/tests.py | 1 + 6 files changed, 210 insertions(+), 116 deletions(-) create mode 100644 .style.yapf (limited to 'talersurvey') diff --git a/.style.yapf b/.style.yapf new file mode 100644 index 0000000..3b39780 --- /dev/null +++ b/.style.yapf @@ -0,0 +1,5 @@ +[style] +based_on_style = pep8 +coalesce_brackets=True +column_limit=80 +dedent_closing_brackets=True diff --git a/bin/taler-merchant-survey b/bin/taler-merchant-survey index 418cd78..2da6fde 100755 --- a/bin/taler-merchant-survey +++ b/bin/taler-merchant-survey @@ -28,7 +28,6 @@ import site import logging from talersurvey.talerconfig import TalerConfig - LOGGER = logging.getLogger(__name__) # No perfect match to our logging format, but good enough ... UWSGI_LOGFMT = "%(ltime) %(proto) %(method) %(uri) %(proto) => %(status)" @@ -43,13 +42,11 @@ def handle_serve_http(args): port = args.port if port is None: port = TC["survey"]["http_port"].value_int(required=True) - spec = ":%d" % (port,) - os.execlp("uwsgi", "uwsgi", - "--master", - "--die-on-term", - "--log-format", UWSGI_LOGFMT, - "--http", spec, - "--module", "talersurvey") + spec = ":%d" % (port, ) + os.execlp( + "uwsgi", "uwsgi", "--master", "--die-on-term", "--log-format", + UWSGI_LOGFMT, "--http", spec, "--module", "talersurvey" + ) ## @@ -60,22 +57,22 @@ def handle_serve_http(args): # # @param command line options. def handle_serve_uwsgi(args): - del args # pacify PEP checkers - serve_uwsgi = TC["survey"]["uwsgi_serve"].value_string(required=True).lower() - params = ["uwsgi", "uwsgi", - "--master", - "--die-on-term", - "--log-format", UWSGI_LOGFMT, - "--module", "talersurvey"] + del args # pacify PEP checkers + serve_uwsgi = TC["survey"]["uwsgi_serve"].value_string(required=True + ).lower() + params = [ + "uwsgi", "uwsgi", "--master", "--die-on-term", "--log-format", + UWSGI_LOGFMT, "--module", "talersurvey" + ] if serve_uwsgi == "tcp": port = TC["survey"]["uwsgi_port"].value_int(required=True) - spec = ":%d" % (port,) + spec = ":%d" % (port, ) params.extend(["--socket", spec]) elif serve_uwsgi == "unix": spec = TC["survey"]["uwsgi_unixpath"].value_filename(required=True) mode = TC["survey"]["uwsgi_unixpath_mode"].value_filename(required=True) params.extend(["--socket", spec]) - params.extend(["--chmod-socket="+mode]) + params.extend(["--chmod-socket=" + mode]) os.makedirs(os.path.dirname(spec), exist_ok=True) logging.info("launching uwsgi with argv %s", params[1:]) os.execlp(*params) @@ -84,14 +81,21 @@ def handle_serve_uwsgi(args): ## @cond PARSER = argparse.ArgumentParser() PARSER.set_defaults(func=None) -PARSER.add_argument('--config', '-c', - help="configuration file to use", - metavar="CONFIG", type=str, - dest="config", default=None) +PARSER.add_argument( + '--config', + '-c', + help="configuration file to use", + metavar="CONFIG", + type=str, + dest="config", + default=None +) SUB = PARSER.add_subparsers() P = SUB.add_parser('serve-http', help="Serve over HTTP") -P.add_argument("--port", "-p", dest="port", type=int, default=None, metavar="PORT") +P.add_argument( + "--port", "-p", dest="port", type=int, default=None, metavar="PORT" +) P.set_defaults(func=handle_serve_http) P = SUB.add_parser('serve-uwsgi', help="Serve over UWSGI") diff --git a/setup.py b/setup.py index cf6f1ca..fa132d6 100755 --- a/setup.py +++ b/setup.py @@ -1,30 +1,32 @@ from setuptools import setup, find_packages -setup(name='talersurvey', - version='0.6.0pre1', - description='Example survey site for GNU Taler', - url='git://taler.net/survey', - author='Marcello Stanisci', - author_email='stanisci.m@gmail.com', - license='GPL', - packages=find_packages(), - install_requires=["Flask>=0.10", "jsmin"], - test_suite="nose.collector", - tests_require=["mock", "nose", "requests", "uwsgi"], - package_data={ - '':[ - "survey/templates/*.html", - "survey/static/favicon.ico", - "survey/static/*.svg", - "survey/static/*.css", - "survey/static/*.js", - "survey/static/*.js.tar.gz", - "survey/static/web-common/*.png", - "survey/static/web-common/*.css", - "survey/static/web-common/*.js", - "survey/static/web-common/*.js.tar.gz", - "survey/static/web-common/*.html", - ] - }, - scripts=['./bin/taler-merchant-survey'], - zip_safe=False) +setup( + name='talersurvey', + version='0.6.0pre1', + description='Example survey site for GNU Taler', + url='git://taler.net/survey', + author='Marcello Stanisci', + author_email='stanisci.m@gmail.com', + license='GPL', + packages=find_packages(), + install_requires=["Flask>=0.10", "jsmin"], + test_suite="nose.collector", + tests_require=["mock", "nose", "requests", "uwsgi"], + package_data={ + '': [ + "survey/templates/*.html", + "survey/static/favicon.ico", + "survey/static/*.svg", + "survey/static/*.css", + "survey/static/*.js", + "survey/static/*.js.tar.gz", + "survey/static/web-common/*.png", + "survey/static/web-common/*.css", + "survey/static/web-common/*.js", + "survey/static/web-common/*.js.tar.gz", + "survey/static/web-common/*.html", + ] + }, + scripts=['./bin/taler-merchant-survey'], + zip_safe=False +) diff --git a/talersurvey/survey/survey.py b/talersurvey/survey/survey.py index 79d0f16..1c6b8aa 100644 --- a/talersurvey/survey/survey.py +++ b/talersurvey/survey/survey.py @@ -48,14 +48,21 @@ LOGGER = logging.getLogger(__name__) # the merchant backend. # @return a flask-native response object. def backend_error(requests_response): - LOGGER.error("Backend error: status code: " - + str(requests_response.status_code)) + LOGGER.error( + "Backend error: status code: " + str(requests_response.status_code) + ) try: - return flask.jsonify(requests_response.json()), requests_response.status_code + return flask.jsonify( + requests_response.json() + ), requests_response.status_code except json.decoder.JSONDecodeError: - LOGGER.error("Backend error (NO JSON returned): status code: " - + str(requests_response.status_code)) - return flask.jsonify(dict(error="Backend died, no JSON got from it")), 502 + LOGGER.error( + "Backend error (NO JSON returned): status code: " + + str(requests_response.status_code) + ) + return flask.jsonify( + dict(error="Backend died, no JSON got from it") + ), 502 ## @@ -66,14 +73,15 @@ def backend_error(requests_response): def utility_processor(): def env(name, default=None): return os.environ.get(name, default) + def prettydate(talerdate): - parsed_time = re.search(r"/Date\(([0-9]+)\)/", talerdate) - if not parsed_time: - return "malformed date given" - parsed_time = int(parsed_time.group(1)) - timestamp = datetime.datetime.fromtimestamp(parsed_time) - # returns the YYYY-MM-DD date format. - return timestamp.strftime("%Y-%b-%d") + parsed_time = re.search(r"/Date\(([0-9]+)\)/", talerdate) + if not parsed_time: + return "malformed date given" + parsed_time = int(parsed_time.group(1)) + timestamp = datetime.datetime.fromtimestamp(parsed_time) + # returns the YYYY-MM-DD date format. + return timestamp.strftime("%Y-%b-%d") return dict(env=env, prettydate=prettydate) @@ -99,17 +107,26 @@ def err_abort(abort_status_code, **params): def backend_post(endpoint, json): headers = {"Authorization": "ApiKey " + APIKEY} try: - resp = requests.post(urljoin(BACKEND_URL, endpoint), json=json, headers=headers) + resp = requests.post( + urljoin(BACKEND_URL, endpoint), json=json, headers=headers + ) except requests.ConnectionError: err_abort(500, message="Could not establish connection to backend") try: response_json = resp.json() except ValueError: - err_abort(500, message="Could not parse response from backend", - status_code=resp.status_code) + err_abort( + 500, + message="Could not parse response from backend", + status_code=resp.status_code + ) if resp.status_code != 200: - err_abort(500, message="Backend returned error status", - json=response_json, status_code=resp.status_code) + err_abort( + 500, + message="Backend returned error status", + json=response_json, + status_code=resp.status_code + ) return response_json @@ -123,7 +140,9 @@ def backend_post(endpoint, json): def backend_get(endpoint, params): headers = {"Authorization": "ApiKey " + APIKEY} try: - resp = requests.get(urljoin(BACKEND_URL, endpoint), params=params, headers=headers) + resp = requests.get( + urljoin(BACKEND_URL, endpoint), params=params, headers=headers + ) except requests.ConnectionError: err_abort(500, message="Could not establish connection to backend") try: @@ -131,8 +150,12 @@ def backend_get(endpoint, params): except ValueError: err_abort(500, message="Could not parse response from backend") if resp.status_code != 200: - err_abort(500, message="Backend returned error status", - json=response_json, status_code=resp.status_code) + err_abort( + 500, + message="Backend returned error status", + json=response_json, + status_code=resp.status_code + ) return response_json @@ -144,9 +167,11 @@ def backend_get(endpoint, params): # (and execution stack!). @app.errorhandler(Exception) def internal_error(e): - return flask.render_template("templates/error.html", - message="Internal error", - stack=traceback.format_exc()) + return flask.render_template( + "templates/error.html", + message="Internal error", + stack=traceback.format_exc() + ) ## @@ -156,8 +181,12 @@ def internal_error(e): @app.route("/favicon.ico") def favicon(): print("will look into: " + os.path.join(app.root_path, 'static')) - return flask.send_from_directory(os.path.join(app.root_path, 'static'), - "favicon.ico", mimetype="image/vnd.microsoft.ico") + return flask.send_from_directory( + os.path.join(app.root_path, 'static'), + "favicon.ico", + mimetype="image/vnd.microsoft.ico" + ) + ## # Give information about the tip reserve status. @@ -169,6 +198,7 @@ def survey_stats(): stats = backend_get("tip-query", dict(instance="default")) return flask.render_template("templates/survey_stats.html", stats=stats) + ## # Tell the backend to 'authorize' a tip; this means that # the backend will allocate a certain amount to be later @@ -179,17 +209,21 @@ def survey_stats(): # otherwise. @app.route("/submit-survey", methods=["POST"]) def submit_survey(): - tip_spec = dict(amount=CURRENCY + ":1.0", - next_url=os.environ.get("TALER_ENV_URL_INTRO", "https://taler.net/"), - instance="default", - justification="Payment methods survey") + tip_spec = dict( + amount=CURRENCY + ":1.0", + next_url=os.environ.get("TALER_ENV_URL_INTRO", "https://taler.net/"), + instance="default", + justification="Payment methods survey" + ) resp = backend_post("tip-authorize", tip_spec) if resp.get("tip_redirect_url"): return flask.redirect(resp["tip_redirect_url"]) - err_abort(500, message="Tipping failed, unexpected backend response", - json=resp) + err_abort( + 500, message="Tipping failed, unexpected backend response", json=resp + ) + ## # Serve the main index page. @@ -197,4 +231,6 @@ def submit_survey(): # @return response object of the index page. @app.route("/", methods=["GET"]) def index(): - return flask.render_template("templates/index.html", merchant_currency=CURRENCY) + return flask.render_template( + "templates/index.html", merchant_currency=CURRENCY + ) diff --git a/talersurvey/talerconfig.py b/talersurvey/talerconfig.py index 4a44c97..1a33294 100644 --- a/talersurvey/talerconfig.py +++ b/talersurvey/talerconfig.py @@ -38,17 +38,20 @@ try: except ImportError: pass + ## # Exception class for a any configuration error. class ConfigurationError(Exception): pass + ## # Exception class for malformed strings having with parameter # expansion. class ExpansionSyntaxError(Exception): pass + ## # Do shell-style parameter expansion. # Supported syntax: @@ -80,7 +83,7 @@ def expand(var: str, getter: Callable[[str], str]) -> str: end += 1 if balance != 0: raise ExpansionSyntaxError("unbalanced parentheses") - piece = var[start+2:end-1] + piece = var[start + 2:end - 1] if piece.find(":-") > 0: varname, alt = piece.split(":-", 1) replace = getter(varname) @@ -93,9 +96,9 @@ def expand(var: str, getter: Callable[[str], str]) -> str: replace = var[start:end] else: end = start + 2 - while end < len(var) and var[start+1:end+1].isalnum(): + while end < len(var) and var[start + 1:end + 1].isalnum(): end += 1 - varname = var[start+1:end] + varname = var[start + 1:end] replace = getter(varname) if replace is None: replace = var[start:end] @@ -104,6 +107,7 @@ def expand(var: str, getter: Callable[[str], str]) -> str: return result + var[pos:] + ## # A configuration entry. class Entry: @@ -164,11 +168,16 @@ class Entry: if self.value is None: if warn: if default is not None: - LOGGER.warning("Configuration is missing option '%s' in section '%s',\ - falling back to '%s'", self.option, self.section, default) + LOGGER.warning( + "Configuration is missing option '%s' in section '%s',\ + falling back to '%s'", self.option, + self.section, default + ) else: - LOGGER.warning("Configuration ** is missing option '%s' in section '%s'", - self.option.upper(), self.section.upper()) + LOGGER.warning( + "Configuration ** is missing option '%s' in section '%s'", + self.option.upper(), self.section.upper() + ) return default return self.value @@ -190,6 +199,7 @@ class Entry: except ValueError: raise ConfigurationError("Expected number for option '%s' in section '%s'" \ % (self.option.upper(), self.section.upper())) + ## # Fetch value to substitute to expansion variables. # @@ -231,6 +241,7 @@ class Entry: return "" return "%s:%s" % (self.filename, self.lineno) + ## # Represent a section by inheriting from 'defaultdict'. class OptionDict(collections.defaultdict): @@ -280,6 +291,7 @@ class OptionDict(collections.defaultdict): def __setitem__(self, chunk: str, value: Entry) -> None: super().__setitem__(chunk.lower(), value) + ## # Collection of all the (@a OptionDict) sections. class SectionDict(collections.defaultdict): @@ -313,6 +325,7 @@ class SectionDict(collections.defaultdict): def __setitem__(self, chunk: str, value: OptionDict) -> None: super().__setitem__(chunk.lower(), value) + ## # One loaded taler configuration, including base configuration # files and included files. @@ -323,7 +336,7 @@ class TalerConfig: # # @param self the object itself. def __init__(self) -> None: - self.sections = SectionDict() # just plain dict + self.sections = SectionDict() # just plain dict ## # Load a configuration file, instantiating a config object. @@ -362,7 +375,8 @@ class TalerConfig: # a error occurs). def value_string(self, section, option, **kwargs) -> str: return self.sections[section][option].value_string( - kwargs.get("default"), kwargs.get("required"), kwargs.get("warn")) + kwargs.get("default"), kwargs.get("required"), kwargs.get("warn") + ) ## # Get a value from the config that should be a filename. @@ -377,7 +391,8 @@ class TalerConfig: # a error occurs). def value_filename(self, section, option, **kwargs) -> str: return self.sections[section][option].value_filename( - kwargs.get("default"), kwargs.get("required"), kwargs.get("warn")) + kwargs.get("default"), kwargs.get("required"), kwargs.get("warn") + ) ## # Get a integer value from the config. @@ -391,7 +406,8 @@ class TalerConfig: # a error occurs). def value_int(self, section, option, **kwargs) -> int: return self.sections[section][option].value_int( - kwargs.get("default"), kwargs.get("required"), kwargs.get("warn")) + kwargs.get("default"), kwargs.get("required"), kwargs.get("warn") + ) ## # Load default values from canonical locations. @@ -465,36 +481,59 @@ class TalerConfig: if line.startswith("@INLINE@"): pair = line.split() if 2 != len(pair): - LOGGER.error("invalid inlined config filename given ('%s')" % line) - continue + LOGGER.error( + "invalid inlined config filename given ('%s')" % + line + ) + continue if pair[1].startswith("/"): self.load_file(pair[1]) else: - self.load_file(os.path.join(os.path.dirname(filename), pair[1])) + self.load_file( + os.path.join( + os.path.dirname(filename), pair[1] + ) + ) continue if line.startswith("["): if not line.endswith("]"): - LOGGER.error("invalid section header in line %s: %s", - lineno, repr(line)) + LOGGER.error( + "invalid section header in line %s: %s", lineno, + repr(line) + ) section_name = line.strip("[]").strip().strip('"') current_section = section_name continue if current_section is None: - LOGGER.error("option outside of section in line %s: %s", lineno, repr(line)) + LOGGER.error( + "option outside of section in line %s: %s", lineno, + repr(line) + ) continue pair = line.split("=", 1) if len(pair) != 2: - LOGGER.error("invalid option in line %s: %s", lineno, repr(line)) + LOGGER.error( + "invalid option in line %s: %s", lineno, repr(line) + ) key = pair[0].strip() value = pair[1].strip() if value.startswith('"'): value = value[1:] if not value.endswith('"'): - LOGGER.error("mismatched quotes in line %s: %s", lineno, repr(line)) + LOGGER.error( + "mismatched quotes in line %s: %s", lineno, + repr(line) + ) else: value = value[:-1] - entry = Entry(self.sections, current_section, key, - value=value, filename=filename, lineno=lineno) + entry = Entry( + self.sections, + current_section, + key, + value=value, + filename=filename, + lineno=lineno + ) sections[current_section][key] = entry except FileNotFoundError: # not logging here, as this interests the final user mostly. @@ -503,23 +542,22 @@ class TalerConfig: ## # Dump the textual representation of a config object. - # + # # Format: - # + # # [section] # option = value # FIXME (what is location?) # # @param self the object itself, that will be dumped. def dump(self) -> None: for kv_section in self.sections.items(): - print("[%s]" % (kv_section[1].section_name,)) + print("[%s]" % (kv_section[1].section_name, )) for kv_option in kv_section[1].items(): print("%s = %s # %s" % \ (kv_option[1].option, kv_option[1].value, kv_option[1].location())) - ## # Return a whole section from this object. # @@ -538,14 +576,22 @@ if __name__ == "__main__": import argparse PARSER = argparse.ArgumentParser() - PARSER.add_argument("--section", "-s", dest="section", - default=None, metavar="SECTION") - PARSER.add_argument("--option", "-o", dest="option", - default=None, metavar="OPTION") - PARSER.add_argument("--config", "-c", dest="config", - default=None, metavar="FILE") - PARSER.add_argument("--filename", "-f", dest="expand_filename", - default=False, action='store_true') + PARSER.add_argument( + "--section", "-s", dest="section", default=None, metavar="SECTION" + ) + PARSER.add_argument( + "--option", "-o", dest="option", default=None, metavar="OPTION" + ) + PARSER.add_argument( + "--config", "-c", dest="config", default=None, metavar="FILE" + ) + PARSER.add_argument( + "--filename", + "-f", + dest="expand_filename", + default=False, + action='store_true' + ) ARGS = PARSER.parse_args() TC = TalerConfig.from_file(ARGS.config) diff --git a/talersurvey/tests.py b/talersurvey/tests.py index d25da48..d13e2f1 100644 --- a/talersurvey/tests.py +++ b/talersurvey/tests.py @@ -35,5 +35,6 @@ class SurveyTestCase(unittest.TestCase): survey.app.testing = True self.app = survey.app.test_client() + if __name__ == "__main__": unittest.main() -- cgit v1.2.3 From 095aa94e9adfaf1c60260839782c741b40b10e8f Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 30 Aug 2019 14:13:23 +0200 Subject: mobile tipping --- talersurvey/survey/survey.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'talersurvey') diff --git a/talersurvey/survey/survey.py b/talersurvey/survey/survey.py index 1c6b8aa..e64de96 100644 --- a/talersurvey/survey/survey.py +++ b/talersurvey/survey/survey.py @@ -199,6 +199,12 @@ def survey_stats(): return flask.render_template("templates/survey_stats.html", stats=stats) +def get_qrcode_svg(data): + factory = qrcode.image.svg.SvgImage + img = qrcode.make(data, image_factory=factory) + return lxml.etree.tostring(img.get_image()).decode("utf-8") + + ## # Tell the backend to 'authorize' a tip; this means that # the backend will allocate a certain amount to be later @@ -215,10 +221,18 @@ def submit_survey(): instance="default", justification="Payment methods survey" ) - resp = backend_post("tip-authorize", tip_spec) - - if resp.get("tip_redirect_url"): - return flask.redirect(resp["tip_redirect_url"]) + backend_resp = backend_post("tip-authorize", tip_spec) + + taler_tip_uri = backend_resp.get("taler_tip_uri") + if taler_tip_uri: + qrcode_svg = get_qrcode_svg(taler_tip_uri) + content = flask.render_tempate( + "templates/show_tip.html", + qrcode_svg=qrcode_svg, + taler_tip_uri=taler_tip_uri, + ) + headers = {"Taler", taler_tip_uri} + return flask.Response(content, status=402, headers) err_abort( 500, message="Tipping failed, unexpected backend response", json=resp -- cgit v1.2.3 From 2840396446ccc913e7cc7f6f813eddf8888e9463 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 30 Aug 2019 14:13:44 +0200 Subject: qr code template --- talersurvey/survey/templates/show_tip.html | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 talersurvey/survey/templates/show_tip.html (limited to 'talersurvey') diff --git a/talersurvey/survey/templates/show_tip.html b/talersurvey/survey/templates/show_tip.html new file mode 100644 index 0000000..1c6317a --- /dev/null +++ b/talersurvey/survey/templates/show_tip.html @@ -0,0 +1,35 @@ +{% extends "templates/base.html" %} + + +{% block meta %} + +{% endblock meta %} + +{% block main %} + +

Tip Offered

+ +
+

+ Looks like your browser doesn't support GNU Taler payments. You can try + installing a wallet browser extension. +

+
+ +
+ +

+ You can use this QR code to receive a tip with your mobile wallet: +

+ + {{ qrcode_svg | safe }} + +

+ Click this link to open your system's Taler wallet if it exists. +

+ +
+ +{% endblock main %} -- cgit v1.2.3 From 2f09f9049d1dca01dfe7c49fadf75c6eff321808 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 30 Aug 2019 14:14:30 +0200 Subject: deps and imports --- setup.py | 2 +- talersurvey/survey/survey.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'talersurvey') diff --git a/setup.py b/setup.py index fa132d6..01425ac 100755 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ setup( packages=find_packages(), install_requires=["Flask>=0.10", "jsmin"], test_suite="nose.collector", - tests_require=["mock", "nose", "requests", "uwsgi"], + tests_require=["mock", "nose", "requests", "uwsgi", "qrcode", "lxml"], package_data={ '': [ "survey/templates/*.html", diff --git a/talersurvey/survey/survey.py b/talersurvey/survey/survey.py index e64de96..076aa93 100644 --- a/talersurvey/survey/survey.py +++ b/talersurvey/survey/survey.py @@ -26,6 +26,9 @@ from urllib.parse import urljoin import flask import requests import traceback +import qrcode +import qrcode.image.svg +import lxml.etree from ..talerconfig import TalerConfig BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -- cgit v1.2.3 From 991e4c08cb5a5cb89557743e707041f97d55107f Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 30 Aug 2019 14:15:28 +0200 Subject: set headers correctly --- talersurvey/survey/survey.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'talersurvey') diff --git a/talersurvey/survey/survey.py b/talersurvey/survey/survey.py index 076aa93..7ac4efa 100644 --- a/talersurvey/survey/survey.py +++ b/talersurvey/survey/survey.py @@ -235,7 +235,7 @@ def submit_survey(): taler_tip_uri=taler_tip_uri, ) headers = {"Taler", taler_tip_uri} - return flask.Response(content, status=402, headers) + return flask.Response(content, status=402, headers=headers) err_abort( 500, message="Tipping failed, unexpected backend response", json=resp -- cgit v1.2.3 From 894c77695f9eca57390825b5894e3796b57454b0 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 30 Aug 2019 14:18:12 +0200 Subject: typo --- talersurvey/survey/survey.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'talersurvey') diff --git a/talersurvey/survey/survey.py b/talersurvey/survey/survey.py index 7ac4efa..76e2dbb 100644 --- a/talersurvey/survey/survey.py +++ b/talersurvey/survey/survey.py @@ -229,7 +229,7 @@ def submit_survey(): taler_tip_uri = backend_resp.get("taler_tip_uri") if taler_tip_uri: qrcode_svg = get_qrcode_svg(taler_tip_uri) - content = flask.render_tempate( + content = flask.render_template( "templates/show_tip.html", qrcode_svg=qrcode_svg, taler_tip_uri=taler_tip_uri, -- cgit v1.2.3 From 6caf873159bc7482771dc65e8f0bed28c89a65ef Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 30 Aug 2019 14:19:03 +0200 Subject: typo --- talersurvey/survey/survey.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'talersurvey') diff --git a/talersurvey/survey/survey.py b/talersurvey/survey/survey.py index 76e2dbb..14e2258 100644 --- a/talersurvey/survey/survey.py +++ b/talersurvey/survey/survey.py @@ -205,7 +205,7 @@ def survey_stats(): def get_qrcode_svg(data): factory = qrcode.image.svg.SvgImage img = qrcode.make(data, image_factory=factory) - return lxml.etree.tostring(img.get_image()).decode("utf-8") + return lxml.etree.tostring(img.get_image()).decode("utf-8") ## @@ -234,7 +234,7 @@ def submit_survey(): qrcode_svg=qrcode_svg, taler_tip_uri=taler_tip_uri, ) - headers = {"Taler", taler_tip_uri} + headers = {"Taler": taler_tip_uri} return flask.Response(content, status=402, headers=headers) err_abort( -- cgit v1.2.3 From 18ab3d0f84c42de7a6e7ca29448020945fb05f62 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 30 Aug 2019 14:20:01 +0200 Subject: no more wallet detection --- talersurvey/survey/templates/index.html | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'talersurvey') diff --git a/talersurvey/survey/templates/index.html b/talersurvey/survey/templates/index.html index ffd8f61..e58e669 100644 --- a/talersurvey/survey/templates/index.html +++ b/talersurvey/survey/templates/index.html @@ -7,11 +7,7 @@ and get a nice tip - via your Taler wallet - from this shop! (survey stats)

-
-

The survey is not possible without the wallet; - please install one!

-
-
+
What do you prefer?
-- cgit v1.2.3