diff --git a/login.py b/login.py
index 0bd97e1..2f66b73 100644
--- a/login.py
+++ b/login.py
@@ -1,18 +1,97 @@
import requests
import re
+import os
import dataset
import pushover
import http.cookiejar
import time
import math
import dateparser
+import contextlib
import logging
db = dataset.connect('sqlite:///infomentor.db')
pushover.init('***REMOVED***')
logging.basicConfig(level=logging.INFO)
-logger = logging.getLogger(__name__)
+logger = logging.getLogger('Infomentor Notifier')
+
+
+class NewsInformer(object):
+ def __init__(self, username, password, pushover, logger=None):
+ if logger is None:
+ logger = logging.getLogger(__name__)
+ self.username = username
+ self.password = password
+ self.pushover = pushover
+ self._setup_db()
+ self.im = Infomentor(logger=logger)
+
+ def _setup_db(self):
+ self.db_news = db.create_table(
+ 'news',
+ primary_id='id',
+ primary_type=db.types.integer
+ )
+ self.db_notification = db.create_table(
+ 'news_notification',
+ primary_id='id',
+ primary_type=db.types.integer
+ )
+
+ def send_notification(self, news_id, text, title, attachment=None, timestamp=True):
+ logger.info('sending notification: %s', title)
+ text = text.replace('
', '\n')
+ try:
+ pushover.Client(self.pushover).send_message(
+ text,
+ title=title,
+ attachment=attachment,
+ html=True,
+ timestamp=timestamp
+ )
+ self.db_notification.insert(
+ {'id': news_id, 'username': self.username}
+ )
+ except pushover.RequestError as e:
+ self.logger.error('Sending notification failed', exc_info=e)
+
+ def _notification_sent(self, news_id):
+ entry = self.db_notification.find_one(id=news_id, username=self.username)
+ return entry is not None
+
+ def notify_news(self):
+ im = Infomentor(logger=logger)
+ im.login(self.username, self.password)
+ im_news = im.get_news()
+ logger.info('Parsing %d news', im_news['totalItems'])
+ for news_item in im_news['items']:
+ storenewsdata = self.db_news.find_one(id=news_item['id'])
+ if storenewsdata is None:
+ logger.info('NEW article found %s', news_item['title'])
+ newsdata = im.get_article(news_item['id'])
+ storenewsdata = {
+ k: newsdata[k] for k in ('id', 'title', 'content', 'date')
+ }
+ self.db_news.insert(storenewsdata)
+ if not self._notification_sent(news_item['id']):
+ logger.info('Notify %s about %s', self.username, news_item['title'])
+ image = None
+ if im.get_newsimage(news_item['id']):
+ image = open('{}.image'.format(news_item['id']), 'rb')
+
+ parsed_date = dateparser.parse(storenewsdata['date'])
+ timestamp = math.floor(parsed_date.timestamp())
+ self.send_notification(
+ news_item['id'],
+ storenewsdata['content'],
+ storenewsdata['title'],
+ attachment=image,
+ timestamp=timestamp
+ )
+ if image is not None:
+ image.close()
+
class Infomentor(object):
@@ -25,12 +104,13 @@ class Infomentor(object):
self.logger = logger
self.session = requests.Session()
- self.session.cookies = http.cookiejar.MozillaCookieJar(filename='im.cookies')
- self.session.cookies.load(ignore_discard=True, ignore_expires=True)
self.session.headers.update({'User-Agent': 'Mozilla/5.0'})
self._last_result = None
def login(self, user, password):
+ self.session.cookies = http.cookiejar.MozillaCookieJar(filename='{}.cookies'.format(user))
+ with contextlib.suppress(FileNotFoundError):
+ self.session.cookies.load(ignore_discard=True, ignore_expires=True)
if not self.logged_in():
self._do_login(user, password)
@@ -45,6 +125,7 @@ class Infomentor(object):
rem = re.findall(r'name="oauth_token" value="([^"]*)"',
self._last_result.text)
if len(rem) != 1:
+ self.logger.error('OAUTH_TOKEN not found')
raise Exception('Invalid Count of tokens')
oauth_token = rem[0]
return oauth_token
@@ -83,10 +164,12 @@ class Infomentor(object):
for f in hiddenfields:
names = re.findall('name="([^"]*)"', f)
if len(names) != 1:
- raise Exception('Invalid Count of fieldnames')
+ self.logger.error('Could not parse hidden field (fieldname)')
+ continue
values = re.findall('value="([^"]*)"', f)
if len(values) != 1:
- raise Exception('Invalid Count of values')
+ self.logger.error('Could not parse hidden field (value)')
+ continue
field_values[names[0]] = values[0]
return field_values
@@ -151,15 +234,17 @@ class Infomentor(object):
def get_newsimage(self, id):
self.logger.info('fetching article image: %s', id)
+ filename = '{}.image'.format(id)
+ if os.path.isfile(filename):
+ return True
url = self._mim_url('News/NewsImage/GetImage?id={}'.format(id))
r = self._do_get(url)
if r.status_code != 200:
return False
- with open('{}.image'.format(id), 'wb+') as f:
+ with open(filename, 'wb+') as f:
f.write(r.content)
return True
-
def get_calendar(self):
data = {
'UTCOffset': '-120',
@@ -167,43 +252,27 @@ class Infomentor(object):
'end': '2019-09-01'
}
self.logger.info('fetching calendar')
- r = self._do_post(self._mim_url('Calendar/Calendar/getEntries'), data=data)
+ r = self._do_post(
+ self._mim_url('Calendar/Calendar/getEntries'),
+ data=data
+ )
return r.json()
-def send_notification(text, title, attachment=None, timestamp=True):
- logger.info('sending notification: %s', title)
- text = text.replace('
', '\n')
- pushover.Client('u5w9h8gc7hpzvr5a2kh2xh4m9zpidq').send_message(text, title=title, attachment=attachment, html=True, timestamp=timestamp)
-
-
def main():
- im = Infomentor(logger=logger)
- im.login('mbilger', 'jpEWG9hK8vXA8NaJFuKf')
- im_news = im.get_news()
- db_news = db.create_table('news', primary_id='id', primary_type=db.types.integer)
- for news_item in im_news['items']:
- if db_news.find_one(id=news_item['id']) is None:
- newsdata = im.get_article(news_item['id'])
- storenewsdata = {
- 'id': newsdata['id'],
- 'title': newsdata['title'],
- 'content': newsdata['content'],
- 'date': newsdata['date'],
- }
- db_news.insert(storenewsdata)
- image = None
- if im.get_newsimage(news_item['id']):
- image = open('{}.image'.format(news_item['id']), 'rb')
+ db_users = db.create_table(
+ 'user',
+ primary_id='username',
+ primary_type=db.types.string
+ )
+ for user in db_users:
+ if user['password'] == '':
+ logger.warning('User %s not enabled', user['username'])
+ continue;
+ ni = NewsInformer(**user)
+ ni.notify_news()
- timestamp = math.floor(dateparser.parse(newsdata['date']).timestamp())
-
- send_notification(newsdata['content'], newsdata['title'], attachment=image, timestamp=timestamp)
- if image is not None:
- image.close()
-
-# init("")
-# Client("").send_message("Hello!", title="Hello")
if __name__ == "__main__":
main()
+