-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
-import constants
-import file_writer
-import gkeepapi
+import logging
import os
import re
+from typing import Dict
+
+import gkeepapi # type: ignore
+
+import kiosk_constants
+import file_writer
import renderer
-import secrets
+import kiosk_secrets as secrets
-class gkeep_renderer(renderer.debuggable_abstaining_renderer):
- def __init__(self, name_to_timeout_dict):
- super(gkeep_renderer, self).__init__(name_to_timeout_dict, True)
- self.keep = gkeepapi.Keep()
- success = self.keep.login(secrets.google_keep_username,
- secrets.google_keep_password)
- if success:
- self.debug_print("Connected with gkeep.")
- else:
- self.debug_print("Error connecting with gkeep.")
+
+logger = logging.getLogger(__name__)
+
+
+class gkeep_renderer(renderer.abstaining_renderer):
+ def __init__(self, name_to_timeout_dict: Dict[str, int]) -> None:
+ super().__init__(name_to_timeout_dict)
self.colors_by_name = {
- 'white' : '#002222',
- 'green' : '#345920',
- 'darkblue' : '#1F3A5F',
- 'blue' : '#2D545E',
- 'orange' : '#604A19',
- 'red' : '#5C2B29',
- 'purple' : '#42275E',
- 'pink' : '#5B2245',
- 'yellow' : '#635D19',
- 'brown' : '#442F19',
- 'gray' : '#3c3f4c',
- 'teal' : '#16504B'
+ "white": "#002222",
+ "green": "#345920",
+ "darkblue": "#1F3A5F",
+ "blue": "#2D545E",
+ "orange": "#604A19",
+ "red": "#5C2B29",
+ "purple": "#42275E",
+ "pink": "#5B2245",
+ "yellow": "#635D19",
+ "brown": "#442F19",
+ "gray": "#3c3f4c",
+ "teal": "#16504B",
}
+ self.keep = gkeepapi.Keep()
+ self.token_file = "./.google_keep_token"
+ if os.path.exists(self.token_file):
+ logger.debug("Attempting to reuse persisted Google Keep login token...")
+ try:
+ with open(self.token_file, "r") as rf:
+ token = "".join(rf.readlines()).strip()
+ self.keep.resume(secrets.google_keep_username, token)
+ logger.debug("Successfully reused existing login token.")
+ except gkeepapi.exception.LoginException:
+ logger.warning("Invalid token, attempting to re-login.")
- def debug_prefix(self):
+ if not self.keep.login(
+ secrets.google_keep_username,
+ secrets.google_keep_password,
+ secrets.google_keep_mac,
+ ):
+ raise Exception("Error connecting with Google Keep?!")
+ logger.debug("Successfully logged in with Google Keep")
+
+ def debug_prefix(self) -> str:
return "gkeep"
- def periodic_render(self, key):
- strikethrough = re.compile('(\u2611[^\n]*)\n', re.UNICODE)
- linkify = re.compile(r'.*(https?:\/\/\S+).*')
+ def periodic_render(self, key: str) -> bool:
+ strikethrough = re.compile("(\u2611[^\n]*)\n", re.UNICODE)
+ # linkify = re.compile(r".*(https?:\/\/\S+).*")
self.keep.sync()
- result_list = self.keep.find(labels=[self.keep.findLabel('kiosk')])
+ result_list = self.keep.find(labels=[self.keep.findLabel("kiosk")])
for note in result_list:
title = note.title
title = title.replace(" ", "-")
title = title.replace("/", "")
- filename = "%s_2_3600.html" % title
+ filename = f"{title}_2_3600.html"
contents = note.text + "\n"
- self.debug_print("Note title '%s'" % title)
- if contents != '' and not contents.isspace():
- contents = strikethrough.sub('', contents)
- contents = contents.replace(u'\u2610',
- u'<LI><INPUT TYPE="checkbox"> ')
-
- #self.debug_print("Note contents:\n%s" % contents)
- contents = linkify.sub(r'<a href="\1">\1</a>', contents)
+ logger.debug(f"Note title '{title}'")
+ if contents != "" and not contents.isspace():
+ contents = strikethrough.sub("", contents)
+ logger.debug(f"Note contents:\n{contents}")
+ contents = contents.replace(
+ "\u2610 ", '<LI><INPUT TYPE="checkbox"> '
+ )
+ # contents = linkify.sub(r'<a href="\1">\1</a>', contents)
individual_lines = contents.split("\n")
num_lines = len(individual_lines)
- max_length = 0
- indent = 0
contents = ""
for x in individual_lines:
- length = len(x)
- if length > max_length:
- max_length = length
- spaces = len(x) - len(x.lstrip(' '))
- spaces /= 2
- x = x.lstrip(' ')
- if spaces > indent:
+ leading_spaces = len(x) - len(x.lstrip(" "))
+ leading_spaces //= 2
+ leading_spaces = int(leading_spaces)
+ x = x.lstrip(" ")
+ # logger.debug(" * (%d) '%s'" % (leading_spaces, x))
+ for y in range(0, leading_spaces):
x = "<UL>" + x
- elif spaces < indent:
- x = "</UL>" + x
- indent = spaces
+ for y in range(0, leading_spaces):
+ x = x + "</UL>"
contents = contents + x + "\n"
individual_lines = contents.split("\n")
if color in list(self.colors_by_name.keys()):
color = self.colors_by_name[color]
else:
- self.debug_print("Unknown color '%s'" % color)
- f = file_writer.file_writer(filename)
- f.write("""
+ logger.debug(f"Unknown color '{color}'")
+ print(f"TITLE: {color} {note.title}")
+ with file_writer.file_writer(filename) as f:
+ f.write(
+ """
<STYLE type="text/css">
a:link { color:#88bfbf; }
ul { list-style-type:none; }
</STYLE>
-<DIV STYLE="border-radius: 25px; border-style: solid; padding: 20px; background-color: %s; color: #eeeeee; font-size: x-large;">
-<p style="color: #ffffff; font-size:larger"><B>%s</B></p>
-<HR style="border-top: 3px solid white;">""" % (color, note.title))
- if num_lines >= 12 and max_length < 120:
- self.debug_print("%d lines (max=%d chars): two columns" %
- (num_lines, max_length))
- f.write("<TABLE BORDER=0 WIDTH=100%%><TR valign=\"top\">")
- f.write("<TD WIDTH=50%% style=\"color:#eeeeee; font-size:large\">\n")
- f.write("<FONT><UL>")
- count = 0
- for x in individual_lines:
- f.write(x + "\n")
- count += 1
- if count == num_lines / 2:
- f.write("</UL></FONT></TD>\n")
- f.write("<TD WIDTH=50%% style=\"color:#eeeeee; font-size:large\">\n")
- f.write("<FONT><UL>")
- f.write("</UL></FONT></TD></TR></TABLE></DIV>\n");
- else:
- self.debug_print("%d lines (max=%d chars): one column" %
- (num_lines, max_length))
- f.write("<FONT><UL>%s</UL></FONT>" % contents)
- f.write("</DIV>")
- f.close()
+<DIV STYLE="border-radius:25px; border-style:solid; padding:20px; background-color:%s; color:#eeeeee; font-size:x-large;">
+"""
+ % color
+ )
+ f.write(
+ f"""
+<p style="color:#ffffff; font-size:larger"><B>{note.title}</B></p>
+<HR style="border-top:3px solid white;">
+"""
+ )
+ if num_lines >= 10:
+ logger.debug(f"{num_lines} lines: two column mode")
+ f.write('<TABLE BORDER=0 WIDTH=100%><TR valign="top">')
+ f.write(
+ '<TD WIDTH=50% style="color:#eeeeee; font-size:large">\n'
+ )
+ f.write("<FONT><UL STYLE='list-style-type:none'>")
+ count = 0
+ for x in individual_lines:
+ f.write(x + "\n")
+ count += 1
+ if count == num_lines / 2:
+ f.write("</UL></FONT></TD>\n")
+ f.write(
+ '<TD WIDTH=50% style="color:#eeeeee; font-size:large">\n'
+ )
+ f.write("<FONT><UL STYLE='list-style-type:none'>")
+ f.write("</UL></FONT></TD></TR></TABLE></DIV>")
+ else:
+ logger.debug(f"{num_lines} lines: one column mode")
+ f.write(f"<FONT><UL>{contents}</UL></FONT>")
+ f.write("</DIV>")
else:
- self.debug_print("Note is empty, deleting %s." % filename)
- _ = os.path.join(constants.pages_dir, filename)
+ logger.debug(f"Note is empty, deleting {filename}.")
+ _ = os.path.join(kiosk_constants.pages_dir, filename)
try:
os.remove(_)
except:
pass
+
+ if self.token_file:
+ token = self.keep.getMasterToken()
+ os.umask(0)
+ descriptor = os.open(
+ path=self.token_file,
+ flags=(os.O_WRONLY | os.O_CREAT | os.O_TRUNC),
+ mode=0o600,
+ )
+ with open(descriptor, "w") as wf:
+ print(token, file=wf)
+ logger.debug("Saved Google Keep token successfully.")
return True
+
# Test
-#x = gkeep_renderer({"Test", 1234})
-#x.periodic_render("Test")
+# logger.setLevel(logging.DEBUG)
+# ch = logging.StreamHandler()
+# ch.setLevel(logging.DEBUG)
+# formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+# ch.setFormatter(formatter)
+# logger.addHandler(ch)
+# x = gkeep_renderer({"Test", 1234})
+# x.periodic_render("Test")