This commit is contained in:
parent
776fb7da75
commit
5d2065ae85
@ -2,8 +2,6 @@ from enum import Enum, Flag
|
||||
|
||||
import TeamTalkPy
|
||||
|
||||
major, minor, patch, build = TeamTalkPy.ttstr(TeamTalkPy.getVersion()).split(".")
|
||||
|
||||
|
||||
class State(Enum):
|
||||
NOT_CONNECTED = 0
|
||||
@ -147,7 +145,7 @@ class UserStatusMode(Flag):
|
||||
N = 4096
|
||||
|
||||
|
||||
class UserRightPre15(Flag):
|
||||
class UserRight(Flag):
|
||||
Null = TeamTalkPy.UserRight.USERRIGHT_NONE
|
||||
MultiLogin = TeamTalkPy.UserRight.USERRIGHT_MULTI_LOGIN
|
||||
ViewAllUsers = TeamTalkPy.UserRight.USERRIGHT_VIEW_ALL_USERS
|
||||
@ -174,75 +172,6 @@ class UserRightPre15(Flag):
|
||||
ViewHiddenChannels = TeamTalkPy.UserRight.USERRIGHT_VIEW_HIDDEN_CHANNELS
|
||||
|
||||
|
||||
if major == "5" and minor >= "15":
|
||||
class UserRight15(Flag):
|
||||
Null = TeamTalkPy.UserRight.USERRIGHT_NONE
|
||||
MultiLogin = TeamTalkPy.UserRight.USERRIGHT_MULTI_LOGIN
|
||||
ViewAllUsers = TeamTalkPy.UserRight.USERRIGHT_VIEW_ALL_USERS
|
||||
CreateTemporaryChannel = TeamTalkPy.UserRight.USERRIGHT_CREATE_TEMPORARY_CHANNEL
|
||||
ModifyChannels = TeamTalkPy.UserRight.USERRIGHT_MODIFY_CHANNELS
|
||||
BroadcastTextMessage = TeamTalkPy.UserRight.USERRIGHT_TEXTMESSAGE_BROADCAST
|
||||
KickUsers = TeamTalkPy.UserRight.USERRIGHT_KICK_USERS
|
||||
BanUsers = TeamTalkPy.UserRight.USERRIGHT_BAN_USERS
|
||||
MoveUsers = TeamTalkPy.UserRight.USERRIGHT_MOVE_USERS
|
||||
OperatorEnable = TeamTalkPy.UserRight.USERRIGHT_OPERATOR_ENABLE
|
||||
UploadFiles = TeamTalkPy.UserRight.USERRIGHT_UPLOAD_FILES
|
||||
DownloadFiles = TeamTalkPy.UserRight.USERRIGHT_DOWNLOAD_FILES
|
||||
UpdateServerProperties = TeamTalkPy.UserRight.USERRIGHT_UPDATE_SERVERPROPERTIES
|
||||
TransmitVoice = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_VOICE
|
||||
TransmitVideoCapture = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_VIDEOCAPTURE
|
||||
TransmitDesktop = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_DESKTOP
|
||||
TransmitDesktopInput = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_DESKTOPINPUT
|
||||
TransmitMediaFileAudio = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_MEDIAFILE_AUDIO
|
||||
TransmitMediaFileVideo = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_MEDIAFILE_VIDEO
|
||||
TransmitMediaFile = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_MEDIAFILE
|
||||
LockedNickname = TeamTalkPy.UserRight.USERRIGHT_LOCKED_NICKNAME
|
||||
LockedStatus = TeamTalkPy.UserRight.USERRIGHT_LOCKED_STATUS
|
||||
RecordVoice = TeamTalkPy.UserRight.USERRIGHT_RECORD_VOICE
|
||||
ViewHiddenChannels = TeamTalkPy.UserRight.USERRIGHT_VIEW_HIDDEN_CHANNELS
|
||||
textMessageUser = TeamTalkPy.UserRight.USERRIGHT_TEXTMESSAGE_USER
|
||||
textMessageChannel = TeamTalkPy.UserRight.USERRIGHT_TEXTMESSAGE_CHANNEL
|
||||
|
||||
UserRight = UserRight15
|
||||
else:
|
||||
UserRight = UserRightPre15
|
||||
|
||||
|
||||
class UserRight15(Flag):
|
||||
Null = TeamTalkPy.UserRight.USERRIGHT_NONE
|
||||
MultiLogin = TeamTalkPy.UserRight.USERRIGHT_MULTI_LOGIN
|
||||
ViewAllUsers = TeamTalkPy.UserRight.USERRIGHT_VIEW_ALL_USERS
|
||||
CreateTemporaryChannel = TeamTalkPy.UserRight.USERRIGHT_CREATE_TEMPORARY_CHANNEL
|
||||
ModifyChannels = TeamTalkPy.UserRight.USERRIGHT_MODIFY_CHANNELS
|
||||
BroadcastTextMessage = TeamTalkPy.UserRight.USERRIGHT_TEXTMESSAGE_BROADCAST
|
||||
KickUsers = TeamTalkPy.UserRight.USERRIGHT_KICK_USERS
|
||||
BanUsers = TeamTalkPy.UserRight.USERRIGHT_BAN_USERS
|
||||
MoveUsers = TeamTalkPy.UserRight.USERRIGHT_MOVE_USERS
|
||||
OperatorEnable = TeamTalkPy.UserRight.USERRIGHT_OPERATOR_ENABLE
|
||||
UploadFiles = TeamTalkPy.UserRight.USERRIGHT_UPLOAD_FILES
|
||||
DownloadFiles = TeamTalkPy.UserRight.USERRIGHT_DOWNLOAD_FILES
|
||||
UpdateServerProperties = TeamTalkPy.UserRight.USERRIGHT_UPDATE_SERVERPROPERTIES
|
||||
TransmitVoice = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_VOICE
|
||||
TransmitVideoCapture = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_VIDEOCAPTURE
|
||||
TransmitDesktop = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_DESKTOP
|
||||
TransmitDesktopInput = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_DESKTOPINPUT
|
||||
TransmitMediaFileAudio = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_MEDIAFILE_AUDIO
|
||||
TransmitMediaFileVideo = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_MEDIAFILE_VIDEO
|
||||
TransmitMediaFile = TeamTalkPy.UserRight.USERRIGHT_TRANSMIT_MEDIAFILE
|
||||
LockedNickname = TeamTalkPy.UserRight.USERRIGHT_LOCKED_NICKNAME
|
||||
LockedStatus = TeamTalkPy.UserRight.USERRIGHT_LOCKED_STATUS
|
||||
RecordVoice = TeamTalkPy.UserRight.USERRIGHT_RECORD_VOICE
|
||||
ViewHiddenChannels = TeamTalkPy.UserRight.USERRIGHT_VIEW_HIDDEN_CHANNELS
|
||||
textMessageUser = TeamTalkPy.UserRight.USERRIGHT_TEXTMESSAGE_USER
|
||||
textMessageChannel = TeamTalkPy.UserRight.USERRIGHT_TEXTMESSAGE_CHANNEL
|
||||
|
||||
|
||||
if major == "5" and minor >= "15":
|
||||
UserRight = UserRight15
|
||||
else:
|
||||
UserRight = UserRightPre15
|
||||
|
||||
|
||||
class UserAccount:
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -1,75 +1,26 @@
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import platform
|
||||
from typing import Callable, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bot.translator import Translator
|
||||
|
||||
app_name = "pandorafox♾"
|
||||
app_version = "2.4.1"
|
||||
|
||||
def get_system_info() -> str:
|
||||
system = platform.system()
|
||||
release = platform.release()
|
||||
version = platform.version()
|
||||
machine = platform.machine() or "unknown"
|
||||
processor = platform.processor() or "unknown"
|
||||
architecture = platform.architecture()[0] # '64bit' or '32bit'
|
||||
|
||||
if system == "Windows":
|
||||
try:
|
||||
import winreg
|
||||
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows NT\CurrentVersion")
|
||||
product_name = winreg.QueryValueEx(key, "ProductName")[0]
|
||||
release_id = winreg.QueryValueEx(key, "ReleaseId")[0]
|
||||
system_str = f"{product_name} {release_id}"
|
||||
except Exception:
|
||||
system_str = f"Windows {release}"
|
||||
elif system == "Linux":
|
||||
try:
|
||||
# Trying to get CPU info from /proc/cpuinfo
|
||||
with open("/proc/cpuinfo") as f:
|
||||
cpu_info = f.read()
|
||||
# Get the processor information
|
||||
processor = next((line.split(":")[1].strip() for line in cpu_info.splitlines() if "model name" in line), "unknown")
|
||||
os_info = {}
|
||||
with open("/etc/os-release") as f:
|
||||
for line in f:
|
||||
if "=" in line:
|
||||
k, v = line.strip().split("=", 1)
|
||||
os_info[k] = v.strip('"')
|
||||
name = os_info.get("PRETTY_NAME") or os_info.get("NAME", "Linux")
|
||||
system_str = name
|
||||
except Exception:
|
||||
system_str = f"Linux {release}"
|
||||
elif system == "Darwin":
|
||||
mac_ver = platform.mac_ver()[0]
|
||||
system_str = f"macOS {mac_ver or release}"
|
||||
else:
|
||||
system_str = f"{system} {release}"
|
||||
|
||||
return f"{system_str} | Arch: {architecture} | Machine: {machine} | CPU: {processor}"
|
||||
|
||||
client_name = f"{app_name}-Version{app_version}-{get_system_info()}"
|
||||
|
||||
app_name = "WalkMan"
|
||||
app_version = "2.3.5"
|
||||
client_name = app_name + "-V (Version)" + app_version
|
||||
about_text: Callable[[Translator], str] = lambda translator: translator.translate(
|
||||
"""\
|
||||
A media streaming bot for TeamTalk.
|
||||
Authors: Amir Gumerov, Vladislav Kopylov, Beqa Gozalishvili, Kirill Belousov.
|
||||
Home page: https://github.com/gumerov-amir/TTMediaBot
|
||||
Pandorabox writer: Rexya, Muhammad.
|
||||
Extended from pandoraBox (https://www.dropbox.com/scl/fi/w59od6p43v474cdqfllt1/PandoraBox.zip?rlkey=sghktp7rbuxknbz9b3v9lqfii&dl=1)
|
||||
Currently maintain by Rafli On Techlabs git
|
||||
Visit us on: https://git.techlabs.lol/radiant_code/teamtalkbot
|
||||
Currently Running under: techlabs.lol (Leap over limits!)
|
||||
License: MIT License\
|
||||
"""
|
||||
)
|
||||
|
||||
start_bottt: Callable[[Translator], str] = lambda translator: translator.translate(
|
||||
"""\
|
||||
Hello there!
|
||||
I'm PandoraFox, your go-to companion for discovering amazing songs and audio through YouTube, Yandex Music (Currently unavailable), and VK.
|
||||
I'm PandoraBox, your go-to companion for discovering amazing songs and audio through YouTube, Yandex Music, and VK.
|
||||
Hosted by TechLabsStudio, I'm all set to bring audio magic to your TeamTalk experience.
|
||||
To get started, simply send me a private message with a specific command.
|
||||
Here's how you can interact with me:
|
||||
@ -80,17 +31,25 @@ If you encounter any issues or want to chat with us, feel free to reach out.
|
||||
Thank you for choosing our service, and have a fantastic day!\
|
||||
"""
|
||||
)
|
||||
|
||||
contacts_bot: Callable[[Translator], str] = lambda translator: translator.translate(
|
||||
"""\
|
||||
If you encounter any issues with this bot, please reach out to our dedicated technicians:
|
||||
🦊 Rafli:
|
||||
rafli@techlabs.lol
|
||||
t.me/rafli_ir
|
||||
|
||||
- Muhammad:
|
||||
- WhatsApp: https://api.whatsapp.com/send?phone=6282156978782
|
||||
- Telegram: https://t.me/muha_aku
|
||||
|
||||
- Rexya:
|
||||
- WhatsApp: https://api.whatsapp.com/send?phone=6288222553434
|
||||
- Email: rexya@infiartt.com
|
||||
|
||||
- rafli:
|
||||
- email: rafli@techlabs.lol
|
||||
- telegram: rafli_ir
|
||||
|
||||
Join the TTMediaBot Official Group on Telegram: https://t.me/TTMediaBot_chat\
|
||||
"""
|
||||
)
|
||||
|
||||
fallback_service = "yt"
|
||||
loop_timeout = 0.01
|
||||
max_message_length = 512
|
||||
|
32
bot/cache.py
32
bot/cache.py
@ -12,37 +12,25 @@ import portalocker
|
||||
if TYPE_CHECKING:
|
||||
from bot.player.track import Track
|
||||
|
||||
|
||||
cache_data_type = Dict[str, Any]
|
||||
|
||||
|
||||
class Cache:
|
||||
def __init__(self, cache_data: cache_data_type):
|
||||
self.cache_version = cache_data.get("cache_version", CacheManager.version)
|
||||
self.recents: deque[Track] = deque(
|
||||
cache_data.get("recents", []),
|
||||
maxlen=app_vars.recents_max_lenth
|
||||
self.cache_version = cache_data["cache_version"] if "cache_version" in cache_data else CacheManager.version
|
||||
self.recents: deque[Track] = (
|
||||
cache_data["recents"]
|
||||
if "recents" in cache_data
|
||||
else deque(maxlen=app_vars.recents_max_lenth)
|
||||
)
|
||||
self.favorites: Dict[str, List[Track]] = (
|
||||
cache_data["favorites"] if "favorites" in cache_data else {}
|
||||
)
|
||||
self.favorites: Dict[str, List[Track]] = cache_data.get("favorites", {})
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
# Pastikan semua track di-recents & favorites adalah versi raw (non-stream)
|
||||
sanitized_recents = deque(
|
||||
(track.get_raw() if hasattr(track, "get_raw") else track)
|
||||
for track in self.recents
|
||||
)
|
||||
sanitized_favorites = {
|
||||
user: [
|
||||
track.get_raw() if hasattr(track, "get_raw") else track
|
||||
for track in tracks
|
||||
]
|
||||
for user, tracks in self.favorites.items()
|
||||
}
|
||||
return {
|
||||
"cache_version": self.cache_version,
|
||||
"recents": sanitized_recents,
|
||||
"favorites": sanitized_favorites
|
||||
}
|
||||
return {"cache_version": self.cache_version, "recents": self.recents, "favorites": self.favorites}
|
||||
|
||||
|
||||
class CacheManager:
|
||||
|
@ -40,7 +40,8 @@ class CommandProcessor:
|
||||
"contacts": user_commands.ContactsBot,
|
||||
"help": user_commands.HelpCommand,
|
||||
"p": user_commands.PlayPauseCommand,
|
||||
"e": user_commands.QueueCommand,
|
||||
"e": user_commands.EnqueueCommand,
|
||||
"q": user_commands.QueueCommand,
|
||||
"u": user_commands.PlayUrlCommand,
|
||||
"sv": user_commands.ServiceCommand,
|
||||
"s": user_commands.StopCommand,
|
||||
|
@ -1,7 +1,6 @@
|
||||
from __future__ import annotations
|
||||
from typing import List, Optional, TYPE_CHECKING
|
||||
import os
|
||||
import re
|
||||
|
||||
from bot.commands.command import Command
|
||||
from bot.player.enums import Mode, State, TrackType
|
||||
@ -116,6 +115,51 @@ class PlayUrlCommand(Command):
|
||||
else:
|
||||
raise errors.InvalidArgumentError
|
||||
|
||||
class EnqueueCommand(Command):
|
||||
@property
|
||||
def help(self) -> str:
|
||||
return self.translator.translate(
|
||||
"QUERY Finds a matching track and adds it to the queue"
|
||||
)
|
||||
|
||||
def __call__(self, arg: str, user: User) -> Optional[str]:
|
||||
if not arg:
|
||||
raise errors.InvalidArgumentError
|
||||
|
||||
self.run_async(
|
||||
self.ttclient.send_message,
|
||||
self.translator.translate("Searching and adding to the queue..."),
|
||||
user,
|
||||
)
|
||||
try:
|
||||
track_list = self.service_manager.service.search(arg)
|
||||
|
||||
# Take only the first track from the search results to enqueue
|
||||
track_to_queue = [track_list[0]]
|
||||
|
||||
# Check if the player was stopped to provide the correct response message
|
||||
was_stopped = self.player.state == State.Stopped
|
||||
|
||||
# Call the enqueue function with the single track
|
||||
self.run_async(self.player.enqueue, track_to_queue)
|
||||
|
||||
# Create the response message
|
||||
if not was_stopped:
|
||||
# If already playing, confirm the track was added to the queue
|
||||
return self.translator.translate("Added to queue: {}").format(
|
||||
track_to_queue[0].name
|
||||
)
|
||||
else:
|
||||
# If it was stopped, the track will start playing immediately
|
||||
return self.translator.translate("Playing {}").format(
|
||||
track_to_queue[0].name
|
||||
)
|
||||
except errors.NothingFoundError:
|
||||
return self.translator.translate("Nothing was found for your query")
|
||||
except errors.ServiceError:
|
||||
return self.translator.translate(
|
||||
"The selected service is currently unavailable"
|
||||
)
|
||||
|
||||
class StopCommand(Command):
|
||||
@property
|
||||
@ -583,67 +627,6 @@ class DownloadCommand(Command):
|
||||
else:
|
||||
return self.translator.translate("Nothing is playing")
|
||||
|
||||
class QueueCommand(Command):
|
||||
@property
|
||||
def help(self) -> str:
|
||||
return self.translator.translate(
|
||||
"QUERY Adds a track to the queue. If no track is playing, plays immediately."
|
||||
)
|
||||
|
||||
def __call__(self, arg: str, user: User) -> Optional[str]:
|
||||
if not arg:
|
||||
raise errors.InvalidArgumentError
|
||||
|
||||
self.run_async(
|
||||
self.ttclient.send_message,
|
||||
self.translator.translate("Searching..."),
|
||||
user,
|
||||
)
|
||||
|
||||
try:
|
||||
if re.match(r'http[s]?://', arg):
|
||||
# Kalau URL, langsung stream
|
||||
tracks = self.module_manager.streamer.get(arg, user.is_admin if user is not None else True)
|
||||
self.player.add_to_queue(tracks)
|
||||
else:
|
||||
# Kalau bukan URL, cari lagu dari service
|
||||
tracks = self.service_manager.service.search(arg)
|
||||
self.player.add_to_queue(tracks)
|
||||
|
||||
# Kalau gak lagi main apa-apa, langsung play
|
||||
if self.player.state != State.Playing:
|
||||
self.player.play_next()
|
||||
|
||||
if self.config.general.send_channel_messages:
|
||||
if re.match(r'http[s]?://', arg):
|
||||
message = self.translator.translate(
|
||||
"{nickname} added a stream URL to the queue."
|
||||
).format(nickname=user.nickname)
|
||||
else:
|
||||
message = self.translator.translate(
|
||||
"{nickname} added {request} to the queue."
|
||||
).format(nickname=user.nickname, request=arg)
|
||||
|
||||
self.run_async(
|
||||
self.ttclient.send_message,
|
||||
message,
|
||||
type=2,
|
||||
)
|
||||
|
||||
if re.match(r'http[s]?://', arg):
|
||||
return self.translator.translate("Added stream URL to the queue.")
|
||||
else:
|
||||
return self.translator.translate("Added {} to the queue.").format(
|
||||
tracks[0].name
|
||||
)
|
||||
|
||||
except errors.NothingFoundError:
|
||||
return self.translator.translate("Nothing is found for your query")
|
||||
except errors.ServiceError:
|
||||
return self.translator.translate(
|
||||
"The selected service is currently unavailable"
|
||||
)
|
||||
|
||||
class ChangeLogCommand(Command):
|
||||
@property
|
||||
def help(self) -> str:
|
||||
@ -689,3 +672,31 @@ class DefaultSeekStepCommand(Command):
|
||||
else:
|
||||
return self.translator.translate("Default Seek step can not be blank, Please specify default Seek step!")
|
||||
|
||||
class QueueCommand(Command):
|
||||
@property
|
||||
def help(self) -> str:
|
||||
return self.translator.translate("Displays the current song queue")
|
||||
|
||||
def __call__(self, arg: str, user: User) -> Optional[str]:
|
||||
if not self.player.track_list or self.player.state == State.Stopped:
|
||||
return self.translator.translate("The queue is empty.")
|
||||
|
||||
# Get the currently playing track
|
||||
now_playing = self.player.track
|
||||
response = self.translator.translate("Now Playing: {track_name}\n\nQueue:\n").format(track_name=now_playing.name)
|
||||
|
||||
# Get the rest of the queue (all tracks after the current one)
|
||||
queue_list = self.player.track_list[self.player.track_index + 1:]
|
||||
|
||||
if not queue_list:
|
||||
response += self.translator.translate("No more tracks in the queue.")
|
||||
return response
|
||||
|
||||
for i, track in enumerate(queue_list[:10]): # Show max 10 tracks
|
||||
response += f"{i + 1}. {track.name}\n"
|
||||
|
||||
if len(queue_list) > 10:
|
||||
remaining = len(queue_list) - 10
|
||||
response += self.translator.translate("\n...and {count} more.").format(count=remaining)
|
||||
|
||||
return response
|
@ -43,6 +43,7 @@ class Player:
|
||||
self.state = State.Stopped
|
||||
self.mode = Mode.TrackList
|
||||
self.volume = self.config.default_volume
|
||||
self.manual_queue = False
|
||||
|
||||
def initialize(self) -> None:
|
||||
logging.debug("Initializing player")
|
||||
@ -55,6 +56,21 @@ class Player:
|
||||
self._player.observe_property("media-title", self.on_metadata_update)
|
||||
logging.debug("Player callbacks registered")
|
||||
|
||||
def enqueue(self, tracks: List[Track]) -> None:
|
||||
"""Adds tracks to the queue, clearing the old playlist if needed."""
|
||||
if self.state == State.Stopped or not self.track_list:
|
||||
self.play(tracks)
|
||||
self.manual_queue = True
|
||||
else:
|
||||
if not self.manual_queue:
|
||||
now_playing_track = self.track_list[self.track_index]
|
||||
self.track_list = [now_playing_track]
|
||||
self.track_index = 0 # Reset index
|
||||
self.manual_queue = True # Activate manual queue mode
|
||||
|
||||
# Now, just add the new track(s) to the end of the (possibly new) list.
|
||||
self.track_list.extend(tracks)
|
||||
|
||||
def close(self) -> None:
|
||||
logging.debug("Closing player")
|
||||
if self.state != State.Stopped:
|
||||
@ -68,6 +84,7 @@ class Player:
|
||||
start_track_index: Optional[int] = None,
|
||||
) -> None:
|
||||
if tracks != None:
|
||||
self.manual_queue = False
|
||||
self.track_list = tracks
|
||||
if not start_track_index and self.mode == Mode.Random:
|
||||
self.shuffle(True)
|
||||
@ -105,7 +122,6 @@ class Player:
|
||||
self.cache_manager.save()
|
||||
self._player.pause = False
|
||||
self._player.play(arg)
|
||||
self._player.volume = self.volume
|
||||
|
||||
def next(self) -> None:
|
||||
track_index = self.track_index
|
||||
@ -157,7 +173,7 @@ class Player:
|
||||
def play_by_index(self, index: int) -> None:
|
||||
if index < len(self.track_list) and index >= (0 - len(self.track_list)):
|
||||
self.track = self.track_list[index]
|
||||
self.track_index = index
|
||||
self.track_index = self.track_list.index(self.track)
|
||||
self._play(self.track.url)
|
||||
self.state = State.Playing
|
||||
else:
|
||||
@ -182,25 +198,6 @@ class Player:
|
||||
raise ValueError()
|
||||
self._player.speed = arg
|
||||
|
||||
def add_to_queue(self, tracks: List[Track]) -> None:
|
||||
"""Adds tracks to the queue."""
|
||||
self.track_list.extend(tracks)
|
||||
logging.debug(f"Added {len(tracks)} track(s) to the queue.")
|
||||
|
||||
# If nothing is playing, start playing the next track
|
||||
if self.state == State.Stopped and len(self.track_list) > 0:
|
||||
self.play_next()
|
||||
|
||||
def play_next(self) -> None:
|
||||
"""Play the next track in the queue."""
|
||||
if len(self.track_list) > 0:
|
||||
self.track_index = 0 # Start with the first track
|
||||
self.track = self.track_list[self.track_index]
|
||||
self._play(self.track.url)
|
||||
self.state = State.Playing
|
||||
else:
|
||||
self.state = State.Stopped
|
||||
|
||||
def seek_back(self, step: Optional[float] = None) -> None:
|
||||
step = step if step else self.config.seek_step
|
||||
if step <= 0:
|
||||
|
@ -1,6 +1,9 @@
|
||||
This change log is written to find out the changes that have been made by Pandora, and the source code still refers to TTMediaBot.
|
||||
24-08-2025
|
||||
1. Added queue.
|
||||
|
||||
5/17/2025
|
||||
rollback to TTSDk5.12 due 5.8 is gone.
|
||||
rollback to TTSDk5.12 due to 5.8 is gone.
|
||||
5/14/2025
|
||||
Added entry for scheduler command on readme.md
|
||||
Fixed file caching:
|
||||
|
Loading…
x
Reference in New Issue
Block a user