migrated to logging api

This commit is contained in:
aj 2019-08-07 15:45:25 +01:00
parent 2768854a9e
commit 4cc5475de7
15 changed files with 153 additions and 102 deletions

View File

@ -1,17 +1,28 @@
from spotframework.net.user import User from spotframework.net.user import User
from spotframework.net.network import Network from spotframework.net.network import Network
import spotframework.log.log as log
import spotframework.net.const as const import spotframework.net.const as const
import spotframework.io.json as json import spotframework.io.json as json
import os import os
import datetime import datetime
import logging
logger = logging.getLogger('spotframework')
log_format = '%(asctime)s %(levelname)s %(name)s:%(funcName)s - %(message)s'
file_handler = logging.FileHandler(".spot/alarm.log")
formatter = logging.Formatter(log_format)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
def check_phone(): def check_phone():
response = os.system("ping -c 1 -w5 " + os.environ['PHONEIP'] + " > /dev/null 2>&1") response = os.system("ping -c 1 -w5 " + os.environ['PHONEIP'] + " > /dev/null 2>&1")
log.log('checking for phone') logger.info('checking for phone')
if response == 0: if response == 0:
return True return True
else: else:
@ -54,7 +65,5 @@ if __name__ == '__main__':
network.set_volume(data['alarm']['volume']) network.set_volume(data['alarm']['volume'])
network.next() network.next()
log.dump_log() except Exception as e:
logger.exception('exception occured')
except:
log.dump_log()

View File

