This commit is contained in:
Lartza 2020-03-10 23:07:29 +02:00
parent b2ced96ba4
commit 213a6c084b
14 changed files with 27 additions and 86 deletions

View File

@ -1,6 +1,5 @@
# coding=utf-8 # coding=utf-8
import logging import logging
import os.path
import pymumble.pymumble_py3 as pymumble import pymumble.pymumble_py3 as pymumble
import re import re
@ -10,12 +9,9 @@ import util
import variables as var import variables as var
from librb import radiobrowser from librb import radiobrowser
from database import SettingsDatabase, MusicDatabase from database import SettingsDatabase, MusicDatabase
from media.item import item_builders, item_loaders, item_id_generators, dict_to_item, dicts_to_items from media.item import item_id_generators, dict_to_item, dicts_to_items
from media.cache import get_cached_wrapper_from_scrap, get_cached_wrapper_by_id, get_cached_wrappers_by_tags from media.cache import get_cached_wrapper_from_scrap, get_cached_wrapper_by_id, get_cached_wrappers_by_tags
from media.file import FileItem from media.url_from_playlist import get_playlist_info
from media.url_from_playlist import PlaylistURLItem, get_playlist_info
from media.url import URLItem
from media.radio import RadioItem
log = logging.getLogger("bot") log = logging.getLogger("bot")
@ -281,7 +277,6 @@ def cmd_play_file(bot, user, text, command, parameter, do_not_refresh_cache=Fals
def cmd_play_file_match(bot, user, text, command, parameter, do_not_refresh_cache=False): def cmd_play_file_match(bot, user, text, command, parameter, do_not_refresh_cache=False):
global log global log
music_folder = var.music_folder
if parameter: if parameter:
files = var.cache.files files = var.cache.files
msgs = [constants.strings('multiple_file_added') + "<ul>"] msgs = [constants.strings('multiple_file_added') + "<ul>"]
@ -701,12 +696,10 @@ def cmd_remove(bot, user, text, command, parameter):
global log global log
# Allow to remove specific music into the queue with a number # Allow to remove specific music into the queue with a number
if parameter and parameter.isdigit() and int(parameter) > 0 \ if parameter and parameter.isdigit() and 0 < int(parameter) <= len(var.playlist):
and int(parameter) <= len(var.playlist):
index = int(parameter) - 1 index = int(parameter) - 1
removed = None
if index == var.playlist.current_index: if index == var.playlist.current_index:
removed = var.playlist.remove(index) removed = var.playlist.remove(index)
@ -766,7 +759,6 @@ def cmd_queue(bot, user, text, command, parameter):
else: else:
msgs = [constants.strings('queue_contents')] msgs = [constants.strings('queue_contents')]
for i, music in enumerate(var.playlist): for i, music in enumerate(var.playlist):
newline = ''
tags = '' tags = ''
if len(music.item().tags) > 0: if len(music.item().tags) > 0:
tags = "<sup>{}</sup>".format(", ".join(music.item().tags)) tags = "<sup>{}</sup>".format(", ".join(music.item().tags))
@ -854,8 +846,6 @@ def cmd_add_tag(bot, user, text, command, parameter):
global log global log
params = parameter.split() params = parameter.split()
index = ""
tags = []
if len(params) == 2: if len(params) == 2:
index = params[0] index = params[0]
tags = list(map(lambda t: t.strip(), params[1].split(","))) tags = list(map(lambda t: t.strip(), params[1].split(",")))
@ -892,8 +882,6 @@ def cmd_remove_tag(bot, user, text, command, parameter):
params = parameter.split() params = parameter.split()
index = ""
tags = []
if len(params) == 2: if len(params) == 2:
index = params[0] index = params[0]
tags = list(map(lambda t: t.strip(), params[1].split(","))) tags = list(map(lambda t: t.strip(), params[1].split(",")))
@ -1007,7 +995,6 @@ def cmd_search_library(bot, user, text, command, parameter):
def cmd_shortlist(bot, user, text, command, parameter): def cmd_shortlist(bot, user, text, command, parameter):
global song_shortlist, log global song_shortlist, log
indexes = []
try: try:
indexes = [int(i) for i in parameter.split(" ")] indexes = [int(i) for i in parameter.split(" ")]
except ValueError: except ValueError:
@ -1047,7 +1034,6 @@ def cmd_shortlist(bot, user, text, command, parameter):
def cmd_delete_from_library(bot, user, text, command, parameter): def cmd_delete_from_library(bot, user, text, command, parameter):
global song_shortlist, log global song_shortlist, log
indexes = []
try: try:
indexes = [int(i) for i in parameter.split(" ")] indexes = [int(i) for i in parameter.split(" ")]
except ValueError: except ValueError:

View File

@ -2,33 +2,31 @@ import variables as var
def strings(option, *argv, **kwargs): def strings(option, *argv, **kwargs):
string = ""
try: try:
string = var.config.get("strings", option) string = var.config.get("strings", option)
except KeyError as e: except KeyError:
raise KeyError("Missed strings in configuration file: '{string}'. ".format(string=option) + raise KeyError("Missed strings in configuration file: '{string}'. ".format(string=option)
"Please restore you configuration file back to default if necessary.") + "Please restore you configuration file back to default if necessary.")
if argv or kwargs: if argv or kwargs:
try: try:
formatted = string.format(*argv, **kwargs) formatted = string.format(*argv, **kwargs)
return formatted return formatted
except KeyError as e: except KeyError as e:
raise KeyError( raise KeyError(
"Missed/Unexpected placeholder {{{placeholder}}} in string '{string}'. ".format(placeholder=str(e).strip("'"), string=option) + "Missed/Unexpected placeholder {{{placeholder}}} in string '{string}'. ".format(placeholder=str(e).strip("'"), string=option)
"Please restore you configuration file back to default if necessary.") + "Please restore you configuration file back to default if necessary.")
except TypeError as e: except TypeError:
raise KeyError( raise KeyError(
"Missed placeholder in string '{string}'. ".format(string=option) + "Missed placeholder in string '{string}'. ".format(string=option)
"Please restore you configuration file back to default if necessary.") + "Please restore you configuration file back to default if necessary.")
else: else:
return string return string
def commands(command): def commands(command):
string = ""
try: try:
string = var.config.get("commands", command) string = var.config.get("commands", command)
return string return string
except KeyError as e: except KeyError:
raise KeyError("Missed command in configuration file: '{string}'. ".format(string=command) + raise KeyError("Missed command in configuration file: '{string}'. ".format(string=command)
"Please restore you configuration file back to default if necessary.") + "Please restore you configuration file back to default if necessary.")

View File

@ -15,7 +15,6 @@ class SettingsDatabase:
# connect # connect
conn = sqlite3.connect(self.db_path) conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
self.db_version_check_and_create() self.db_version_check_and_create()

View File

@ -16,7 +16,7 @@ import time
class ReverseProxied(object): class ReverseProxied(object):
'''Wrap the application in this middleware and configure the """Wrap the application in this middleware and configure the
front-end server to add these headers, to let you quietly bind front-end server to add these headers, to let you quietly bind
this to a URL other than / and to an HTTP scheme that is this to a URL other than / and to an HTTP scheme that is
different than what is used locally. different than what is used locally.
@ -31,7 +31,7 @@ class ReverseProxied(object):
} }
:param app: the WSGI application :param app: the WSGI application
''' """
def __init__(self, app): def __init__(self, app):
self.app = app self.app = app

View File

@ -1,8 +1,5 @@
import requests import requests
from xml.etree import ElementTree
from urllib.parse import urljoin
from librb.rbConstants import endpoints, BASE_URL from librb.rbConstants import endpoints, BASE_URL

View File

@ -1,11 +1,10 @@
import logging import logging
import os import os
from database import MusicDatabase
import json import json
import threading import threading
from media.item import item_builders, item_loaders, item_id_generators, dict_to_item, dicts_to_items from media.item import item_builders, item_id_generators, dict_to_item
from database import MusicDatabase from database import MusicDatabase
import variables as var import variables as var
import util import util
@ -18,6 +17,7 @@ class MusicCache(dict):
self.log = logging.getLogger("bot") self.log = logging.getLogger("bot")
self.dir = None self.dir = None
self.files = [] self.files = []
self.file_id_lookup = {}
self.dir_lock = threading.Lock() self.dir_lock = threading.Lock()
def get_item_by_id(self, bot, id): # Why all these functions need a bot? Because it need the bot to send message! def get_item_by_id(self, bot, id): # Why all these functions need a bot? Because it need the bot to send message!
@ -111,7 +111,6 @@ class MusicCache(dict):
self.dir_lock.acquire() self.dir_lock.acquire()
self.log.info("library: rebuild directory cache") self.log.info("library: rebuild directory cache")
self.files = [] self.files = []
self.file_id_lookup = {}
files = util.get_recursive_file_list_sorted(var.music_folder) files = util.get_recursive_file_list_sorted(var.music_folder)
self.dir = util.Dir(var.music_folder) self.dir = util.Dir(var.music_folder)
for file in files: for file in files:

View File

@ -1,4 +1,3 @@
import logging
import os import os
import re import re
from io import BytesIO from io import BytesIO
@ -6,9 +5,7 @@ import base64
import hashlib import hashlib
import mutagen import mutagen
from PIL import Image from PIL import Image
import json
import util
import variables as var import variables as var
from media.item import BaseItem, item_builders, item_loaders, item_id_generators from media.item import BaseItem, item_builders, item_loaders, item_id_generators
import constants import constants
@ -83,7 +80,7 @@ class FileItem(BaseItem):
return True return True
def _get_info_from_tag(self): def _get_info_from_tag(self):
match = re.search("(.+)\.(.+)", self.uri()) match = re.search(r"(.+)\.(.+)", self.uri())
assert match is not None assert match is not None
file_no_ext = match[1] file_no_ext = match[1]

View File

@ -1,15 +1,4 @@
import logging import logging
import threading
import os
import re
from io import BytesIO
import base64
import hashlib
import mutagen
from PIL import Image
import util
import variables as var
item_builders = {} item_builders = {}
item_loaders = {} item_loaders = {}
@ -117,5 +106,3 @@ class BaseItem:
def to_dict(self): def to_dict(self):
return {"type": self.type, "id": self.id, "ready": self.ready, "path": self.path, "tags": self.tags} return {"type": self.type, "id": self.id, "ready": self.ready, "path": self.path, "tags": self.tags}

View File

@ -359,4 +359,3 @@ class AutoPlaylist(OneshotPlaylist):
if len(self) == 0: if len(self) == 0:
self.refresh() self.refresh()
return super().next() return super().next()

View File

@ -16,12 +16,11 @@ def get_radio_server_description(url):
global log global log
log.debug("radio: fetching radio server description") log.debug("radio: fetching radio server description")
p = re.compile('(https?\:\/\/[^\/]*)', re.IGNORECASE) p = re.compile('(https?://[^/]*)', re.IGNORECASE)
res = re.search(p, url) res = re.search(p, url)
base_url = res.group(1) base_url = res.group(1)
url_icecast = base_url + '/status-json.xsl' url_icecast = base_url + '/status-json.xsl'
url_shoutcast = base_url + '/stats?json=1' url_shoutcast = base_url + '/stats?json=1'
title_server = None
try: try:
r = requests.get(url_shoutcast, timeout=10) r = requests.get(url_shoutcast, timeout=10)
data = r.json() data = r.json()
@ -31,7 +30,7 @@ def get_radio_server_description(url):
except (requests.exceptions.ConnectionError, except (requests.exceptions.ConnectionError,
requests.exceptions.HTTPError, requests.exceptions.HTTPError,
requests.exceptions.ReadTimeout, requests.exceptions.ReadTimeout,
requests.exceptions.Timeout) as e: requests.exceptions.Timeout):
error_traceback = traceback.format_exc() error_traceback = traceback.format_exc()
error = error_traceback.rstrip().split("\n")[-1] error = error_traceback.rstrip().split("\n")[-1]
log.debug("radio: unsuccessful attempts on fetching radio description (shoutcast): " + error) log.debug("radio: unsuccessful attempts on fetching radio description (shoutcast): " + error)
@ -52,7 +51,7 @@ def get_radio_server_description(url):
except (requests.exceptions.ConnectionError, except (requests.exceptions.ConnectionError,
requests.exceptions.HTTPError, requests.exceptions.HTTPError,
requests.exceptions.ReadTimeout, requests.exceptions.ReadTimeout,
requests.exceptions.Timeout) as e: requests.exceptions.Timeout):
error_traceback = traceback.format_exc() error_traceback = traceback.format_exc()
error = error_traceback.rstrip().split("\n")[-1] error = error_traceback.rstrip().split("\n")[-1]
log.debug("radio: unsuccessful attempts on fetching radio description (icecast): " + error) log.debug("radio: unsuccessful attempts on fetching radio description (icecast): " + error)
@ -82,7 +81,7 @@ def get_radio_title(url):
requests.exceptions.HTTPError, requests.exceptions.HTTPError,
requests.exceptions.ReadTimeout, requests.exceptions.ReadTimeout,
requests.exceptions.Timeout, requests.exceptions.Timeout,
KeyError) as e: KeyError):
log.debug("radio: unsuccessful attempts on fetching radio title (icy)") log.debug("radio: unsuccessful attempts on fetching radio title (icy)")
return url return url
@ -163,6 +162,3 @@ class RadioItem(BaseItem):
def display_type(self): def display_type(self):
return constants.strings("radio") return constants.strings("radio")

View File

@ -149,8 +149,6 @@ class URLItem(BaseItem):
self.ready = "preparing" self.ready = "preparing"
self.log.info("bot: downloading url (%s) %s " % (self.title, self.url)) self.log.info("bot: downloading url (%s) %s " % (self.title, self.url))
ydl_opts = ""
ydl_opts = { ydl_opts = {
'format': 'bestaudio/best', 'format': 'bestaudio/best',
'outtmpl': save_path, 'outtmpl': save_path,
@ -170,7 +168,7 @@ class URLItem(BaseItem):
for i in range(attempts): for i in range(attempts):
self.log.info("bot: download attempts %d / %d" % (i+1, attempts)) self.log.info("bot: download attempts %d / %d" % (i+1, attempts))
try: try:
info = ydl.extract_info(self.url) ydl.extract_info(self.url)
download_succeed = True download_succeed = True
break break
except: except:

View File

@ -1,8 +1,6 @@
import youtube_dl import youtube_dl
import constants import constants
import media
import variables as var import variables as var
import hashlib
from media.item import item_builders, item_loaders, item_id_generators from media.item import item_builders, item_loaders, item_id_generators
from media.url import URLItem, url_item_id_generator from media.url import URLItem, url_item_id_generator

View File

@ -14,8 +14,6 @@ import os
import os.path import os.path
import pymumble.pymumble_py3 as pymumble import pymumble.pymumble_py3 as pymumble
import variables as var import variables as var
import hashlib
import youtube_dl
import logging import logging
import logging.handlers import logging.handlers
import traceback import traceback
@ -25,9 +23,6 @@ import util
import command import command
import constants import constants
from database import SettingsDatabase, MusicDatabase from database import SettingsDatabase, MusicDatabase
import media.url
import media.file
import media.radio
import media.system import media.system
from media.playlist import BasePlaylist from media.playlist import BasePlaylist
from media.cache import MusicCache from media.cache import MusicCache
@ -585,7 +580,6 @@ def start_web_interface(addr, port):
# setup logger # setup logger
werkzeug_logger = logging.getLogger('werkzeug') werkzeug_logger = logging.getLogger('werkzeug')
logfile = util.solve_filepath(var.config.get('webinterface', 'web_logfile')) logfile = util.solve_filepath(var.config.get('webinterface', 'web_logfile'))
handler = None
if logfile: if logfile:
handler = logging.handlers.RotatingFileHandler(logfile, mode='a', maxBytes=10240) # Rotate after 10KB handler = logging.handlers.RotatingFileHandler(logfile, mode='a', maxBytes=10240) # Rotate after 10KB
else: else:

13
util.py
View File

@ -6,23 +6,16 @@ import magic
import os import os
import sys import sys
import variables as var import variables as var
import constants
import zipfile import zipfile
import requests import requests
import mutagen
import re import re
import subprocess as sp import subprocess as sp
import logging import logging
import youtube_dl import youtube_dl
from importlib import reload from importlib import reload
from PIL import Image
from io import BytesIO
from sys import platform from sys import platform
import traceback import traceback
import urllib.request import urllib.request
import base64
import media
import media.radio
from packaging import version from packaging import version
log = logging.getLogger("bot") log = logging.getLogger("bot")
@ -173,7 +166,7 @@ def url_unban(url):
def pipe_no_wait(pipefd): def pipe_no_wait(pipefd):
''' Used to fetch the STDERR of ffmpeg. pipefd is the file descriptor returned from os.pipe()''' """ Used to fetch the STDERR of ffmpeg. pipefd is the file descriptor returned from os.pipe()"""
if platform == "linux" or platform == "linux2" or platform == "darwin": if platform == "linux" or platform == "linux2" or platform == "darwin":
import fcntl import fcntl
import os import os
@ -316,13 +309,13 @@ def youtube_search(query):
try: try:
r = requests.get("https://www.youtube.com/results", params={'search_query': query}, timeout=5) r = requests.get("https://www.youtube.com/results", params={'search_query': query}, timeout=5)
results = re.findall("watch\?v=(.*?)\".*?title=\"(.*?)\".*?" results = re.findall(r"watch\?v=(.*?)\".*?title=\"(.*?)\".*?"
"(?:user|channel).*?>(.*?)<", r.text) # (id, title, uploader) "(?:user|channel).*?>(.*?)<", r.text) # (id, title, uploader)
if len(results) > 0: if len(results) > 0:
return results return results
except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError, requests.exceptions.Timeout) as e: except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError, requests.exceptions.Timeout):
error_traceback = traceback.format_exc().split("During")[0] error_traceback = traceback.format_exc().split("During")[0]
log.error("util: youtube query failed with error:\n %s" % error_traceback) log.error("util: youtube query failed with error:\n %s" % error_traceback)
return False return False