Merge pull request #12 from tswfi/pylint

lint evertyhing
This commit is contained in:
Ville Ranki 2020-01-04 23:08:50 +02:00 committed by GitHub
commit 325e1e623c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 138 additions and 87 deletions

6
.gitignore vendored
View File

@ -1,3 +1,9 @@
# editors
.vscode
# ignore Pipfile.lock
Pipfile.lock
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

View File

@ -16,6 +16,9 @@ igramscraper = "*"
[dev-packages]
pylint = "*"
pycodestyle = "*"
flake8 = "*"
autopep8 = "*"
[requires]
python_version = "3.7"

56
bot.py
View File

@ -1,25 +1,29 @@
#!/usr/bin/env python3
import asyncio
import os
import json
import glob
import traceback
import importlib
import sys
import re
import requests
import json
import os
import re
import sys
import traceback
import urllib.parse
from nio import (AsyncClient, RoomMessageText, RoomMessageUnknown, JoinError, InviteEvent)
import requests
from nio import AsyncClient, InviteEvent, JoinError, RoomMessageText
# Couple of custom exceptions
class CommandRequiresAdmin(Exception):
pass
class CommandRequiresOwner(Exception):
pass
class Bot:
appid = 'org.vranki.hemppa'
version = '1.1'
@ -59,11 +63,12 @@ class Bot:
if not self.is_owner(event):
raise CommandRequiresOwner
# Returns true if event's sender is admin in the room event was sent in, or is bot owner
# Returns true if event's sender is admin in the room event was sent in,
# or is bot owner
def is_admin(self, room, event):
if self.is_owner(event):
return True
if not event.sender in room.power_levels.users:
if event.sender not in room.power_levels.users:
return False
return room.power_levels.users[event.sender] >= 50
@ -77,9 +82,9 @@ class Bot:
if "get_settings" in dir(moduleobject):
try:
module_settings[modulename] = moduleobject.get_settings()
except:
except Exception:
traceback.print_exc(file=sys.stderr)
data = { self.appid: self.version, 'module_settings': module_settings}
data = {self.appid: self.version, 'module_settings': module_settings}
self.set_account_data(data)
def load_settings(self, data):
@ -91,8 +96,9 @@ class Bot:
if data['module_settings'].get(modulename):
if "set_settings" in dir(moduleobject):
try:
moduleobject.set_settings(data['module_settings'][modulename])
except:
moduleobject.set_settings(
data['module_settings'][modulename])
except Exception:
traceback.print_exc(file=sys.stderr)
async def message_cb(self, room, event):
@ -114,7 +120,7 @@ class Bot:
await self.send_text(room, f'Sorry, you need admin power level in this room to run that command.')
except CommandRequiresOwner:
await self.send_text(room, f'Sorry, only bot owner can run that command.')
except:
except Exception:
await self.send_text(room, f'Module {command} experienced difficulty: {sys.exc_info()[0]} - see log for details')
traceback.print_exc(file=sys.stderr)
@ -124,12 +130,13 @@ class Bot:
result = await self.client.join(room.room_id)
if type(result) == JoinError:
print(f"Error joining room {room.room_id} (attempt %d): %s",
attempt, result.message,
)
attempt, result.message,
)
else:
break
else:
print(f'Received invite event, but not joining as sender is not owner or bot not configured to join on invite. {event}')
print(
f'Received invite event, but not joining as sender is not owner or bot not configured to join on invite. {event}')
def load_module(self, modulename):
try:
@ -157,7 +164,7 @@ class Bot:
if "matrix_poll" in dir(moduleobject):
try:
await moduleobject.matrix_poll(bot, self.pollcount)
except:
except Exception:
traceback.print_exc(file=sys.stderr)
await asyncio.sleep(10)
@ -178,11 +185,13 @@ class Bot:
response = requests.get(ad_url)
if response.status_code == 200:
return response.json()
print(f'Getting account data failed: {response} {response.json()} - this is normal if you have not saved any settings yet.')
print(
f'Getting account data failed: {response} {response.json()} - this is normal if you have not saved any settings yet.')
return None
def init(self):
self.client = AsyncClient(os.environ['MATRIX_SERVER'], os.environ['MATRIX_USER'])
self.client = AsyncClient(
os.environ['MATRIX_SERVER'], os.environ['MATRIX_USER'])
self.client.access_token = os.getenv('MATRIX_ACCESS_TOKEN')
self.join_on_invite = os.getenv("JOIN_ON_INVITE") is not None
self.owners = os.environ['BOT_OWNERS'].split(',')
@ -195,13 +204,14 @@ class Bot:
if "matrix_stop" in dir(moduleobject):
try:
moduleobject.matrix_stop(bot)
except:
except Exception:
traceback.print_exc(file=sys.stderr)
async def run(self):
if not self.client.access_token:
await self.client.login(os.environ['MATRIX_PASSWORD'])
print("Logged in with password, access token:", self.client.access_token)
print("Logged in with password, access token:",
self.client.access_token)
await self.client.sync()
@ -211,7 +221,7 @@ class Bot:
if "matrix_start" in dir(moduleobject):
try:
moduleobject.matrix_start(bot)
except:
except Exception:
traceback.print_exc(file=sys.stderr)
self.poll_task = asyncio.get_event_loop().create_task(self.poll_timer())

View File

@ -1,8 +1,9 @@
import shlex
from datetime import datetime
class MatrixModule:
daily_commands = dict() # room_id -> command json
daily_commands = dict() # room_id -> command json
last_hour = datetime.now().hour
async def matrix_message(self, bot, room, event):
@ -16,7 +17,8 @@ class MatrixModule:
dailycmd = args[2]
if not self.daily_commands.get(room.room_id):
self.daily_commands[room.room_id] = []
self.daily_commands[room.room_id].append({ 'time': dailytime, 'command': dailycmd })
self.daily_commands[room.room_id].append(
{'time': dailytime, 'command': dailycmd})
bot.save_settings()
await bot.send_text(room, 'Daily command added.')
elif len(args) == 1:
@ -31,7 +33,7 @@ class MatrixModule:
return('Runs scheduled commands')
def get_settings(self):
return { 'daily_commands': self.daily_commands }
return {'daily_commands': self.daily_commands}
def set_settings(self, data):
if data.get('daily_commands'):

View File

@ -1,16 +1,13 @@
from __future__ import print_function
from datetime import datetime
import datetime
import pickle
import os.path
import time
import os
import os.path
import pickle
from datetime import datetime
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
#
# Google calendar notifications
@ -20,18 +17,19 @@ from google.auth.transport.requests import Request
# can be copied to another computer.
#
class MatrixModule:
def matrix_start(self, bot):
self.bot = bot
self.SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
self.credentials_file = "credentials.json"
self.service = None
self.calendar_rooms = dict() # Contains room_id -> [calid, calid] ..
self.calendar_rooms = dict() # Contains room_id -> [calid, calid] ..
creds = None
if not os.path.exists(self.credentials_file) or os.path.getsize(self.credentials_file) == 0:
return # No-op if not set up
return # No-op if not set up
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
@ -45,7 +43,8 @@ class MatrixModule:
else:
flow = InstalledAppFlow.from_client_secrets_file(
self.credentials_file, self.SCOPES)
creds = flow.run_local_server(port=0) # urn:ietf:wg:oauth:2.0:oob
# urn:ietf:wg:oauth:2.0:oob
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
@ -54,14 +53,15 @@ class MatrixModule:
self.service = build('calendar', 'v3', credentials=creds)
try:
calendar_list = self.service.calendarList().list().execute()['items']
print(f'Google calendar set up successfully with access to {len(calendar_list)} calendars:\n')
calendar_list = self.service.calendarList().list().execute()[
'items']
print(
f'Google calendar set up successfully with access to {len(calendar_list)} calendars:\n')
for calendar in calendar_list:
print(calendar['summary'] + ' - ' + calendar['id'])
except:
except Exception:
print('Getting calendar list failed!')
async def matrix_message(self, bot, room, event):
if not self.service:
await bot.send_text(room, 'Google calendar not set up for this bot.')
@ -95,7 +95,8 @@ class MatrixModule:
else:
self.calendar_rooms[room.room_id] = [calid]
print(f'Calendars now for this room {self.calendar_rooms.get(room.room_id)}')
print(
f'Calendars now for this room {self.calendar_rooms.get(room.room_id)}')
bot.save_settings()
@ -111,7 +112,8 @@ class MatrixModule:
if self.calendar_rooms.get(room.room_id):
self.calendar_rooms[room.room_id].remove(calid)
print(f'Calendars now for this room {self.calendar_rooms.get(room.room_id)}')
print(
f'Calendars now for this room {self.calendar_rooms.get(room.room_id)}')
bot.save_settings()
@ -141,28 +143,29 @@ class MatrixModule:
startTime = datetime.datetime.utcnow()
now = startTime.isoformat() + 'Z'
events_result = self.service.events().list(calendarId=calid, timeMin=now,
maxResults=10, singleEvents=True,
orderBy='startTime').execute()
maxResults=10, singleEvents=True,
orderBy='startTime').execute()
events = events_result.get('items', [])
return events
def list_today(self, calid):
startTime = datetime.datetime.utcnow()
startTime = startTime.replace(hour = 0, minute = 0, second = 0, microsecond=0)
startTime = startTime.replace(
hour=0, minute=0, second=0, microsecond=0)
endTime = startTime + datetime.timedelta(hours=24)
now = startTime.isoformat() + 'Z'
end = endTime.isoformat() + 'Z'
print('Looking for events between', now, end)
events_result = self.service.events().list(calendarId=calid, timeMin=now,
timeMax=end, maxResults=10, singleEvents=True,
orderBy='startTime').execute()
timeMax=end, maxResults=10, singleEvents=True,
orderBy='startTime').execute()
return events_result.get('items', [])
def help(self):
return('Google calendar. Lists 10 next events by default. today = list today\'s events.')
def get_settings(self):
return { 'calendar_rooms': self.calendar_rooms }
return {'calendar_rooms': self.calendar_rooms}
def set_settings(self, data):
if data.get('calendar_rooms'):

