mirror of
https://github.com/migatu/conjurer.git
synced 2026-07-14 21:38:38 +00:00
Tag: 1.24
Intermediate commits (oldest → newest): - Merge branch 'main' of https://github.com/migatu/conjurer - Merge branch 'main' of https://github.com/migatu/conjurer - BGFX - Function for idv3 and bugfix - Merge branch 'main' of https://github.com/migatu/conjurer - Logs additional - LGFIX - FIXED! - Arguments added to the utility. - Fix old bug - add exception handling - Literowka - Hej hoppsan! - Add comment - Fixc Fixc - Fixit - Inside joke very boomer much wow - Fixing logging issues in music_functions.py and other_functions.py - Maybe this will fix - test - test - another attempt to fix the bug - Maybe this is the fix ? - Maybe fix
This commit is contained in:
@@ -6,17 +6,32 @@ API endpoints.
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
|
||||
# from flask_autoindex import AutoIndex
|
||||
from datetime import datetime
|
||||
from logging import handlers
|
||||
from pathlib import Path
|
||||
from platform import uname
|
||||
from sys import platform
|
||||
from flask import Flask, jsonify, redirect, request, send_from_directory, render_template
|
||||
|
||||
import requests
|
||||
from flask import (
|
||||
Flask,
|
||||
jsonify,
|
||||
redirect,
|
||||
render_template,
|
||||
request,
|
||||
send_from_directory,
|
||||
)
|
||||
from waitress import serve
|
||||
|
||||
MAIN_BOT_ADDRESS = "http://192.168.1.191:5000"
|
||||
MUSIC_TRACKER = "/prepped_tracks"
|
||||
HOST_ADDRESS = "192.168.1.15"
|
||||
PORT_ADDRESS = 5000
|
||||
if platform in ("linux", "linux2"):
|
||||
@@ -27,6 +42,8 @@ if platform in ("linux", "linux2"):
|
||||
NETRC_FILE = "/home/mtuszowski/.netrc"
|
||||
LOGSTORE = "/home/mtuszowski/conjurer/logs/"
|
||||
ENCODING = "utf-8"
|
||||
RADIOLOG_PATH = "/home/pi/Conjurer/radio_log.log"
|
||||
PERSISTENCE_PATH = "/home/pi/Conjurer/persistence.log"
|
||||
|
||||
else:
|
||||
LOGFILE = "/home/pi/Conjurer/discord_mus_service.log"
|
||||
@@ -35,17 +52,21 @@ if platform in ("linux", "linux2"):
|
||||
ENCODING = "utf-8"
|
||||
MUSIC_FOLDER = "/home/pi/RetroPie/mp3/"
|
||||
PRIORITY_FOLDER = "/home/pi/RetroPie/mp3/Magiczne i chuj/"
|
||||
RADIOLOG_PATH = "/home/pi/Conjurer/radio_log.log"
|
||||
PERSISTENCE_PATH = "/home/pi/Conjurer/persistence.log"
|
||||
|
||||
|
||||
random.seed()
|
||||
music_file_list = []
|
||||
priority_list = []
|
||||
|
||||
|
||||
def rescan():
|
||||
"""
|
||||
The `rescan` function logs a message, scans for mp3 files in a specified folder,
|
||||
and adds them to a list of music files.
|
||||
"""
|
||||
logging.info("Rescan triggered")
|
||||
logger = logging.getLogger("conjurer_musician")
|
||||
logger.info("Rescan triggered")
|
||||
|
||||
for mp3_item in Path.glob(Path(MUSIC_FOLDER), "**/*.mp3"):
|
||||
temp_music_file = mp3_item.as_posix()
|
||||
@@ -60,8 +81,8 @@ def rescan():
|
||||
priority_list.append(temp_music_file)
|
||||
|
||||
with open(
|
||||
"/home/pi/Conjurer/all_playlist.playlist", "w", encoding="utf-8"
|
||||
) as w_file:
|
||||
"/home/pi/Conjurer/all_playlist.playlist", "w", encoding="utf-8"
|
||||
) as w_file:
|
||||
try:
|
||||
for item in music_file_list:
|
||||
w_file.write(item)
|
||||
@@ -82,14 +103,87 @@ def thread_rescan():
|
||||
The `thread_rescan` function periodically triggers a rescan operation after a specified time
|
||||
interval.
|
||||
"""
|
||||
logging.info("Starting filesystemupdater")
|
||||
logger = logging.getLogger("conjurer_musician")
|
||||
logger.info("Starting filesystemupdater")
|
||||
while True:
|
||||
time.sleep(60 * 60 * 24)
|
||||
logging.info("Rescan triggered")
|
||||
logger.info("Rescan triggered")
|
||||
rescan()
|
||||
|
||||
|
||||
def scan_tracks():
|
||||
# Set the filename and open the file
|
||||
logger = logging.getLogger("conjurer_musician")
|
||||
|
||||
file = open(RADIOLOG_PATH, "r")
|
||||
# Find the size of the file and move to the end
|
||||
st_results = os.stat(RADIOLOG_PATH)
|
||||
st_size = st_results[6]
|
||||
file.seek(st_size)
|
||||
st_results1 = os.stat(PERSISTENCE_PATH)
|
||||
prev_st_size1 = st_results[6]
|
||||
|
||||
while 1:
|
||||
|
||||
st_results1 = os.stat(PERSISTENCE_PATH)
|
||||
st_size1 = st_results1[6]
|
||||
if prev_st_size1 != st_size1:
|
||||
while prev_st_size1 != st_size1:
|
||||
prev_st_size1 = st_size1
|
||||
st_results1 = os.stat(PERSISTENCE_PATH)
|
||||
st_size1 = st_results1[6]
|
||||
time.sleep(0.1)
|
||||
file1 = open(PERSISTENCE_PATH, "r")
|
||||
lines = file1.readlines()
|
||||
result = ["next", lines[2]]
|
||||
file1.close()
|
||||
returned = requests.post(
|
||||
f"{MAIN_BOT_ADDRESS}{MUSIC_TRACKER}", json=result, timeout=360
|
||||
)
|
||||
logger.info("SENT")
|
||||
logger.info(returned.status_code)
|
||||
logger.info("SEND CONFIRMED")
|
||||
|
||||
where = file.tell()
|
||||
line = file.readline()
|
||||
if not line:
|
||||
time.sleep(1)
|
||||
file.seek(where)
|
||||
else:
|
||||
if re.match(".*Prepared.*", line):
|
||||
result = None
|
||||
if re.match(".*jingles.*", line):
|
||||
logger.info("jingles")
|
||||
logger.info(line) # already has newline
|
||||
result = ["jingles", line]
|
||||
elif re.match(".*priority.*", line):
|
||||
logger.info("priority")
|
||||
logger.info(line) # already has newline
|
||||
result = ["priority", line]
|
||||
elif re.match(".*hit.*", line):
|
||||
logger.info("hit")
|
||||
logger.info(line) # already has newline
|
||||
result = ["hit", line]
|
||||
elif re.match(".*all_playlist.*", line):
|
||||
logger.info("all")
|
||||
logger.info(line) # already has newline
|
||||
result = ["all", line]
|
||||
elif re.match(".*request.*", line):
|
||||
logger.info("requests")
|
||||
logger.info(line) # already has newline
|
||||
result = ["requests", line]
|
||||
if result:
|
||||
returned = requests.post(
|
||||
f"{MAIN_BOT_ADDRESS}{MUSIC_TRACKER}", json=result, timeout=360
|
||||
)
|
||||
logger.info("SENT")
|
||||
logger.info(returned.status_code)
|
||||
logger.info("SEND CONFIRMED")
|
||||
time.sleep(0.1)
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
# AutoIndex(app, browse_root="/")
|
||||
|
||||
|
||||
# TODO: Odpalić wyszukiwarki w wątkach i dopiero po wszystkim zsumować wyszukiwanie.
|
||||
@@ -247,9 +341,10 @@ def stream_music():
|
||||
:return: A JSON response containing a key "music_file_list" with the value of the variable `music_file_list`.
|
||||
"""
|
||||
|
||||
#return send_from_directory("/tmp/hls", "stream.m3u8")
|
||||
# return send_from_directory("/tmp/hls", "stream.m3u8")
|
||||
return render_template("/home/pi/Conjurer/stream.html")
|
||||
|
||||
|
||||
@app.route("/<string:file_name>")
|
||||
def stream(file_name):
|
||||
"""
|
||||
@@ -265,6 +360,7 @@ def stream(file_name):
|
||||
video_dir = "/tmp/hls"
|
||||
return send_from_directory(video_dir, file_name)
|
||||
|
||||
|
||||
@app.route("/stream_mp3", methods=["GET"])
|
||||
def stream_music_mp3():
|
||||
"""
|
||||
@@ -284,8 +380,10 @@ def clear_pr_pls():
|
||||
:return: A JSON response indicating the success of the operation.
|
||||
"""
|
||||
app.logger.info("CLEARING PLAYLIST")
|
||||
with open('/home/pi/Conjurer/priority_queue.playlist', 'w', encoding='utf-8') as cleared_pl:
|
||||
cleared_pl.write('')
|
||||
with open(
|
||||
"/home/pi/Conjurer/priority_queue.playlist", "w", encoding="utf-8"
|
||||
) as cleared_pl:
|
||||
cleared_pl.write("")
|
||||
|
||||
return_data = jsonify(isError=False, message="Success", statusCode=200, data=[])
|
||||
return return_data, 200
|
||||
@@ -355,21 +453,20 @@ def add_request():
|
||||
app.logger.info(record)
|
||||
app.logger.info(record["lista_slow"])
|
||||
app.logger.info(record["UUID"])
|
||||
return_data = wyszukaj(
|
||||
record["lista_slow"], 0, app.logger, False
|
||||
)
|
||||
return_data = wyszukaj(record["lista_slow"], 0, app.logger, False)
|
||||
|
||||
with open(
|
||||
"/home/pi/Conjurer/request.playlist", "a", encoding="utf-8"
|
||||
) as s_file:
|
||||
with open("/home/pi/Conjurer/request.playlist", "a", encoding="utf-8") as s_file:
|
||||
for item in return_data:
|
||||
s_file.write(item[1] + "\n")
|
||||
return_data = (
|
||||
jsonify(isError=False, message="Success", statusCode=200, data={"status": "OK"}),
|
||||
jsonify(
|
||||
isError=False, message="Success", statusCode=200, data={"status": "OK"}
|
||||
),
|
||||
200,
|
||||
)
|
||||
return return_data
|
||||
|
||||
|
||||
@app.route("/create_priority_playlist", methods=["POST"])
|
||||
def create_priority_playlist():
|
||||
"""
|
||||
@@ -391,13 +488,14 @@ def create_priority_playlist():
|
||||
return_data = wyszukaj(
|
||||
record["lista_slow"], record["dlugosc_plejlisty"], app.logger, False
|
||||
)
|
||||
with open(
|
||||
"/home/pi/Conjurer/request.playlist", "a", encoding="utf-8"
|
||||
) as s_file:
|
||||
random.shuffle(return_data)
|
||||
with open("/home/pi/Conjurer/request.playlist", "a", encoding="utf-8") as s_file:
|
||||
for item in return_data:
|
||||
s_file.write(item[1] + "\n")
|
||||
return_data = (
|
||||
jsonify(isError=False, message="Success", statusCode=200, data={"status": "OK"}),
|
||||
jsonify(
|
||||
isError=False, message="Success", statusCode=200, data={"status": "OK"}
|
||||
),
|
||||
200,
|
||||
)
|
||||
return return_data
|
||||
@@ -430,7 +528,9 @@ def add_to_priority():
|
||||
for item in return_data:
|
||||
s_file.write(item[1] + "\n")
|
||||
return_data = (
|
||||
jsonify(isError=False, message="Success", statusCode=200, data={"status": "OK"}),
|
||||
jsonify(
|
||||
isError=False, message="Success", statusCode=200, data={"status": "OK"}
|
||||
),
|
||||
200,
|
||||
)
|
||||
return return_data
|
||||
@@ -489,5 +589,9 @@ if __name__ == "__main__":
|
||||
for worker in threads:
|
||||
worker.start()
|
||||
|
||||
time.sleep(60)
|
||||
threads.append(threading.Thread(target=scan_tracks))
|
||||
threads[2].start()
|
||||
|
||||
for worker in threads:
|
||||
worker.join()
|
||||
|
||||
@@ -2,9 +2,47 @@
|
||||
"""This module contains utility scripts used by musi radiostation Conjurer"""
|
||||
import time
|
||||
import re
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from mutagen.easyid3 import EasyID3
|
||||
from mutagen.mp3 import MP3
|
||||
|
||||
|
||||
def update_metadata(folder_path):
|
||||
for root, _, files in os.walk(folder_path):
|
||||
for file in files:
|
||||
if file.endswith(".mp3"):
|
||||
file_path = os.path.join(root, file)
|
||||
|
||||
# Sample logic for guessing metadata from filename
|
||||
# Assuming the filename format is "Artist - Title.mp3"
|
||||
try:
|
||||
artist, title = file.rsplit(" - ", 1)
|
||||
title = title.replace(".mp3", "")
|
||||
except ValueError:
|
||||
# If file name doesn't fit the expected pattern, skip
|
||||
print(f"Skipping file due to unexpected format: {file}")
|
||||
continue
|
||||
|
||||
try:
|
||||
# Load the mp3 file
|
||||
audio = MP3(file_path, ID3=EasyID3)
|
||||
|
||||
# Update metadata
|
||||
audio["artist"] = artist.strip()
|
||||
audio["title"] = title.strip()
|
||||
|
||||
# Save changes
|
||||
audio.save()
|
||||
print(f"Updated metadata for: {file}")
|
||||
except Exception as e:
|
||||
print(f"Failed to update metadata for {file}: {e}")
|
||||
|
||||
|
||||
NAME = "/home/pi/Conjurer/persistence.log"
|
||||
|
||||
|
||||
def print_top():
|
||||
"""
|
||||
Prints the top 65 lines from a file specified by the NAME variable.
|
||||
@@ -13,7 +51,7 @@ def print_top():
|
||||
line = ""
|
||||
buffer = ""
|
||||
with open(NAME, "r", encoding="utf-8") as f:
|
||||
for _ in range (45):
|
||||
for _ in range(45):
|
||||
line = f.readline()
|
||||
if re.match(".*mp3", line):
|
||||
buffer += line
|
||||
@@ -22,5 +60,39 @@ def print_top():
|
||||
print("=====================================")
|
||||
time.sleep(180)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Perform operations on a directory of .mp3 files."
|
||||
)
|
||||
|
||||
# Positional argument for choosing the function to execute
|
||||
parser.add_argument(
|
||||
"operation",
|
||||
type=str,
|
||||
choices=["update_metadata", "print_top"],
|
||||
help="Operation to perform: update_metadata or print_top.",
|
||||
default="print_top",
|
||||
)
|
||||
|
||||
# Positional argument for folder path
|
||||
parser.add_argument("folder", type=str, help="Path to the folder to operate on.")
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.operation == "update_metadata":
|
||||
if args.folder:
|
||||
folder_to_scan = args.folder
|
||||
else:
|
||||
print("Please provide a folder path to scan.")
|
||||
raise ValueError("No folder path provided.")
|
||||
|
||||
if args.operation == "update_metadata" and os.path.isdir(folder_to_scan):
|
||||
update_metadata(folder_to_scan)
|
||||
elif args.operation == "print_top":
|
||||
print_top()
|
||||
else:
|
||||
print(f"The specified path is not a directory: {folder_to_scan}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print_top()
|
||||
main()
|
||||
|
||||
@@ -56,7 +56,6 @@ s = crossfade(fade_out=2., fade_in=2., duration=4., fallback(id="switcher", trac
|
||||
|
||||
# Set up an interactive harbor for controlling the stream
|
||||
interactive.harbor(port = 9999)
|
||||
|
||||
# Set up interactive controls for bass boost
|
||||
f = interactive.float("f", description="Frequency", min=0., max=1000., unit="Hz", 200.)
|
||||
g = interactive.float("g", description="Gain", min=0., max=20., unit="dB", 8.)
|
||||
@@ -64,25 +63,34 @@ b = bass_boost(frequency=f, gain=g, s)
|
||||
s = add([s, b])
|
||||
|
||||
# Set up interactive control for main volume
|
||||
a = interactive.float("main_volume", min=0., max=20., 1.)
|
||||
a = interactive.float("main_volume", min=0., max=20., 1.1)
|
||||
s = compress.multiband.interactive(bands=7, s)
|
||||
|
||||
mic_gain = interactive.float("mic_volume", min=0., max=120., 0.5)
|
||||
|
||||
# Apply audio processing effects
|
||||
s = nrj(normalize(s))
|
||||
tmic = buffer(input.pulseaudio()) # Microphone
|
||||
mic = amplify(mic_gain, tmic)
|
||||
mic = gate(threshold=-80., range=-120., mic)
|
||||
mic = compress(threshold=0., ratio=2.,mic)
|
||||
mic = nrj(normalize(mic))
|
||||
mic = blank.strip(max_blank=15., min_noise=.1, threshold=-30., mic)
|
||||
mic = fallback(id="switcher2", track_sensitive=false, [mic, blank()])
|
||||
|
||||
# Apply audio processing effects
|
||||
s = nrj(s)
|
||||
s = amplify(a, s)
|
||||
|
||||
mic = buffer(input.pulseaudio()) # Microphone
|
||||
mic = gate(threshold=-30., range=-80., mic)
|
||||
mic = blank.strip(max_blank=10., min_noise=.1, threshold=-20., mic)
|
||||
|
||||
s = add([s, mic])
|
||||
#w = interactive.float("wetness", min=0., max=1., 1.)
|
||||
#s = dry_wet(w,s,s2)
|
||||
|
||||
|
||||
# Skip blank sections in the stream
|
||||
s = blank.skip(max_blank=10., s)
|
||||
|
||||
#Manual audition override
|
||||
live_enabled = interactive.bool("Going Live!", true)
|
||||
|
||||
s = add([mic,s])
|
||||
s=switch(track_sensitive=false,
|
||||
[(live_enabled, mic),
|
||||
({true}, s)])
|
||||
|
||||
# Configure logging settings
|
||||
log_to_stdout = true
|
||||
log_to_file = true
|
||||
@@ -98,9 +106,9 @@ set("log.file.path", logpath)
|
||||
# Set up emergency fallback track
|
||||
emergency = single("/home/pi/RetroPie/mp3/Youtube/Dr. Peacock - Trip to Ireland [GvrvQTUbUcA].mp3")
|
||||
radio = fallback(id="switcher2", track_sensitive=false, [s, emergency])
|
||||
|
||||
# Set up an interactive control for skipping tracks
|
||||
p = interactive.bool("Skip track", false)
|
||||
|
||||
def http_skip(~protocol, ~data, ~headers, uri)=
|
||||
radio.skip()
|
||||
http.response(code=200,data="Skipped")
|
||||
@@ -130,6 +138,7 @@ interactive.persistent("script.params")
|
||||
|
||||
# Configure output formats and destinations
|
||||
|
||||
|
||||
output.icecast(%mp3, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="mp3-stream", radio)
|
||||
output.pulseaudio(radio)
|
||||
#output.file.hls("/tmp/hls", [("mp3-low", %mp3(bitrate=96)), ("mp3-hi", %mp3(bitrate=160))], radio)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
tmic = buffer(input.pulseaudio()) # Microphone
|
||||
|
||||
if tmic.is_active() then
|
||||
log.info("Buffer active")
|
||||
end
|
||||
|
||||
if tmic.is_ready() then
|
||||
log.info("Buffer ready")
|
||||
end
|
||||
if tmic.is_up() then
|
||||
log.info("Buffer up")
|
||||
end
|
||||
|
||||
interactive.harbor(port = 9999)
|
||||
|
||||
mic_gain = interactive.float("mic_volume", min=0., max=20., 6.)
|
||||
|
||||
mic = amplify(mic_gain, tmic)
|
||||
#mic = gate(threshold=-80., range=-120., mic)
|
||||
#mic = compress(threshold=0., ratio=2.,mic)
|
||||
#mic = blank.strip(max_blank=10., min_noise=.1, threshold=-20., mic)
|
||||
|
||||
output.pulseaudio(mic)
|
||||
Reference in New Issue
Block a user