big work-in-progress: image support added, experimenting with font sizes, inverted text, line width, line height & more. Disabled all RSS feeds for now, except the toots coming from post.lurk.org... to be continued!
This commit is contained in:
parent
5cd98e3e06
commit
e7adf397e7
@ -2,7 +2,6 @@
|
||||
|
||||
https://televex.vvvvvvaria.org/
|
||||
|
||||
|
||||
Experimental communication tools (televex screen + televex print).
|
||||
|
||||
## TeleVex Screen
|
||||
@ -17,7 +16,10 @@ Live: in the Varia windows.
|
||||
|
||||
## TeleVex Print
|
||||
|
||||
(Flask application + EPSON printer)
|
||||
web interface -----> printer
|
||||
Multifeeder -----> printer
|
||||
|
||||
(Flask web application + EPSON printer)
|
||||
|
||||
`$ make print`
|
||||
|
||||
@ -25,7 +27,7 @@ The main script is: `print/start.py`
|
||||
|
||||
Live: <https://televex.vvvvvvaria.org/print/>
|
||||
|
||||
Local: `localhost:5000`
|
||||
Local: `localhost:5000/print`
|
||||
|
||||
## Install TeleVex
|
||||
|
||||
|
@ -11,11 +11,12 @@ from tools.televex import televex
|
||||
# Create the application.
|
||||
APP = flask.Flask(__name__)
|
||||
|
||||
# Connect to the printer
|
||||
lp, lp_printer = televex.connect()
|
||||
|
||||
# Set up a JSON database for storing printed items
|
||||
db = televex.database('printed.json')
|
||||
db_path = 'printed.json'
|
||||
db = televex.database(db_path)
|
||||
|
||||
# Connect to the printer
|
||||
lp = televex.connect()
|
||||
|
||||
# Check the Multifeeder regulary (every 10 min)
|
||||
# https://github.com/viniciuschiele/flask-apscheduler
|
||||
@ -28,7 +29,7 @@ scheduler.start()
|
||||
@scheduler.task('interval', id='check', minutes=1)
|
||||
def check():
|
||||
try:
|
||||
url = 'https://multi.vvvvvvaria.org/API/latest/10'
|
||||
url = 'https://multi.vvvvvvaria.org/API/latest/3'
|
||||
response = urllib.request.urlopen(url).read()
|
||||
feed = json.loads(response)
|
||||
except:
|
||||
@ -36,25 +37,38 @@ def check():
|
||||
|
||||
for post in feed:
|
||||
source = post['feed_details']['rss']
|
||||
txt = post['summary']
|
||||
televex.print_now(txt, source, db, post=post, lp=lp, lp_printer=lp_printer)
|
||||
|
||||
|
||||
# only print toots for now (this is a test)
|
||||
if 'post.lurk.org' in source:
|
||||
txt, date = televex.preprocess(post, type='rss')
|
||||
already_in_db = televex.update_db(db, db_path, txt, source, date)
|
||||
if already_in_db == False:
|
||||
televex.print_now(txt, lp=lp, type='rss')
|
||||
|
||||
@APP.route('/print/', methods=['GET', 'POST'])
|
||||
def print():
|
||||
txt = request.args.get('printing', '')
|
||||
img = request.files.get('img')
|
||||
|
||||
if txt:
|
||||
source = 'TeleVex'
|
||||
televex.print_now(txt, source, db, lp=lp, lp_printer=lp_printer)
|
||||
|
||||
txt, date = televex.preprocess(txt, type='txt')
|
||||
televex.update_db(db, db_path, txt, source, date)
|
||||
televex.print_now(txt, lp=lp, type='txt')
|
||||
return flask.redirect(flask.url_for('print'))
|
||||
|
||||
return flask.render_template('index.html')
|
||||
elif img:
|
||||
source = 'TeleVex'
|
||||
img, date = televex.preprocess(img, type='img')
|
||||
televex.update_db(db, db_path, 'IMAGE', source, date)
|
||||
televex.print_now(img, lp=lp, type='img')
|
||||
return flask.redirect(flask.url_for('print'))
|
||||
|
||||
return flask.render_template('print.html')
|
||||
|
||||
@APP.route('/printed/', methods=['GET'])
|
||||
def printed():
|
||||
items = json.loads(open(db).read())
|
||||
return flask.render_template('printed.html', items=items)
|
||||
db = televex.database(db_path)
|
||||
return flask.render_template('printed.html', items=db)
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP.debug=True
|
||||
|
@ -1,5 +1,4 @@
|
||||
body{
|
||||
color:magenta;
|
||||
margin:2em;
|
||||
}
|
||||
div#print,
|
||||
@ -12,7 +11,7 @@ div#multifeeder div.multipost{
|
||||
margin:1em 0;
|
||||
}
|
||||
div#webcam img{
|
||||
width:500px;
|
||||
width: 500px;
|
||||
}
|
||||
pre{
|
||||
margin: 1em 0;
|
||||
|
@ -21,10 +21,11 @@
|
||||
|
||||
<br>
|
||||
|
||||
<h2>Image printing access point (not working yet)</h2>
|
||||
<form action="" method="GET">
|
||||
<button>Select image</button>
|
||||
<input class="submit" type="submit" value="print image"/>
|
||||
<h2>Image printing access point (png, jpg, gif)</h2>
|
||||
<form action="" method="POST" enctype=multipart/form-data>
|
||||
<input type="file" name="img" accept=".png, .jpg, .gif">
|
||||
<br><br>
|
||||
<input class="submit" type="submit" value="print"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -2,94 +2,116 @@ import sys, os, re, json
|
||||
from datetime import datetime, date
|
||||
import html2text
|
||||
from escpos import printer
|
||||
|
||||
from tools.asciiWriter.text import make_column
|
||||
from tools.asciiWriter.utils import merge, print_lines, make_lines, translate
|
||||
from PIL import Image
|
||||
import base64
|
||||
import io
|
||||
|
||||
def connect():
|
||||
# Get the printer's USB initializing code with $ sudo lsbusb
|
||||
try:
|
||||
lp = printer.Usb(0x4b8,0xe15)
|
||||
lp_printer = True
|
||||
# lp = printer.Usb(0x4b8,0xe15) # televex printer @ Varia
|
||||
lp = printer.Usb(0x4b8,0xe03) # printer @ poel
|
||||
except:
|
||||
lp = None
|
||||
lp_printer = False
|
||||
|
||||
return lp, lp_printer
|
||||
return lp
|
||||
|
||||
def database(db):
|
||||
if not os.path.exists(db):
|
||||
with open(db, 'w') as f:
|
||||
def database(db_path):
|
||||
if not os.path.exists(db_path):
|
||||
with open(db_path, 'w') as f:
|
||||
f.write(json.dumps({ "printed" : [] }, indent=4))
|
||||
|
||||
f = open(db_path).read()
|
||||
db = json.loads(f)
|
||||
|
||||
return db
|
||||
|
||||
def html2plain(html):
|
||||
# remove HTML tags
|
||||
txt = re.sub(r'<.*?>', '', html)
|
||||
|
||||
# make line breaks
|
||||
# https://git.vvvvvvaria.org/mb/ascii-art-but-with-unicode
|
||||
width = 48
|
||||
layers = []
|
||||
lines, remaining = make_column(txt, line_width=width)
|
||||
layers.append(lines)
|
||||
merged = merge(width, len(lines), ' ', layers)
|
||||
txt = ''
|
||||
for line in merged:
|
||||
txt += '{}\n'.format(''.join(line))
|
||||
|
||||
|
||||
return txt
|
||||
|
||||
def update_db(txt, source, db, post=None):
|
||||
try:
|
||||
items = json.loads(open(db).read())
|
||||
except:
|
||||
items = { "printed" : [] } # Hmm ...
|
||||
|
||||
# save the publishing date of this post
|
||||
if post:
|
||||
def preprocess(output, type=None):
|
||||
# date_str = None
|
||||
if type == 'txt':
|
||||
txt = output
|
||||
if type == 'txt' or type == 'img':
|
||||
post_date = datetime.now()
|
||||
date_str = post_date.strftime('%Y-%m-%d_%H-%M-%S')
|
||||
if type == 'rss':
|
||||
post = output
|
||||
txt = post['summary']
|
||||
year = post['published_parsed'][0]
|
||||
month = post['published_parsed'][1]
|
||||
day = post['published_parsed'][2]
|
||||
post_date = date(year, month, day)
|
||||
date_str = post_date.strftime('%Y-%m-%d')
|
||||
post = None
|
||||
else:
|
||||
post_date = datetime.now()
|
||||
date_str = post_date.strftime('%Y-%m-%d_%H-%M-%S')
|
||||
if type == 'txt' or type == 'rss':
|
||||
output = html2plain(txt)
|
||||
|
||||
# clean txt from HTML tags
|
||||
txt = html2plain(txt)
|
||||
# limit printouts to 25 lines (this is a test)
|
||||
# lines = [line for line in txt.split('\n')][:25]
|
||||
# txt = '\n'.join(lines)
|
||||
|
||||
# add txt to database
|
||||
return output, date_str
|
||||
|
||||
def update_db(db, db_path, post, source, date, type=None):
|
||||
# add post to database
|
||||
# and check if this item is new
|
||||
item = {
|
||||
'source' : source,
|
||||
'date' : date_str,
|
||||
'printed' : txt
|
||||
'date' : date,
|
||||
'printed' : post
|
||||
}
|
||||
if item not in items['printed']:
|
||||
new_item = True
|
||||
with open(db, 'w') as out:
|
||||
items['printed'].append(item)
|
||||
out.write(json.dumps(items, indent=4))
|
||||
if item not in db['printed']:
|
||||
already_in_db = False
|
||||
with open(db_path, 'w') as out:
|
||||
db['printed'].append(item)
|
||||
out.write(json.dumps(db, indent=4))
|
||||
out.close()
|
||||
else:
|
||||
new_item = False
|
||||
already_in_db = True
|
||||
|
||||
return new_item, txt
|
||||
return already_in_db
|
||||
|
||||
def print_now(txt, source, db, post=None, lp=None, lp_printer=None):
|
||||
# check if this is a new item
|
||||
new_item, txt = update_db(txt, source, db, post=post)
|
||||
def print_now(output, lp=None, type=None):
|
||||
# configure the printouts
|
||||
if lp:
|
||||
if type == 'rss':
|
||||
lp.set(
|
||||
invert=True,
|
||||
font='b',
|
||||
width=6, # 1-8
|
||||
height=6, # 1-8
|
||||
)
|
||||
lp.line_spacing(spacing=75) # 0 - 255
|
||||
columns = 12 # b 8 8
|
||||
elif type == "txt":
|
||||
lp.set(
|
||||
align='left',
|
||||
font='b',
|
||||
text_type='normal', # B, U, U2, BU, BU2, NORMAL
|
||||
width=1, # 1-8
|
||||
height=1, # 1-8
|
||||
density=9, # 0-8, 9=keep unchanged
|
||||
invert=False,
|
||||
smooth=False,
|
||||
flip=False
|
||||
)
|
||||
lp.line_spacing(spacing=65) # 0 - 255
|
||||
# columns = 48 # a 1 1
|
||||
columns = 65 # b 1 1
|
||||
elif type == 'img':
|
||||
lp.line_spacing(spacing=50) # 0 - 255
|
||||
|
||||
# if this item is new
|
||||
# then print!
|
||||
if new_item == True:
|
||||
if lp_printer == True:
|
||||
lp.text(txt)
|
||||
# print
|
||||
if lp:
|
||||
if type == 'txt' or type == 'rss':
|
||||
lp.block_text(output, columns=columns) # columns=line width
|
||||
lp.cut()
|
||||
else:
|
||||
# or print in the terminal!
|
||||
sys.stderr.write('Printing output to the terminal:\n\n'+txt+'\n\n')
|
||||
elif type == 'img':
|
||||
lp.image(output)
|
||||
lp.cut()
|
||||
else:
|
||||
sys.stderr.write('Printing output to the terminal:\n\n'+txt+'\n\n')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user