View File

@ -1,14 +1,17 @@
from igramscraper.instagram import Instagram
from igramscraper.exception.instagram_not_found_exception import InstagramNotFoundException
from datetime import datetime, timedelta
from random import randrange
from igramscraper.exception.instagram_not_found_exception import \
InstagramNotFoundException
from igramscraper.instagram import Instagram
class MatrixModule:
instagram = Instagram()
known_ids = set()
account_rooms = dict() # Roomid -> [account, account..]
next_poll_time = dict() # Roomid -> datetime, None = not polled yet
account_rooms = dict() # Roomid -> [account, account..]
next_poll_time = dict() # Roomid -> datetime, None = not polled yet
async def matrix_poll(self, bot, pollcount):
if len(self.account_rooms):
@ -27,7 +30,8 @@ class MatrixModule:
try:
await self.poll_account(bot, account, roomid, send_messages)
except InstagramNotFoundException:
print('ig error: there is ', account, ' account that does not exist - deleting from room')
print('ig error: there is ', account,
' account that does not exist - deleting from room')
self.account_rooms[roomid].remove(account)
bot.save_settings()
@ -77,7 +81,8 @@ class MatrixModule:
else:
self.account_rooms[room.room_id] = [account]
print(f'Accounts now for this room {self.account_rooms.get(room.room_id)}')
print(
f'Accounts now for this room {self.account_rooms.get(room.room_id)}')
try:
await self.poll_account(bot, account, room.room_id, False)
@ -91,18 +96,20 @@ class MatrixModule:
bot.must_be_admin(room, event)
account = args[2]
print(f'Removing account {account} from room id {room.room_id}')
print(
f'Removing account {account} from room id {room.room_id}')
if self.account_rooms.get(room.room_id):
self.account_rooms[room.room_id].remove(account)
print(f'Accounts now for this room {self.account_rooms.get(room.room_id)}')
print(
f'Accounts now for this room {self.account_rooms.get(room.room_id)}')
bot.save_settings()
await bot.send_text(room, 'Removed instagram account from this room')
def get_settings(self):
return { 'account_rooms': self.account_rooms }
return {'account_rooms': self.account_rooms}
def set_settings(self, data):
if data.get('account_rooms'):

View File

@ -1,8 +1,10 @@
from geopy.geocoders import Nominatim
from nio import (RoomMessageUnknown)
from nio import RoomMessageUnknown
class MatrixModule:
bot = None
def matrix_start(self, bot):
self.bot = bot
bot.client.add_event_callback(self.unknown_cb, RoomMessageUnknown)
@ -26,7 +28,8 @@ class MatrixModule:
float(latlon[0])
float(latlon[1])
osm_link = 'https://www.openstreetmap.org/?mlat=' + latlon[0] + "&mlon=" + latlon[1]
osm_link = 'https://www.openstreetmap.org/?mlat=' + \
latlon[0] + "&mlon=" + latlon[1]
plain = sender + ' 🚩 ' + osm_link
html = f'{sender} 🚩 <a href={osm_link}>{location_text}</a>'

View File

@ -1,13 +1,13 @@
import subprocess
import os
import urllib.request
class MatrixModule:
async def matrix_message(self, bot, room, event):
args = event.body.split()
if len(args) == 2:
icao = args[1]
metar_url = "https://tgftp.nws.noaa.gov/data/observations/metar/stations/" + icao.upper() + ".TXT"
metar_url = "https://tgftp.nws.noaa.gov/data/observations/metar/stations/" + \
icao.upper() + ".TXT"
response = urllib.request.urlopen(metar_url)
lines = response.readlines()
await bot.send_text(room, lines[1].decode("utf-8").strip())

View File

@ -1,6 +1,6 @@
import os
import urllib.request
class MatrixModule:
async def matrix_message(self, bot, room, event):
args = event.body.split()

