app.py 5.97 KB
Newer Older
gijs's avatar
gijs committed
1
2
#!/usr/bin/env/ python

gijs's avatar
gijs committed
3
4
5
6
7
8
9
10
11
12
13
14
#    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
gijs's avatar
gijs committed
15
# from weasyprint import HTML
gijs's avatar
gijs committed
16
from pagedjs import make_pdf
gijs's avatar
gijs committed
17
18
from settings import DEBUG, BASEURL, DEFAULT_LANGUAGE, SECRET_KEY

gijs's avatar
gijs committed
19
20
import textwrap

gijs's avatar
gijs committed
21
22
import os
from fcntl import lockf, LOCK_EX, LOCK_UN
gijs's avatar
gijs committed
23

gijs's avatar
gijs committed
24
# Spacy tries to import CUDA, do not break when it fails
gijs's avatar
gijs committed
25
try:
gijs's avatar
gijs committed
26
  from paseo import crear_camino
gijs's avatar
gijs committed
27
28
29
30
31
32
except ModuleNotFoundError:
  pass

import os.path

basepath = os.path.dirname(__file__)
gijs's avatar
gijs committed
33
34

app = Flask(__name__)
gijs's avatar
gijs committed
35
app.secret_key = SECRET_KEY
gijs's avatar
gijs committed
36

gijs's avatar
gijs committed
37
38
39
# Book HTML is loaded through filesystem, in a tmp dir, make path absolute.
PAGEDJS_STATIC_DIR = os.path.join(basepath, 'static')

gijs's avatar
gijs committed
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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

gijs's avatar
gijs committed
81
82
83
84
85
86
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 ]

gijs's avatar
gijs committed
87
88
89
90
91
92
93
94
95
96
97
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():
gijs's avatar
gijs committed
98
99
100
101
  context = {
    BASEURL: BASEURL
  }
  return render_template('index.html', **context)
gijs's avatar
gijs committed
102
103

def index_en():
gijs's avatar
gijs committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  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
gijs's avatar
gijs committed
130
131
132
133
134
135
136
137
138
139
140

@app.route('{}/en'.format(BASEURL))
def en():
  set_language('en')
  return index()
  
@app.route('{}/es'.format(BASEURL))
def es():
  set_language('es')
  return index()

gijs's avatar
gijs committed
141
142
@app.route('{}/'.format(BASEURL))
def index():
gijs's avatar
gijs committed
143
144
145
146
  if get_language() == 'es':
    return index_es()
  else:
    return index_en()
gijs's avatar
gijs committed
147

gijs's avatar
gijs committed
148
149
150
151
def book_es ():
  edition_count = get_edition_count_es()

  fragment = max(0, min(1, int(request.form['fragment'])))  
gijs's avatar
gijs committed
152
153
154
155
156

  first_word = 'un'

  if fragment == 0:
    novel = os.path.join(basepath, '../data/emilia_prueba.txt')
gijs's avatar
gijs committed
157
158
    author = 'Emilia Pardo Bazán' # Non breaking spaces
    title = 'La Madre Naturaleza' # Non breaking spaces
gijs's avatar
gijs committed
159
160
  else:
    novel = os.path.join(basepath, '../data/prueba.txt')
gijs's avatar
gijs committed
161
    author = 'Benito Pérez Gáldos' # Non breaking spaces
gijs's avatar
gijs committed
162
163
    title = 'Miau'

gijs's avatar
gijs committed
164
165
  path = add_last_word_previous_step(crear_camino(novel, first_word, 'es'))
  complete_sentence = path[-1][1] + path[-1][0]
gijs's avatar
gijs committed
166

gijs's avatar
gijs committed
167
168
169
170
171
  context = { 
    'title': title, 
    'author': author, 
    'path': path, 
    'STATIC_DIR': '/static' if DEBUG else PAGEDJS_STATIC_DIR,
gijs's avatar
gijs committed
172
173
    'DEBUG': DEBUG,
    'edition_count': edition_count,
gijs's avatar
gijs committed
174
175
    'sources': read_sources('paseo.py', 'medialab.py'),
    'complete_sentence': complete_sentence,
gijs's avatar
gijs committed
176
177
  }
  
gijs's avatar
gijs committed
178
  html = render_template('book.html', **context)
gijs's avatar
gijs committed
179
180
181
182
183
  
  if (DEBUG):
    return html
  else:
    pdf = make_pdf(html)
gijs's avatar
gijs committed
184

gijs's avatar
gijs committed
185
    r = Response(pdf, mimetype='application/pdf')
gijs's avatar
gijs committed
186

gijs's avatar
gijs committed
187
    r.headers.extend({
gijs's avatar
gijs committed
188
      'Content-Disposition': 'attachment; filename="Paseo por arboles de Madrid.pdf"'
gijs's avatar
gijs committed
189
    })
gijs's avatar
gijs committed
190

gijs's avatar
gijs committed
191
    return r
gijs's avatar
gijs committed
192
193
194
195
196
197
198
199
200

def book_en ():
  edition_count = get_edition_count_en()
  
  fragment = max(0, min(1, int(request.form['fragment'])))  

  first_word = 'a'

  if fragment == 0:
gijs's avatar
gijs committed
201
    novel = os.path.join(basepath, '../data/emilia_english_fragment.txt')
gijs's avatar
gijs committed
202
203
204
    author = 'Emilia Pardo Bazán' # Non breaking spaces
    title = 'The Swan of Vila Morta' # Non breaking spaces
  else:
gijs's avatar
gijs committed
205
    novel = os.path.join(basepath, '../data/benito_english_fragment.txt')
gijs's avatar
gijs committed
206
207
208
    author = 'Benito Pérez Gáldos' # Non breaking spaces
    title = 'Marianela'

gijs's avatar
gijs committed
209
210
  path = add_last_word_previous_step(crear_camino(novel, first_word, 'en'))
  complete_sentence = path[-1][1] + path[-1][0]
gijs's avatar
gijs committed
211
212
213
214
215
216
217
218

  context = { 
    'title': title, 
    'author': author, 
    'path': path, 
    'STATIC_DIR': '/static' if DEBUG else PAGEDJS_STATIC_DIR,
    'DEBUG': DEBUG,
    'edition_count': edition_count,
gijs's avatar
gijs committed
219
220
    'sources': read_sources('paseo.py', 'medialab.py'),
    'complete_sentence': complete_sentence,
gijs's avatar
gijs committed
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
  }
  
  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()