def select_field(data):
    select_doc, select_tag, select_text, select_line = Doc().ttl()
    with select_tag('div', klass="form-group"):
        select_line('label', data['name'])
        with select_doc.select(('v-model', data['vmodel']),
                               name=data['name'],
                               klass="custom-select"):
            for val, desc in zip(data['values'], data['label']):
                with select_doc.option(value=val):
                    select_text(desc)
    return select_doc.getvalue()
Example #2
0
 def test_select_option(self):
     doc, tag, text = Doc(defaults={
         'ingredient': ['chocolate', 'coffee']
     }).tagtext()
     with doc.select(name='ingredient', multiple="multiple"):
         for value, description in (("chocolate", "Dark Chocolate"),
                                    ("almonds", "Roasted almonds"),
                                    ("honey", "Acacia honey"),
                                    ("coffee", "Ethiopian coffee")):
             with doc.option(value=value):
                 text(description)
     root = ET.fromstring(doc.getvalue())
     self.assertEqual(root[3].attrib['selected'], 'selected')
Example #3
0
 def test_select_option(self):
     doc, tag, text = Doc(
         defaults = {'ingredient': ['chocolate', 'coffee']}
     ).tagtext()
     with doc.select(name = 'ingredient', multiple = "multiple"):
         for value, description in (
             ("chocolate", "Dark Chocolate"),
             ("almonds", "Roasted almonds"),
             ("honey", "Acacia honey"),
             ("coffee", "Ethiopian coffee")
         ):
             with doc.option(value = value):
                 text(description)
     root = ET.fromstring(doc.getvalue())
     self.assertEqual(root[3].attrib['selected'], 'selected')
Example #4
0
    ).tagtext()

doc.asis('<!DOCTYPE html>')

with tag('html'):
    with tag('body'):
        with tag('form', action = ""):
            with tag('br'):
                text('Default OpenVPN configuration path: ' + OPENVPN_PATH)
            with tag('br'):
                text('Curent server: ' + current_server)
            with tag('br'):
                text('')
            with tag('label'):
                text("Select a VPN server")
            with doc.select(name = 'server'):
                lst = os.listdir(OPENVPN_PATH)
                lst.sort()
                for file in lst:
                    if file.endswith(".conf"):
                        with doc.option(value = file):
                            text(file.split(".conf")[0])
            doc.stag('input', type = "submit", value = "Set")

        if query.has_key('server'):
            server = query['server'][0]
            info = set_server(server).split("\n")
            for openvpn_info in info:
                with tag('br'):
                     text(openvpn_info)
Example #5
0
from yattag import Doc
from yattag import indent

from yattag import Doc

doc, tag, text, line = Doc(defaults={
    'ingredient': ['chocolate', 'coffee']
}).ttl()

with tag('form', action=""):
    line('label', 'Select one or more ingredients')
    with doc.select(name='ingredient', multiple="multiple"):
        for value, description in (("chocolate", "Dark Chocolate"),
                                   ("almonds", "Roasted almonds"),
                                   ("honey", "Acacia honey"),
                                   ("coffee", "Ethiopian coffee")):
            with doc.option(value=value):
                text(description)
    doc.stag('input', type="submit", value="Validate")

result = indent(doc.getvalue(),
                indentation='    ',
                newline='\r\n',
                indent_text=True)
