big cleanup and rearrange into modules. added skeleton for publications CMS. added a sales dept to play vids from barcodes.
parent
7df4a77645
commit
66ef6b4318
@ -1,50 +0,0 @@
|
|||||||
import twitter
|
|
||||||
|
|
||||||
from bureau import Bureau, add_command, add_api
|
|
||||||
|
|
||||||
|
|
||||||
class MailRoom(Bureau):
|
|
||||||
"""
|
|
||||||
The Mail Room handles (electronic) post for the other Bureaus of
|
|
||||||
the Screenless Office.
|
|
||||||
"""
|
|
||||||
|
|
||||||
name = "Mail Room"
|
|
||||||
prefix = "PS"
|
|
||||||
version = 0
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
Bureau.__init__(self)
|
|
||||||
|
|
||||||
@add_command("fax", "Send a Document Camera Image via Email")
|
|
||||||
def fax(self, to_id):
|
|
||||||
"""
|
|
||||||
Takes a photograph using the document camera and sends it in an E-mail.
|
|
||||||
"""
|
|
||||||
callback = self.prefix + "fax."
|
|
||||||
args = {"to_id": to_id}
|
|
||||||
self.send("PXphoto.", {"callback": callback, "cb_args": args})
|
|
||||||
|
|
||||||
@add_api("tweetpic_cb", "callback for tweet_pic")
|
|
||||||
def tweetpic_cb(self, data):
|
|
||||||
"""
|
|
||||||
This does the actual uploading of the picture.
|
|
||||||
"""
|
|
||||||
photo = data["photo"]
|
|
||||||
auth = twitter.OAuth(
|
|
||||||
"423391766-bhjHwzD1eJfxB9s7ZvmeHReNVJM0d93kJ8KSrHEZ",
|
|
||||||
"qSvSYMs4lpSKbZtiuOjB1Gon5rzye8whvadcOdDpFocwa",
|
|
||||||
"arI4UCnfMeKZwAnyvJJIHVnUN",
|
|
||||||
"agrtzvh3eqSNlZpmPJZ0otclqSUjLKI3JrqugCPrp1Ch9dqsTl")
|
|
||||||
t = twitter.Twitter(auth=auth)
|
|
||||||
|
|
||||||
with open(photo, "rb") as imagefile:
|
|
||||||
imagedata = imagefile.read()
|
|
||||||
t_up = twitter.Twitter(domain='upload.twitter.com', auth=auth)
|
|
||||||
id_img1 = str(t_up.media.upload(media=imagedata)["media_id"])
|
|
||||||
t.statuses.update(status="PTT ★", media_ids=id_img1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
pr = PublicRelations()
|
|
||||||
pr.run()
|
|
@ -0,0 +1,4 @@
|
|||||||
|
from . import mailroom
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ihr.main()
|
@ -0,0 +1,90 @@
|
|||||||
|
import email.header
|
||||||
|
|
||||||
|
import imapclient
|
||||||
|
|
||||||
|
from bureau import Bureau, add_command, add_api
|
||||||
|
|
||||||
|
|
||||||
|
class MailRoom(Bureau):
|
||||||
|
"""
|
||||||
|
The Mail Room handles (electronic) post for the other Bureaus of
|
||||||
|
the Screenless Office.
|
||||||
|
"""
|
||||||
|
|
||||||
|
name = "Mail Room"
|
||||||
|
prefix = "PO"
|
||||||
|
version = 0
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
Bureau.__init__(self)
|
||||||
|
# TODO: multiple accounts / folders
|
||||||
|
if "user" in self.config:
|
||||||
|
self.login = self.config["user"]["login"]
|
||||||
|
self.password = self.config["user"]["password"]
|
||||||
|
self.host = self.config["user"]["host"]
|
||||||
|
self.imapserv = imapclient.IMAPClient(self.host, use_uid=True, ssl=True)
|
||||||
|
self.imapserv.login(self.login, self.password)
|
||||||
|
self.imapserv.select_folder("INBOX")
|
||||||
|
else:
|
||||||
|
print("you need to configure an IMAP account!")
|
||||||
|
print("add a [user] section to PO.ini with:")
|
||||||
|
print(" login = mylogin")
|
||||||
|
print(" password = mypassword")
|
||||||
|
print(" host = my.imap.server.address.com")
|
||||||
|
|
||||||
|
@add_command("fax", "Send a Document Camera Image via Email")
|
||||||
|
def fax(self, data):
|
||||||
|
"""
|
||||||
|
Takes a photograph using the document camera and sends it in an E-mail.
|
||||||
|
"""
|
||||||
|
self.send("PXphoto.")
|
||||||
|
|
||||||
|
@add_command("rd", "Print full email")
|
||||||
|
def read(self, data):
|
||||||
|
"""
|
||||||
|
Prints out the full detailed version of an email.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@add_command("d", "Delete email")
|
||||||
|
def delete(self, data):
|
||||||
|
"""
|
||||||
|
Deletes an email and moves it to the trash folder.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@add_command("s", "Mark as spam")
|
||||||
|
def mark_spam(self, data):
|
||||||
|
"""
|
||||||
|
Flags an email as spam, mark as read and move it to the configured SPAM
|
||||||
|
folder.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@add_command("re", "Reply with scan")
|
||||||
|
def reply_scan(self, data):
|
||||||
|
"""
|
||||||
|
Reply to the sender of a mail with the PDF currently queued in the
|
||||||
|
document scanner.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@add_api("unread", "Get unread mails")
|
||||||
|
def unread(self):
|
||||||
|
"""
|
||||||
|
Polls the currently configured IMAP server and returns a dict
|
||||||
|
containing unread emails.
|
||||||
|
"""
|
||||||
|
messages = self.imapserv.sort("ARRIVAL", ["UNSEEN"])
|
||||||
|
print("%d unread messages in INBOX" % len(messages))
|
||||||
|
return self.imapserv.fetch(messages, ['FLAGS', 'INTERNALDATE',
|
||||||
|
'ENVELOPE', 'RFC822.SIZE'])
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
mr = MailRoom()
|
||||||
|
mr.run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -0,0 +1,4 @@
|
|||||||
|
from . import publications
|
||||||
|
|
||||||
|
def main():
|
||||||
|
publications.main()
|
@ -0,0 +1,68 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
import PIL
|
||||||
|
|
||||||
|
from bureau import Bureau, add_command, add_api
|
||||||
|
|
||||||
|
|
||||||
|
class Publications(Bureau):
|
||||||
|
"""
|
||||||
|
The Publications Office serves as a kind of screenless content management
|
||||||
|
system. Create, update and organize your sites while doing most of the work
|
||||||
|
on paper or anything you can photograph.
|
||||||
|
"""
|
||||||
|
|
||||||
|
name = "Publications Office"
|
||||||
|
prefix = "PB"
|
||||||
|
version = 0
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
Bureau.__init__(self)
|
||||||
|
self.db = os.path.expanduser("~/.screenless/PB.data")
|
||||||
|
if not os.path.exists(self.db):
|
||||||
|
os.mkdir(self.db)
|
||||||
|
|
||||||
|
|
||||||
|
@add_command("new", "Create a new Publication/Site")
|
||||||
|
def new_site(self):
|
||||||
|
"""
|
||||||
|
Create a new Publication/Site, set up config and tace a picture from
|
||||||
|
the document camera as the index page. Finally, it will print out
|
||||||
|
the main page with commands for working with the site.
|
||||||
|
"""
|
||||||
|
site_dir = os.path.join(self.db, "1")
|
||||||
|
site_id = 1
|
||||||
|
while os.path.exists(site_dir):
|
||||||
|
site_id += 1
|
||||||
|
site_dir = os.path.join(self.db, str(site_id))
|
||||||
|
os.mkdir(site_dir)
|
||||||
|
|
||||||
|
root_d = {"template": "default", "id": site_id}
|
||||||
|
with open(os.path.join(site_dir, "root.json", "w")) as root_json:
|
||||||
|
root_json.write(json.dumps(root_d))
|
||||||
|
|
||||||
|
photo = self.send("PX", "photo")["photo"]
|
||||||
|
|
||||||
|
# TODO: come up with a generic set of img form operations for Bureau
|
||||||
|
# should map regions defined with percentages to names
|
||||||
|
form_img = PIL.Image.open(photo)
|
||||||
|
fx, fy = form_img.size
|
||||||
|
title_region = (0, 0, 0.5 * fx, 0.125 * fy)
|
||||||
|
title_img = form_img.crop(title_region)
|
||||||
|
content_region = (0, 0.125 * fy, fx, fy)
|
||||||
|
content_img = form_img.crop(content_region)
|
||||||
|
|
||||||
|
def _update_page(self, site, page):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
pb = Publications()
|
||||||
|
pb.run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -0,0 +1,4 @@
|
|||||||
|
from . import sales
|
||||||
|
|
||||||
|
def main():
|
||||||
|
sales.main()
|
@ -0,0 +1,11 @@
|
|||||||
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
|
import code128
|
||||||
|
|
||||||
|
chars = string.ascii_letters + string.digits
|
||||||
|
for code in range(30):
|
||||||
|
code = ''.join(random.choice(chars) for _ in range(5))
|
||||||
|
code = "SAp." + code
|
||||||
|
with open("/tmp/" + code + ".svg", "w") as f:
|
||||||
|
f.write(code128.svg(code, caption=True))
|
@ -0,0 +1,43 @@
|
|||||||
|
import glob
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from bureau import Bureau, add_command
|
||||||
|
|
||||||
|
|
||||||
|
class Sales(Bureau):
|
||||||
|
"""
|
||||||
|
The sales department makes presentations to potential customers.
|
||||||
|
"""
|
||||||
|
|
||||||
|
name = "Sales Office"
|
||||||
|
prefix = "SA"
|
||||||
|
version = 0
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
Bureau.__init__(self)
|
||||||
|
try:
|
||||||
|
self.db = os.mkdir("SA")
|
||||||
|
except FileExistsError:
|
||||||
|
pass # we've already got a db folder
|
||||||
|
|
||||||
|
@add_command("p", "Play Media")
|
||||||
|
def print_fortune(self, data):
|
||||||
|
"""
|
||||||
|
Shows media on a connected projector or plays audio.
|
||||||
|
"""
|
||||||
|
searchpath = "SA/SAp." + data + "*"
|
||||||
|
print("looking in ", searchpath)
|
||||||
|
mediapath = glob.glob(searchpath)[0]
|
||||||
|
print("playing", mediapath)
|
||||||
|
cli = ["mplayer", "-fs", mediapath]
|
||||||
|
jux = subprocess.Popen(cli)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
sa = Sales()
|
||||||
|
sa.run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue