Second wave of initial code changes.
This commit is contained in:
parent
b1e21af243
commit
de270bc842
10
Dockerfile
10
Dockerfile
@ -1,12 +1,12 @@
|
||||
ARG ARCH=
|
||||
FROM python:3.11-slim-bullseye AS python-builder
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
WORKDIR /botamusique
|
||||
WORKDIR /bragi
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y gcc g++ ffmpeg libjpeg-dev libmagic-dev opus-tools zlib1g-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY . /botamusique
|
||||
COPY . /bragi
|
||||
RUN python3 -m venv venv \
|
||||
&& venv/bin/pip install wheel \
|
||||
&& venv/bin/pip install -r requirements.txt
|
||||
@ -17,9 +17,9 @@ EXPOSE 8181
|
||||
RUN apt update && \
|
||||
apt install --no-install-recommends -y opus-tools ffmpeg libmagic-dev curl tar && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=python-builder /botamusique /botamusique
|
||||
WORKDIR /botamusique
|
||||
COPY --from=python-builder /bragi /bragi
|
||||
WORKDIR /bragi
|
||||
RUN chmod +x entrypoint.sh
|
||||
|
||||
ENTRYPOINT [ "/botamusique/entrypoint.sh" ]
|
||||
ENTRYPOINT [ "/bragi/entrypoint.sh" ]
|
||||
CMD ["venv/bin/python", "mumbleBot.py"]
|
||||
|
@ -3,18 +3,18 @@ ARG ARCH=
|
||||
FROM ${ARCH}python:3-slim-bullseye AS source
|
||||
ARG VERSION=master
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
WORKDIR /botamusique
|
||||
WORKDIR /bragi
|
||||
RUN apt-get update && apt-get install -y git
|
||||
RUN git clone --recurse-submodules https://github.com/azlux/botamusique.git . && git checkout $VERSION
|
||||
RUN git clone --recurse-submodules https://github.com/azlux/bragi.git . && git checkout $VERSION
|
||||
|
||||
|
||||
FROM ${ARCH}python:3-slim-bullseye AS python-builder
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
WORKDIR /botamusique
|
||||
WORKDIR /bragi
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y gcc ffmpeg libjpeg-dev libmagic-dev opus-tools zlib1g-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=source /botamusique .
|
||||
COPY --from=source /bragi .
|
||||
RUN python3 -m venv venv \
|
||||
&& venv/bin/pip install wheel \
|
||||
&& venv/bin/pip install -r requirements.txt
|
||||
@ -22,30 +22,30 @@ RUN python3 -m venv venv \
|
||||
|
||||
FROM ${ARCH}node:14-bullseye-slim AS node-builder
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
WORKDIR /botamusique/web
|
||||
COPY --from=source /botamusique/web .
|
||||
WORKDIR /bragi/web
|
||||
COPY --from=source /bragi/web .
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
|
||||
|
||||
FROM ${ARCH}python:3-slim-bullseye AS template-builder
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
WORKDIR /botamusique
|
||||
COPY --from=python-builder /botamusique .
|
||||
COPY --from=node-builder /botamusique/templates templates
|
||||
RUN venv/bin/python scripts/translate_templates.py --lang-dir /botamusique/lang --template-dir /botamusique/web/templates
|
||||
WORKDIR /bragi
|
||||
COPY --from=python-builder /bragi .
|
||||
COPY --from=node-builder /bragi/templates templates
|
||||
RUN venv/bin/python scripts/translate_templates.py --lang-dir /bragi/lang --template-dir /bragi/web/templates
|
||||
|
||||
|
||||
FROM ${ARCH}python:3-slim-bullseye
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
EXPOSE 8181
|
||||
WORKDIR /botamusique
|
||||
WORKDIR /bragi
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y ffmpeg libmagic-dev opus-tools zlib1g \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=python-builder /botamusique .
|
||||
COPY --from=node-builder /botamusique/static static
|
||||
COPY --from=template-builder /botamusique/templates templates
|
||||
COPY --from=python-builder /bragi .
|
||||
COPY --from=node-builder /bragi/static static
|
||||
COPY --from=template-builder /bragi/templates templates
|
||||
RUN chmod +x entrypoint.sh
|
||||
ENTRYPOINT [ "/botamusique/entrypoint.sh" ]
|
||||
CMD ["/botamusique/venv/bin/python", "/botamusique/mumbleBot.py"]
|
||||
ENTRYPOINT [ "/bragi/entrypoint.sh" ]
|
||||
CMD ["/bragi/venv/bin/python", "/bragi/mumbleBot.py"]
|
||||
|
103
command.py
103
command.py
@ -1,4 +1,8 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
import logging
|
||||
import secrets
|
||||
import datetime
|
||||
@ -8,7 +12,6 @@ import pymumble_py3 as pymumble
|
||||
|
||||
from constants import tr_cli as tr
|
||||
from constants import commands
|
||||
import interface
|
||||
import util
|
||||
import variables as var
|
||||
from pyradios import RadioBrowser
|
||||
@ -53,7 +56,6 @@ def register_all_commands(bot):
|
||||
bot.register_command(commands('remove'), cmd_remove)
|
||||
bot.register_command(commands('remove_tag'), cmd_remove_tag)
|
||||
bot.register_command(commands('repeat'), cmd_repeat)
|
||||
bot.register_command(commands('requests_webinterface_access'), cmd_web_access)
|
||||
bot.register_command(commands('rescan'), cmd_refresh_cache, no_partial_match=True)
|
||||
bot.register_command(commands('search'), cmd_search_library)
|
||||
bot.register_command(commands('skip'), cmd_skip)
|
||||
@ -65,13 +67,9 @@ def register_all_commands(bot):
|
||||
bot.register_command(commands('yt_search'), cmd_yt_search)
|
||||
|
||||
# admin command
|
||||
bot.register_command(commands('add_webinterface_user'), cmd_web_user_add, admin=True)
|
||||
bot.register_command(commands('drop_database'), cmd_drop_database, no_partial_match=True, admin=True)
|
||||
bot.register_command(commands('kill'), cmd_kill, admin=True)
|
||||
bot.register_command(commands('list_webinterface_user'), cmd_web_user_list, admin=True)
|
||||
bot.register_command(commands('remove_webinterface_user'), cmd_web_user_remove, admin=True)
|
||||
bot.register_command(commands('max_volume'), cmd_max_volume, admin=True)
|
||||
bot.register_command(commands('update'), cmd_update, no_partial_match=True, admin=True)
|
||||
bot.register_command(commands('url_ban'), cmd_url_ban, no_partial_match=True, admin=True)
|
||||
bot.register_command(commands('url_ban_list'), cmd_url_ban_list, no_partial_match=True, admin=True)
|
||||
bot.register_command(commands('url_unban'), cmd_url_unban, no_partial_match=True, admin=True)
|
||||
@ -647,17 +645,6 @@ def cmd_kill(bot, user, text, command, parameter):
|
||||
bot.exit = True
|
||||
|
||||
|
||||
def cmd_update(bot, user, text, command, parameter):
|
||||
global log
|
||||
|
||||
if bot.is_admin(user):
|
||||
bot.mumble.users[text.actor].send_text_message(
|
||||
tr('start_updating'))
|
||||
msg = util.update(bot.version)
|
||||
bot.mumble.users[text.actor].send_text_message(msg)
|
||||
else:
|
||||
bot.mumble.users[text.actor].send_text_message(
|
||||
tr('not_admin'))
|
||||
|
||||
|
||||
def cmd_stop_and_getout(bot, user, text, command, parameter):
|
||||
@ -1249,88 +1236,6 @@ def cmd_refresh_cache(bot, user, text, command, parameter):
|
||||
bot.mumble.users[text.actor].send_text_message(tr('not_admin'))
|
||||
|
||||
|
||||
def cmd_web_access(bot, user, text, command, parameter):
|
||||
auth_method = var.config.get("webinterface", "auth_method")
|
||||
|
||||
if auth_method == 'token':
|
||||
interface.banned_ip = []
|
||||
interface.bad_access_count = {}
|
||||
|
||||
user_info = var.db.get("user", user, fallback='{}')
|
||||
user_dict = json.loads(user_info)
|
||||
if 'token' in user_dict:
|
||||
var.db.remove_option("web_token", user_dict['token'])
|
||||
|
||||
token = secrets.token_urlsafe(5)
|
||||
user_dict['token'] = token
|
||||
user_dict['token_created'] = str(datetime.datetime.now())
|
||||
user_dict['last_ip'] = ''
|
||||
var.db.set("web_token", token, user)
|
||||
var.db.set("user", user, json.dumps(user_dict))
|
||||
|
||||
access_address = var.config.get("webinterface", "access_address") + "/?token=" + token
|
||||
else:
|
||||
access_address = var.config.get("webinterface", "access_address")
|
||||
|
||||
bot.send_msg(tr('webpage_address', address=access_address), text)
|
||||
|
||||
|
||||
def cmd_user_password(bot, user, text, command, parameter):
|
||||
if not parameter:
|
||||
bot.send_msg(tr('bad_parameter', command=command), text)
|
||||
return
|
||||
|
||||
user_info = var.db.get("user", user, fallback='{}')
|
||||
user_dict = json.loads(user_info)
|
||||
user_dict['password'], user_dict['salt'] = util.get_salted_password_hash(parameter)
|
||||
|
||||
var.db.set("user", user, json.dumps(user_dict))
|
||||
|
||||
bot.send_msg(tr('user_password_set'), text)
|
||||
|
||||
|
||||
def cmd_web_user_add(bot, user, text, command, parameter):
|
||||
if not parameter:
|
||||
bot.send_msg(tr('bad_parameter', command=command), text)
|
||||
return
|
||||
|
||||
auth_method = var.config.get("webinterface", "auth_method")
|
||||
|
||||
if auth_method == 'password':
|
||||
web_users = json.loads(var.db.get("privilege", "web_access", fallback='[]'))
|
||||
if parameter not in web_users:
|
||||
web_users.append(parameter)
|
||||
var.db.set("privilege", "web_access", json.dumps(web_users))
|
||||
bot.send_msg(tr('web_user_list', users=", ".join(web_users)), text)
|
||||
else:
|
||||
bot.send_msg(tr('command_disabled', command=command), text)
|
||||
|
||||
|
||||
def cmd_web_user_remove(bot, user, text, command, parameter):
|
||||
if not parameter:
|
||||
bot.send_msg(tr('bad_parameter', command=command), text)
|
||||
return
|
||||
|
||||
auth_method = var.config.get("webinterface", "auth_method")
|
||||
|
||||
if auth_method == 'password':
|
||||
web_users = json.loads(var.db.get("privilege", "web_access", fallback='[]'))
|
||||
if parameter in web_users:
|
||||
web_users.remove(parameter)
|
||||
var.db.set("privilege", "web_access", json.dumps(web_users))
|
||||
bot.send_msg(tr('web_user_list', users=", ".join(web_users)), text)
|
||||
else:
|
||||
bot.send_msg(tr('command_disabled', command=command), text)
|
||||
|
||||
|
||||
def cmd_web_user_list(bot, user, text, command, parameter):
|
||||
auth_method = var.config.get("webinterface", "auth_method")
|
||||
|
||||
if auth_method == 'password':
|
||||
web_users = json.loads(var.db.get("privilege", "web_access", fallback='[]'))
|
||||
bot.send_msg(tr('web_user_list', users=", ".join(web_users)), text)
|
||||
else:
|
||||
bot.send_msg(tr('command_disabled', command=command), text)
|
||||
|
||||
|
||||
def cmd_version(bot, user, text, command, parameter):
|
||||
|
@ -1,5 +1,6 @@
|
||||
# ========================================================
|
||||
# botamusique Default Configuration File
|
||||
# Bragi Default Configuration File
|
||||
# Forked from botamusique by azlux
|
||||
# Version 6
|
||||
# ========================================================
|
||||
# WARNING:
|
||||
@ -31,7 +32,6 @@ admin =
|
||||
allow_other_channel_message = False
|
||||
allow_private_message = True
|
||||
announce_current_music = True
|
||||
auto_check_update = True
|
||||
autoplay_length = 5
|
||||
avatar =
|
||||
bandwidth = 96000
|
||||
@ -59,28 +59,13 @@ refresh_cache_on_startup = True
|
||||
save_music_library = True
|
||||
save_playlist = True
|
||||
stereo = True
|
||||
target_version = git
|
||||
tmp_folder = /tmp/
|
||||
tmp_folder_max_size = 10
|
||||
username = botamusique
|
||||
username = bragi
|
||||
volume = 0.8
|
||||
when_nobody_in_channel = nothing
|
||||
when_nobody_in_channel_ignore =
|
||||
|
||||
[webinterface]
|
||||
access_address = http://127.0.0.1:8181
|
||||
auth_method = none
|
||||
enabled = False
|
||||
flask_secret = ChangeThisPassword
|
||||
is_web_proxified = True
|
||||
listening_addr = 127.0.0.1
|
||||
listening_port = 8181
|
||||
max_attempts = 10
|
||||
max_upload_file_size = 30M
|
||||
password =
|
||||
upload_enabled = True
|
||||
user =
|
||||
web_logfile =
|
||||
|
||||
[debug]
|
||||
ffmpeg = False
|
||||
@ -102,7 +87,6 @@ user_agent =
|
||||
[commands]
|
||||
add_from_shortlist = shortlist, sl
|
||||
add_tag = addtag
|
||||
add_webinterface_user = webuseradd
|
||||
change_user_password = password
|
||||
clear = clear
|
||||
command_symbol = !:!
|
||||
@ -118,7 +102,6 @@ joinme = joinme
|
||||
kill = kill
|
||||
last = last
|
||||
list_file = listfile
|
||||
list_webinterface_user = webuserlist
|
||||
max_volume = maxvolume
|
||||
mode = mode
|
||||
pause = pause
|
||||
@ -135,16 +118,13 @@ rb_play = rbplay
|
||||
rb_query = rbquery
|
||||
remove = rm
|
||||
remove_tag = untag
|
||||
remove_webinterface_user = webuserdel
|
||||
repeat = repeat
|
||||
requests_webinterface_access = web
|
||||
rescan = rescan
|
||||
search = search
|
||||
skip = skip
|
||||
split_username_at_space = False
|
||||
stop = stop
|
||||
stop_and_getout = oust
|
||||
update = update
|
||||
url_ban = urlban
|
||||
url_ban_list = urlbanlist
|
||||
url_unban = urlunban
|
||||
|
@ -1,5 +1,6 @@
|
||||
# ========================================================
|
||||
# botamusique example configuration file
|
||||
# Bragi example configuration file
|
||||
# Forked from botamusique by azlux
|
||||
# Version 6
|
||||
# ========================================================
|
||||
# Rename this file to configuration.ini after editing.
|
||||
@ -22,7 +23,7 @@ port = 64738
|
||||
# 'username': The bot's username.
|
||||
# 'comment': Comment displayed on the bot's profile.
|
||||
# 'avatar': Path to an image used for the bot's avatar (PNG recommended, 128 KB max).
|
||||
#username = botamusique
|
||||
#username = bragi
|
||||
#comment = "Hi, I'm here to play radio, local music or youtube/soundcloud music. Have fun!"
|
||||
#avatar =
|
||||
|
||||
@ -155,46 +156,7 @@ port = 64738
|
||||
# query youtube", you should provide a value here.
|
||||
#youtube_query_cookie = {"CONSENT": "paste your CONSENT cookie value here"}
|
||||
|
||||
# The [webinterface] section stores settings related to the web interface.
|
||||
[webinterface]
|
||||
# 'enabled': Whether to enable the web interface to allow managing your playlist,
|
||||
# uploading tracks, etc.
|
||||
# The web interface is disabled by default for security and performance reasons.
|
||||
# 'access_address': URL provided to users when the public URL for the
|
||||
# web interface is requested.
|
||||
#enabled = False
|
||||
#listening_addr = 127.0.0.1
|
||||
#listening_port = 8181
|
||||
#is_web_proxified = True
|
||||
#access_address = http://127.0.0.1:8181
|
||||
|
||||
# 'web_logfile': If this is provided, web server access logs are written to this file.
|
||||
#web_logfile =
|
||||
|
||||
# 'auth_method': Method used to authenticate users accessing the web interface.
|
||||
# One of 'none', 'password' or 'token'. If this is set to 'token', a unique token
|
||||
# is used for authentication.
|
||||
# 'max_attempts': Amount of incorrect login attempts needed before being banned.
|
||||
# Regenerating a token or rebooting the bot will reset this number.
|
||||
#auth_method = token
|
||||
#max_attempts = 10
|
||||
|
||||
# 'user', 'password': If auth_method is set to 'password', you'll need to set
|
||||
# the default username and password, which is set by these two options.
|
||||
# You can add more users using the '!webadduser' command.
|
||||
#user = botamusique
|
||||
#password = mumble
|
||||
|
||||
# 'flask_secret': To use a token, Flask needs a password to encrypt/sign cookies.
|
||||
# This is absolutely necessary if auth_method is 'token'!
|
||||
#flask_secret = ChangeThisPassword
|
||||
|
||||
# 'upload_enabled': Whether to enable the upload function of the web interface.
|
||||
# If this is False, only admins can upload files.
|
||||
# 'maximum_upload_file_size': Maximum file size allowed for uploads.
|
||||
# Can be specified in B, KB, MB, GB, or TB.
|
||||
#upload_enabled = True
|
||||
#max_upload_file_size = 30MB
|
||||
# Web interface has been removed from Bragi
|
||||
|
||||
# The [debug] section contains settings to enable debugging messaages.
|
||||
[debug]
|
||||
|
@ -1,3 +1,8 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
import os
|
||||
import json
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
import os
|
||||
import re
|
||||
import sqlite3
|
||||
|
@ -51,14 +51,14 @@ fi
|
||||
|
||||
if [ -n "$BAM_CONFIG_file" ]; then
|
||||
if [ ! -f "$BAM_CONFIG_file" ]; then
|
||||
cp "/botamusique/configuration.example.ini" "$BAM_CONFIG_file"
|
||||
cp "/bragi/configuration.example.ini" "$BAM_CONFIG_file"
|
||||
fi
|
||||
command+=( "--config" "$BAM_CONFIG_file" )
|
||||
else
|
||||
if [ ! -f "/botamusique/configuration.ini" ]; then
|
||||
cp "/botamusique/configuration.example.ini" "/botamusique/configuration.ini"
|
||||
if [ ! -f "/bragi/configuration.ini" ]; then
|
||||
cp "/bragi/configuration.example.ini" "/bragi/configuration.ini"
|
||||
fi
|
||||
command+=( "--config" "/botamusique/configuration.ini" )
|
||||
command+=( "--config" "/bragi/configuration.ini" )
|
||||
fi
|
||||
|
||||
exec "${command[@]}"
|
||||
|
@ -36,7 +36,7 @@
|
||||
"multiple_file_deleted": "Multiple items deleted from the library:",
|
||||
"multiple_file_found": "Found:",
|
||||
"multiple_matches": "File not found! Possible candidates:",
|
||||
"new_version_found": "<h2>Update Available!</h2> Version {new_version} of botamusique is available! <hr />\n<h3>Changelog</h3> {changelog} <hr /> Send <i>!update</i> to update!",
|
||||
"new_version_found": "<h2>Update Available!</h2> Version {new_version} of bragi is available! <hr />\n<h3>Changelog</h3> {changelog} <hr /> Send <i>!update</i> to update!",
|
||||
"next_to_play": "Next song.",
|
||||
"no_file": "File not found.",
|
||||
"not_admin": "You are not an admin!",
|
||||
@ -60,7 +60,7 @@
|
||||
"removed_tags_from_all": "Removed tags <i>{tags}</i> from songs on the playlist.",
|
||||
"removing_item": "Removed entry {item} from playlist.",
|
||||
"repeat": "Repeat {song} for {n} times.",
|
||||
"report_version": "The current version of botamusique is <b>{version}</b>.",
|
||||
"report_version": "The current version of bragi is <b>{version}</b>.",
|
||||
"shortlist_instruction": "Use <i>!sl {indexes}</i> to play the item you want.",
|
||||
"start_updating": "Start updating...",
|
||||
"stopped": "Music stopped.",
|
||||
@ -68,7 +68,7 @@
|
||||
"unable_download": "Unable to download <b>{item}</b>. Removed from the library.",
|
||||
"unable_play": "Unable to play <b>{item}</b>. Removed from the library.",
|
||||
"unknown_mode": "Unknown playback mode '{mode}'. It should be one of <i>one-shot</i>, <i>repeat</i>, <i>random</i>.",
|
||||
"update_successful": "<h2>botamusique v{version} Installed!</h2><hr />\n<h3>Changelog</h3> {changelog} <hr /> Visit <a href=\"https://github.com/azlux/botamusique\">our github repo</a> for more details!",
|
||||
"update_successful": "<h2>bragi v{version} Installed!</h2><hr />\n<h3>Changelog</h3> {changelog} <hr /> Visit <a href=\"https://github.com/azlux/bragi\">our github repo</a> for more details!",
|
||||
"url": "URL",
|
||||
"url_ban": "The URL {url} is banned! Removed from playlist!",
|
||||
"url_ban_list": "List of banned URL: <br>{list}",
|
||||
@ -105,7 +105,7 @@
|
||||
"add_url": "Add URL",
|
||||
"add_youtube_or_soundcloud_url": "Add Youtube or Soundcloud URL",
|
||||
"are_you_really_sure": "Are you really sure?",
|
||||
"aria_botamusique_logo": "Botamusique Logo: a fox with two headphones, enjoying the music",
|
||||
"aria_bragi_logo": "Botamusique Logo: a fox with two headphones, enjoying the music",
|
||||
"aria_default_cover": "A black square with two eighth notes beamed together.",
|
||||
"aria_empty_box": "A drawing of an empty box.",
|
||||
"aria_remove_this_song": "Remove this song from the current playlist",
|
||||
@ -141,7 +141,7 @@
|
||||
"no_tag": "No tag",
|
||||
"oneshot": "One-shot",
|
||||
"open_volume_controls": "Open Volume Controls",
|
||||
"page_title": "botamusique Web Interface",
|
||||
"page_title": "bragi Web Interface",
|
||||
"pause": "Pause",
|
||||
"play": "Play",
|
||||
"playlist_controls": "Playlist controls",
|
||||
|
@ -0,0 +1,4 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
@ -1,3 +1,8 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
import os
|
||||
import re
|
||||
from io import BytesIO
|
||||
|
@ -1,3 +1,8 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
import logging
|
||||
|
||||
item_builders = {}
|
||||
|
@ -1,3 +1,8 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
import json
|
||||
import threading
|
||||
import logging
|
||||
|
@ -1,3 +1,8 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
import re
|
||||
import logging
|
||||
import struct
|
||||
|
@ -1,3 +1,8 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
import threading
|
||||
import logging
|
||||
import os
|
||||
|
@ -1,3 +1,8 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
import logging
|
||||
import yt_dlp as youtube_dl
|
||||
from constants import tr_cli as tr
|
||||
|
60
mumbleBot.py
60
mumbleBot.py
@ -1,5 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
@ -36,7 +40,7 @@ class MumbleBot:
|
||||
|
||||
def __init__(self, args):
|
||||
self.log = logging.getLogger("bot")
|
||||
self.log.info(f"bot: botamusique version {self.get_version()}, starting...")
|
||||
self.log.info(f"bot: bragi version {self.get_version()}, starting...")
|
||||
signal.signal(signal.SIGINT, self.ctrl_caught)
|
||||
self.cmd_handle = {}
|
||||
|
||||
@ -48,8 +52,6 @@ class MumbleBot:
|
||||
self.channel = var.config.get("server", "channel")
|
||||
|
||||
var.user = args.user
|
||||
var.is_proxified = var.config.getboolean(
|
||||
"webinterface", "is_web_proxified")
|
||||
|
||||
# Flags to indicate the bot is exiting (Ctrl-C, or !kill)
|
||||
self.exit = False
|
||||
@ -187,26 +189,7 @@ class MumbleBot:
|
||||
|
||||
self.redirect_ffmpeg_log = var.config.getboolean('debug', 'redirect_ffmpeg_log')
|
||||
|
||||
if var.config.getboolean("bot", "auto_check_update"):
|
||||
def check_update():
|
||||
nonlocal self
|
||||
new_version, changelog = util.check_update(self.get_version())
|
||||
if new_version:
|
||||
self.send_channel_msg(tr('new_version_found', new_version=new_version, changelog=changelog))
|
||||
|
||||
th = threading.Thread(target=check_update, name="UpdateThread")
|
||||
th.daemon = True
|
||||
th.start()
|
||||
|
||||
last_startup_version = var.db.get("bot", "version", fallback=None)
|
||||
try:
|
||||
if not last_startup_version or version.parse(last_startup_version) < version.parse(self.version):
|
||||
var.db.set("bot", "version", self.version)
|
||||
if var.config.getboolean("bot", "auto_check_update"):
|
||||
changelog = util.fetch_changelog()
|
||||
self.send_channel_msg(tr("update_successful", version=self.version, changelog=changelog))
|
||||
except version.InvalidVersion:
|
||||
var.db.set("bot", "version", self.version)
|
||||
var.db.set("bot", "version", self.version)
|
||||
|
||||
# Set the CTRL+C shortcut
|
||||
def ctrl_caught(self, signal, frame):
|
||||
@ -753,31 +736,13 @@ class MumbleBot:
|
||||
self.pause_at_id = ""
|
||||
|
||||
|
||||
def start_web_interface(addr, port):
|
||||
global formatter
|
||||
import interface
|
||||
|
||||
# setup logger
|
||||
werkzeug_logger = logging.getLogger('werkzeug')
|
||||
logfile = util.solve_filepath(var.config.get('webinterface', 'web_logfile'))
|
||||
if logfile:
|
||||
handler = logging.handlers.RotatingFileHandler(logfile, mode='a', maxBytes=10240, backupCount=3) # Rotate after 10KB, leave 3 old logs
|
||||
else:
|
||||
handler = logging.StreamHandler()
|
||||
|
||||
werkzeug_logger.addHandler(handler)
|
||||
|
||||
interface.init_proxy()
|
||||
interface.web.env = 'development'
|
||||
interface.web.secret_key = var.config.get('webinterface', 'flask_secret')
|
||||
interface.web.run(port=port, host=addr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
supported_languages = util.get_supported_language()
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Bot for playing music on Mumble')
|
||||
description='Bragi - Bot for playing music on Mumble')
|
||||
|
||||
# General arguments
|
||||
parser.add_argument("--config", dest='config', type=str, default='configuration.ini',
|
||||
@ -950,17 +915,6 @@ if __name__ == '__main__':
|
||||
var.bot_logger.info("bot: load playlist from previous session")
|
||||
var.playlist.load()
|
||||
|
||||
# ============================
|
||||
# Start the web interface
|
||||
# ============================
|
||||
if var.config.getboolean("webinterface", "enabled"):
|
||||
wi_addr = var.config.get("webinterface", "listening_addr")
|
||||
wi_port = var.config.getint("webinterface", "listening_port")
|
||||
tt = threading.Thread(
|
||||
target=start_web_interface, name="WebThread", args=(wi_addr, wi_port))
|
||||
tt.daemon = True
|
||||
bot_logger.info('Starting web interface on {}:{}'.format(wi_addr, wi_port))
|
||||
tt.start()
|
||||
|
||||
# Start the main loop.
|
||||
var.bot.loop()
|
||||
|
@ -1,4 +1,3 @@
|
||||
flask
|
||||
yt-dlp
|
||||
python-magic
|
||||
Pillow
|
||||
|
20
update.sh
20
update.sh
@ -2,18 +2,18 @@
|
||||
|
||||
case "$1" in
|
||||
stable)
|
||||
curl -Lo /tmp/botamusique.tar.gz https://packages.azlux.fr/botamusique/sources-stable.tar.gz
|
||||
tar -xzf /tmp/botamusique.tar.gz -C /tmp/
|
||||
cp -r /tmp/botamusique/* .
|
||||
rm -r /tmp/botamusique
|
||||
rm -r /tmp/botamusique.tar.gz
|
||||
curl -Lo /tmp/bragi.tar.gz https://packages.azlux.fr/bragi/sources-stable.tar.gz
|
||||
tar -xzf /tmp/bragi.tar.gz -C /tmp/
|
||||
cp -r /tmp/bragi/* .
|
||||
rm -r /tmp/bragi
|
||||
rm -r /tmp/bragi.tar.gz
|
||||
;;
|
||||
testing)
|
||||
curl -Lo /tmp/botamusique.tar.gz https://packages.azlux.fr/botamusique/sources-testing.tar.gz
|
||||
tar -xzf /tmp/botamusique.tar.gz -C /tmp/
|
||||
cp -r /tmp/botamusique/* .
|
||||
rm -r /tmp/botamusique
|
||||
rm -r /tmp/botamusique.tar.gz
|
||||
curl -Lo /tmp/bragi.tar.gz https://packages.azlux.fr/bragi/sources-testing.tar.gz
|
||||
tar -xzf /tmp/bragi.tar.gz -C /tmp/
|
||||
cp -r /tmp/bragi/* .
|
||||
rm -r /tmp/bragi
|
||||
rm -r /tmp/bragi.tar.gz
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
|
68
util.py
68
util.py
@ -1,5 +1,9 @@
|
||||
#!/usr/bin/python3
|
||||
# coding=utf-8
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
import hashlib
|
||||
import html
|
||||
@ -102,64 +106,8 @@ def get_user_ban():
|
||||
return res
|
||||
|
||||
|
||||
def new_release_version(target):
|
||||
if target == "testing":
|
||||
r = requests.get("https://packages.azlux.fr/botamusique/testing-version")
|
||||
else:
|
||||
r = requests.get("https://packages.azlux.fr/botamusique/version")
|
||||
v = r.text
|
||||
return v.rstrip()
|
||||
|
||||
|
||||
def fetch_changelog():
|
||||
r = requests.get("https://packages.azlux.fr/botamusique/changelog")
|
||||
c = r.text
|
||||
return c
|
||||
|
||||
|
||||
def check_update(current_version):
|
||||
global log
|
||||
log.debug("update: checking for updates...")
|
||||
new_version = new_release_version(var.config.get('bot', 'target_version'))
|
||||
if version.parse(new_version) > version.parse(current_version):
|
||||
changelog = fetch_changelog()
|
||||
log.info(f"update: new version {new_version} found, current installed version {current_version}.")
|
||||
log.info(f"update: changelog: {changelog}")
|
||||
changelog = changelog.replace("\n", "<br>")
|
||||
return new_version, changelog
|
||||
else:
|
||||
log.debug("update: no new version found.")
|
||||
return None, None
|
||||
|
||||
|
||||
def update(current_version):
|
||||
global log
|
||||
|
||||
target = var.config.get('bot', 'target_version')
|
||||
new_version = new_release_version(target)
|
||||
msg = ""
|
||||
if target == "git":
|
||||
msg = "git install, I do nothing<br/>"
|
||||
|
||||
elif (target == "stable" and version.parse(new_version) > version.parse(current_version)) or \
|
||||
(target == "testing" and version.parse(new_version) != version.parse(current_version)):
|
||||
log.info('update: new version, start updating...')
|
||||
tp = sp.check_output(['/usr/bin/env', 'bash', 'update.sh', target]).decode()
|
||||
log.debug(tp)
|
||||
log.info('update: update pip libraries dependencies')
|
||||
sp.check_output([var.config.get('bot', 'pip3_path'), 'install', '--upgrade', '-r', 'requirements.txt']).decode()
|
||||
msg = "New version installed, please restart the bot.<br/>"
|
||||
|
||||
log.info(f'update: starting update {YT_PKG_NAME} via pip3')
|
||||
tp = sp.check_output([var.config.get('bot', 'pip3_path'), 'install', '--upgrade', YT_PKG_NAME]).decode()
|
||||
if f"Collecting {YT_PKG_NAME}" in tp.splitlines():
|
||||
msg += "Update done: " + tp.split('Successfully installed')[1]
|
||||
else:
|
||||
msg += YT_PKG_NAME.capitalize() + " is up-to-date"
|
||||
|
||||
reload(youtube_dl)
|
||||
msg += "<br/>" + YT_PKG_NAME.capitalize() + " reloaded"
|
||||
return msg
|
||||
|
||||
|
||||
def pipe_no_wait():
|
||||
@ -311,7 +259,7 @@ def get_url_from_input(string):
|
||||
else:
|
||||
return ""
|
||||
|
||||
match = re.search("(http|https)://(\S*)?/(\S*)", string, flags=re.IGNORECASE)
|
||||
match = re.search(r"(http|https)://(\S*)?/(\S*)", string, flags=re.IGNORECASE)
|
||||
if match:
|
||||
url = match[1].lower() + "://" + match[2].lower() + "/" + match[3]
|
||||
# https://github.com/mumble-voip/mumble/issues/4999
|
||||
@ -376,7 +324,7 @@ def get_media_duration(path):
|
||||
|
||||
|
||||
def parse_time(human):
|
||||
match = re.search("(?:(\d\d):)?(?:(\d\d):)?(\d+(?:\.\d*)?)", human, flags=re.IGNORECASE)
|
||||
match = re.search(r"(?:(\d\d):)?(?:(\d\d):)?(\d+(?:\.\d*)?)", human, flags=re.IGNORECASE)
|
||||
if match:
|
||||
if match[1] is None and match[2] is None:
|
||||
return float(match[3])
|
||||
@ -399,7 +347,7 @@ def format_time(seconds):
|
||||
def parse_file_size(human):
|
||||
units = {"B": 1, "KB": 1024, "MB": 1024 * 1024, "GB": 1024 * 1024 * 1024, "TB": 1024 * 1024 * 1024 * 1024,
|
||||
"K": 1024, "M": 1024 * 1024, "G": 1024 * 1024 * 1024, "T": 1024 * 1024 * 1024 * 1024}
|
||||
match = re.search("(\d+(?:\.\d*)?)\s*([A-Za-z]+)", human, flags=re.IGNORECASE)
|
||||
match = re.search(r"(\d+(?:\.\d*)?)\s*([A-Za-z]+)", human, flags=re.IGNORECASE)
|
||||
if match:
|
||||
num = float(match[1])
|
||||
unit = match[2].upper()
|
||||
@ -428,7 +376,7 @@ def get_supported_language():
|
||||
lang_files = os.listdir(os.path.join(root_dir, 'lang'))
|
||||
lang_list = []
|
||||
for lang_file in lang_files:
|
||||
match = re.search("([a-z]{2}_[A-Z]{2})\.json", lang_file)
|
||||
match = re.search(r"([a-z]{2}_[A-Z]{2})\.json", lang_file)
|
||||
if match:
|
||||
lang_list.append(match[1])
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
#
|
||||
# Bragi - A Mumble music bot
|
||||
# Forked from botamusique by azlux (https://github.com/azlux/botamusque)
|
||||
#
|
||||
|
||||
from typing import Type, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
Loading…
x
Reference in New Issue
Block a user