|
|
|
@ -4,6 +4,8 @@ import requests
|
|
|
|
|
import re
|
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
|
|
|
|
|
|
import asyncio
|
|
|
|
|
from nio import ClientConfig, AsyncClient, LoginResponse, InviteEvent
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_accesstoken_from_file(accesstoken_path):
|
|
|
|
@ -12,6 +14,11 @@ def get_accesstoken_from_file(accesstoken_path):
|
|
|
|
|
accesstoken_file.close()
|
|
|
|
|
|
|
|
|
|
return single_accesstoken
|
|
|
|
|
async def on_event(room, event):
|
|
|
|
|
if hasattr(event, 'membership'):
|
|
|
|
|
if event.membership == 'invite':
|
|
|
|
|
# automatically join invites
|
|
|
|
|
await matrix[event.source['state_key']].join(room.room_id)
|
|
|
|
|
def get_blog():
|
|
|
|
|
url = 'https://news.blizzard.com/en-us/'
|
|
|
|
|
html = requests.get(url).text
|
|
|
|
@ -57,7 +64,7 @@ def get_blog():
|
|
|
|
|
def get_body(post):
|
|
|
|
|
body = post['title']+"\n"
|
|
|
|
|
|
|
|
|
|
if post['description'] != '':
|
|
|
|
|
if post['description']:
|
|
|
|
|
body += post['description']+"\n"
|
|
|
|
|
|
|
|
|
|
body += post['url']
|
|
|
|
@ -68,22 +75,95 @@ def get_formatted_body(post):
|
|
|
|
|
formatted_body += '<h5>'+post['title']+'</h5>'
|
|
|
|
|
formatted_body += '</a>'
|
|
|
|
|
|
|
|
|
|
if post['description'] != '':
|
|
|
|
|
if post['description']:
|
|
|
|
|
formatted_body += '<p>'+post['description']+'</p>'
|
|
|
|
|
|
|
|
|
|
formatted_body += post['url']
|
|
|
|
|
|
|
|
|
|
return formatted_body
|
|
|
|
|
async def main():
|
|
|
|
|
next_batch = {}
|
|
|
|
|
for game in device:
|
|
|
|
|
# initialize new client
|
|
|
|
|
mxid = '@'+mxid_prefix+game+':'+homeserver_name
|
|
|
|
|
config = ClientConfig(store_sync_tokens=True)
|
|
|
|
|
matrix[mxid] = AsyncClient(homeserver_url,
|
|
|
|
|
config=config)
|
|
|
|
|
|
|
|
|
|
# login
|
|
|
|
|
login_response = LoginResponse(mxid,
|
|
|
|
|
device[game]['id'],
|
|
|
|
|
device[game]['accesstoken'])
|
|
|
|
|
await matrix[mxid].receive_response(login_response)
|
|
|
|
|
|
|
|
|
|
matrix[mxid].add_event_callback(on_event, InviteEvent)
|
|
|
|
|
|
|
|
|
|
# do a first sync
|
|
|
|
|
sync_filter = {
|
|
|
|
|
'room': {
|
|
|
|
|
'state': {
|
|
|
|
|
'types': ['m.room.member'],
|
|
|
|
|
'lazy_load_members': True
|
|
|
|
|
},
|
|
|
|
|
'timeline': {
|
|
|
|
|
'types': ['invalid']
|
|
|
|
|
},
|
|
|
|
|
'ephemeral': {
|
|
|
|
|
'types': ['invalid']
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
next_batch_state = await matrix[mxid].room_get_state_event(admin_room,
|
|
|
|
|
event_type,
|
|
|
|
|
mxid)
|
|
|
|
|
if 'token' in next_batch_state.content:
|
|
|
|
|
try:
|
|
|
|
|
sync = await matrix[mxid].sync(timeout=30000,
|
|
|
|
|
sync_filter=sync_filter,
|
|
|
|
|
since=next_batch_state.content['token'])
|
|
|
|
|
next_batch[mxid] = sync.next_batch
|
|
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
# when there is no next_batch token or first sync threw an error,
|
|
|
|
|
# then do a first sync without next_batch
|
|
|
|
|
sync = await matrix[mxid].sync(timeout=30000,
|
|
|
|
|
sync_filter=sync_filter)
|
|
|
|
|
next_batch[mxid] = sync.next_batch
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
for mxid in next_batch:
|
|
|
|
|
sync = await matrix[mxid].sync(timeout=30000,
|
|
|
|
|
sync_filter=sync_filter,
|
|
|
|
|
since=next_batch[mxid])
|
|
|
|
|
next_batch[mxid] = sync.next_batch
|
|
|
|
|
|
|
|
|
|
await matrix[mxid].room_put_state(room_id=admin_room,
|
|
|
|
|
event_type=event_type,
|
|
|
|
|
state_key=mxid,
|
|
|
|
|
content={'token': next_batch[mxid]})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
homeserver = environ['HOMESERVER_URL']
|
|
|
|
|
mxid = environ['MXID_PREFIX']
|
|
|
|
|
homeserver_name = environ['HOMESERVER_NAME']
|
|
|
|
|
homeserver_url = environ['HOMESERVER_URL']
|
|
|
|
|
mxid_prefix = environ['MXID_PREFIX']
|
|
|
|
|
admin_room = environ['ADMIN_ROOM']
|
|
|
|
|
|
|
|
|
|
accesstoken = {}
|
|
|
|
|
for key in environ:
|
|
|
|
|
if (game := re.match('^ACCESSTOKEN_([A-Z]*)_FILE$', key)) is not None:
|
|
|
|
|
accesstoken[game[1].lower()] = get_accesstoken_from_file(environ[key])
|
|
|
|
|
device = {}
|
|
|
|
|
for var in environ:
|
|
|
|
|
if (game := re.match('^DEVICEID_([A-Z]*)$', var)) is not None:
|
|
|
|
|
device[game[1].lower()] = {'id': environ[var]}
|
|
|
|
|
for var in environ:
|
|
|
|
|
if (game := re.match('^ACCESSTOKEN_([A-Z]*)_FILE$', var)) is not None:
|
|
|
|
|
device[game[1].lower()]['accesstoken'] = get_accesstoken_from_file(environ[var])
|
|
|
|
|
|
|
|
|
|
event_type = 'de.lubiland.snowstorm-matrix.next_batch'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
matrix = {}
|
|
|
|
|
|
|
|
|
|
asyncio.run(main())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
blog = get_blog()
|
|
|
|
|