add python prototype
This commit is contained in:
commit
f58b3b9819
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
config.py
|
14
README.md
Normal file
14
README.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Logmatters
|
||||||
|
|
||||||
|
To run, add to `config.py`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
driver = {
|
||||||
|
'url': 'mattermost.example',
|
||||||
|
'login_id': '',
|
||||||
|
'password': '',
|
||||||
|
'port': 443
|
||||||
|
}
|
||||||
|
|
||||||
|
logdir = 'logs'
|
||||||
|
```
|
103
main.py
Normal file
103
main.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
import functools
|
||||||
|
import contextlib
|
||||||
|
import asyncio
|
||||||
|
import concurrent
|
||||||
|
import logging
|
||||||
|
import selectors
|
||||||
|
|
||||||
|
from mattermostdriver import Driver, Websocket # pip install mattermostdriver
|
||||||
|
|
||||||
|
import config
|
||||||
|
|
||||||
|
|
||||||
|
logging.basicConfig(level='INFO')
|
||||||
|
|
||||||
|
|
||||||
|
class MatterLog:
|
||||||
|
|
||||||
|
__slots__ = ['driver', 'logdir']
|
||||||
|
|
||||||
|
def __init__(self, driver, loop, logdir):
|
||||||
|
self.driver = driver
|
||||||
|
self.logdir = logdir
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def channel_file(self, team, channel):
|
||||||
|
current = os.path.join(self.logdir, team, channel, 'current')
|
||||||
|
os.makedirs(os.path.dirname(current), exist_ok=True)
|
||||||
|
with open(current, 'a') as f:
|
||||||
|
yield f
|
||||||
|
|
||||||
|
async def __call__(self, event):
|
||||||
|
event = json.loads(event)
|
||||||
|
if 'event' not in event:
|
||||||
|
logging.warning('received none-event: ' + str(event))
|
||||||
|
elif event['event'] in MatterLog.IGNORED_EVENTS:
|
||||||
|
pass
|
||||||
|
elif not hasattr(self, 'handle_' + event['event']):
|
||||||
|
logging.warning('no handler for event: ' + str(event))
|
||||||
|
else:
|
||||||
|
await getattr(self, 'handle_' + event['event'])(event['data'])
|
||||||
|
|
||||||
|
IGNORED_EVENTS = { 'emoji_added', 'hello', 'license_changed',
|
||||||
|
'preference_changed', 'preferences_changed', 'preferences_deleted',
|
||||||
|
'typing' }
|
||||||
|
|
||||||
|
async def handle_posted(self, data):
|
||||||
|
post = json.loads(data['post'])
|
||||||
|
with self.channel_file(self.cached_team_name(data['team_id']), data['channel_name']) as f:
|
||||||
|
if post.get('root_id'):
|
||||||
|
print(post['create_at'], post['id'], 'REPLY', post['original_id'], data['sender_name'][1:], post['message'], sep='\t', file=f)
|
||||||
|
else:
|
||||||
|
print(post['create_at'], post['id'], 'MSG', data['sender_name'][1:], post['message'], sep='\t', file=f)
|
||||||
|
|
||||||
|
@functools.lru_cache
|
||||||
|
def cached_team_name(self, team):
|
||||||
|
return self.driver.teams.get_team(team)['name']
|
||||||
|
|
||||||
|
|
||||||
|
async def messageloop(driver, loop, logdir):
|
||||||
|
selector = selectors.DefaultSelector()
|
||||||
|
for team in driver.teams.get_teams():
|
||||||
|
for channel in driver.channels.get_channels_for_user(driver.client.userid, team['id']):
|
||||||
|
sayfile = os.path.join(logdir, team['name'], channel['name'], 'say')
|
||||||
|
|
||||||
|
if os.path.exists(sayfile): os.unlink(sayfile)
|
||||||
|
os.makedirs(os.path.dirname(sayfile), exist_ok=True)
|
||||||
|
os.mkfifo(sayfile)
|
||||||
|
f = os.open(sayfile, os.O_RDONLY | os.O_NONBLOCK)
|
||||||
|
selector.register(f, selectors.EVENT_READ, (sayfile, channel['id']))
|
||||||
|
|
||||||
|
while True:
|
||||||
|
events = await loop.run_in_executor(None, lambda: selector.select())
|
||||||
|
for key, mask in events:
|
||||||
|
selector.unregister(key.fileobj)
|
||||||
|
message = os.read(key.fileobj, 1024)
|
||||||
|
os.close(key.fileobj)
|
||||||
|
if message:
|
||||||
|
driver.posts.create_post(options={
|
||||||
|
'channel_id': key.data[1],
|
||||||
|
'message': message.decode()
|
||||||
|
})
|
||||||
|
f = os.open(key.data[0], os.O_RDONLY | os.O_NONBLOCK)
|
||||||
|
selector.register(f, selectors.EVENT_READ, key.data)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
driver = Driver(config.driver)
|
||||||
|
driver.login()
|
||||||
|
|
||||||
|
def listen(driver):
|
||||||
|
websocket = Websocket(driver.options, driver.client.token)
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
loop.set_debug(True)
|
||||||
|
loop.create_task(messageloop(driver, loop, config.logdir))
|
||||||
|
loop.run_until_complete(websocket.connect(MatterLog(driver, loop, config.logdir)))
|
Loading…
Reference in New Issue
Block a user