@ -1,14 +1,24 @@
from spotframework.net.user import User from spotframework.net.user import User
from spotframework.net.network import Network from spotframework.net.network import Network
import spotframework.io.csv as csvwrite import spotframework.io.csv as csvwrite
import spotframework.log.log as log
import sys import sys
import datetime import datetime
import os import os
import logging
if __name__ == '__main__': if __name__ == '__main__':
logger = logging.getLogger('spotframework')
log_format = '%(asctime)s %(levelname)s %(name)s:%(funcName)s - %(message)s'
file_handler = logging.FileHandler(".spot/backup.log")
formatter = logging.Formatter(log_format)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
try: try:
network = Network(User(os.environ['SPOTCLIENT'], network = Network(User(os.environ['SPOTCLIENT'],
@ -32,7 +42,5 @@ if __name__ == '__main__':
for play in playlists: for play in playlists:
csvwrite.export_playlist(play, totalpath) csvwrite.export_playlist(play, totalpath)
log.dump_log() except Exception as e:
logger.exception(f'exception occured')
except:
log.dump_log()

View File

@ -1,7 +1,6 @@
import spotframework.net.const as const import spotframework.net.const as const
from spotframework.net.network import Network from spotframework.net.network import Network
from spotframework.net.user import User from spotframework.net.user import User
import spotframework.log.log as log
import spotframework.io.json as json import spotframework.io.json as json
import spotframework.util.monthstrings as monthstrings import spotframework.util.monthstrings as monthstrings
from spotframework.engine.playlistengine import PlaylistEngine from spotframework.engine.playlistengine import PlaylistEngine
@ -13,13 +12,25 @@ from spotframework.engine.filter.deduplicatebyname import DeduplicateByName
import os import os
import datetime import datetime
import sys import sys
import logging
import requests import requests
logger = logging.getLogger('spotframework')
log_format = '%(asctime)s %(levelname)s %(name)s - %(funcName)s - %(message)s'
file_handler = logging.FileHandler(".spot/generate_playlists.log")
formatter = logging.Formatter(log_format)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
def update_super_playlist(engine, data_dict): def update_super_playlist(engine, data_dict):
log.log("makePlaylist", data_dict['name']) logger.info(f"makePlaylist {data_dict['name']}")
processors = [DeduplicateByID()] processors = [DeduplicateByID()]
@ -98,10 +109,10 @@ def go():
specials_to_execute = ['recents'] specials_to_execute = ['recents']
if len(not_found) > 0: if len(not_found) > 0:
log.log('arg not found', not_found) logger.error(f'arg not found {not_found}')
if len(to_execute) <= 0 and len(specials_to_execute) <= 0: if len(to_execute) <= 0 and len(specials_to_execute) <= 0:
log.log('none to execute, terminating') logger.critical('none to execute, terminating')
return return
net = Network(User(os.environ['SPOTCLIENT'], net = Network(User(os.environ['SPOTCLIENT'],
@ -119,16 +130,14 @@ def go():
update_recents_playlist(engine, data) update_recents_playlist(engine, data)
else: else:
log.log("config json not found") logger.critical("config json not found")
if 'SLACKHOOK' in os.environ: if 'SLACKHOOK' in os.environ:
requests.post(os.environ['SLACKHOOK'], json={"text": "spot playlists: config json not found"}) requests.post(os.environ['SLACKHOOK'], json={"text": "spot playlists: config json not found"})
log.dump_log()
except Exception as e: except Exception as e:
log.log("exception occured", e) logger.exception("exception occured")
if 'SLACKHOOK' in os.environ: if 'SLACKHOOK' in os.environ:
requests.post(os.environ['SLACKHOOK'], json={"text": f"spot playlists: exception occured {e}"}) requests.post(os.environ['SLACKHOOK'], json={"text": f"spot playlists: exception occured {e}"})
log.dump_log()
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -7,8 +7,6 @@ def run_user_playlist(event, context):
name = base64.b64decode(event['data']).decode('utf-8') name = base64.b64decode(event['data']).decode('utf-8')
username = event['attributes']['username'] username = event['attributes']['username']
print(f'{username} - {name}')
from spotframework.google.run_user_playlist import run_user_playlist as run from spotframework.google.run_user_playlist import run_user_playlist as run
run(username, name) run(username, name)

View File

@ -1,18 +1,19 @@
cachetools==3.1.1 cachetools==3.1.1
certifi==2019.3.9 certifi==2019.6.16
chardet==3.0.4 chardet==3.0.4
google-api-core==1.14.2 google-api-core==1.14.2
google-auth==1.6.3 google-auth==1.6.3
google-cloud-core==1.0.3 google-cloud-core==1.0.3
google-cloud-firestore==1.3.0 google-cloud-firestore==1.4.0
google-cloud-logging==1.12.1
googleapis-common-protos==1.6.0 googleapis-common-protos==1.6.0
grpcio==1.22.0 grpcio==1.22.0
idna==2.8 idna==2.8
protobuf==3.9.0 protobuf==3.9.1
pyasn1==0.4.6 pyasn1==0.4.6
pyasn1-modules==0.2.5 pyasn1-modules==0.2.6
pytz==2019.2 pytz==2019.2
requests==2.21.0 requests==2.22.0
rsa==4.0 rsa==4.0
six==1.12.0 six==1.12.0
urllib3==1.24.3 urllib3==1.25.3

View File

@ -0,0 +1,27 @@
import logging
import os
logger = logging.getLogger(__name__)
logger.setLevel('INFO')
log_format = '%(levelname)s %(name)s:%(funcName)s - %(message)s'
formatter = logging.Formatter(log_format)
if os.environ.get('CLOUD', None):
from google.cloud import logging as glogging
from google.cloud.logging.handlers import CloudLoggingHandler
client = glogging.Client()
# handler = client.get_default_handler()
handler = CloudLoggingHandler(client)
handler.setFormatter(formatter)
logger.addHandler(handler)
else:
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)

View File

@ -1,11 +1,12 @@
import spotframework.log.log as log
import requests import requests
import os import os
import logging
import spotframework.util.monthstrings as monthstrings import spotframework.util.monthstrings as monthstrings
from spotframework.engine.filter.addedsince import AddedSince from spotframework.engine.filter.addedsince import AddedSince
logger = logging.getLogger(__name__)
class PlaylistEngine: class PlaylistEngine:
@ -20,7 +21,7 @@ class PlaylistEngine:
self.playlists += self.net.get_user_playlists() self.playlists += self.net.get_user_playlists()
def get_playlist_tracks(self, playlist): def get_playlist_tracks(self, playlist):
log.log(f"pulling tracks for {playlist.name}") logger.info(f"pulling tracks for {playlist.name}")
playlist.tracks = self.net.get_playlist_tracks(playlist.playlistid) playlist.tracks = self.net.get_playlist_tracks(playlist.playlistid)
def make_playlist(self, playlist_parts, processors=[], include_recommendations=False, recommendation_limit=10): def make_playlist(self, playlist_parts, processors=[], include_recommendations=False, recommendation_limit=10):
@ -44,7 +45,7 @@ class PlaylistEngine:
tracks += [i for i in playlist_tracks if i['is_local'] is False] tracks += [i for i in playlist_tracks if i['is_local'] is False]
else: else:
log.log(f"requested playlist {part} not found") logger.warning(f"requested playlist {part} not found")
if 'SLACKHOOK' in os.environ: if 'SLACKHOOK' in os.environ:
requests.post(os.environ['SLACKHOOK'], json={"text": f"spot playlists: {part} not found"}) requests.post(os.environ['SLACKHOOK'], json={"text": f"spot playlists: {part} not found"})
@ -58,7 +59,7 @@ class PlaylistEngine:
tracks += self.net.get_recommendations(tracks=[i['id'] for i in tracks], tracks += self.net.get_recommendations(tracks=[i['id'] for i in tracks],
response_limit=recommendation_limit)['tracks'] response_limit=recommendation_limit)['tracks']
except Exception as e: except Exception as e:
print(e) logger.exception('exception occured')
# print(tracks) # print(tracks)
return tracks return tracks

View File

@ -1,6 +1,7 @@
from google.cloud import firestore from google.cloud import firestore
import datetime import datetime
import logging
from spotframework.engine.playlistengine import PlaylistEngine from spotframework.engine.playlistengine import PlaylistEngine
from spotframework.engine.filter.shuffle import Shuffle from spotframework.engine.filter.shuffle import Shuffle
@ -17,8 +18,12 @@ captured_playlists = []
def run_user_playlist(username, playlist_name): def run_user_playlist(username, playlist_name):
logger = logging.getLogger(__name__)
users = [i for i in db.collection(u'spotify_users').where(u'username', u'==', username).stream()] users = [i for i in db.collection(u'spotify_users').where(u'username', u'==', username).stream()]
logger.info(f'{username} / {playlist_name}')
if len(users) == 1: if len(users) == 1:
user_dict = users[0].to_dict() user_dict = users[0].to_dict()
@ -32,10 +37,12 @@ def run_user_playlist(username, playlist_name):
playlist_dict = playlists[0].to_dict() playlist_dict = playlists[0].to_dict()
if playlist_dict['playlist_id'] is None: if playlist_dict['playlist_id'] is None:
raise Exception('no playlist id to populate') logger.critical(f'no playlist id to populate ({username}/{playlist_name})')
return
if len(playlist_dict['parts']) == 0 and len(playlist_dict['playlist_references']) == 0: if len(playlist_dict['parts']) == 0 and len(playlist_dict['playlist_references']) == 0:
raise Exception('no playlists to use for creation') logger.critical(f'no playlists to use for creation ({username}/{playlist_name})')
return
spotify_keys = db.document('key/spotify').get().to_dict() spotify_keys = db.document('key/spotify').get().to_dict()
@ -78,10 +85,12 @@ def run_user_playlist(username, playlist_name):
engine.change_description(sorted(submit_parts), playlist_dict['playlist_id']) engine.change_description(sorted(submit_parts), playlist_dict['playlist_id'])
else: else:
raise Exception('multiple/no playlists found') logger.critical(f'multiple/no playlists found ({username}/{playlist_name})')
return
else: else:
raise Exception('multiple/no user(s) found') logger.critical(f'multiple/no user(s) found ({username}/{playlist_name})')
return
def generate_parts(user_id, name): def generate_parts(user_id, name):

View File

@ -1,14 +1,15 @@
import csv import csv
import datetime import datetime
import logging
import spotframework.log.log as log logger = logging.getLogger(__name__)
headers = ['name', 'artist', 'album', 'album artist', 'added', 'track id', 'album id', 'added by'] headers = ['name', 'artist', 'album', 'album artist', 'added', 'track id', 'album id', 'added by']
def export_playlist(playlist, path, name=None): def export_playlist(playlist, path, name=None):
log.log('exportPlaylist', playlist.name, path, name) logger.info(f'{playlist.name} {path} {name}')
date = str(datetime.datetime.now()) date = str(datetime.datetime.now())

View File

@ -1,12 +1,13 @@
import json import json
import os import os
import logging
import spotframework.log.log as log logger = logging.getLogger(__name__)
def load_json(path): def load_json(path):
log.log("load json", path) logger.info(f"{path}")
if os.path.exists(path): if os.path.exists(path):
with open(path, 'r') as fileobj: with open(path, 'r') as fileobj:
@ -15,6 +16,6 @@ def load_json(path):
return data return data
else: else:
log.log("load json", "file doesn't exist") logger.error("file doesn't exist")
return None return None

View File

@ -1,28 +0,0 @@
import os
import datetime
import spotframework.net.const as const
logentries = []
def log(entry, *args):
timestamp = datetime.datetime.now()
output = str(timestamp) + ' ' + entry + ' ' + ' '.join([str(i) for i in args])
logentries.append(output)
print(output)
def dump_log():
if not os.path.exists(os.path.join(const.config_path, 'log')):
os.makedirs(os.path.join(const.config_path, 'log'))
with open(os.path.join(const.config_path, 'log', '{}_log'.format(datetime.datetime.now().strftime('%m_%y'))), 'a+') as file_obj:
for entry in logentries:
file_obj.write(entry + '\n')

View File

@ -1,11 +1,13 @@
import requests import requests
import random import random
import logging
from . import const from . import const
from spotframework.model.playlist import Playlist from spotframework.model.playlist import Playlist
import spotframework.log.log as log
limit = 50 limit = 50
logger = logging.getLogger(__name__)
class Network: class Network:
@ -19,10 +21,10 @@ class Network:
req = requests.get(const.api_url + url, params=params, headers=headers) req = requests.get(const.api_url + url, params=params, headers=headers)
if 200 <= req.status_code < 300: if 200 <= req.status_code < 300:
log.log(method, 'get', str(req.status_code)) logger.debug(f'{method} get {req.status_code}')
return req.json() return req.json()
else: else:
log.log(method, 'get', str(req.status_code), req.text) logger.error(f'{method} get {req.status_code} {req.text}')
return None return None
@ -33,10 +35,10 @@ class Network:
req = requests.post(const.api_url + url, params=params, json=json, headers=headers) req = requests.post(const.api_url + url, params=params, json=json, headers=headers)
if 200 <= req.status_code < 300: if 200 <= req.status_code < 300:
log.log(method, 'post', str(req.status_code)) logger.debug(f'{method} post {req.status_code}')
return req return req
else: else:
log.log(method, 'post', str(req.status_code), req.text) logger.error(f'{method} post {req.status_code} {req.text}')
return None return None
@ -47,30 +49,27 @@ class Network:
req = requests.put(const.api_url + url, params=params, json=json, headers=headers) req = requests.put(const.api_url + url, params=params, json=json, headers=headers)
if 200 <= req.status_code < 300: if 200 <= req.status_code < 300:
log.log(method, 'put', str(req.status_code)) logger.debug(f'{method} put {req.status_code}')
return req return req
else: else:
log.log(method, 'put', str(req.status_code), req.text) logger.error(f'{method} put {req.status_code} {req.text}')
return None return None
def get_playlist(self, playlistid, tracksonly=False): def get_playlist(self, playlistid):
log.log("getPlaylist", playlistid) logger.info(f"{playlistid}")
tracks = self.get_playlist_tracks(playlistid) tracks = self.get_playlist_tracks(playlistid)
playlist = Playlist(playlistid) playlist = Playlist(playlistid)
playlist.tracks += tracks playlist.tracks += tracks
if not tracksonly:
pass
return playlist return playlist
def get_playlists(self, offset=0): def get_playlists(self, offset=0):
log.log("getPlaylists", offset) logger.info(f"{offset}")
playlists = [] playlists = []
@ -100,13 +99,13 @@ class Network:
def get_user_playlists(self): def get_user_playlists(self):
log.log("getUserPlaylists") logger.info('retrieved')
return list(filter(lambda x: x.userid == self.user.username, self.get_playlists())) return list(filter(lambda x: x.userid == self.user.username, self.get_playlists()))
def get_playlist_tracks(self, playlistid, offset=0): def get_playlist_tracks(self, playlistid, offset=0):
log.log("getPlaylistTracks", playlistid, offset) logger.info(f"{playlistid}{' ' + str(offset) if offset is not 0 else ''}")
tracks = [] tracks = []
@ -114,7 +113,10 @@ class Network:
resp = self._make_get_request('getPlaylistTracks', f'playlists/{playlistid}/tracks', params=params) resp = self._make_get_request('getPlaylistTracks', f'playlists/{playlistid}/tracks', params=params)
tracks += resp['items'] if resp and resp.get('items'):
tracks += resp['items']
else:
logger.warning(f'{playlistid} no response or items')
if resp['next']: if resp['next']:
tracks += self.get_playlist_tracks(playlistid, offset + limit) tracks += self.get_playlist_tracks(playlistid, offset + limit)
@ -123,25 +125,25 @@ class Network:
def get_available_devices(self): def get_available_devices(self):
log.log("getAvailableDevices") logger.info("retrieved")
return self._make_get_request('getAvailableDevices', 'me/player/devices') return self._make_get_request('getAvailableDevices', 'me/player/devices')
def get_player(self): def get_player(self):
log.log("getPlayer") logger.info("retrieved")
return self._make_get_request('getPlayer', 'me/player') return self._make_get_request('getPlayer', 'me/player')
def get_device_id(self, devicename): def get_device_id(self, devicename):
log.log("getDeviceID", devicename) logger.info(f"{devicename}")
return next((i for i in self.get_available_devices()['devices'] if i['name'] == devicename), None)['id'] return next((i for i in self.get_available_devices()['devices'] if i['name'] == devicename), None)['id']
def play(self, uri, deviceid=None): def play(self, uri, deviceid=None):
log.log("play", uri, deviceid) logger.info(f"{uri}{' ' + deviceid if deviceid is not None else ''}")
if deviceid is not None: if deviceid is not None:
params = {'device_id': deviceid} params = {'device_id': deviceid}
@ -154,7 +156,7 @@ class Network:
def pause(self, deviceid=None): def pause(self, deviceid=None):
log.log("pause", deviceid) logger.info(f"{deviceid if deviceid is not None else ''}")
if deviceid is not None: if deviceid is not None:
params = {'device_id': deviceid} params = {'device_id': deviceid}
@ -165,7 +167,7 @@ class Network:
def next(self, deviceid=None): def next(self, deviceid=None):
log.log("next", deviceid) logger.info(f"{deviceid if deviceid is not None else ''}")
if deviceid is not None: if deviceid is not None:
params = {'device_id': deviceid} params = {'device_id': deviceid}
@ -176,7 +178,7 @@ class Network:
def set_shuffle(self, state, deviceid=None): def set_shuffle(self, state, deviceid=None):
log.log("setShuffle", state, deviceid) logger.info(f"{state}{' ' + deviceid if deviceid is not None else ''}")
params = {'state': str(state).lower()} params = {'state': str(state).lower()}
@ -187,9 +189,9 @@ class Network:
def set_volume(self, volume, deviceid=None): def set_volume(self, volume, deviceid=None):
log.log("setVolume", volume, deviceid) logger.info(f"{volume}{' ' + deviceid if deviceid is not None else ''}")
if 0 <= int(volume) <= 100: if volume.isdigit() and 0 <= int(volume) <= 100:
params = {'volume_percent': volume} params = {'volume_percent': volume}
@ -199,11 +201,11 @@ class Network:
req = self._make_put_request('setVolume', 'me/player/volume', params=params) req = self._make_put_request('setVolume', 'me/player/volume', params=params)
else: else:
log.log("setVolume", volume, "not allowed") logger.error(f"{volume} not accepted value")
def make_playlist(self, name, description=None, public=True, collaborative=False): def make_playlist(self, name, description=None, public=True, collaborative=False):
log.log("makePlaylist", name, f'description:{description}', f'public:{public}', f'collaborative:{collaborative}') logger.info(f"{name}, desc: {description}, public: {public}, collab: {collaborative}")
headers = {"Content-Type": "application/json"} headers = {"Content-Type": "application/json"}
@ -225,7 +227,7 @@ class Network:
def replace_playlist_tracks(self, playlistid, uris): def replace_playlist_tracks(self, playlistid, uris):
log.log("replacePlaylistTracks", playlistid) logger.info(f"{playlistid}")
headers = {"Content-Type": "application/json"} headers = {"Content-Type": "application/json"}
@ -241,7 +243,7 @@ class Network:
def change_playlist_details(self, playlistid, name=None, public=None, collaborative=None, description=None): def change_playlist_details(self, playlistid, name=None, public=None, collaborative=None, description=None):
log.log("changePlaylistDetails", playlistid) logger.info(f"{playlistid}")
headers = {"Content-Type": "application/json"} headers = {"Content-Type": "application/json"}
@ -264,7 +266,7 @@ class Network:
def add_playlist_tracks(self, playlistid, uris): def add_playlist_tracks(self, playlistid, uris):
log.log("addPlaylistTracks", playlistid) logger.info(f"{playlistid}")
headers = {"Content-Type": "application/json"} headers = {"Content-Type": "application/json"}
@ -281,6 +283,8 @@ class Network:
def get_recommendations(self, tracks=None, artists=None, response_limit=10): def get_recommendations(self, tracks=None, artists=None, response_limit=10):
logger.info(f'tracks: {tracks}, artists {artists}, sample: {response_limit}')
params = {'limit': response_limit} params = {'limit': response_limit}
if tracks: if tracks:

View File

@ -1,5 +1,8 @@
import requests import requests
from base64 import b64encode from base64 import b64encode
import logging
logger = logging.getLogger(__name__)
class User: class User:
@ -24,12 +27,20 @@ class User:
req = requests.post('https://accounts.spotify.com/api/token', data=data, headers=headers) req = requests.post('https://accounts.spotify.com/api/token', data=data, headers=headers)
if req.status_code is 200: if 200 <= req.status_code < 300:
logger.debug('token refreshed')
self.accesstoken = req.json()['access_token'] self.accesstoken = req.json()['access_token']
else:
logger.error(f'http error {req.status_code}')
def get_info(self): def get_info(self):
headers = {'Authorization': 'Bearer %s' % self.accesstoken} headers = {'Authorization': 'Bearer %s' % self.accesstoken}
req = requests.get('https://api.spotify.com/v1/me', headers=headers) req = requests.get('https://api.spotify.com/v1/me', headers=headers)
return req.json()
if 200 <= req.status_code < 300:
logger.debug(f'retrieved {req.status_code}')
return req.json()
else:
logger.error(f'http error {req.status_code}')