|
|
import argparse
|
|
|
import sys
|
|
|
import os
|
|
|
import six
|
|
|
from random import randint
|
|
|
import random
|
|
|
from PIL import Image, ImageOps
|
|
|
import curses
|
|
|
import sys, termios, tty, os, time
|
|
|
import apirequest
|
|
|
import imageprinter
|
|
|
import requests
|
|
|
import subprocess
|
|
|
from subprocess import check_output
|
|
|
import datetime
|
|
|
import time
|
|
|
import re
|
|
|
|
|
|
class Printer():
|
|
|
ESC = b'\x1B'
|
|
|
FORMFEED = b'\x0C'
|
|
|
UNDERLINEDON = b'\x1B'+b'\x2D'+b'\x31'
|
|
|
UNDERLINEDOFF = b'\x1B'+b'\x2D'+b'\x30'
|
|
|
ITALICON = b'\x1B'+b'\x34'
|
|
|
ITALICOFF = b'\x1B'+b'\x35'
|
|
|
CPITWELF = b'\x1B'+b'\x4D'
|
|
|
NLQ= b'\x1B'+b'\x78'+b'\x31'
|
|
|
NLQ2 = b'\x1B'+b'\x6B'+b'\x01'
|
|
|
BOLDON = b'\x1B'+b'\x45'
|
|
|
BOLDOFF = b'\x1B'+b'\x46'
|
|
|
DHON = b'\x1B'+b'\x77'+b'\x01'
|
|
|
DHOFF = b'\x1B'+b'\x77'+b'\x00'
|
|
|
COMPRON = b'\x1B'+b'\x0f'
|
|
|
COMPROFF = b'\x1B'+b'\x12'
|
|
|
CHANGE_EMULATION = ESC+b'\x7B'+b'\x65'
|
|
|
LINE_FEED = b'\n'
|
|
|
CARIDGE_RET = b'\x0D'
|
|
|
CHARWIDTH = 70 #78 is actual, but -8 for safty
|
|
|
printedheight = 0
|
|
|
pages = 1
|
|
|
strokes = 0
|
|
|
lineheight = 33
|
|
|
debug = False
|
|
|
target = "/dev/usb/lp0"
|
|
|
if debug:
|
|
|
target = "/dev/tty"
|
|
|
|
|
|
|
|
|
def formfeed(self, exit=False):
|
|
|
with open(self.target, 'wb') as printer:
|
|
|
if not self.debug:
|
|
|
while self.checkpagebreak(printer, exit) == False:
|
|
|
self.printedheight+=(self.lineheight/216)
|
|
|
printer.write(self.LINE_FEED)
|
|
|
|
|
|
|
|
|
|
|
|
def printchar(self,char):
|
|
|
with open(self.target, 'wb') as printer:
|
|
|
if self.debug:
|
|
|
printer.write(bytes(str(char), 'utf-8'))
|
|
|
else:
|
|
|
printer.write(self.ESC+b"\x7B"+b"\x41")
|
|
|
char=self.strokes*" "+char
|
|
|
printer.write(bytes(str(char), 'utf-8'))
|
|
|
printer.write(self.ESC+b"\x25"+b"\x46"+b"\x0F"+b"\x00"+b"\x04"+b"\x08"+b"\x00")
|
|
|
self.strokes += 1
|
|
|
if(self.strokes>self.CHARWIDTH):
|
|
|
self.checkpagebreak(printer)
|
|
|
self.printedheight+=(self.lineheight/216)
|
|
|
printer.write(self.LINE_FEED)
|
|
|
self.strokes = 0
|
|
|
|
|
|
def printstring(self,string, formating="p"):
|
|
|
strokesinline = 0
|
|
|
with open(self.target, 'wb') as printer:
|
|
|
if self.debug:
|
|
|
if formating == "compr":
|
|
|
self.CHARWIDTH = 120
|
|
|
else:
|
|
|
self.CHARWIDTH = 70
|
|
|
if formating == "u":
|
|
|
printer.write(b"\x1B"+b"\x5B"+b"\x34"+b"\x6D")
|
|
|
printer.write(bytes(str(string), 'utf-8'))
|
|
|
printer.write(b"\x1B"+b"\x5B"+b"\x30"+b"\x6D")
|
|
|
else:
|
|
|
for word in re.split(r'(\s+)', string):
|
|
|
if "&&ref" in word and "&&endref" not in word:
|
|
|
subwords = word.split("&&ref")
|
|
|
word = subwords[1]
|
|
|
printer.write(b"\x1B"+b"\x5B"+b"\x34"+b"\x6D")
|
|
|
if "&&endref" in word:
|
|
|
subwords = word.split("&&endref")
|
|
|
word = subwords[1]
|
|
|
printer.write(b"\x1B"+b"\x5B"+b"\x30"+b"\x6D")
|
|
|
|
|
|
strokesinline += len(word)
|
|
|
if "\n" in word:
|
|
|
strokesinline = 0
|
|
|
if strokesinline > self.CHARWIDTH:
|
|
|
printer.write(self.LINE_FEED)
|
|
|
strokesinline = len(word)
|
|
|
if strokesinline > self.CHARWIDTH:
|
|
|
firstpart = word[:self.CHARWIDTH]
|
|
|
secondpart = word[self.CHARWIDTH:]
|
|
|
printer.write(bytes(str(firstpart), 'utf-8'))
|
|
|
printer.write(self.LINE_FEED)
|
|
|
printer.write(bytes(str(secondpart), 'utf-8'))
|
|
|
|
|
|
elif not (strokesinline == 1 and word == " "):
|
|
|
printer.write(bytes(str(word), 'utf-8'))
|
|
|
|
|
|
else:
|
|
|
printer.write(self.ESC+b"\x7B"+b"\x41")
|
|
|
printer.write(self.ESC + b"\x33" + bytes([self.lineheight]));
|
|
|
#printer.write(self.NLQ)
|
|
|
#printer.write(self.NLQ2)
|
|
|
self.CHARWIDTH = 70
|
|
|
if formating == "u":
|
|
|
printer.write(self.BOLDON)
|
|
|
if formating == "p":
|
|
|
printer.write(self.CPITWELF)
|
|
|
if formating == "i":
|
|
|
printer.write(self.ITALICON)
|
|
|
if formating == "dh":
|
|
|
printer.write(self.DHON)
|
|
|
if formating == "compr":
|
|
|
printer.write(self.COMPRON)
|
|
|
self.CHARWIDTH = 120
|
|
|
if formating == "compru":
|
|
|
printer.write(self.UNDERLINEDON)
|
|
|
printer.write(self.COMPRON)
|
|
|
self.CHARWIDTH = 120
|
|
|
|
|
|
for word in re.split(r'(\s+)', string):
|
|
|
if "&&ref" in word:
|
|
|
subwords = word.split("&&ref")
|
|
|
word = subwords[1]
|
|
|
printer.write(self.COMPRON)
|
|
|
if "&&endref" in word:
|
|
|
subwords = word.split("&&endref")
|
|
|
word = subwords[1]
|
|
|
printer.write(self.COMPROFF)
|
|
|
if "&&uline" in word:
|
|
|
subwords = word.split("&&uline")
|
|
|
word = subwords[1]
|
|
|
printer.write(self.UNDERLINEDON)
|
|
|
if "&&enduline" in word:
|
|
|
subwords = word.split("&&enduline")
|
|
|
word = subwords[1]
|
|
|
printer.write(self.UNDERLINEDOFF)
|
|
|
strokesinline += len(word)
|
|
|
if "\n" in word:
|
|
|
for _ in range(word.count("\n")):
|
|
|
strokesinline = 0
|
|
|
self.checkpagebreak(printer)
|
|
|
self.printedheight+=(self.lineheight/216)
|
|
|
if strokesinline > self.CHARWIDTH:
|
|
|
self.checkpagebreak(printer)
|
|
|
self.printedheight+=(self.lineheight/216)
|
|
|
printer.write(self.LINE_FEED)
|
|
|
strokesinline = len(word)
|
|
|
if strokesinline > self.CHARWIDTH:
|
|
|
firstpart = word[:self.CHARWIDTH]
|
|
|
secondpart = word[self.CHARWIDTH:]
|
|
|
printer.write(bytes(str(firstpart), 'utf-8'))
|
|
|
self.checkpagebreak(printer)
|
|
|
self.printedheight+=(self.lineheight/216)
|
|
|
printer.write(self.LINE_FEED)
|
|
|
printer.write(bytes(str(secondpart), 'utf-8'))
|
|
|
elif not (strokesinline == 1 and word == " "):
|
|
|
printer.write(str(word).encode("ascii","ignore"))
|
|
|
if formating == "u":
|
|
|
printer.write(self.BOLDOFF)
|
|
|
if formating == "i":
|
|
|
printer.write(self.ITALICOFF)
|
|
|
if formating == "dh":
|
|
|
printer.write(self.DHOFF)
|
|
|
if formating == "compr":
|
|
|
printer.write(self.COMPROFF)
|
|
|
if formating == "compru":
|
|
|
printer.write(self.COMPROFF)
|
|
|
printer.write(self.UNDERLINEDOFF)
|
|
|
#printer.write(self.ESC+b"\x25"+b"\x46"+b"\x0F"+b"\x00"+b"\x04"+b"\x08"+b"\x00")
|
|
|
try:
|
|
|
self.newline()
|
|
|
except:
|
|
|
time.sleep(1)
|
|
|
self.newline()
|
|
|
|
|
|
def newline(self):
|
|
|
global strokes
|
|
|
with open(self.target, 'wb') as printer:
|
|
|
if not self.debug:
|
|
|
self.checkpagebreak(printer)
|
|
|
printer.write(self.ESC + b"\x33" + bytes([self.lineheight]));
|
|
|
self.printedheight+=(self.lineheight/216)
|
|
|
printer.write(self.LINE_FEED)
|
|
|
self.strokes = 0
|
|
|
|
|
|
def checkpagebreak(self, printer, exit=False):
|
|
|
print(self.printedheight)
|
|
|
if self.printedheight+(self.lineheight/216)*4 > 11.69:
|
|
|
printer.write(self.ESC + b"\x33" + bytes([self.lineheight]));
|
|
|
printer.write(self.LINE_FEED)
|
|
|
printer.write(self.LINE_FEED)
|
|
|
printer.write(bytes(str("PAGE "+str(self.pages)), 'utf-8'));
|
|
|
printer.write(self.LINE_FEED)
|
|
|
printer.write(self.LINE_FEED)
|
|
|
printer.write(self.LINE_FEED)
|
|
|
printer.write(self.ESC + b"\x33" + bytes([20]));
|
|
|
printer.write(self.LINE_FEED)
|
|
|
printer.write(self.ESC + b"\x33" + bytes([self.lineheight]));
|
|
|
if not exit:
|
|
|
printer.write(self.COMPRON)
|
|
|
printer.write(bytes(str("------------------------------------------------------ POETIC SOFTWARE PUBLICATION -----------------------------------------------------"), 'utf-8'));
|
|
|
printer.write(self.COMPROFF)
|
|
|
printer.write(self.LINE_FEED)
|
|
|
self.printedheight=(self.lineheight/216)
|
|
|
self.pages+=1
|
|
|
else:
|
|
|
self.printedheight=0
|
|
|
self.pages=1
|
|
|
return True
|
|
|
else:
|
|
|
return False
|
|
|
|
|
|
def printimagefromurl(self, url):
|
|
|
page = requests.get(url)
|
|
|
f_ext = os.path.splitext(url)[-1]
|
|
|
f_name = 'img{}'.format(f_ext)
|
|
|
with open(f_name, 'wb') as f:
|
|
|
f.write(page.content)
|
|
|
|
|
|
if self.debug:
|
|
|
#rows, columns = os.popen('stty size', 'r').read().split()
|
|
|
#subprocess.call(["catimg","-w",columns,f_name])
|
|
|
subprocess.call(["feh",f_name])
|
|
|
else:
|
|
|
imagelines = imageprinter.print(f_name,True)
|
|
|
#((imagelines*22)%self.lineheight)/11
|
|
|
|
|
|
if self.printedheight + (22/216)*imagelines +(self.lineheight/216)*4 > 11.69:
|
|
|
self.formfeed()
|
|
|
self.printedheight += (22/216)*imagelines
|
|
|
imageprinter.print(f_name)
|
|
|
with open('/dev/usb/lp0', 'wb') as printer:
|
|
|
printer.write(self.ESC + b"\x33" + bytes([11]));
|
|
|
for _ in range(int(((imagelines*22)%self.lineheight)/11)):
|
|
|
self.checkpagebreak(printer)
|
|
|
self.printedheight += (11/216)
|
|
|
printer.write(self.LINE_FEED)
|
|
|
print(imagelines)
|
|
|
print(((imagelines*22)%self.lineheight)/11)
|
|
|
printer.write(self.ESC + b"\x33" + bytes([self.lineheight]));
|
|
|
self.newline()
|
|
|
|
|
|
# 10 lines 220
|
|
|
|
|
|
|
|
|
class Terminal():
|
|
|
lineinput = ""
|
|
|
commandMode = True
|
|
|
writeloop = True
|
|
|
|
|
|
commands = {
|
|
|
"help":"get help on the commands",
|
|
|
"start":"start publication",
|
|
|
"list":"list theses and exercises",
|
|
|
"exercise <number>":"see the exercise with the <number> specified",
|
|
|
"thesis <number>":"see the thesis with the <number> specified",
|
|
|
"whois <person>":"get biography of person given",
|
|
|
"exit":"finish the publication",
|
|
|
}
|
|
|
|
|
|
def __init__(self,printer, persons):
|
|
|
self.printer = printer
|
|
|
self.persons = persons
|
|
|
|
|
|
def waittostart(self):
|
|
|
self.writeloop = True
|
|
|
while self.writeloop:
|
|
|
char = self.getch()
|
|
|
self.writeloop = False
|
|
|
self.lineinput = ""
|
|
|
continue
|
|
|
|
|
|
def waitforinput(self, nocommand=False):
|
|
|
self.writeloop = True
|
|
|
self.printer.printchar("> ")
|
|
|
while self.writeloop:
|
|
|
char = self.getch()
|
|
|
if (ord(char) == 27):
|
|
|
print("exit publication :-(")
|
|
|
exit(0)
|
|
|
if (ord(char) == 13):
|
|
|
self.printer.newline()
|
|
|
if not nocommand:
|
|
|
if not self.lineinput == "":
|
|
|
self.command(self.lineinput)
|
|
|
self.lineinput = ""
|
|
|
self.printer.printchar("> ")
|
|
|
else:
|
|
|
self.writeloop = False
|
|
|
|
|
|
else:
|
|
|
self.lineinput+=char
|
|
|
self.printer.printchar(char)
|
|
|
|
|
|
def getch(self):
|
|
|
fd = sys.stdin.fileno()
|
|
|
old_settings = termios.tcgetattr(fd)
|
|
|
try:
|
|
|
tty.setraw(sys.stdin.fileno())
|
|
|
ch = sys.stdin.read(1)
|
|
|
|
|
|
finally:
|
|
|
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
|
|
return ch
|
|
|
|
|
|
def scanwifi(self):
|
|
|
self.printer.newline()
|
|
|
out = check_output(["nmcli", "dev", "wif"])
|
|
|
self.printer.printstring(out.decode("utf-8"))
|
|
|
|
|
|
def list(self):
|
|
|
self.printer.printstring("theses on POETIC SOFTWARE", "u")
|
|
|
result = apirequest.getcategory("thesis")
|
|
|
for i, line in enumerate(result):
|
|
|
printer.printstring(str(i+1)+" "+line)
|
|
|
self.printer.newline()
|
|
|
self.printer.printstring("exercises in POETIC SOFTWARE","u")
|
|
|
result = apirequest.getcategory("exercise")
|
|
|
for i, line in enumerate(result):
|
|
|
printer.printstring(str(i+1)+" "+line)
|
|
|
self.printer.newline()
|
|
|
|
|
|
def command(self, command):
|
|
|
#print("received command: "+str(command))
|
|
|
if "help" == str(command):
|
|
|
self.printer.printstring("The user in this publication is an active agent. The publication can be assembled according to your own wishes using commands. The following commands can be used.")
|
|
|
for key, help in self.commands.items():
|
|
|
self.printer.printstring(key+":")
|
|
|
self.printer.printstring(" "+help)
|
|
|
#self.writeloop = False
|
|
|
|
|
|
elif "list" == str(command):
|
|
|
self.list()
|
|
|
|
|
|
elif "start" == str(command) or "restart" == str(command):
|
|
|
main()
|
|
|
|
|
|
elif "ff" == str(command):
|
|
|
self.printer.formfeed()
|
|
|
|
|
|
elif str(command).split(" ")[0] == "exercise" or str(command).split(" ")[0] == "thesis":
|
|
|
part = str(command).split(" ")[0]
|
|
|
arguments = str(command.strip()).split(" ")
|
|
|
arguments.pop(0)
|
|
|
if len(arguments) < 1:
|
|
|
self.printer.printstring("no argument given. Usage: "+part+" <number>")
|
|
|
else:
|
|
|
for i,arg in enumerate(arguments):
|
|
|
if arg.isdigit():
|
|
|
number = int(arg)
|
|
|
if number > len(apirequest.getcategory(part)):
|
|
|
self.printer.printstring("Number must be inbetween 1 and "+ str(len(apirequest.getcategory(part))))
|
|
|
else:
|
|
|
result = apirequest.gettitle(part, number)
|
|
|
for line in result:
|
|
|
self.printer.printstring(line, "u")
|
|
|
result = apirequest.getimages(part, number)
|
|
|
for img in result:
|
|
|
self.printer.printimagefromurl(img)
|
|
|
#get and print content of thesis or exercise
|
|
|
result = apirequest.getcontent(part, number)
|
|
|
for line in result:
|
|
|
self.printer.printstring(line)
|
|
|
#check for specific things like the wifi
|
|
|
if apirequest.gettitle(part, number)[0] == "Wifi Poem":
|
|
|
self.scanwifi()
|
|
|
result = apirequest.getlinks(part, number)
|
|
|
self.printer.newline()
|
|
|
for i, line in enumerate(result):
|
|
|
if i%2 == 0:
|
|
|
self.printer.printstring(line, "compru")
|
|
|
else:
|
|
|
self.printer.printstring(line, "compr")
|
|
|
self.printer.newline()
|
|
|
else:
|
|
|
self.printer.printstring("not a number")
|
|
|
|
|
|
elif str(command).split(" ")[0] == "whois":
|
|
|
if str(command).split(" ")[1] in self.persons:
|
|
|
self.printer.printstring(self.persons[str(command).split(" ")[1]])
|
|
|
else:
|
|
|
self.printer.printstring("Sorry not found, try " + random.choice(list(self.persons)))
|
|
|
|
|
|
elif "exit" == str(command):
|
|
|
self.printer.printstring("Imprint", "u")
|
|
|
self.printer.newline()
|
|
|
self.printer.printstring("2019, Piet Zwart Institute, Rotterdam")
|
|
|
self.printer.printstring("Published by Alexander Roidl")
|
|
|
self.printer.printstring("and (enter your name)")
|
|
|
self.printer.newline()
|
|
|
self.waitforinput(nocommand=True)
|
|
|
self.printer.newline()
|
|
|
self.printer.printstring("Special thanks to Aymeric Mansoux, Marloes de Valk, Michael Murtaugh, André Castro, Clara Balaguer, Amy Suo Wu, Leslie Robbins, Angeliki, Alice, Tash, Zalan, Joca, Jule")
|
|
|
self.printer.formfeed(True)
|
|
|
main()
|
|
|
|
|
|
else:
|
|
|
self.printer.printstring("~ command not found. type help for a list of available commands")
|
|
|
self.printer.newline()
|
|
|
|
|
|
#if the command is valid we want to execute the command and continue the story
|
|
|
#self.writeloop = False
|
|
|
|
|
|
persons = {
|
|
|
"Kittler":"Friedrich A. Kittler (June 12, 1943 – October 18, 2011) was a literary scholar and a media theorist. His works relate to media, technology, and the military. ",
|
|
|
"Alex":"Alexander Roidl created Poetic Software as part of his Master's thesis.",
|
|
|
"Michael":"Michael Murtaugh is an independent computer programmer (automatist.org) and a member of Constant Art & Media (constantvzw.org) in Brussels where he lives.",
|
|
|
"Aymeric":"Aymeric Mansoux (FR) is an artist, musician and media researcher, with a background in economics, fine art, graphic design, and computer programming. ",
|
|
|
"Jule":"Jule Ulrych is an evironmental activist and passionate vegan food lover living in Den Haag."
|
|
|
}
|
|
|
printer = Printer()
|
|
|
term = Terminal(printer, persons)
|
|
|
now = datetime.datetime.now()
|
|
|
|
|
|
ascii = '''::::::::: :::::::: :::::::::: ::::::::::: ::::::::::: ::::::::
|
|
|
:+: :+: :+: :+: :+: :+: :+: :+: :+:
|
|
|
+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+
|
|
|
+#++:++#+ +#+ +:+ +#++:++# +#+ +#+ +#+
|
|
|
+#+ +#+ +#+ +#+ +#+ +#+ +#+
|
|
|
#+# #+# #+# #+# #+# #+# #+# #+#
|
|
|
### ######## ########## ### ########### ########
|
|
|
|
|
|
:::::::: :::::::: :::::::::: ::::::::::: ::: ::: ::: ::::::::: ::::::::::
|
|
|
:+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+:
|
|
|
+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+
|
|
|
+#++:++#++ +#+ +:+ :#::+::# +#+ +#+ +:+ +#+ +#++:++#++: +#++:++#: +#++:++#
|
|
|
+#+ +#+ +#+ +#+ +#+ +#+ +#+#+ +#+ +#+ +#+ +#+ +#+ +#+
|
|
|
#+# #+# #+# #+# #+# #+# #+#+# #+#+# #+# #+# #+# #+# #+#
|
|
|
######## ######## ### ### ### ### ### ### ### ### ##########
|
|
|
|
|
|
SOFTWARE & ART'''
|
|
|
|
|
|
def main():
|
|
|
term.waittostart()
|
|
|
printer.printstring(ascii, "compr")
|
|
|
printer.formfeed();
|
|
|
printer.newline()
|
|
|
printer.printstring("W E L C O M E !", "dh")
|
|
|
printer.newline()
|
|
|
printer.printstring(now.strftime("%Y-%m-%d %H:%M"), "compr")
|
|
|
printer.newline()
|
|
|
#
|
|
|
# # printer.formfeed()
|
|
|
|
|
|
printer.printstring("---------------")
|
|
|
printer.printstring("POETIC SOFTWARE")
|
|
|
printer.printstring("---------------")
|
|
|
printer.printstring("type help for help")
|
|
|
printer.newline()
|
|
|
result = apirequest.gettitle("introduction", 1)
|
|
|
for line in result:
|
|
|
printer.printstring(line, "u")
|
|
|
result = apirequest.getcontent("introduction", 1)
|
|
|
for line in result:
|
|
|
printer.printstring(line)
|
|
|
|
|
|
printer.newline()
|
|
|
term.list()
|
|
|
printer.printstring("SELECT which one to see, for exercise type: exercise <number> and for thesis type: thesis <number>")
|
|
|
printer.newline()
|
|
|
term.waitforinput()
|
|
|
|
|
|
main()
|