|
|
|
|
#!/usr/bin/env/ python
|
|
|
|
|
|
|
|
|
|
# Copyright (C) 2021, Anais Berck
|
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
# (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
# This program 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: <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
from flask import Flask, render_template, request, Response, session
|
|
|
|
|
# from weasyprint import HTML
|
|
|
|
|
from pagedjs import make_pdf
|
|
|
|
|
from settings import DEBUG, BASEURL, DEFAULT_LANGUAGE, SECRET_KEY
|
|
|
|
|
|
|
|
|
|
import textwrap
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
from fcntl import lockf, LOCK_EX, LOCK_UN
|
|
|
|
|
|
|
|
|
|
# Spacy tries to import CUDA, do not break when it fails
|
|
|
|
|
try:
|
|
|
|
|
from paseo import crear_camino
|
|
|
|
|
except ModuleNotFoundError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
import os.path
|
|
|
|
|
|
|
|
|
|
basepath = os.path.dirname(__file__)
|
|
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
app.secret_key = SECRET_KEY
|
|
|
|
|
|
|
|
|
|
# Book HTML is loaded through filesystem, in a tmp dir, make path absolute.
|
|
|
|
|
PAGEDJS_STATIC_DIR = os.path.join(basepath, 'static')
|
|
|
|
|
|
|
|
|
|
COUNTER_PATH_ES = 'edition_counter.txt'
|
|
|
|
|
COUNTER_PATH_EN = 'edition_counter_en.txt'
|
|
|
|
|
|
|
|
|
|
def get_edition_count_es():
|
|
|
|
|
fd = os.open(COUNTER_PATH_ES, os.O_RDWR|os.O_CREAT)
|
|
|
|
|
lockf(fd, LOCK_EX)
|
|
|
|
|
fo = os.fdopen(fd, 'r+', encoding='utf-8')
|
|
|
|
|
content = fo.read()
|
|
|
|
|
if not content:
|
|
|
|
|
edition_count = 0
|
|
|
|
|
else:
|
|
|
|
|
edition_count = int(content.strip())
|
|
|
|
|
edition_count += 1
|
|
|
|
|
fo.seek(0)
|
|
|
|
|
fo.truncate()
|
|
|
|
|
fo.write(str(edition_count))
|
|
|
|
|
fo.flush()
|
|
|
|
|
lockf(fd, LOCK_UN)
|
|
|
|
|
os.close(fd)
|
|
|
|
|
|
|
|
|
|
return edition_count
|
|
|
|
|
|
|
|
|
|
def get_edition_count_en():
|
|
|
|
|
fd = os.open(COUNTER_PATH_EN, os.O_RDWR|os.O_CREAT)
|
|
|
|
|
lockf(fd, LOCK_EX)
|
|
|
|
|
fo = os.fdopen(fd, 'r+', encoding='utf-8')
|
|
|
|
|
content = fo.read()
|
|
|
|
|
if not content:
|
|
|
|
|
edition_count = 0
|
|
|
|
|
else:
|
|
|
|
|
edition_count = int(content.strip())
|
|
|
|
|
edition_count += 1
|
|
|
|
|
fo.seek(0)
|
|
|
|
|
fo.truncate()
|
|
|
|
|
fo.write(str(edition_count))
|
|
|
|
|
fo.flush()
|
|
|
|
|
lockf(fd, LOCK_UN)
|
|
|
|
|
os.close(fd)
|
|
|
|
|
|
|
|
|
|
return edition_count
|
|
|
|
|
|
|
|
|
|
def wrap (text, width):
|
|
|
|
|
return'\n'.join(['\n'.join(textwrap.wrap(line, width=width)) for line in text.splitlines()])
|
|
|
|
|
|
|
|
|
|
def read_sources (*paths):
|
|
|
|
|
return [ (p, wrap(open(p, 'r').read(), 105)) for p in paths ]
|
|
|
|
|
|
|
|
|
|
def get_language():
|
|
|
|
|
if 'LANGUAGE' in session:
|
|
|
|
|
return session['LANGUAGE']
|
|
|
|
|
else:
|
|
|
|
|
return DEFAULT_LANGUAGE
|
|
|
|
|
|
|
|
|
|
def set_language(language):
|
|
|
|
|
session['LANGUAGE'] = language
|
|
|
|
|
session.modified = True
|
|
|
|
|
|
|
|
|
|
def index_es():
|
|
|
|
|
context = {
|
|
|
|
|
BASEURL: BASEURL
|
|
|
|
|
}
|
|
|
|
|
return render_template('index.html', **context)
|
|
|
|
|
|
|
|
|
|
def index_en():
|
|
|
|
|
context = {
|
|
|
|
|
BASEURL: BASEURL
|
|
|
|
|
}
|
|
|
|
|
return render_template('index_en.html', **context)
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
Adds the last word of the previous step to the itinerary
|
|
|
|
|
"""
|
|
|
|
|
def add_last_word_previous_step (itinerary):
|
|
|
|
|
new_itinerary = []
|
|
|
|
|
last_word_previous_step = None
|
|
|
|
|
|
|
|
|
|
for step in itinerary:
|
|
|
|
|
new_itinerary.append(
|
|
|
|
|
(
|
|
|
|
|
step[0],
|
|
|
|
|
step[1],
|
|
|
|
|
step[2],
|
|
|
|
|
step[3],
|
|
|
|
|
last_word_previous_step
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
last_word_previous_step = step[3][-1][0]
|
|
|
|
|
|
|
|
|
|
return new_itinerary
|
|
|
|
|
|
|
|
|
|
@app.route('{}/en'.format(BASEURL))
|
|
|
|
|
def en():
|
|
|
|
|
set_language('en')
|
|
|
|
|
return index()
|
|
|
|
|
|
|
|
|
|
@app.route('{}/es'.format(BASEURL))
|
|
|
|
|
def es():
|
|
|
|
|
set_language('es')
|
|
|
|
|
return index()
|
|
|
|
|
|
|
|
|
|
@app.route('{}/'.format(BASEURL))
|
|
|
|
|
def index():
|
|
|
|
|
if get_language() == 'es':
|
|
|
|
|
return index_es()
|
|
|
|
|
else:
|
|
|
|
|
return index_en()
|
|
|
|
|
|
|
|
|
|
def book_es ():
|
|
|
|
|
edition_count = get_edition_count_es()
|
|
|
|
|
|
|
|
|
|
fragment = max(0, min(1, int(request.form['fragment'])))
|
|
|
|
|
|
|
|
|
|
first_word = 'un'
|
|
|
|
|
|
|
|
|
|
if fragment == 0:
|
|
|
|
|
novel = os.path.join(basepath, '../data/emilia_prueba.txt')
|
|
|
|
|
author = 'Emilia Pardo Bazán' # Non breaking spaces
|
|
|
|
|
title = 'La Madre Naturaleza' # Non breaking spaces
|
|
|
|
|
else:
|
|
|
|
|
novel = os.path.join(basepath, '../data/prueba.txt')
|
|
|
|
|
author = 'Benito Pérez Gáldos' # Non breaking spaces
|
|
|
|
|
title = 'Miau'
|
|
|
|
|
|
|
|
|
|
path = add_last_word_previous_step(crear_camino(novel, first_word, 'es'))
|
|
|
|
|
complete_sentence = path[-1][1] + path[-1][0]
|
|
|
|
|
|
|
|
|
|
context = {
|
|
|
|
|
'title': title,
|
|
|
|
|
'author': author,
|
|
|
|
|
'path': path,
|
|
|
|
|
'STATIC_DIR': '/static' if DEBUG else PAGEDJS_STATIC_DIR,
|
|
|
|
|
'DEBUG': DEBUG,
|
|
|
|
|
'edition_count': edition_count,
|
|
|
|
|
'sources': read_sources('paseo.py', 'medialab.py'),
|
|
|
|
|
'complete_sentence': complete_sentence,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html = render_template('book.html', **context)
|
|
|
|
|
|
|
|
|
|
if (DEBUG):
|
|
|
|
|
return html
|
|
|
|
|
else:
|
|
|
|
|
pdf = make_pdf(html)
|
|
|
|
|
|
|
|
|
|
r = Response(pdf, mimetype='application/pdf')
|
|
|
|
|
|
|
|
|
|
r.headers.extend({
|
|
|
|
|
'Content-Disposition': 'attachment; filename="Paseo por arboles de Madrid.pdf"'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return r
|
|
|
|
|
|
|
|
|
|
def book_en ():
|
|
|
|
|
edition_count = get_edition_count_en()
|
|
|
|
|
|
|
|
|
|
fragment = max(0, min(1, int(request.form['fragment'])))
|
|
|
|
|
|
|
|
|
|
first_word = 'a'
|
|
|
|
|
|
|
|
|
|
if fragment == 0:
|
|
|
|
|
novel = os.path.join(basepath, '../data/emilia_english.txt')
|
|
|
|
|
author = 'Emilia Pardo Bazán' # Non breaking spaces
|
|
|
|
|
title = 'The Swan of Vila Morta' # Non breaking spaces
|
|
|
|
|
else:
|
|
|
|
|
novel = os.path.join(basepath, '../data/benito_english.txt')
|
|
|
|
|
author = 'Benito Pérez Gáldos' # Non breaking spaces
|
|
|
|
|
title = 'Marianela'
|
|
|
|
|
|
|
|
|
|
path = add_last_word_previous_step(crear_camino(novel, first_word, 'en'))
|
|
|
|
|
complete_sentence = path[-1][1] + path[-1][0]
|
|
|
|
|
|
|
|
|
|
context = {
|
|
|
|
|
'title': title,
|
|
|
|
|
'author': author,
|
|
|
|
|
'path': path,
|
|
|
|
|
'STATIC_DIR': '/static' if DEBUG else PAGEDJS_STATIC_DIR,
|
|
|
|
|
'DEBUG': DEBUG,
|
|
|
|
|
'edition_count': edition_count,
|
|
|
|
|
'sources': read_sources('paseo.py', 'medialab.py'),
|
|
|
|
|
'complete_sentence': complete_sentence,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html = render_template('book_en.html', **context)
|
|
|
|
|
|
|
|
|
|
if (DEBUG):
|
|
|
|
|
return html
|
|
|
|
|
else:
|
|
|
|
|
pdf = make_pdf(html)
|
|
|
|
|
|
|
|
|
|
r = Response(pdf, mimetype='application/pdf')
|
|
|
|
|
|
|
|
|
|
r.headers.extend({
|
|
|
|
|
'Content-Disposition': 'attachment; filename="Walk along the trees of Madrid.pdf"'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return r
|
|
|
|
|
@app.route('{}/book'.format(BASEURL), methods=['POST'])
|
|
|
|
|
def book():
|
|
|
|
|
if get_language() == 'es':
|
|
|
|
|
return book_es()
|
|
|
|
|
else:
|
|
|
|
|
return book_en()
|