or re.search('[Cc]annabis', title) is not None
or re.search('[Cc]annabis', description) is not None
or 'THC' in title
+ or re.search('[Tt]op.[Rr]ated', title) is not None
or re.search('[Ll]ose [Ww]eight', title) is not None
or re.search('[Ll]ose [Ww]eight', description) is not None
)
filename = f"/timestamps/last_camera_motion_{camera}"
ts = os.stat(filename).st_ctime
age = now - ts
- if ts != self.last_trigger_timestamp[camera] and age < 10:
- logger.info(f'{camera} is triggered; {filename} touched {age}s ago (@{ts}')
+ print(f'{camera} => {age}')
+ if ts != self.last_trigger_timestamp[camera]:
self.last_trigger_timestamp[camera] = ts
- num_cameras_with_recent_triggers += 1
+ if age < 15:
+ logger.info(f'{camera} is triggered; {filename} touched {age}s ago (@{ts}')
+ num_cameras_with_recent_triggers += 1
- self.triggers_in_the_past_seven_min[camera] = 0
- filename = f"/timestamps/camera_motion_history_{camera}"
- with open(filename, "r") as f:
- contents = f.readlines()
- for x in contents:
- x = x.strip()
- age = now - int(x)
- if age < (60 * 7):
- self.triggers_in_the_past_seven_min[camera] += 1
+ self.triggers_in_the_past_seven_min[camera] = 0
+ filename = f"/timestamps/camera_motion_history_{camera}"
+ with open(filename, "r") as f:
+ contents = f.readlines()
+ for x in contents:
+ x = x.strip()
+ age = now - int(x)
+ if age < (60 * 7):
+ self.triggers_in_the_past_seven_min[camera] += 1
+ print(f'{camera} past 7m: {self.triggers_in_the_past_seven_min[camera]}')
# Second pass, see whether we want to trigger due to
# camera activity we found. All cameras timestamps were
# just considered and should be up-to-date. Some logic to
# squelch spammy cameras unless more than one is triggered
# at the same time.
+ print(f'{num_cameras_with_recent_triggers}')
for camera in camera_list:
- if (now - self.last_trigger_timestamp[camera]) < 10:
+ if (now - self.last_trigger_timestamp[camera]) < 15:
if (
self.triggers_in_the_past_seven_min[camera] <= 4
or num_cameras_with_recent_triggers > 1
):
- logger.info(f'{camera} has {self.triggers_in_the_past_seven_min[camera]} triggers in the past 7d.')
- logger.info(f'{num_cameras_with_recent_triggers} cameras are triggered right now.')
+ print(f'{camera} has {self.triggers_in_the_past_seven_min[camera]} triggers in the past 7d.')
+ print(f'{num_cameras_with_recent_triggers} cameras are triggered right now.')
age = now - self.last_trigger_timestamp[camera]
priority = self.choose_priority(camera, int(age))
- logger.info(f'*** CAMERA TRIGGER (hidden/{camera}.html @ {priority}) ***')
+ print(f'*** CAMERA TRIGGER (hidden/{camera}.html @ {priority}) ***')
triggers.append(
(
f"hidden/unwrapped_{camera}.html",
import time
from typing import Any, Callable, List, Optional, Set, Tuple
-import datetime_utils
+from pyutilz.datetimez import datetime_utils
import kiosk_constants
import trigger
from typing import Dict, List, Optional, Union
import xml.etree.ElementTree as ET
+from scottutilz import profanity_filter
+
import file_writer
import grab_bag
import renderer
import page_builder
-import profanity_filter
logger = logging.getLogger(__file__)
}
self.keep = gkeepapi.Keep()
success = self.keep.login(
- secrets.google_keep_username, secrets.google_keep_password
+ secrets.google_keep_username,
+ secrets.google_keep_password,
+ secrets.google_keep_mac,
)
if success:
logger.debug("Connected with gkeep.")
def periodic_render(self, key: str) -> bool:
strikethrough = re.compile("(\u2611[^\n]*)\n", re.UNICODE)
- linkify = re.compile(r".*(https?:\/\/\S+).*")
+ #linkify = re.compile(r".*(https?:\/\/\S+).*")
self.keep.sync()
result_list = self.keep.find(labels=[self.keep.findLabel("kiosk")])
num_lines = len(individual_lines)
contents = ""
for x in individual_lines:
- length = len(x)
leading_spaces = len(x) - len(x.lstrip(" "))
leading_spaces //= 2
leading_spaces = int(leading_spaces)
<HR style="border-top:3px solid white;">
"""
)
- if num_lines >= 12:
+ if num_lines >= 10:
logger.debug(
f"{num_lines} lines: two column mode"
)
import pvporcupine
import pytz
-import bootstrap
-import config
-import datetime_utils
-import file_utils
+from pyutilz import (
+ bootstrap,
+ config,
+)
+from pyutilz.datetimez import datetime_utils
+from pyutilz.files import file_utils
import kiosk_constants
import file_writer
"Trip to California, '16",
"Trip to San Francisco",
"Trip to East Coast '16",
+ "Turkey 2022",
"Tuscany 2008",
"Yosemite 2010",
"WA Roadtrip, 2021",
import pymyq # type: ignore
from typing import Dict, Optional
-import datetime_utils
+from pyutilz.datetimez import datetime_utils
import kiosk_constants
import file_writer
import praw # type: ignore
+from scottutilz import profanity_filter
+
import file_writer
import grab_bag
import page_builder
-import profanity_filter
import renderer
import kiosk_secrets as secrets
import time
from typing import Dict, Optional, Set
-from decorator_utils import invocation_logged
+from pyutilz.decorator_utils import invocation_logged
logger = logging.getLogger(__file__)
"SPY",
"BTC-USD",
"IEMG",
- "OPTAX",
+ "ABHYX",
"SPAB",
"SPHD",
"GC=F",
#!/usr/bin/env python3
-import datetime
import json
import logging
import requests
from typing import Dict
-import datetime_utils
import file_writer
import renderer
ret = f'''
<TABLE>
<TR>
- <TD><B>temperature:</B></TD>
- <TD>{conditions['temperature']}°{conditions['temperatureUnit'][0]}</TD>
+ <TD WIDTH="150"><FONT SIZE=+2><B>Temp:</B></FONT></TD>
+ <TD><FONT SIZE=+2>{conditions['temperature']}°{conditions['temperatureUnit'][0]}</FONT></TD>
</TR>
<TR>
- <TD><B>weather:</B></TD>
- <TD>{conditions['weather']}</TD>
+ <TD><FONT SIZE=+2><B>Weather:</B></FONT></TD>
+ <TD><FONT SIZE=+2>{conditions['weather']}</FONT></TD>
</TR>
<TR>
- <TD><B>road:</B></TD>
- <TD>{conditions['roadCondition']}</TD>
+ <TD><FONT SIZE=+2><B>Roadway:</B></FONT></TD>
+ <TD><FONT SIZE=+2>{conditions['roadCondition']}</FONT></TD>
</TR>'''
- if 'restrictionOne' in conditions or 'restrictionTwo' in conditions:
+ if 'restrictionOne' in conditions and 'restrictionTwo' in conditions:
ret += '''
<TR>
- <TD><B>restrictions:</B></TD>
- <TD>'''
- if 'restrictionOne' in conditions:
+ <TD><FONT SIZE=+2><B>Restrictions:</B></FONT></TD>
+ <TD><FONT SIZE=+2>'''
+ count = 0
+ msg = conditions['restrictionOne'].get('publicPage', 'no restrictions')
+ if msg.lower() != 'no restrictions':
+ count += 1
+ msg = conditions['restrictionTwo'].get('publicPage', 'no restrictions')
+ if msg.lower() != 'no restrictions':
+ count += 1
+ if count == 2:
ret += f'''
- {conditions['restrictionOne']['travelDirectionName']}:
- {conditions['restrictionOne']['publicPage']}<BR>'''
- if 'restrictionTwo' in conditions:
- ret += f'''
- {conditions['restrictionTwo']['travelDirectionName']}:
- {conditions['restrictionTwo']['publicPage']}'''
- ret += '</TR></TABLE>'
+ <U>{conditions['restrictionOne']['travelDirectionName']}:</U>
+ {conditions['restrictionOne']['publicPage']} <BR>
+ <U>{conditions['restrictionTwo']['travelDirectionName']}:</U>
+ {conditions['restrictionTwo']['publicPage']}'''
+ elif count == 1:
+ msg = conditions['restrictionOne'].get('publicPage', 'no restrictions')
+ if msg.lower() != 'no restrictions':
+ ret += f'''
+ <U>{conditions['restrictionOne']['travelDirectionName']}:</U>
+ {conditions['restrictionOne']['publicPage']}<BR>'''
+ else:
+ ret += f'''
+ <U>{conditions['restrictionTwo']['travelDirectionName']}:</U>
+ {conditions['restrictionTwo']['publicPage']}<BR>'''
+ else:
+ ret += '''None.<BR>'''
+ ret += '</FONT></TD></TR></TABLE>'
return ret
def render_forecast(forecasts: Dict[str, str]) -> str:
color = ' BGCOLOR="#dfefff"'
ret += f'''
<TR>
- <TD{color}><B>{f['periodText']}</B></TD>
+ <TD WIDTH="150" valign="top" {color}><B>{f['periodText']}</B></TD>
<TD{color}>{f['forecastText']}</TD>
</TR>'''
ret += '</TABLE>'
if camera['cameraId'] == 8063:
return f'''
<CENTER>
- <IMG SRC={camera['cameraUrl']} WIDTH={camera['width']}>
+ <A HREF='https://wsdot.com/travel/real-time/mountainpasses/Stevens'>
+ <IMG SRC={camera['cameraUrl']} WIDTH={camera['width'] * 1.75}>
+ </A>
<BR>
- <B>{camera['cameraLabel']} ({camera['direction']})</B>
+ <I>{camera['cameraLabel']} ({camera['direction']})</I>
</CENTER>'''
return ''
conditions = contents['condition']
cameras = contents['cameras']
forecasts = contents['stationForecasts'][0]
- now = datetime_utils.now_pacific()
- tss = conditions['displayDate']
- tss = tss.replace('Z', '+00:00')
- ts = datetime.datetime.strptime(tss, '%Y-%m-%dT%H:%M:%S.%f%z')
- tss = datetime_utils.describe_timedelta_briefly(now - ts)
with file_writer.file_writer('stevens-conditions_5_3000.html') as f:
f.write(f'''
-<H2>Stevens Pass Conditions ~{tss} ago:</H2>
+<H1>Stevens Pass Conditions:</H1>
<HR>
<TABLE WIDTH=90%>
<TR>
return True
return False
-test = stevens_renderer({"Test", 123})
-test.periodic_render("Test")
+# Test:
+#test = stevens_renderer({"Test", 123})
+#test.periodic_render("Test")
return True
# Test
-#x = stock_quote_renderer({}, ["MSFT", "GOOG", "BTC-USD", "OPTAX", "GC=F", "VNQ"], { "BTC-USD": "BTC", "GC=F": "GOLD" })
+#x = stock_quote_renderer({}, ["MSFT", "GOOG", "BTC-USD", "ABHYX", "GC=F", "VNQ"], { "BTC-USD": "BTC", "GC=F": "GOLD" })
#x.periodic_render(None)
from typing import Dict
from bs4 import BeautifulSoup # type: ignore
+from pyutilz import profanity_filter
import file_writer
import grab_bag
import page_builder
-import profanity_filter
import renderer
# Test
-#x = stranger_events_renderer({"Test", 123})
-#x.periodic_render("Fetch Events")
-#x.periodic_render("Shuffle Events")
+x = stranger_events_renderer({"Test", 123})
+x.periodic_render("Fetch Events")
+x.periodic_render("Shuffle Events")
from typing import Dict, List
import tweepy # type: ignore
+from pyutilz import profanity_filter
import file_writer
import renderer
-import profanity_filter
import kiosk_secrets as secrets