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 ":"see the exercise with the specified", "thesis ":"see the thesis with the specified", "whois ":"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+" ") 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 and for thesis type: thesis ") printer.newline() term.waitforinput() main()