gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-survey] branch master updated (08191f9 -> 141e949)


From: gnunet
Subject: [GNUnet-SVN] [taler-survey] branch master updated (08191f9 -> 141e949)
Date: Thu, 29 Aug 2019 23:08:42 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a change to branch master
in repository survey.

    from 08191f9  simple build system
     new daebe19  missing files
     new 141e949  make pretty

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .style.yapf                  |   5 +
 Makefile                     |  39 +++++
 bin/taler-merchant-survey    | 115 +++++++++++++++
 configure                    |  87 ++++++++++++
 contrib/Doxyfile             | 331 +++++++++++++++++++++++++++++++++++++++++++
 setup.py                     |  58 ++++----
 talersurvey/survey/survey.py | 102 ++++++++-----
 talersurvey/talerconfig.py   | 112 ++++++++++-----
 talersurvey/tests.py         |   1 +
 9 files changed, 756 insertions(+), 94 deletions(-)
 create mode 100644 .style.yapf
 create mode 100644 Makefile
 create mode 100755 bin/taler-merchant-survey
 create mode 100755 configure
 create mode 100644 contrib/Doxyfile

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/Makefile b/Makefile
new file mode 100644
index 0000000..b5c1128
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,39 @@
+install_global=false
+-include config.mk
+
+.PHONY: all
+all:
+       @echo "This is a python project, no compilation required"
+
+.PHONY: install
+
+ifeq ($(install_global), true)
+install: install-global
+else
+install: install-local
+endif
+
+.PHONY: install-global
+install-global:
+       pip3 install .
+
+.PHONY: install-local
+install-local:
+       pip3 install . --user
+
+# run testcases
+.PHONY: check
+check:
+       python3 setup.py test
+
+.PHONY: clean
+clean:
+       @echo nothing to do
+
+.PHONY: dist
+dist:
+       git archive --format=tar.gz HEAD -o taler-merchant-survey.tar.gz
+
+.PHONY: pretty
+pretty:
+       yapf -r -i talersurvey/
diff --git a/bin/taler-merchant-survey b/bin/taler-merchant-survey
new file mode 100755
index 0000000..2da6fde
--- /dev/null
+++ b/bin/taler-merchant-survey
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+
+##
+# This file is part of TALER
+# (C) 2017 INRIA
+#
+# TALER is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Affero General Public
+# License as published by the Free Software Foundation; either
+# version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with TALER; see the file COPYING.  If not,
+# see <http://www.gnu.org/licenses/>
+#
+#  @author Florian Dold
+#  @file Standalone script to launch the Survey site.
+
+import argparse
+import sys
+import os
+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)"
+
+
+##
+# This function interprets the 'serve-http' subcommand.
+# The effect it to launch the Survey site as a HTTP service.
+#
+# @param args command line options.
+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"
+    )
+
+
+##
+# This function interprets the 'serve-uwsgi' subcommand.
+# The effect is to launch the Survey UWSGI service.  This
+# type of service is usually used when the HTTP Survey interface
+# is accessed via a reverse proxy (like Nginx, for example).
+#
+# @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"
+    ]
+    if serve_uwsgi == "tcp":
+        port = TC["survey"]["uwsgi_port"].value_int(required=True)
+        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])
+        os.makedirs(os.path.dirname(spec), exist_ok=True)
+    logging.info("launching uwsgi with argv %s", params[1:])
+    os.execlp(*params)
+
+
+## @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
+)
+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.set_defaults(func=handle_serve_http)
+
+P = SUB.add_parser('serve-uwsgi', help="Serve over UWSGI")
+P.set_defaults(func=handle_serve_uwsgi)
+
+ARGS = PARSER.parse_args()
+## @endcond
+
+if getattr(ARGS, 'func', None) is None:
+    PARSER.print_help()
+    sys.exit(1)
+
+if ARGS.config is not None:
+    os.environ["TALER_CONFIG_FILE"] = ARGS.config
+TC = TalerConfig.from_file(os.environ.get("TALER_CONFIG_FILE"))
+
+ARGS.func(ARGS)
diff --git a/configure b/configure
new file mode 100755
index 0000000..469bad7
--- /dev/null
+++ b/configure
@@ -0,0 +1,87 @@
+#!/usr/bin/env bash
+
+set -eu
+
+usage() {
+  echo "Usage: ./configure [OPTION]"
+  echo
+  echo "Configuration:"
+  echo "  -h, --help              display this help and exit"
+  echo
+  echo "Installation directories:"
+  echo "  --destination=[local|global] install Python package locally or 
globally"
+}
+
+
+# -allow a command to fail with !’s side effect on errexit
+# -use return value from ${PIPESTATUS[0]}, because ! hosed $?
+! getopt --test > /dev/null
+if [[ ${PIPESTATUS[0]} -ne 4 ]]; then
+    echo 'getopt not available'
+    exit 1
+fi
+
+LONGOPTS=destination:,help
+OPTIONS=h
+
+! PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- 
"$@")
+if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
+    # e.g. return value is 1
+    #  then getopt has complained about wrong arguments to stdout
+    exit 2
+fi
+
+# read getopt’s output this way to handle the quoting right:
+eval set -- "$PARSED"
+
+destination="local"
+
+while true; do
+    case "$1" in
+      --destination)
+        destination="$2"
+        shift 2
+        ;;
+      -h|--help)
+        usage
+        exit 1
+        ;;
+      --)
+        shift
+        break
+        ;;
+      *)
+        echo "Programming error"
+        exit 3
+        ;;
+    esac
+done
+
+case "$destination" in
+  local)
+    install_global=false
+    ;;
+  global)
+    install_global=true
+    ;;
+  *)
+    echo "Destination (--destination) must be 'local' or 'global', paths are 
not allowed."
+    exit 3
+    ;;
+esac
+
+cat << EOF > config.mk
+# this file is autogenerated by ./configure
+install_global=$install_global
+EOF
+
+
+if ! python3 --version &>/dev/null; then
+  echo 'Error: python3 missing'
+  exit 1
+fi
+
+if ! pip3 --version &>/dev/null; then
+  echo 'Error: pip3 missing'
+  exit 1
+fi
diff --git a/contrib/Doxyfile b/contrib/Doxyfile
new file mode 100644
index 0000000..518c651
--- /dev/null
+++ b/contrib/Doxyfile
@@ -0,0 +1,331 @@
+# Doxyfile 1.8.13
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING      = UTF-8
+PROJECT_NAME           = "taler-survey"
+PROJECT_NUMBER         =
+PROJECT_BRIEF          =
+PROJECT_LOGO           =
+OUTPUT_DIRECTORY       = doxygen-doc/
+CREATE_SUBDIRS         = NO
+ALLOW_UNICODE_NAMES    = NO
+OUTPUT_LANGUAGE        = English
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = YES
+STRIP_FROM_PATH        =
+STRIP_FROM_INC_PATH    =
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+QT_AUTOBRIEF           = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS           = YES
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 4
+ALIASES                =
+TCL_SUBST              =
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+OPTIMIZE_FOR_FORTRAN   = NO
+OPTIMIZE_OUTPUT_VHDL   = NO
+EXTENSION_MAPPING      = in=Python
+MARKDOWN_SUPPORT       = YES
+TOC_INCLUDE_HEADINGS   = 0
+AUTOLINK_SUPPORT       = YES
+BUILTIN_STL_SUPPORT    = NO
+CPP_CLI_SUPPORT        = NO
+SIP_SUPPORT            = NO
+IDL_PROPERTY_SUPPORT   = YES
+DISTRIBUTE_GROUP_DOC   = NO
+GROUP_NESTED_COMPOUNDS = NO
+SUBGROUPING            = YES
+INLINE_GROUPED_CLASSES = NO
+INLINE_SIMPLE_STRUCTS  = NO
+TYPEDEF_HIDES_STRUCT   = NO
+LOOKUP_CACHE_SIZE      = 0
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = NO
+EXTRACT_PACKAGE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+EXTRACT_ANON_NSPACES   = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+HIDE_COMPOUND_REFERENCE= NO
+SHOW_INCLUDE_FILES     = YES
+SHOW_GROUPED_MEMB_INC  = NO
+FORCE_LOCAL_INCLUDES   = NO
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_MEMBERS_CTORS_1ST = NO
+SORT_GROUP_NAMES       = NO
+SORT_BY_SCOPE_NAME     = NO
+STRICT_PROTO_MATCHING  = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       =
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_FILES             = YES
+SHOW_NAMESPACES        = NO
+FILE_VERSION_FILTER    =
+LAYOUT_FILE            =
+CITE_BIB_FILES         =
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_AS_ERROR          = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           =
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  =
+INPUT_ENCODING         = UTF-8
+FILE_PATTERNS          = *.py *.in
+RECURSIVE              = YES
+EXCLUDE                = Makefile.in
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       =
+EXCLUDE_SYMBOLS        =
+EXAMPLE_PATH           =
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             =
+INPUT_FILTER           =
+FILTER_PATTERNS        =
+FILTER_SOURCE_FILES    = NO
+FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE =
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION    = NO
+REFERENCES_LINK_SOURCE = YES
+SOURCE_TOOLTIPS        = YES
+USE_HTAGS              = NO
+VERBATIM_HEADERS       = YES
+CLANG_ASSISTED_PARSING = NO
+CLANG_OPTIONS          =
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          =
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            =
+HTML_FOOTER            =
+HTML_STYLESHEET        =
+HTML_EXTRA_STYLESHEET  =
+HTML_EXTRA_FILES       =
+HTML_COLORSTYLE_HUE    = 220
+HTML_COLORSTYLE_SAT    = 100
+HTML_COLORSTYLE_GAMMA  = 80
+HTML_TIMESTAMP         = NO
+HTML_DYNAMIC_SECTIONS  = NO
+HTML_INDEX_NUM_ENTRIES = 100
+GENERATE_DOCSET        = NO
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME  = Publisher
+GENERATE_HTMLHELP      = NO
+CHM_FILE               =
+HHC_LOCATION           =
+GENERATE_CHI           = NO
+CHM_INDEX_ENCODING     =
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+GENERATE_QHP           = NO
+QCH_FILE               =
+QHP_NAMESPACE          = org.doxygen.Project
+QHP_VIRTUAL_FOLDER     = doc
+QHP_CUST_FILTER_NAME   =
+QHP_CUST_FILTER_ATTRS  =
+QHP_SECT_FILTER_ATTRS  =
+QHG_LOCATION           =
+GENERATE_ECLIPSEHELP   = NO
+ECLIPSE_DOC_ID         = org.doxygen.Project
+DISABLE_INDEX          = NO
+GENERATE_TREEVIEW      = NO
+ENUM_VALUES_PER_LINE   = 4
+TREEVIEW_WIDTH         = 250
+EXT_LINKS_IN_WINDOW    = NO
+FORMULA_FONTSIZE       = 10
+FORMULA_TRANSPARENT    = YES
+USE_MATHJAX            = NO
+MATHJAX_FORMAT         = HTML-CSS
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_EXTENSIONS     =
+MATHJAX_CODEFILE       =
+SEARCHENGINE           = YES
+SERVER_BASED_SEARCH    = NO
+EXTERNAL_SEARCH        = NO
+SEARCHENGINE_URL       =
+SEARCHDATA_FILE        = searchdata.xml
+EXTERNAL_SEARCH_ID     =
+EXTRA_SEARCH_MAPPINGS  =
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4
+EXTRA_PACKAGES         =
+LATEX_HEADER           =
+LATEX_FOOTER           =
+LATEX_EXTRA_STYLESHEET =
+LATEX_EXTRA_FILES      =
+PDF_HYPERLINKS         = YES
+USE_PDFLATEX           = YES
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+LATEX_SOURCE_CODE      = NO
+LATEX_BIB_STYLE        = plain
+LATEX_TIMESTAMP        = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    =
+RTF_EXTENSIONS_FILE    =
+RTF_SOURCE_CODE        = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_SUBDIR             =
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+GENERATE_DOCBOOK       = NO
+DOCBOOK_OUTPUT         = docbook
+DOCBOOK_PROGRAMLISTING = NO
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           =
+INCLUDE_FILE_PATTERNS  =
+PREDEFINED             =
+EXPAND_AS_DEFINED      =
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+TAGFILES               =
+GENERATE_TAGFILE       =
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+EXTERNAL_PAGES         = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = NO
+MSCGEN_PATH            =
+DIA_PATH               =
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = YES
+DOT_NUM_THREADS        = 0
+DOT_FONTNAME           = Helvetica
+DOT_FONTSIZE           = 10
+DOT_FONTPATH           =
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+UML_LIMIT_NUM_FIELDS   = 10
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+CALLER_GRAPH           = NO
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+INTERACTIVE_SVG        = NO
+DOT_PATH               =
+DOTFILE_DIRS           =
+MSCFILE_DIRS           =
+DIAFILE_DIRS           =
+PLANTUML_JAR_PATH      =
+PLANTUML_CFG_FILE      =
+PLANTUML_INCLUDE_PATH  =
+DOT_GRAPH_MAX_NODES    = 50
+MAX_DOT_GRAPH_DEPTH    = 0
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
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='address@hidden',
-      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='address@hidden',
+    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 "<unknown>"
         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()

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]