mirror of
https://github.com/migatu/conjurer.git
synced 2026-07-14 21:38:38 +00:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d8f5bd1805 | |||
| 3f68c6aaed | |||
| aee53de258 | |||
| 20caa5600a | |||
| 4a4f8df06e | |||
| 6c9f01971a | |||
| 211c45891e | |||
| de3d6a8f42 | |||
| 9c027fd636 | |||
| 9af6b8e187 | |||
| d00ede6c62 | |||
| 5b7d7b31b2 | |||
| 00172920a9 | |||
| 5e3ffdacb5 | |||
| 471d4e923b | |||
| d11f5d8d24 | |||
| cfb26d95a4 | |||
| 5e14299fef | |||
| 126de9a4a4 | |||
| 0d132983fc | |||
| 67cae0e68e | |||
| eabd0e8e1e | |||
| f7c91e3874 | |||
| c224b2ccc8 | |||
| 3ca9f2c6f3 | |||
| c52d55e0a2 | |||
| e1fa15abb3 | |||
| 74c76e639d | |||
| 35a65e48e9 | |||
| 5d5c136b41 | |||
| b9fbc0f910 | |||
| fd742c8f1c |
@@ -6,4 +6,8 @@
|
||||
plugins
|
||||
user_trunk.yaml
|
||||
user.yaml
|
||||
<<<<<<< HEAD
|
||||
tmp
|
||||
=======
|
||||
tools
|
||||
>>>>>>> c7dc465 (Parametryzacja "muzyki mojego ludu")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
|
||||
version: 0.1
|
||||
cli:
|
||||
<<<<<<< HEAD
|
||||
version: 1.20.1
|
||||
# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins)
|
||||
plugins:
|
||||
@@ -10,10 +11,44 @@ plugins:
|
||||
ref: v1.4.5
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
|
||||
=======
|
||||
version: 1.12.1
|
||||
plugins:
|
||||
sources:
|
||||
- id: trunk
|
||||
ref: v0.0.22
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
lint:
|
||||
enabled:
|
||||
- actionlint@1.6.25
|
||||
- markdownlint@0.35.0
|
||||
- trivy@0.43.1
|
||||
- trufflehog@3.44.0
|
||||
- pylint
|
||||
- codespell
|
||||
- cspell
|
||||
- git-diff-check
|
||||
- eslint
|
||||
- prettier
|
||||
- semgrep
|
||||
- autopep8
|
||||
- bandit
|
||||
- black
|
||||
- flake8
|
||||
- isort
|
||||
- mypy
|
||||
- pylint
|
||||
- ruff
|
||||
- semgrep
|
||||
- yapf
|
||||
- gitleaks
|
||||
|
||||
>>>>>>> c7dc465 (Parametryzacja "muzyki mojego ludu")
|
||||
runtimes:
|
||||
enabled:
|
||||
- node@18.12.1
|
||||
- python@3.10.8
|
||||
<<<<<<< HEAD
|
||||
# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
|
||||
lint:
|
||||
enabled:
|
||||
@@ -31,6 +66,8 @@ lint:
|
||||
- trivy@0.50.1
|
||||
- trufflehog@3.71.0
|
||||
- yamllint@1.35.1
|
||||
=======
|
||||
>>>>>>> c7dc465 (Parametryzacja "muzyki mojego ludu")
|
||||
actions:
|
||||
disabled:
|
||||
- trunk-announce
|
||||
|
||||
@@ -38,10 +38,10 @@ import spotipy
|
||||
from discord.ext import commands
|
||||
from spotipy.oauth2 import SpotifyClientCredentials
|
||||
|
||||
import yt_dlp
|
||||
from spotify_dl import spotify
|
||||
from spotify_dl import youtube as youtube_download
|
||||
|
||||
from spotify_dl import spotify
|
||||
|
||||
Music_Config = TypedDict(
|
||||
"Music_Config",
|
||||
{
|
||||
@@ -68,6 +68,11 @@ MEMORY_FIVE_MUZYKA = ""
|
||||
SETTINGS_FILE = ""
|
||||
ENCODING = ""
|
||||
GRAPHICS_PATH = ""
|
||||
MUZYKA_MOJEGO_LUDU_HISTORIA = 1500
|
||||
MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE = 30
|
||||
MUZYKA_MOJEGO_LUDU_PLAJLISTA = 30
|
||||
|
||||
|
||||
# *=========================================== Platform Specific Predefines
|
||||
|
||||
if platform in ("linux", "linux2"):
|
||||
@@ -187,7 +192,6 @@ async def on_ready():
|
||||
logger.debug("%s has connected to Discord!", client.user)
|
||||
await client.change_presence(activity=discord.Game(name="Axe Throwing Darts"))
|
||||
await client.tree.sync()
|
||||
# await tree.sync(guild=discord.Object(id=Your guild id))
|
||||
await check()
|
||||
|
||||
|
||||
@@ -270,22 +274,25 @@ async def on_message(message):
|
||||
if "conjurer:" in message.content:
|
||||
async with channel.typing():
|
||||
logger.debug("Procedura chatu")
|
||||
|
||||
message.content = message.content.replace("conjurer: ", "")
|
||||
|
||||
prompt = message.content
|
||||
|
||||
if message.author.nick:
|
||||
username = message.author.nick
|
||||
else:
|
||||
username = message.author.name
|
||||
vykidailo = False
|
||||
bartender = False
|
||||
if kondziu_mentioned:
|
||||
prompt = message.clean_content
|
||||
else:
|
||||
prompt = message.content
|
||||
for role in message.author.roles:
|
||||
if role.name == "Vykidailo":
|
||||
vykidailo = True
|
||||
if role.name == "Bartender":
|
||||
bartender = True
|
||||
global MESSAGE_TABLE # pylint: disable=global-statement
|
||||
|
||||
result, MESSAGE_TABLE = await handle_response(
|
||||
prompt, vykidailo, bartender, MESSAGE_TABLE, username, False
|
||||
)
|
||||
@@ -446,6 +453,20 @@ async def play(ctx, zamawial=None, arg=None):
|
||||
await ctx.send(result)
|
||||
|
||||
|
||||
async def archive_channel(channel_no):
|
||||
channel = client.get_channel(channel_no)
|
||||
messages = [message async for message in channel.history(limit=None)]
|
||||
path_newfile = (
|
||||
f"{LOGSTORE}channeldump_{channel_no}_{datetime.now()}.json"
|
||||
)
|
||||
new_data = []
|
||||
for message in messages:
|
||||
pass
|
||||
with open(path_newfile, "x", encoding=ENCODING) as new_file:
|
||||
new_file.seek(0)
|
||||
json.dump(new_data, new_file, indent=4)
|
||||
|
||||
|
||||
async def check():
|
||||
"""Funkcja sprawdzająca czy grać następny kawałek."""
|
||||
while True:
|
||||
@@ -564,14 +585,14 @@ async def handle_response(prompt, vykidailo, bartender, history, username, music
|
||||
# * extend bo 20 ostatnich
|
||||
if music:
|
||||
history.append(message_table_muzyka[0])
|
||||
history.extend(message_table_muzyka[-20:])
|
||||
history.extend(message_table_muzyka[-15:])
|
||||
else:
|
||||
history.append(MESSAGE_TABLE[0])
|
||||
history.extend(MESSAGE_TABLE[-20:])
|
||||
history.extend(MESSAGE_TABLE[-15:])
|
||||
logger.info("Historia wysłana:")
|
||||
logger.debug(history)
|
||||
response = await openai.ChatCompletion.acreate(
|
||||
model="gpt-3.5-turbo", messages=history
|
||||
model="gpt-4", messages=history
|
||||
)
|
||||
await asyncio.sleep(10)
|
||||
result = ""
|
||||
@@ -685,6 +706,8 @@ async def get_file(ctx, source, link):
|
||||
"force_keyframes": True,
|
||||
},
|
||||
]
|
||||
#TODO: Make sponsorblock work
|
||||
sponsorblock_postprocessor = []
|
||||
if platform == "win32":
|
||||
dir_path = "G:\\Muzyka\\Youtube"
|
||||
else:
|
||||
@@ -693,7 +716,6 @@ async def get_file(ctx, source, link):
|
||||
"proxy": "",
|
||||
"default_search": "ytsearch",
|
||||
"format": "bestaudio/best",
|
||||
"postprocessors": sponsorblock_postprocessor,
|
||||
"noplaylist": True,
|
||||
"no_color": False,
|
||||
"paths": {"home": dir_path},
|
||||
@@ -803,7 +825,7 @@ async def wyszukaj(ctx, how_many=0, slowa_kluczowe=None):
|
||||
It is an optional parameter with a default value of 0, which means that if no value is provided for
|
||||
how_many, the function will return all search results, defaults to 0 (optional)
|
||||
"""
|
||||
# TODO: Potem dorobić wyszukiwania po kawałkach słów
|
||||
#TODO: Przerobić na webservice
|
||||
# i sieć neuronową z możliwością wyrażenia opinii o dopasowaniu.
|
||||
if slowa_kluczowe:
|
||||
word_list = slowa_kluczowe
|
||||
@@ -819,11 +841,11 @@ async def wyszukaj(ctx, how_many=0, slowa_kluczowe=None):
|
||||
skip_start = 2
|
||||
else:
|
||||
skip_start = 1
|
||||
for word in word_list[skip_start:]:
|
||||
async for word in async_iterator_generator(word_list[skip_start:]):
|
||||
token_weight = len(word)
|
||||
logger.info("Słowo kluczowe: %s", word)
|
||||
itr = 0
|
||||
for file in music_file_list:
|
||||
async for file in async_iterator_generator(music_file_list):
|
||||
file = file.split(SEPARATOR_FILE_PATH)
|
||||
|
||||
char_remove = [
|
||||
@@ -849,8 +871,8 @@ async def wyszukaj(ctx, how_many=0, slowa_kluczowe=None):
|
||||
"mp3",
|
||||
]
|
||||
all_words = []
|
||||
for f_iter in file:
|
||||
for char in char_remove:
|
||||
async for f_iter in async_iterator_generator(file):
|
||||
async for char in async_iterator_generator(char_remove):
|
||||
f_iter = f_iter.replace(char, "")
|
||||
tmp = f_iter.split()
|
||||
all_words.extend(tmp)
|
||||
@@ -861,7 +883,7 @@ async def wyszukaj(ctx, how_many=0, slowa_kluczowe=None):
|
||||
else:
|
||||
skip = 4
|
||||
matched_times = 1
|
||||
for itm in all_words[skip:]:
|
||||
async for itm in async_iterator_generator(all_words[skip:]):
|
||||
pingu += 1
|
||||
pattern = ".*" + word + ".*"
|
||||
if re.match(pattern, itm, re.IGNORECASE):
|
||||
@@ -1278,7 +1300,8 @@ async def zagraj_mi_kawalek(ctx):
|
||||
async with ctx.typing():
|
||||
search_time_glob = datetime.now()
|
||||
logger.info("Zaczynam szukać timestamp %s", datetime.now())
|
||||
file = await wyszukaj(ctx=ctx)
|
||||
coro = asyncio.to_thread(wyszukaj,ctx=ctx)
|
||||
file = await coro
|
||||
logger.info(
|
||||
"Koniec szukania(timestamp %s zajęło %s",
|
||||
datetime.now(),
|
||||
@@ -1530,6 +1553,7 @@ async def get_image_stable_diffusion(ctx):
|
||||
description="Gra muzyke wyszukana na bazie tematow konwersacji na kanale NZ",
|
||||
guild=discord.Object(id=664789470779932693),
|
||||
)
|
||||
# trunk-ignore(pylint/R0912)
|
||||
async def zagraj_muzyke_mego_ludu(ctx):
|
||||
"""
|
||||
Play completeley random playlist based on messaging history.
|
||||
@@ -1541,7 +1565,7 @@ async def zagraj_muzyke_mego_ludu(ctx):
|
||||
"""
|
||||
stats = {}
|
||||
if ctx:
|
||||
stat_iter = get_stats(ctx, 1500)
|
||||
stat_iter = get_stats(ctx, MUZYKA_MOJEGO_LUDU_HISTORIA)
|
||||
async for name, how_many in stat_iter:
|
||||
if len(name) > 3:
|
||||
stats[name] = how_many
|
||||
@@ -1556,7 +1580,7 @@ async def zagraj_muzyke_mego_ludu(ctx):
|
||||
async with ctx.typing():
|
||||
logger.info("Zaczynam szukać timestamp %s", datetime.now())
|
||||
search_time_glob = datetime.now()
|
||||
file = await wyszukaj(ctx=ctx, how_many=100, slowa_kluczowe=key_words[:30])
|
||||
file = await wyszukaj(ctx=ctx, how_many=MUZYKA_MOJEGO_LUDU_PLAJLISTA, slowa_kluczowe=key_words[:MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE])
|
||||
logger.info(
|
||||
"Koniec szukania(timestamp %s zajęło %s",
|
||||
datetime.now(),
|
||||
@@ -1596,6 +1620,38 @@ async def zagraj_muzyke_mego_ludu(ctx):
|
||||
logger.info("Plejlista zrobiona")
|
||||
|
||||
|
||||
# trunk-ignore(mypy/arg-type)
|
||||
@client.hybrid_command(
|
||||
name="parametry_muzyki_mego_ludu",
|
||||
description="Konfiguruje komende zagraj muzyke mojego ludu",
|
||||
guild=discord.Object(id=664789470779932693),
|
||||
)
|
||||
async def parametry_muzyki_mego_ludu(ctx, ile_historii=1500, ile_slow_kluczowych=30, jak_dluga_plejlista=30):
|
||||
"""
|
||||
The function `parametry_muzyki_mego_ludu` sets global variables for the number of history entries,
|
||||
number of keywords, and length of playlist for a music application.
|
||||
|
||||
:param ctx: The `ctx` parameter is typically used in Discord.py, a Python library for creating
|
||||
Discord bots. It represents the context of the command being executed, including information about
|
||||
the message, the server, and the user who invoked the command
|
||||
:param ile_historii: The parameter "ile_historii" represents the number of history items for the
|
||||
music playlist, defaults to 1500 (optional)
|
||||
:param ile_slow_kluczowych: The parameter "ile_slow_kluczowych" represents the number of keywords or
|
||||
key phrases related to music that you want to include in your analysis or search, defaults to 30
|
||||
(optional)
|
||||
:param jak_dluga_plejlista: The parameter "jak_dluga_plejlista" determines the length of the
|
||||
playlist. It specifies how many songs should be included in the playlist, defaults to 30 (optional)
|
||||
"""
|
||||
|
||||
if ctx:
|
||||
global MUZYKA_MOJEGO_LUDU_HISTORIA # pylint: disable=global-statement
|
||||
MUZYKA_MOJEGO_LUDU_HISTORIA = ile_historii
|
||||
global MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE # pylint: disable=global-statement
|
||||
MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE = ile_slow_kluczowych
|
||||
global MUZYKA_MOJEGO_LUDU_PLAJLISTA # pylint: disable=global-statement
|
||||
MUZYKA_MOJEGO_LUDU_PLAJLISTA = jak_dluga_plejlista
|
||||
|
||||
|
||||
# *================================== Run
|
||||
# trunk-ignore(mypy/arg-type)
|
||||
client.run(TOKEN)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Conjurer
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/home/pi/Conjurer/env/bin/python3 /home/pi/Conjurer/bot.py
|
||||
Restart=on-abort
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,190 @@
|
||||
import re
|
||||
import logging
|
||||
import threading
|
||||
import time
|
||||
from flask import Flask, jsonify, request
|
||||
import netrc
|
||||
import json
|
||||
from json.decoder import JSONDecodeError
|
||||
from platform import uname
|
||||
from sys import platform
|
||||
from urllib.request import urlopen
|
||||
from habanero import Crossref
|
||||
from waitress import serve
|
||||
|
||||
if platform in ("linux", "linux2"):
|
||||
SEPARATOR_FILE_PATH = "/"
|
||||
if "microsoft-standard" in uname().release:
|
||||
NETRC_FILE = "/home/mtuszowski/.netrc"
|
||||
else:
|
||||
NETRC_FILE = "/home/pi/.netrc"
|
||||
elif platform == "win32":
|
||||
NETRC_FILE = "C:\\Users\\mtusz\\.netrc"
|
||||
|
||||
#HOST_ADDRESS = "192.168.1.191"
|
||||
HOST_ADDRESS = "0.0.0.0"
|
||||
PORT_ADDRESS = 5001
|
||||
|
||||
class Librarian(object):
|
||||
|
||||
def __init__(self) -> None:
|
||||
netrc_mod = netrc.netrc(NETRC_FILE)
|
||||
authTokens = netrc_mod.authenticators("crossref")
|
||||
self.cr = Crossref(mailto=authTokens[0])
|
||||
self.limit = 1000
|
||||
self.fetched = 0
|
||||
self.hit = 0
|
||||
self.total = 0
|
||||
|
||||
def search_crossref(self, query, uuid):
|
||||
search_result_from_cr = self.cr.works(query = query, limit = self.limit)
|
||||
self.total = search_result_from_cr['message']['total-results']
|
||||
self.fetched = len(search_result_from_cr['message']['items'])
|
||||
#add to sql with UUID
|
||||
#sql row - title, doi, author, uuid, last retrieved, is_available
|
||||
with open("results.json", "r+", encoding="UTF-8") as data_file:
|
||||
# First we load existing data into a dict.
|
||||
try:
|
||||
file_data = json.load(data_file)
|
||||
except JSONDecodeError:
|
||||
file_data = []
|
||||
# Join new_data with file_data inside emp_details
|
||||
summarized_results = []
|
||||
for item in search_result_from_cr['message']['items']:
|
||||
container = "NO"
|
||||
if "container-title" in item:
|
||||
container = "YES"
|
||||
summarized_results.append({"DOI" : item['DOI'], "title": item['title'] if 'title' in item else None,"type": item['type'] if 'type' in item else None, "container": container})
|
||||
result = {"UUID": uuid, "total_results": search_result_from_cr['message']['total-results'], "on_page" : 1, "summary":summarized_results, "results":search_result_from_cr['message']['items'], }
|
||||
file_data.append(result)
|
||||
print("Saving")
|
||||
data_file.seek(0)
|
||||
# convert back to json.
|
||||
json.dump(file_data, data_file, indent=4)
|
||||
return result
|
||||
|
||||
|
||||
def check_if_exists(self,page_url):
|
||||
#TODO: Spowolnic
|
||||
#TODO: Sprawdzac po mirrorach
|
||||
#TODO: sprawdzac w tym jebanym pliku
|
||||
in_scihub_db = True
|
||||
if not page_url.startswith(("http:", "https:")):
|
||||
raise ValueError("URL must start with 'http:' or 'https:'")
|
||||
# trunk-ignore(bandit/B310)
|
||||
with urlopen(page_url) as response:
|
||||
data = response.read()
|
||||
text = data.decode("utf-8")
|
||||
for line in text.splitlines():
|
||||
if re.match(r".*Unfortunately, Sci-Hub doesn't have the requested document.*", line):
|
||||
return None
|
||||
if in_scihub_db:
|
||||
return text
|
||||
return None
|
||||
|
||||
def download(self, page_url):
|
||||
if response := self.check_if_exists(page_url):
|
||||
for line in response.splitlines():
|
||||
if m := re.match(r".*<embed type=\"application.pdf\"\s*src=\"(.*\.pdf)",line):
|
||||
return "https:" + str(m.group(1))
|
||||
return None
|
||||
|
||||
def provide_sci_hub_link(self, page_url):
|
||||
if self.check_if_exists(page_url):
|
||||
return page_url
|
||||
return None
|
||||
|
||||
def refine_query(self, unrefined_reqult):
|
||||
print("Refine result")
|
||||
refined_result = []
|
||||
for item in unrefined_reqult["summary"]:
|
||||
if item["container"] == "NO" and item["title"]:
|
||||
item_link = "https://sci-hub.se/" + str(item['DOI'])
|
||||
if self.check_if_exists(item_link):
|
||||
refined_result.append(item)
|
||||
print ("HIT")
|
||||
print(item["title"])
|
||||
time.sleep(0.01)
|
||||
print("Existing hits")
|
||||
self.hit = len(refined_result)
|
||||
return refined_result
|
||||
|
||||
def answer_query(self, query, uuid):
|
||||
#Search sql for UUID
|
||||
#SQL SELECT * FROM RESULTS WHERE UUID = uuid
|
||||
print("Answer result")
|
||||
uuid_found = False
|
||||
database = None
|
||||
with open("results.json", "r", encoding="UTF-8") as new_file:
|
||||
#tu logika komunikacji z SQL i cała logika związana z wyszukaniem
|
||||
#ale tymczasowo plik
|
||||
try:
|
||||
database = json.load(new_file)
|
||||
except JSONDecodeError:
|
||||
pass
|
||||
if database:
|
||||
for item in database:
|
||||
if item["UUID"] == uuid:
|
||||
print (item["UUID"])
|
||||
uuid_found = True
|
||||
return self.refine_query(item)
|
||||
|
||||
if not uuid_found:
|
||||
answer = self.search_crossref(query=query, uuid=uuid)
|
||||
return self.refine_query(answer)
|
||||
|
||||
#example not exists
|
||||
#sample_non_existing_page_url = "https://sci-hub.se/10.4324/9781003006237"
|
||||
#sample usage to download
|
||||
#sample_existing_page_url = "https://sci-hub.se/10.1057/9781137435026"
|
||||
#print(cl.download(sample_existing_page_url))
|
||||
#cl.search_crossref("BDSM")
|
||||
|
||||
app = Flask(__name__)
|
||||
def flask_debug():
|
||||
"""
|
||||
The `flask_debug` function starts a Flask application in debug mode without using the reloader.
|
||||
Do not use for production for fucks sake.
|
||||
"""
|
||||
# trunk-ignore(bandit/B201)
|
||||
app.run(debug=True, use_reloader=False, host=HOST_ADDRESS, port=PORT_ADDRESS)
|
||||
|
||||
def waitress_run():
|
||||
"""
|
||||
The `waitress_run` function serves the `app` on host "0.0.0.0"
|
||||
and port 5000 using the Waitress WSGI server.
|
||||
"""
|
||||
serve(app, host=HOST_ADDRESS, port=PORT_ADDRESS)
|
||||
|
||||
@app.route("/query", methods=["POST"])
|
||||
def query_database():
|
||||
record = json.loads(request.data)
|
||||
app.logger.info(record)
|
||||
app.logger.info(record["query"])
|
||||
app.logger.info(record["UUID"])
|
||||
cl = Librarian()
|
||||
answer_data = cl.answer_query(record["query"], record["UUID"])
|
||||
app.logger.info(answer_data)
|
||||
summary = (cl.hit,cl.fetched, cl.total, record["UUID"])
|
||||
answer_data = (summary,answer_data)
|
||||
return_data = (
|
||||
jsonify(isError=False, message="Success", statusCode=200, data=answer_data),
|
||||
200,
|
||||
)
|
||||
return return_data
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger = logging.getLogger('conjurer_musician')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
threads = []
|
||||
#threads.append(threading.Thread(target=waitress_run))
|
||||
threads.append(threading.Thread(target=flask_debug))
|
||||
|
||||
for worker in threads:
|
||||
worker.start()
|
||||
for worker in threads:
|
||||
worker.join()
|
||||
|
||||
#1. robi liste wyników i ją wyświetla - ale tylko tytuły niezależnych dzieł - jeśli jest coś w containerze to trza pogrupować
|
||||
#2. Tworzy przyciski pozwalające sprawdzić czy jest dostępne - i jeśli jest zwraca link
|
||||
#3. Jest też przycisk "more" - wyszukujemy po 100, wyświetlamy po 20. Po 100 jak jeszcze to dopiero odpytujemy crossref przyciski strzałek przesuwają po obecnej porcji danych
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
python3 -m venv /home/pi/Conjurer_librarian/env
|
||||
cp /home/pi/conjurer/conjurer_librarian/conjurer_librarian.py ./Conjurer_librarian/
|
||||
cp /home/pi/conjurer/conjurer_librarian/requirements_librarian.txt ./Conjurer_librarian/
|
||||
cd /home/pi/Conjurer_librarian
|
||||
source /home/pi/Conjurer_librarian/env/bin/activate
|
||||
./env/bin/python3 -m pip install --upgrade pip
|
||||
./env/bin/python3 -m pip install -r requirements_librarian.txt
|
||||
deactivate
|
||||
|
||||
cp /home/pi/conjurer/conjurer_librarian/conjurer_librarian.py ./Conjurer_librarian/
|
||||
@@ -0,0 +1,3 @@
|
||||
habanero
|
||||
waitress
|
||||
flask
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
git pull
|
||||
cd ..
|
||||
cp ./conjurer/bot.py ./Conjurer/
|
||||
cp ./conjurer/settings.json ./Conjurer/
|
||||
cp ./conjurer/system_gpt_settings.json ./Conjurer/
|
||||
cp ./conjurer/install.sh ./Conjurer/
|
||||
cp ./conjurer/requirements.txt ./Conjurer/requirements.txt
|
||||
sudo systemctl restart conjurer.service
|
||||
@@ -0,0 +1,134 @@
|
||||
"""
|
||||
The provided Python script sets up a Flask web server to manage a list of music files, with
|
||||
functions for rescanning the music folder, updating the music list, and serving the music list via
|
||||
API endpoints.
|
||||
"""
|
||||
import json
|
||||
from pathlib import Path
|
||||
from platform import uname
|
||||
import threading
|
||||
import time
|
||||
from sys import platform
|
||||
import logging
|
||||
from flask import Flask, jsonify, request
|
||||
from waitress import serve
|
||||
|
||||
|
||||
HOST_ADDRESS = "192.168.1.15"
|
||||
PORT_ADDRESS = 5000
|
||||
if platform in ("linux", "linux2"):
|
||||
SEPARATOR_FILE_PATH = "/"
|
||||
if "microsoft-standard" in uname().release:
|
||||
LOGFILE = "/home/mtuszowski/conjurer/discord_mus_service.log"
|
||||
MUSIC_FOLDER = "/mnt/g/Muzyka/"
|
||||
NETRC_FILE = "/home/mtuszowski/.netrc"
|
||||
LOGSTORE = "/home/mtuszowski/conjurer/logs/"
|
||||
ENCODING = "utf-8"
|
||||
GRAPHICS_PATH = "/home/mtuszowski/conjurer/Conjurer_graphics/"
|
||||
|
||||
else:
|
||||
LOGFILE = "/home/pi/Conjurer/discord_mus_service.log"
|
||||
MEMORY_FIVE_SIARA = "/home/pi/Conjurer/pamiec.json"
|
||||
SYSTEM_GPT_SETTINGS = "/home/pi/Conjurer/system_gpt_settings.json"
|
||||
MEMORY_FIVE_MUZYKA = "/home/pi/Conjurer/pamiec_muzyki.json"
|
||||
MUSIC_FOLDER = "/home/pi/RetroPie/mp3/"
|
||||
SETTINGS_FILE = "/home/pi/Conjurer/settings.json"
|
||||
NETRC_FILE = "/home/pi/.netrc"
|
||||
LOGSTORE = "/home/pi/RetroPie/logs/"
|
||||
ACCIDENT_LOG = "/home/pi/Conjurer/accident_log.json"
|
||||
ENCODING = "utf-8"
|
||||
GRAPHICS_PATH = "/home/pi/RetroPie/Conjurer_graphics/"
|
||||
DIR_PATH_SADOX = "/home/pi/RetroPie/Fansadox/"
|
||||
|
||||
|
||||
music_file_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")
|
||||
for mp3_item in Path.glob(Path(MUSIC_FOLDER), "**/*.mp3"):
|
||||
temp_music_file = mp3_item.as_posix()
|
||||
if platform == "win32":
|
||||
temp_music_file = temp_music_file.replace("/", "\\")
|
||||
music_file_list.append(temp_music_file)
|
||||
|
||||
def thread_rescan():
|
||||
"""
|
||||
The `thread_rescan` function periodically triggers a rescan operation after a specified time
|
||||
interval.
|
||||
"""
|
||||
logging.info("Starting filesystemupdater")
|
||||
while True:
|
||||
time.sleep(60*60*24)
|
||||
logging.info("Rescan triggered")
|
||||
rescan()
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/mp3", methods=["GET"])
|
||||
def get_music_list():
|
||||
"""
|
||||
The function `get_music_list` returns a JSON object containing a list of music files.
|
||||
:return: A JSON response containing a key "music_file_list" with the value of the variable
|
||||
`music_file_list`.
|
||||
"""
|
||||
return jsonify({"music_file_list": music_file_list})
|
||||
|
||||
|
||||
@app.route("/update_mp3", methods=["POST"])
|
||||
def update_music_list():
|
||||
"""
|
||||
The function `update_music_list` receives a POST request with a JSON payload, logs the received
|
||||
item, adds it to a music file list, and returns a success message along with the updated record.
|
||||
:return: The function `update_music_list` is returning a tuple containing a JSON response and a
|
||||
status code. The JSON response includes keys `isError`, `message`, `statusCode`, and `data`,
|
||||
with values indicating the success of the operation and the data that was
|
||||
received and added to the `music_file_list`.
|
||||
The status code returned is 200, indicating a successful response.
|
||||
"""
|
||||
record = json.loads(request.data)
|
||||
app.logger.info(record["item"])
|
||||
music_file_list.append(record["item"])
|
||||
return_data = (
|
||||
jsonify(isError=False, message="Success", statusCode=200, data=record),
|
||||
200,
|
||||
)
|
||||
return return_data
|
||||
|
||||
def flask_debug():
|
||||
"""
|
||||
The `flask_debug` function starts a Flask application in debug mode without using the reloader.
|
||||
Do not use for production for fucks sake.
|
||||
"""
|
||||
# trunk-ignore(bandit/B201)
|
||||
app.run(debug=True, use_reloader=False, host=HOST_ADDRESS, port=PORT_ADDRESS)
|
||||
|
||||
def waitress_run():
|
||||
"""
|
||||
The `waitress_run` function serves the `app` on host "0.0.0.0"
|
||||
and port 5000 using the Waitress WSGI server.
|
||||
"""
|
||||
serve(app, host=HOST_ADDRESS, port=PORT_ADDRESS)
|
||||
|
||||
def waitress_run():
|
||||
serve(app, host="0.0.0.0", port=5000)
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger = logging.getLogger('conjurer_musician')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
rescan()
|
||||
threads = []
|
||||
threads.append(threading.Thread(target=waitress_run))
|
||||
threads.append(threading.Thread(target=thread_rescan))
|
||||
#threads.append(threading.Thread(target=flask_debug))
|
||||
|
||||
for worker in threads:
|
||||
worker.start()
|
||||
|
||||
for worker in threads:
|
||||
worker.join()
|
||||
|
||||
#TODO: wrzucić wyszukanie i robienie playlist
|
||||
#TODO: Inne pliki - sadox, dokumenty naukowe itp.
|
||||
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Conjurer_musician
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/home/pi/Conjurer-service/conjurer/file_webservice/bin/python3 /home/pi/Conjurer-service/conjurer/file_webservice/conjurer_musician.py
|
||||
Restart=on-abort
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
python3 -m venv /home/pi/Conjurer-service/conjurer/file_webservice
|
||||
source ./bin/activate
|
||||
./bin/python3 -m pip install --upgrade pip
|
||||
./bin/python3 -m pip install -r requirements_musician.txt
|
||||
deactivate
|
||||
|
||||
sudo cp ./conjurer_musician.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl start conjurer_musician.service
|
||||
sudo systemctl enable conjurer_musician.service
|
||||
@@ -0,0 +1,2 @@
|
||||
flask
|
||||
waitress
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
python3 -m venv /home/pi/Conjurer/env
|
||||
source ./env/bin/activate
|
||||
./env/bin/python3 -m pip install --upgrade pip
|
||||
./env/bin/python3 -m pip install -r requirements_bot.txt
|
||||
sed -i -e 's/os.rename/shutil.copy/g' ./env/lib/python3.11/site-packages/spotify_dl/youtube.py
|
||||
sed -i '1i\import shutil' ./env/lib/python3.11/site-packages/spotify_dl/youtube.py
|
||||
deactivate
|
||||
sudo cp ./conjurer.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl start conjurer_musician.service
|
||||
sudo systemctl enable conjurer_musician.service
|
||||
@@ -1,35 +0,0 @@
|
||||
from pathlib import Path, PurePath
|
||||
from platform import uname
|
||||
from sys import platform
|
||||
MUSIC_FOLDER = ""
|
||||
if platform in ("linux", "linux2"):
|
||||
SEPARATOR_FILE_PATH = "/"
|
||||
if "microsoft-standard" in uname().release:
|
||||
LOGFILE = "/home/mtuszowski/conjurer/discord_mus_service.log"
|
||||
MUSIC_FOLDER = "/mnt/g/Muzyka/"
|
||||
NETRC_FILE = "/home/mtuszowski/.netrc"
|
||||
LOGSTORE = "/home/mtuszowski/conjurer/logs/"
|
||||
ENCODING = "utf-8"
|
||||
GRAPHICS_PATH = "/home/mtuszowski/conjurer/Conjurer_graphics/"
|
||||
|
||||
else:
|
||||
LOGFILE = "/home/pi/Conjurer/discord_mus_service.log"
|
||||
MEMORY_FIVE_SIARA = "/home/pi/Conjurer/pamiec.json"
|
||||
SYSTEM_GPT_SETTINGS = "/home/pi/Conjurer/system_gpt_settings.json"
|
||||
MEMORY_FIVE_MUZYKA = "/home/pi/Conjurer/pamiec_muzyki.json"
|
||||
MUSIC_FOLDER = "/home/pi/RetroPie/mp3/"
|
||||
SETTINGS_FILE = "/home/pi/Conjurer/settings.json"
|
||||
NETRC_FILE = "/home/pi/.netrc"
|
||||
LOGSTORE = "/home/pi/RetroPie/logs/"
|
||||
ACCIDENT_LOG = "/home/pi/Conjurer/accident_log.json"
|
||||
ENCODING = "utf-8"
|
||||
GRAPHICS_PATH = "/home/pi/RetroPie/Conjurer_graphics/"
|
||||
DIR_PATH_SADOX = "/home/pi/RetroPie/Fansadox/"
|
||||
|
||||
music_file_list = []
|
||||
for mp3_item in Path.glob(Path(MUSIC_FOLDER), "**/*.mp3"):
|
||||
temp_music_file = mp3_item.as_posix()
|
||||
if platform == "win32":
|
||||
temp_music_file = temp_music_file.replace("/", "\\")
|
||||
music_file_list.append(temp_music_file)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
discord
|
||||
yt_dlp
|
||||
spotify_dl
|
||||
spotipy
|
||||
openai
|
||||
eyed3
|
||||
numpy
|
||||
pdf2image
|
||||
PyPDF2
|
||||
requests
|
||||
spotipy
|
||||
tiktoken
|
||||
PyNaCl
|
||||
+2742
File diff suppressed because it is too large
Load Diff
@@ -97,8 +97,8 @@ def write_tracks(tracks_file, song_dict):
|
||||
def set_tags(temp, filename, kwargs):
|
||||
"""
|
||||
sets song tags after they are downloaded
|
||||
:param temp: contains index used to obtain more info about song being editted
|
||||
:param filename: location of song whose tags are to be editted
|
||||
:param temp: contains index used to obtain more info about song being edited
|
||||
:param filename: location of song whose tags are to be edited
|
||||
:param kwargs: a dictionary of extra arguments to be used in tag editing
|
||||
"""
|
||||
song = kwargs["track_db"][int(temp[-1])]
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
# trunk-ignore-all(pylint/C0301)
|
||||
"""
|
||||
The function `cut_my_life_into_pieces` reads a source file, splits its content based on a file size
|
||||
limit, and writes the parts to separate output files in a specified folder.
|
||||
|
||||
:param lines: The `lines` parameter in the `smart_write` function is a string that contains the text
|
||||
content that you want to write to a file. It represents the actual content that will be written to
|
||||
the file
|
||||
:param file: The code you provided defines two functions: `smart_write` and
|
||||
`cut_my_life_into_pieces`. The `smart_write` function encodes input lines to UTF-8, writes them to a
|
||||
file, and returns the size of the encoded bytes. The `cut_my_life_into_pieces` function reads
|
||||
:return: The functions provided in the code snippet do not explicitly return any values. However,
|
||||
the `smart_write` function returns the size of the encoded bytes of the input `lines` in bytes. The
|
||||
`cut_my_life_into_pieces` function does not have a return statement, so it does not explicitly
|
||||
return any value.
|
||||
"""
|
||||
|
||||
FILE_SIZE_LIMIT = 100000 * 1024
|
||||
SOURCE = "/mnt/n/scimag_2020-05-30.sql/scimag_2020-05-30.sql"
|
||||
Reference in New Issue
Block a user