mirror of
https://github.com/migatu/conjurer.git
synced 2026-07-17 07:12:09 +00:00
Tag: 0.4
Intermediate commits (oldest → newest): - Create python-app.yml - Create python-package.yml - Various fixes - Playlist based on chat history - Additional logging - Improvements - ASync search and moving to fully asynchronous work + responses to config command - Various fixes - Test chat gpt4
This commit is contained in:
@@ -24,7 +24,7 @@ from logging import handlers
|
||||
from pathlib import Path, PurePath
|
||||
from platform import uname
|
||||
from sys import platform
|
||||
from typing import List, TypedDict, Optional
|
||||
from typing import List, Optional, TypedDict
|
||||
|
||||
# *==============Imported libraries
|
||||
import discord
|
||||
@@ -53,10 +53,12 @@ Music_Config = TypedDict(
|
||||
)
|
||||
|
||||
# *=========================================== Predefines
|
||||
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
||||
formatter = logging.Formatter(
|
||||
"%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
||||
MASTER_TIMEOUT = datetime.now()
|
||||
INITIAL_TIME_WAIT = 5
|
||||
MUZYKA: Music_Config = {"playing": False, "ctx": None, "queue": [], "requestor": []}
|
||||
MUZYKA: Music_Config = {"playing": False,
|
||||
"ctx": None, "queue": [], "requestor": []}
|
||||
|
||||
LOGFILE = ""
|
||||
NETRC_FILE = ""
|
||||
@@ -66,6 +68,11 @@ MEMORY_FIVE_MUZYKA = ""
|
||||
SETTINGS_FILE = ""
|
||||
ENCODING = ""
|
||||
GRAPHICS_PATH = ""
|
||||
MUZYKA_MOJEGO_LUDU_HISTORIA = 1500
|
||||
MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE = 15
|
||||
MUZYKA_MOJEGO_LUDU_PLAJLISTA = 30
|
||||
|
||||
|
||||
# *=========================================== Platform Specific Predefines
|
||||
|
||||
if platform in ("linux", "linux2"):
|
||||
@@ -185,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()
|
||||
|
||||
|
||||
@@ -363,7 +369,6 @@ async def disconnect(ctx):
|
||||
|
||||
|
||||
# trunk-ignore(pylint/R0915)
|
||||
# trunk-ignore(pylint/R0914)
|
||||
# trunk-ignore(pylint/R0912)
|
||||
async def play(ctx, zamawial=None, arg=None):
|
||||
"""
|
||||
@@ -449,7 +454,6 @@ async def check():
|
||||
"""Funkcja sprawdzająca czy grać następny kawałek."""
|
||||
while True:
|
||||
# TODO: Tu dołożyć skanowanie rozmiaru pliku logowania oraz plików pamięci i przenoszenie ich na większy dysk.
|
||||
# TODO: Dodać typing i dać znać że wykonuje operacje porządkowania Baru (zamiata, układa szklanki itp.)
|
||||
# trunk-ignore(codespell/misspelled)
|
||||
# TODO: dlaczego sie tu wypierdala
|
||||
if client.voice_clients:
|
||||
@@ -564,10 +568,18 @@ 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:])
|
||||
response = await openai.ChatCompletion.acreate(
|
||||
model="gpt-4-32k", messages=history
|
||||
)
|
||||
|
||||
else:
|
||||
history.append(MESSAGE_TABLE[0])
|
||||
history.extend(MESSAGE_TABLE[-20:])
|
||||
history.extend(MESSAGE_TABLE[-15:])
|
||||
response = await openai.ChatCompletion.acreate(
|
||||
model="gpt-3.5-turbo-16k", messages=history
|
||||
)
|
||||
|
||||
logger.info("Historia wysłana:")
|
||||
logger.debug(history)
|
||||
response = await openai.ChatCompletion.acreate(
|
||||
@@ -631,7 +643,8 @@ async def get_file(ctx, source, link):
|
||||
item_type, item_id = spotify.parse_spotify_url(link)
|
||||
if item_id:
|
||||
file_list = spotify.fetch_tracks(spotify_ctrl, item_type, link)
|
||||
directory_name = spotify.get_item_name(spotify_ctrl, item_type, item_id)
|
||||
directory_name = spotify.get_item_name(
|
||||
spotify_ctrl, item_type, item_id)
|
||||
url_data = {"urls": []}
|
||||
url_dict = {}
|
||||
url_dict["save_path"] = Path(
|
||||
@@ -755,10 +768,42 @@ async def async_iterator_generator(range_of_iterable):
|
||||
"""
|
||||
|
||||
|
||||
async def get_stats(ctx, history_limit):
|
||||
"""
|
||||
The `get_stats` function retrieves the message history of a specific channel and counts the
|
||||
frequency of each word in the messages.
|
||||
|
||||
:param ctx: The `ctx` parameter is an object that represents the context of the command being
|
||||
executed. It contains information such as the message, the author, the server, and other relevant
|
||||
details
|
||||
:param history_limit: The `history_limit` parameter is the maximum number of messages to retrieve
|
||||
from the channel history. It determines how far back in time the statistics will be calculated
|
||||
:return: The function `get_stats` returns a dictionary `stats` that contains the frequency count of
|
||||
words found in the messages from the specified channel.
|
||||
"""
|
||||
channel_id = 1062047367337095268
|
||||
async with ctx.typing():
|
||||
stats = {}
|
||||
channel = client.get_channel(channel_id)
|
||||
messages = [message async for message in channel.history(limit=history_limit)]
|
||||
# traverse the iterable of awaitables
|
||||
for message in messages:
|
||||
# await and get the result from the awaitable
|
||||
result = message.content
|
||||
words = result.split()
|
||||
for word in words:
|
||||
if word in stats:
|
||||
stats[word] += 1
|
||||
else:
|
||||
stats[word] = 1
|
||||
for name, how_many in stats.items():
|
||||
yield name, how_many
|
||||
|
||||
|
||||
# trunk-ignore(pylint/R0914)
|
||||
# trunk-ignore(pylint/R0915)
|
||||
# trunk-ignore(pylint/R0912)
|
||||
async def wyszukaj(ctx, how_many=0):
|
||||
async def wyszukaj(ctx, how_many=0, slowa_kluczowe=None):
|
||||
"""
|
||||
Take in a context object and an optional integer parameter "how_many" and perform search
|
||||
operation on music library.
|
||||
@@ -772,7 +817,10 @@ async def wyszukaj(ctx, how_many=0):
|
||||
"""
|
||||
# TODO: Potem dorobić wyszukiwania po kawałkach słów
|
||||
# i sieć neuronową z możliwością wyrażenia opinii o dopasowaniu.
|
||||
word_list = ctx.message.content.split()
|
||||
if slowa_kluczowe:
|
||||
word_list = slowa_kluczowe
|
||||
else:
|
||||
word_list = ctx.message.content.split()
|
||||
logger.info("Wyszukuje")
|
||||
search_weight = []
|
||||
for _ in range(len(music_file_list)):
|
||||
@@ -783,15 +831,13 @@ async def wyszukaj(ctx, how_many=0):
|
||||
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:
|
||||
if platform == "win32":
|
||||
file = file.split("\\")
|
||||
else:
|
||||
file = file.split("/")
|
||||
async for file in async_iterator_generator(music_file_list):
|
||||
file = file.split(SEPARATOR_FILE_PATH)
|
||||
|
||||
char_remove = [
|
||||
".",
|
||||
"^",
|
||||
@@ -804,6 +850,7 @@ async def wyszukaj(ctx, how_many=0):
|
||||
"[",
|
||||
"]",
|
||||
"\\",
|
||||
"/",
|
||||
"|",
|
||||
"(",
|
||||
")",
|
||||
@@ -814,9 +861,9 @@ async def wyszukaj(ctx, how_many=0):
|
||||
"mp3",
|
||||
]
|
||||
all_words = []
|
||||
for f_iter in file:
|
||||
for char in char_remove:
|
||||
f_iter = f_iter.replace(char, "")
|
||||
async for f_iter in async_iterator_generator(file):
|
||||
async for char in async_iterator_generator(char_remove):
|
||||
f_iter = await remove_characters(f_iter, char)
|
||||
tmp = f_iter.split()
|
||||
all_words.extend(tmp)
|
||||
pingu = 1
|
||||
@@ -826,19 +873,21 @@ async def wyszukaj(ctx, how_many=0):
|
||||
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):
|
||||
temp_weight = (
|
||||
search_weight[itr][0]
|
||||
+ (token_weight + (pingu**1.5) / pattern_len) / matched_times
|
||||
+ (token_weight + (pingu**1.5) /
|
||||
pattern_len) / matched_times
|
||||
)
|
||||
search_weight[itr] = temp_weight, music_file_list[itr]
|
||||
matched_times += 1
|
||||
itr += 1
|
||||
|
||||
logger.info("Stworzylem tablice wag zajęło mi to %s", datetime.now() - time_start)
|
||||
logger.info("Stworzylem tablice wag zajęło mi to %s",
|
||||
datetime.now() - time_start)
|
||||
time_start = datetime.now()
|
||||
item_to_search = await max_weight(search_weight)
|
||||
itr = 0
|
||||
@@ -860,6 +909,18 @@ async def wyszukaj(ctx, how_many=0):
|
||||
return return_list
|
||||
|
||||
|
||||
async def remove_characters(string, character):
|
||||
"""
|
||||
The `remove_characters` function removes all occurrences of a specified character from a given
|
||||
string.
|
||||
|
||||
:param string: The string parameter is the input string from which characters will be removed
|
||||
:param character: The character parameter is the character that you want to remove from the string
|
||||
:return: a new string where all occurrences of the specified character have been removed.
|
||||
"""
|
||||
return string.replace(character, "")
|
||||
|
||||
|
||||
async def max_weight(lista):
|
||||
"""
|
||||
Take a list of weights and return the maximum weight.
|
||||
@@ -1317,7 +1378,7 @@ async def zrob_mi_plejliste(ctx):
|
||||
if metadata.tag.title:
|
||||
reply += " z prywatnej kolekcji Hammera i na Twoją specjalną rpośbę.\n"
|
||||
else:
|
||||
reply += f"{index}. {plik[1]} z prywatnej kolekcji Hammera."
|
||||
reply += f"{index}. {plik[1]} z prywatnej kolekcji Hammera.\n"
|
||||
|
||||
index += 1
|
||||
if len(reply) > 1800:
|
||||
@@ -1487,7 +1548,14 @@ async def get_image_stable_diffusion(ctx):
|
||||
pass
|
||||
|
||||
|
||||
# @client.hybrid_command()
|
||||
# trunk-ignore(mypy/arg-type)
|
||||
@client.hybrid_command(
|
||||
name="zagraj_muzyke_mego_ludu",
|
||||
description="Gra muzyke wyszukana na bazie tematow konwersacji na kanale NZ",
|
||||
guild=discord.Object(id=664789470779932693),
|
||||
)
|
||||
# trunk-ignore(pylint/R0912)
|
||||
# trunk-ignore(pylint/R0915)
|
||||
async def zagraj_muzyke_mego_ludu(ctx):
|
||||
"""
|
||||
Play completeley random playlist based on messaging history.
|
||||
@@ -1497,9 +1565,117 @@ async def zagraj_muzyke_mego_ludu(ctx):
|
||||
channel, the author, and other relevant details. In this case, it is being passed as a parameter to
|
||||
the `get_image
|
||||
"""
|
||||
stats = {}
|
||||
if ctx:
|
||||
logger.info("Zagraj muzyke mego ludu: wywolane")
|
||||
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
|
||||
|
||||
sorted_stats = sorted(stats.items(), key=lambda x: x[1])
|
||||
logger.info("Zagraj muzyke mego ludu:zebrano statystyki")
|
||||
key_words = []
|
||||
for stat in sorted_stats:
|
||||
key_words.append(stat[0])
|
||||
logger.info(sorted_stats[:MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE])
|
||||
logger.info(key_words[:MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE])
|
||||
logger.info(sorted_stats[-MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE:])
|
||||
logger.info(key_words[-MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE:])
|
||||
|
||||
final_key_words = key_words[:MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE]
|
||||
final_key_words.extend(key_words[-MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE:])
|
||||
reply = "Wygenerowana plejlista:\n"
|
||||
async with ctx.typing():
|
||||
logger.info("Zaczynam szukać timestamp %s", datetime.now())
|
||||
search_time_glob = datetime.now()
|
||||
file = await wyszukaj(ctx=ctx, how_many=MUZYKA_MOJEGO_LUDU_PLAJLISTA, slowa_kluczowe=final_key_words)
|
||||
logger.info("Zagraj muzyke mego ludu:wygenerowano plejliste")
|
||||
logger.info(file)
|
||||
logger.info(
|
||||
"Koniec szukania(timestamp %s zajęło %s",
|
||||
datetime.now(),
|
||||
datetime.now() - search_time_glob,
|
||||
)
|
||||
index = 1
|
||||
if file:
|
||||
for plik in file:
|
||||
global MUZYKA # pylint: disable=global-variable-not-assigned
|
||||
MUZYKA["queue"].insert(0, plik[1])
|
||||
MUZYKA["requestor"].insert(0, ctx.author)
|
||||
metadata = eyed3.load(plik[1])
|
||||
if metadata and metadata.tag:
|
||||
if metadata.tag.title:
|
||||
reply += f"{index} {metadata.tag.title}"
|
||||
else:
|
||||
reply += f"{index}. {plik[1]} z prywatnej kolekcji Hammera."
|
||||
|
||||
if metadata.tag.artist:
|
||||
reply += f" wykonawcy {metadata.tag.artist}"
|
||||
if metadata.tag.album:
|
||||
reply += f" z albumu {metadata.tag.album}"
|
||||
if metadata.tag.title:
|
||||
reply += " z prywatnej kolekcji Hammera i na Twoją specjalną rpośbę.\n"
|
||||
else:
|
||||
reply += f"{index}. {plik[1]} z prywatnej kolekcji Hammera.\n"
|
||||
|
||||
index += 1
|
||||
if len(reply) > 1800:
|
||||
await ctx.send(reply)
|
||||
reply = ""
|
||||
else:
|
||||
await ctx.send(
|
||||
"Obawiam się że nie mogę nic znaleźć u siebie. Spróbuj komendy '$dej_co_ze_spotifaja' jeśli masz link"
|
||||
)
|
||||
await ctx.send(reply)
|
||||
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=15, 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:
|
||||
pass
|
||||
async with ctx.typing():
|
||||
# if ':' in ile_historii:
|
||||
# _, _, ile_historii = ile_historii.partition(':')
|
||||
# if ':' in ile_slow_kluczowych:
|
||||
# _, _, ile_slow_kluczowych = ile_slow_kluczowych.partition(':')
|
||||
# if ':' in jak_dluga_plejlista:
|
||||
# _, _, jak_dluga_plejlista = jak_dluga_plejlista.partition(':')
|
||||
try:
|
||||
global MUZYKA_MOJEGO_LUDU_HISTORIA # pylint: disable=global-statement
|
||||
global MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE # pylint: disable=global-statement
|
||||
global MUZYKA_MOJEGO_LUDU_PLAJLISTA # pylint: disable=global-statement
|
||||
logger.info("Długość historii wyszukiwania: %s\n Ilość słów kluczowych: %s\n Długość plejlisty do wygenerowanie: %s", MUZYKA_MOJEGO_LUDU_HISTORIA, MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE, MUZYKA_MOJEGO_LUDU_PLAJLISTA)
|
||||
ctx.send(f"Dotychczasowe wartośći:\n Długość historii wyszukiwania: {MUZYKA_MOJEGO_LUDU_HISTORIA}\n Ilość słów kluczowych: {MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE}\n Długość plejlisty do wygenerowanie:{MUZYKA_MOJEGO_LUDU_PLAJLISTA}")
|
||||
MUZYKA_MOJEGO_LUDU_HISTORIA = ile_historii
|
||||
MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE = ile_slow_kluczowych
|
||||
MUZYKA_MOJEGO_LUDU_PLAJLISTA = jak_dluga_plejlista
|
||||
logger.info("Długość historii wyszukiwania: %s\n Ilość słów kluczowych: %s\n Długość plejlisty do wygenerowanie: %s", MUZYKA_MOJEGO_LUDU_HISTORIA, MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE, MUZYKA_MOJEGO_LUDU_PLAJLISTA)
|
||||
ctx.send(f"Zmienione wartośći:\n Długość historii wyszukiwania: {MUZYKA_MOJEGO_LUDU_HISTORIA}\n Ilość słów kluczowych: {MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE}\n Długość plejlisty do wygenerowanie:{MUZYKA_MOJEGO_LUDU_PLAJLISTA}")
|
||||
except discord.ext.commands.errors.BadArgument as exce:
|
||||
ctx.send("Spierdalaj")
|
||||
logger.info(exce)
|
||||
|
||||
|
||||
# *================================== Run
|
||||
|
||||
Reference in New Issue
Block a user