View File

@ -1,20 +1,22 @@
from pyteamup import Calendar, Event
from datetime import datetime
import time
import os
from datetime import datetime
from pyteamup import Calendar
#
# TeamUp calendar notifications
#
class MatrixModule:
api_key = None
calendar_rooms = dict() # Roomid -> [calid, calid..]
calendars = dict() # calid -> Calendar
calendar_rooms = dict() # Roomid -> [calid, calid..]
calendars = dict() # calid -> Calendar
async def matrix_poll(self, bot, pollcount):
if self.api_key:
if pollcount % (6 * 5) == 0: # Poll every 5 min
await self.poll_all_calendars(bot)
if pollcount % (6 * 5) == 0: # Poll every 5 min
await self.poll_all_calendars(bot)
async def matrix_message(self, bot, room, event):
args = event.body.split()
@ -24,10 +26,14 @@ class MatrixModule:
calendar = self.calendars[calendarid]
events = calendar.get_event_collection()
for event in events:
s = '<b>' + str(event.start_dt.day) + '.' + str(event.start_dt.month)
s = '<b>' + str(event.start_dt.day) + \
'.' + str(event.start_dt.month)
if not event.all_day:
s = s + ' ' + event.start_dt.strftime("%H:%M") + ' (' + str(event.duration) + ' min)'
s = s + '</b> ' + event.title + " " + (event.notes or '')
s = s + ' ' + \
event.start_dt.strftime(
"%H:%M") + ' (' + str(event.duration) + ' min)'
s = s + '</b> ' + event.title + \
" " + (event.notes or '')
await bot.send_html(room, s, s)
elif len(args) == 2:
if args[1] == 'list':
@ -51,7 +57,8 @@ class MatrixModule:
else:
self.calendar_rooms[room.room_id] = [calid]
print(f'Calendars now for this room {self.calendar_rooms.get(room.room_id)}')
print(
f'Calendars now for this room {self.calendar_rooms.get(room.room_id)}')
bot.save_settings()
self.setup_calendars()
@ -65,7 +72,8 @@ class MatrixModule:
if self.calendar_rooms.get(room.room_id):
self.calendar_rooms[room.room_id].remove(calid)
print(f'Calendars now for this room {self.calendar_rooms.get(room.room_id)}')
print(
f'Calendars now for this room {self.calendar_rooms.get(room.room_id)}')
bot.save_settings()
self.setup_calendars()
@ -85,12 +93,12 @@ class MatrixModule:
for roomid in self.calendar_rooms:
calendars = self.calendar_rooms[roomid]
for calendarid in calendars:
events, timestamp = self.poll_server(self.calendars[calendarid])
events, timestamp = self.poll_server(
self.calendars[calendarid])
self.calendars[calendarid].timestamp = timestamp
for event in events:
await bot.send_text(bot.get_room_by_id(roomid), 'Calendar: ' + self.eventToString(event))
def poll_server(self, calendar):
events, timestamp = calendar.get_changed_events(calendar.timestamp)
return events, timestamp
@ -111,9 +119,12 @@ class MatrixModule:
if(event['delete_dt']):
s = event['title'] + ' deleted.'
else:
s = event['title'] + " " + (event['notes'] or '') + ' ' + str(startdt.day) + '.' + str(startdt.month)
s = event['title'] + " " + (event['notes'] or '') + \
' ' + str(startdt.day) + '.' + str(startdt.month)
if not event['all_day']:
s = s + ' ' + startdt.strftime("%H:%M") + ' (' + str(event['duration']) + ' min)'
s = s + ' ' + \
startdt.strftime("%H:%M") + \
' (' + str(event['duration']) + ' min)'
return s
def setup_calendars(self):
@ -126,13 +137,13 @@ class MatrixModule:
self.calendars[calid].timestamp = int(time.time())
def get_settings(self):
return { 'apikey': self.api_key or '', 'calendar_rooms': self.calendar_rooms }
return {'apikey': self.api_key or '', 'calendar_rooms': self.calendar_rooms}
def set_settings(self, data):
if data.get('calendar_rooms'):
self.calendar_rooms = data['calendar_rooms']
if data.get('apikey'):
self.api_key = data['apikey']
if self.api_key and len(self.api_key)==0:
if self.api_key and len(self.api_key) == 0:
self.api_key = None
self.setup_calendars()

View File

@ -1,5 +1,6 @@
import time
class MatrixModule:
def matrix_start(self, bot):
self.starttime = time.time()

5
setup.cfg Normal file
View File

@ -0,0 +1,5 @@
[flake8]
max-line-length = 260
[pycodestyle]
max-line-length = 260