print(result)
Example #6
0
def application(environ, start_response):
    # the environment variable CONTENT_LENGTH may be empty or missing
    try:
        request_body_size = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
        request_body_size = 0
    request_body = environ['wsgi.input'].read(request_body_size)
    env = dict(parse_qsl(request_body.decode()))
    # Initialize search parameters
    search = { 'player': "", 'shard': "", 'guild': "", 'kind': "", }
    for var in search:
       if var in env:
          search[var] = env[var]

    # Filter invalid input
    # An invalid Kind or Shard is reset to All
    # Player + Guild names should only contain "letters" (this includes accented letters)
    if search['kind'] not in kinds:
       search['kind'] = "All"
    if search['shard'] not in ["All"] + nashards + eushards:
       search['shard'] = "All"
    pattern = re.compile('\W+')
    pattern.sub('', search['player'])
    search['player'] = search['player'].capitalize()
    pattern.sub('', search['guild'])

    results = None
    # The model is to print verbose errors to console/log, and print a generic error to Web page
    # Initialize generic error here
    error = None
    # If a player name OR guild name is input, search the DB using all parameters
    if search['player'] != "" or search['guild'] != "":
      query = "SELECT Kind, What, Player, Shard, Guild, Stamp, Id FROM firsts WHERE "
      params = []
      args = []
      for var in search:
         # Don't need to search for shard or kind == All
         if search[var] != "" and (var not in ["kind", "shard"] or search[var] != "All"):
            params.append("{0}=%s ".format(var))
            args.append(search[var])
      query += "AND ".join(params)
      query += " ORDER BY Kind, Stamp"

      connection = None
      try:
         connection = pymysql.connect(host=config["SQLLOC"],
                             user=config["SQLUSER"],
                             password=config["SQLPASS"],
                             db=config["SQLDB"],
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)
      except Exception as e:
         # This just kills one WSGI worker which will be respawned
         # Maybe find how to kill the WSGI server if we assume connection problems (eg wrong pass) are fatal
         print("Failed to connect to SQL database. {0}".format(e), file=sys.stderr)
         error = "Something went wrong with the SQL connection."

      if connection:
         try:
            with connection.cursor() as cursor:
               cursor.execute(query, args)
               results = cursor.fetchall()
         except Exception as e:
            print(e, file=sys.stderr)
            error = "Something went wrong with the SQL query."
         finally:
            connection.close()

    # OK, now start constructing HTML
    # The defaults dict makes the select dropdowns default to the input later
    doc, tag, text, line = Doc(defaults = {'shard': search['shard'], 'kind': search['kind']}).ttl()
    doc.asis('<!DOCTYPE html>')
    with tag('html'):
       with tag('head'):
          doc.stag('meta', ('http-equiv', "Content-Type"), ('content', "text/html; charset=utf-8"))
          doc.stag('link', ('rel', "stylesheet"), ('type', "text/css"), ('href', "style.css"))
          doc.stag('link', ('rel', "stylesheet"), ('type', "text/css"), ('href', "https://www.magelocdn.com/pack/magelo-bar-css2.css"))
          # <script> is NOT a void tag, so need with/pass
          with tag('script', ('src', "./sorttable.js"), ('type', "text/javascript")):
             pass
          with tag('script', ('src', "https://www.magelocdn.com/pack/rift/en/magelo-bar.js#1"), ('type', "text/javascript")):
             pass
          with tag('title'):
             text("RIFT Shard Firsts Search")
       with tag('body'):
          # Prevent Cloudflare interpreting Player@Shard as email
          doc.asis("<!--email_off-->")
          # Intro / search boxes
          with tag('h3'):
             text("Rift Shard Firsts")
          line('p', "This site tells you the shard firsts for your character or guild.")
          with tag('p'):
             # Find date of latest zip
             date = "*unknown*"
             for myfile in glob.glob("{0}/Rift_Discoveries*.zip".format(config['ZIPDIR'])):
                match = re.search(r'\d{4}-\d{1,2}-\d{1,2}', myfile)
                date = datetime.strptime(match.group(), '%Y-%m-%d').date()
             text("Data is checked for from Trion daily. The latest is dated ")
             line('em', "{0}".format(date))
             text(". All information is straight from Trion's ")
             line('a', "public assets", href = "http://webcdn.triongames.com/addons/assets/")
             text(".")
          with tag('form', ('id', "firstfrom")):
             line('label', "Character: ", ('for', "player"))
             doc.stag('input', ('type', "text"), ('name', "player"), ('id', "player"), ('size', "14"), ('maxlength', "255"), ('value', escape(search['player']) if search['player'] != "" else ""))
             line('label', " Shard: ", ('for', "shard"))
             with doc.select(('name', "shard"), ('id', "shard")):
                line('option', "All")
                with tag('optgroup', label = "NA"):
                   for shard in nashards:
                      with doc.option(value = shard):
                         text(shard)
                with tag('optgroup', label = "EU"):
                   for shard in eushards:
                      with doc.option(value = shard):
                         text(shard)
             line('label', " Guild: ", ('for', "guild"))
             doc.stag('input', ('type', "text"), ('name', "guild"), ('id', "guild"), ('size', "14"), ('value', escape(search['guild']) if search['guild'] != "" else ""))
             line('label', " Type: ", ('for', "kind"))
             with doc.select(('name', "kind"), ('id', "kind")):
                for kind in kinds:
                   with doc.option(value = kind):
                      text(kind)
             doc.stag('input', ('type', "submit"), ('formmethod', "post"))
          line('p', "Enter a player name and/or a guild name, then press Submit.")
          # If we had an earlier error, print the generic message here
          if error:
             line('p', error)
          # Print search results
          # The SQL query above can return firsts of 0-6 Kinds, but was only one query.
          # We want to print one table per Kind, and not have empty tables.
          # Thus the manual idx incrementing and starting a new table when a new Kind is encountered
          if results is not None:
            idx = 0
            reslen = len(results)
            for kind in kinds:
               if idx >= reslen: # End of results
                  break
               if results[idx]['Kind'] != kind: # No firsts for this Kind, so go to the next without starting a table for it
                  continue
               line('h4', "{0}s".format(kind), klass = "tablename")
               with tag('table', klass = 'sortable'):
                  with tag('thead'):
                     with tag('tr'):
                        for header in ['Player', 'Guild', 'What', 'Date (UTC)']:
                           line('th', header)
                  with tag('tbody'):
                     # Loop through and print rows until end or next table needed
                     while idx < reslen and results[idx]['Kind'] == kind:
                        with tag('tr'):
                           for cell in ['Player', 'Guild', 'What', 'Stamp']:
                              if cell == 'What':
                                with tag('td'):
                                   magurl = kind.lower()
                                   if magurl == "artifactcollection":
                                      magurl = "artifactset"
                                   line('a', results[idx][cell], href = "https://rift.magelo.com/en/{0}/{1}".format(magurl,results[idx]['Id']))
                              else:
                                 if cell == 'Player':
                                    results[idx][cell] += "@" + results[idx]['Shard']
                                 # The timestamp comes out as a datetime.datetime. Manually make everything a string.
                                 line('td', results[idx][cell].__str__())
                        idx += 1
          with tag('p'):
            text('See other RIFT tools ')
            line('a', "here", href="https://rift.events/main.html")
            text('.')

       doc.asis('<!--/email_off-->')

    start_response('200 OK', [('Content-Type','text/html')])
    return [doc.getvalue().encode('utf8')]