Newer
Older
from flask import Flask, Response, request, render_template
import requests
# from svg_to_hpgl import svgToHPGL
app = Flask(__name__)
title = 'Cobbled paths'
fonts_directory = 'db/'
possible_extensions = [".flf"]
etherpad = 'https://pad.constantvzw.org/p/'
prefix = 'cobbled-pad-'
# VARIABLES 4 CATALOGUE
# ------------------------------
output = {
'stroke': { 'ascii': ' | ' , 'fonts': [] },
'script': { 'ascii': ' _/' , 'fonts': [] },
'block': { 'ascii': '|_|' , 'fonts': [] },
'outline': { 'ascii': '/ /' , 'fonts': [] },
'effect': { 'ascii': ': :' , 'fonts': [] },
'pattern': { 'ascii': ')()' , 'fonts': [] },
# 'fill': { 'ascii': '_/', 'fonts': {} },
# 'directions': { 'ascii': '_/', 'fonts': {} },
# '3d': { 'ascii': '_/', 'fonts': {} },
# 'frame': { 'ascii': '_/', 'fonts': {} },
# 'code': { 'ascii': '_/', 'fonts': {} },
}
databases = {
'default': 'fonts made by the figlet developpers and given with the program, early 1993',
'contributed': 'fonts made by figlet amateurs and submitted to the official figlet ftp, from before 1993 to 2005',
'jave': 'figlet font library of JavE (a free Ascii drawing Editor)',
}
# VARIABLES 4 REGEX
# ------------------------------
# all the character that svgbob understand
spec = [".", ",", "’", "'", "`", "+", "*", "o", "O", "V", "\\-", "|", "~", "_", ":", "!", "<", ">", "v", "^", "/", "\\\\", '\\”', '\\"', "(", ")", "=", "#"]
r_spec = "".join(spec)
r_nspec = "[^" + r_spec + "\€\$\s]"
# autofix regex
autofix = [
# every arrowshead into lines
[re.compile("[<{]"), "("],
[re.compile("[>}L]"), ")"],
[re.compile("[vV]"), "-"],
[re.compile("[\\^]"), "-"],
[";", ":"],
["7", "/"],
[re.compile("[1Tlj\\[\\]]"), "|"],
[re.compile("[Y]"), "+"],
# every not in the spec --> block
[re.compile(r_nspec), "#"],
]
# FUNCTIONS
# ------------------------------
def most_common(lst):
return max(set(lst), key=lst.count)
def text2figlet(input, figfont):
figlet = subprocess.run(["figlet", input, "-f", figfont, "-w", "160"], stdout = subprocess.PIPE, text=True)
return figlet.stdout
def ascii2svg(ascii_input, weight):
svgbob = subprocess.run(["svgbob_cli", '--stroke-width', weight], input = ascii_input, stdout = subprocess.PIPE, text=True)
return svgbob.stdout
def ascii_autofix(ascii):
for regex, replace in autofix:
ascii = re.sub(regex, replace, ascii)
return ascii
def autofix_indication(ascii):
for regex, replace in autofix:
# the two markers have to not appear in any regex
ascii = re.sub(regex, "$" + replace + "€", ascii)
ascii = re.sub("[\$]", "<span class='fix'>", ascii)
ascii = re.sub("[\€]", "</span>", ascii)
return ascii
# _ _
# (_)_ __ __| | _____ __
# | | '_ \ / _` |/ _ \ \/ /
# | | | | | (_| | __/> <
# |_|_| |_|\__,_|\___/_/\_\
#
# PRESENT THE TOOL
@app.route("/")
def index():
return render_template(
'index.html',
title = title)
# _
# __| |_ __ __ ___ __
# / _` | '__/ _` \ \ /\ / /
# | (_| | | | (_| |\ V V /
# \__,_|_| \__,_| \_/\_/
#
# ETHERPAD 2 SVGBOB INTERFACE
# one iframe for the etherpad
# another iframe to dump the generated svg
@app.route("/draw.html")
def draw():
params = {
'pad': request.args.get('p') or 'default',
'weight': request.args.get('w') or '3',
}
params['pad-full'] = etherpad + prefix + params['pad']
return render_template(
'draw.html',
title = title,
params = params)
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# this is the route of the iframe where the svg is generated and dumped
@app.route("/drawing/<id>")
def drawing(id):
params = {
'pad': id or 'default',
'weight': request.args.get('w') or '3',
}
params['pad-full'] = etherpad + prefix + params['pad']
# get pad content
print(' getting ' + params['pad-full'])
pad_export = requests.get(params['pad-full'] + '/export/txt')
ascii_input = pad_export.text
# to SVG
svg = ascii2svg(ascii_input, params['weight']);
return render_template(
'drawing.html',
title = title,
params = params,
svg = svg)
# _ _
# ___ __ _| |_ __ _| | ___ __ _ _ _ ___
# / __/ _` | __/ _` | |/ _ \ / _` | | | |/ _ \
# | (_| (_| | || (_| | | (_) | (_| | |_| | __/
# \___\__,_|\__\__,_|_|\___/ \__, |\__,_|\___|
# |___/
#
# FIGLET 2 SVGBOB INTERACTIVE CATALOGUE
@app.route("/catalogue.html")
def catalogue():
# text and weight as get parameter
params = {
'text': request.args.get('t') or 'Echoes',
'weight': request.args.get('w') or '3',
}
# walk in the figlet font directory
for root, dirs, files in os.walk(fonts_directory):
for name in files:
(basename, ext) = os.path.splitext(name)
if ext in possible_extensions:
figfont = os.path.join(root, name)
print(figfont)
# get font category out of last folder
catalogue = root.split('/')[-2]
type = root.split('/')[-1]
if type in output:
f = {}
output[type]['fonts'].append(f)
f['name'] = name
f['catalogue'] = catalogue
f['ascii'] = text2figlet(params['text'], figfont)
f['svg'] = ascii2svg(f['ascii'], params['weight'])
f['ascii_fix'] = ascii_autofix(f['ascii'])
f['ascii_fix_indication'] = autofix_indication(f['ascii_fix'])
f['svg_fix'] = ascii2svg(f['ascii_fix'], params['weight'])
return render_template(
'catalogue.html',
title = title,
databases = databases,
output = output,
params = params)
# ----------------------------------------------------------
def make_svg ():
return ''
@app.route('/hpgl/')
def hpgl ():
# generate svg
svg = make_svg()
# store as a temporary file
(svg_file, svg_path) = tempfile.mkstemp()
svg_file.write(svg)
# transform to hpgl
hpgl = svgToHPGL(svg_path)
# remove tmp file
os.remove(svg_path)
r = Response(hpgl, mimetype='application/hpgl')
r.headers.extend({
'Content-Disposition': 'attachment; filename="cobbled-paths.hpgl"'
})
return r
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')