Compare commits
8 Commits
199dada246
...
79f1a6afa3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79f1a6afa3 | ||
|
|
194306bc1d | ||
|
|
4f10ed7bad | ||
|
|
2edf12670f | ||
|
|
a027cbe776 | ||
|
|
28396d136f | ||
|
|
2fc705dc6e | ||
|
|
6936b24129 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,4 @@
|
||||
.mypy_cache/
|
||||
*_ui.py
|
||||
*.pyc
|
||||
*.swp
|
||||
tags
|
||||
|
||||
@ -30,9 +30,9 @@ class Config(object):
|
||||
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
|
||||
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None
|
||||
MILLISECOND_SIGFIGS = 0
|
||||
MYSQL_CONNECT = "mysql+mysqldb://musicmuster:musicmuster@localhost/musicmuster"
|
||||
MYSQL_CONNECT = os.environ.get('MYSQL_CONNECT') or "mysql+mysqldb://musicmuster:musicmuster@localhost/musicmuster_dev" # noqa E501
|
||||
NORMALISE_ON_IMPORT = True
|
||||
ROOT = "/home/kae/music"
|
||||
ROOT = os.environ.get('ROOT') or "/home/kae/music"
|
||||
TESTMODE = True
|
||||
TIMER_MS = 500
|
||||
VOLUME_VLC_DEFAULT = 81
|
||||
|
||||
64
app/model.py
64
app/model.py
@ -14,6 +14,7 @@ from sqlalchemy import (
|
||||
String,
|
||||
func
|
||||
)
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
|
||||
from sqlalchemy.orm import relationship, sessionmaker
|
||||
|
||||
@ -106,6 +107,14 @@ class Playdates(Base):
|
||||
track.update_lastplayed()
|
||||
session.commit()
|
||||
|
||||
@staticmethod
|
||||
def last_played(session, track):
|
||||
"Return datetime track last played or None"
|
||||
|
||||
return session.query(Playdates).filter(
|
||||
(Playdates.track_id == track.id)
|
||||
).order_by(Playdates.lastplayed.desc()).first()
|
||||
|
||||
|
||||
class Playlists(Base):
|
||||
"""
|
||||
@ -279,6 +288,20 @@ class PlaylistTracks(Base):
|
||||
session.add(plt)
|
||||
session.commit()
|
||||
|
||||
@staticmethod
|
||||
def get_playlists_containing_track_id(session, track_id):
|
||||
|
||||
playlists = []
|
||||
playlist_ids = session.query(PlaylistTracks.playlist_id).filter(
|
||||
PlaylistTracks.track_id == track_id).all()
|
||||
for p in playlist_ids:
|
||||
playlist = session.query(Playlists).filter(
|
||||
Playlists.id == p[0]).first()
|
||||
if playlist:
|
||||
playlists.append(playlist)
|
||||
|
||||
return playlists
|
||||
|
||||
@staticmethod
|
||||
def move_track(session, from_playlist_id, row, to_playlist_id):
|
||||
DEBUG(
|
||||
@ -458,6 +481,44 @@ class Tracks(Base):
|
||||
ERROR(f"get_track({id}): not found")
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_track_from_filename(session, filename):
|
||||
"""
|
||||
Return track if one and only one track in database has passed
|
||||
filename (ie, basename of path). Return None if zero or more
|
||||
than one track matches.
|
||||
"""
|
||||
|
||||
DEBUG(f"Tracks.get_track_from_filename({filename=})")
|
||||
try:
|
||||
track = session.query(Tracks).filter(Tracks.path.ilike(
|
||||
# TODO: filename separator is hardcoded here
|
||||
f'%/{filename}')).one()
|
||||
return track
|
||||
except (NoResultFound, MultipleResultsFound):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_track_from_path(session, path):
|
||||
"""
|
||||
Return track with passee path, or None.
|
||||
"""
|
||||
|
||||
DEBUG(f"Tracks.get_track_from_path({path=})")
|
||||
|
||||
return session.query(Tracks).filter(Tracks.path == path).first()
|
||||
|
||||
@staticmethod
|
||||
def remove_path(session, path):
|
||||
"Remove track with passed path from database"
|
||||
|
||||
DEBUG(f"Tracks.remove_path({path=})")
|
||||
|
||||
try:
|
||||
session.query(Tracks).filter(Tracks.path == path).delete()
|
||||
except IntegrityError as exception:
|
||||
ERROR(f"Can't remove track with {path=} ({exception=})")
|
||||
|
||||
@staticmethod
|
||||
def search_titles(session, text):
|
||||
return (
|
||||
@ -473,3 +534,6 @@ class Tracks(Base):
|
||||
|
||||
def update_lastplayed(self):
|
||||
self.lastplayed = datetime.now()
|
||||
|
||||
def update_path(self, newpath):
|
||||
self.path = newpath
|
||||
|
||||
@ -311,6 +311,15 @@ class PlaylistTab(QTableWidget):
|
||||
|
||||
return result
|
||||
|
||||
def get_selected_title(self):
|
||||
"Return title of selected row or None"
|
||||
|
||||
if self.selectionModel().hasSelection():
|
||||
row = self.currentRow()
|
||||
return self.item(row, self.COL_TITLE).text()
|
||||
else:
|
||||
return None
|
||||
|
||||
def remove_rows(self, rows):
|
||||
"Remove rows passed in rows list"
|
||||
|
||||
@ -323,15 +332,6 @@ class PlaylistTab(QTableWidget):
|
||||
|
||||
self._repaint()
|
||||
|
||||
def get_selected_title(self):
|
||||
"Return title of selected row or None"
|
||||
|
||||
if self.selectionModel().hasSelection():
|
||||
row = self.currentRow()
|
||||
return self.item(row, self.COL_TITLE).text()
|
||||
else:
|
||||
return None
|
||||
|
||||
def play_started(self):
|
||||
"""
|
||||
Update current track to be what was next, and determine next track.
|
||||
@ -834,6 +834,8 @@ class PlaylistTab(QTableWidget):
|
||||
self._set_row_start_time(row, start_time)
|
||||
next_start_time = self._calculate_next_start_time(
|
||||
session, row, start_time)
|
||||
# Set end time
|
||||
self._set_row_end_time(row, next_start_time)
|
||||
# Set colour
|
||||
self._set_row_colour(
|
||||
row, QColor(Config.COLOUR_NEXT_PLAYLIST))
|
||||
|
||||
147
app/songdb.py
147
app/songdb.py
@ -7,8 +7,9 @@ import tempfile
|
||||
|
||||
from config import Config
|
||||
from log import DEBUG, INFO
|
||||
from model import Tracks, Session
|
||||
from model import Tracks, Playdates, PlaylistTracks, Session
|
||||
from mutagen.flac import FLAC
|
||||
from mutagen.mp3 import MP3
|
||||
from pydub import AudioSegment, effects
|
||||
from tinytag import TinyTag
|
||||
|
||||
@ -22,7 +23,10 @@ def main():
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('-u', '--update',
|
||||
action="store_true", dest="update",
|
||||
default=True, help="Update database")
|
||||
default=False, help="Update database")
|
||||
p.add_argument('-f', '--full-update',
|
||||
action="store_true", dest="full_update",
|
||||
default=False, help="Update database")
|
||||
args = p.parse_args()
|
||||
|
||||
# Run as required
|
||||
@ -30,25 +34,32 @@ def main():
|
||||
INFO("Updating database")
|
||||
with Session() as session:
|
||||
update_db(session)
|
||||
elif args.full_update:
|
||||
INFO("Full update of database")
|
||||
with Session() as session:
|
||||
full_update_db(session)
|
||||
else:
|
||||
INFO("No action specified")
|
||||
|
||||
INFO("Finished")
|
||||
|
||||
|
||||
def create_track_from_file(session, path):
|
||||
"""
|
||||
Create track in database from passed path.
|
||||
Create track in database from passed path, or update database entry
|
||||
if path already in database.
|
||||
|
||||
Return track.
|
||||
"""
|
||||
|
||||
track = Tracks.get_or_create(session, path)
|
||||
tag = TinyTag.get(path)
|
||||
audio = get_audio_segment(path)
|
||||
t = get_music_info(path)
|
||||
track.title = t['title']
|
||||
track.artist = t['artist']
|
||||
track.duration = int(round(
|
||||
t['duration'], Config.MILLISECOND_SIGFIGS) * 1000)
|
||||
|
||||
track.title = tag.title
|
||||
track.artist = tag.artist
|
||||
track.duration = int(round(tag.duration,
|
||||
Config.MILLISECOND_SIGFIGS) * 1000)
|
||||
audio = get_audio_segment(path)
|
||||
track.start_gap = leading_silence(audio)
|
||||
track.fade_at = round(fade_point(audio) / 1000,
|
||||
Config.MILLISECOND_SIGFIGS) * 1000
|
||||
@ -58,6 +69,12 @@ def create_track_from_file(session, path):
|
||||
session.commit()
|
||||
|
||||
if Config.NORMALISE_ON_IMPORT:
|
||||
# Check type
|
||||
ftype = os.path.splitext(path)[1][1:]
|
||||
if ftype not in ['mp3', 'flac']:
|
||||
INFO(f"File type {ftype} not implemented")
|
||||
return track
|
||||
|
||||
# Get current file gid, uid and permissions
|
||||
stats = os.stat(path)
|
||||
try:
|
||||
@ -68,30 +85,42 @@ def create_track_from_file(session, path):
|
||||
DEBUG(f"songdb.create_track_from_file({path}): err1: {str(err)}")
|
||||
return
|
||||
|
||||
# Overwrite original file with normalised output
|
||||
normalised = effects.normalize(audio)
|
||||
try:
|
||||
normalised.export(path, format=os.path.splitext(path)[1][1:])
|
||||
# Fix up permssions and ownership
|
||||
os.chown(path, stats.st_uid, stats.st_gid)
|
||||
os.chmod(path, stats.st_mode)
|
||||
# Copy tags
|
||||
src = FLAC(temp_path)
|
||||
dst = FLAC(path)
|
||||
for tag in src:
|
||||
dst[tag] = src[tag]
|
||||
dst.save()
|
||||
except Exception as err:
|
||||
DEBUG(f"songdb.create_track_from_file({path}): err2: {str(err)}")
|
||||
# Restore original file
|
||||
shutil.copyfile(path, temp_path)
|
||||
finally:
|
||||
if os.path.exists(temp_path):
|
||||
os.remove(temp_path)
|
||||
# Overwrite original file with normalised output
|
||||
normalised = effects.normalize(audio)
|
||||
try:
|
||||
normalised.export(path, format=os.path.splitext(path)[1][1:])
|
||||
# Fix up permssions and ownership
|
||||
os.chown(path, stats.st_uid, stats.st_gid)
|
||||
os.chmod(path, stats.st_mode)
|
||||
# Copy tags
|
||||
if ftype == 'flac':
|
||||
tag_handler = FLAC
|
||||
elif ftype == 'mp3':
|
||||
tag_handler = MP3
|
||||
else:
|
||||
return track
|
||||
src = tag_handler(temp_path)
|
||||
dst = tag_handler(path)
|
||||
for tag in src:
|
||||
dst[tag] = src[tag]
|
||||
dst.save()
|
||||
except Exception as err:
|
||||
DEBUG(f"songdb.create_track_from_file({path}): err2: {str(err)}")
|
||||
# Restore original file
|
||||
shutil.copyfile(path, temp_path)
|
||||
finally:
|
||||
if os.path.exists(temp_path):
|
||||
os.remove(temp_path)
|
||||
|
||||
return track
|
||||
|
||||
|
||||
def full_update_db():
|
||||
"Rescan all entries in database"
|
||||
|
||||
print("Full scan not yet implemented")
|
||||
|
||||
|
||||
def get_audio_segment(path):
|
||||
try:
|
||||
if path.endswith('.mp3'):
|
||||
@ -102,6 +131,21 @@ def get_audio_segment(path):
|
||||
return None
|
||||
|
||||
|
||||
def get_music_info(path):
|
||||
"""
|
||||
Return a dictionary of title, artist, duration-in-milliseconds and path.
|
||||
"""
|
||||
|
||||
tag = TinyTag.get(path)
|
||||
|
||||
return dict(
|
||||
title=tag.title,
|
||||
artist=tag.artist,
|
||||
duration=tag.duration,
|
||||
path=path
|
||||
)
|
||||
|
||||
|
||||
def leading_silence(audio_segment, silence_threshold=Config.DBFS_SILENCE,
|
||||
chunk_size=Config.AUDIO_SEGMENT_CHUNK_SIZE):
|
||||
"""
|
||||
@ -187,14 +231,47 @@ def update_db(session):
|
||||
os_paths_list.append(path)
|
||||
os_paths = set(os_paths_list)
|
||||
|
||||
for path in list(db_paths - os_paths):
|
||||
# TODO
|
||||
INFO(f"To remove from database: {path}")
|
||||
# If a track is moved, only the path will have changed.
|
||||
# For any files we have found whose paths are not in the database,
|
||||
# check to see whether the filename (basename) is present in the
|
||||
# database:
|
||||
|
||||
for path in list(os_paths - db_paths):
|
||||
# TODO
|
||||
INFO(f"Adding to dataabase: {path}")
|
||||
create_track_from_file(session, path)
|
||||
DEBUG(f"songdb.update_db: {path=} not in database")
|
||||
# is filename in database?
|
||||
track = Tracks.get_track_from_filename(session, os.path.basename(path))
|
||||
if not track:
|
||||
DEBUG(f"songdb.update_db: Adding to database: {path}")
|
||||
create_track_from_file(session, path)
|
||||
else:
|
||||
# Check track info matches found track
|
||||
t = get_music_info(path)
|
||||
if t['artist'] == track.artist and t['title'] == track.title:
|
||||
track.update_path(path)
|
||||
else:
|
||||
create_track_from_file(session, path)
|
||||
|
||||
# Refresh database paths
|
||||
db_paths = set(Tracks.get_all_paths(session))
|
||||
# Remote any tracks from database whose paths don't exist
|
||||
for path in list(db_paths - os_paths):
|
||||
track = Tracks.get_track_from_path(session, path)
|
||||
DEBUG(f"songdb.update_db(): remove from database: {path=} {track=}")
|
||||
played = Playdates.last_played(session, track)
|
||||
playlists = PlaylistTracks.get_playlists_containing_track_id(
|
||||
session, track.id)
|
||||
if played:
|
||||
INFO(
|
||||
f"songdb.update_db: Can't remove {track.id=} ({track.path=}) "
|
||||
f"as it's in playdates.id={played.id}"
|
||||
)
|
||||
elif playlists:
|
||||
INFO(
|
||||
f"songdb.update_db: Can't remove {track.id=} ({track.path=} "
|
||||
f"as it's in playlists {[p.name for p in playlists]}"
|
||||
)
|
||||
else:
|
||||
Tracks.remove_path(session, path)
|
||||
|
||||
|
||||
if __name__ == '__main__' and '__file__' in globals():
|
||||
|
||||
34
app/ui/dlg_SelectPlaylist_ui.py
Normal file
34
app/ui/dlg_SelectPlaylist_ui.py
Normal file
@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/dlg_SelectPlaylist.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.11.3
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_dlgSelectPlaylist(object):
|
||||
def setupUi(self, dlgSelectPlaylist):
|
||||
dlgSelectPlaylist.setObjectName("dlgSelectPlaylist")
|
||||
dlgSelectPlaylist.resize(276, 150)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(dlgSelectPlaylist)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.lstPlaylists = QtWidgets.QListWidget(dlgSelectPlaylist)
|
||||
self.lstPlaylists.setObjectName("lstPlaylists")
|
||||
self.verticalLayout.addWidget(self.lstPlaylists)
|
||||
self.buttonBox = QtWidgets.QDialogButtonBox(dlgSelectPlaylist)
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName("buttonBox")
|
||||
self.verticalLayout.addWidget(self.buttonBox)
|
||||
|
||||
self.retranslateUi(dlgSelectPlaylist)
|
||||
self.buttonBox.accepted.connect(dlgSelectPlaylist.accept)
|
||||
self.buttonBox.rejected.connect(dlgSelectPlaylist.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(dlgSelectPlaylist)
|
||||
|
||||
def retranslateUi(self, dlgSelectPlaylist):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
dlgSelectPlaylist.setWindowTitle(_translate("dlgSelectPlaylist", "Dialog"))
|
||||
|
||||
61
app/ui/dlg_search_database_ui.py
Normal file
61
app/ui/dlg_search_database_ui.py
Normal file
@ -0,0 +1,61 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'app/ui/dlg_SearchDatabase.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.4
|
||||
#
|
||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_Dialog(object):
|
||||
def setupUi(self, Dialog):
|
||||
Dialog.setObjectName("Dialog")
|
||||
Dialog.resize(383, 270)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.gridLayout = QtWidgets.QGridLayout()
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.label = QtWidgets.QLabel(Dialog)
|
||||
self.label.setObjectName("label")
|
||||
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
|
||||
self.searchString = QtWidgets.QLineEdit(Dialog)
|
||||
self.searchString.setObjectName("searchString")
|
||||
self.gridLayout.addWidget(self.searchString, 0, 1, 1, 1)
|
||||
self.verticalLayout.addLayout(self.gridLayout)
|
||||
self.matchList = QtWidgets.QListWidget(Dialog)
|
||||
self.matchList.setObjectName("matchList")
|
||||
self.verticalLayout.addWidget(self.matchList)
|
||||
self.dbPath = QtWidgets.QLabel(Dialog)
|
||||
self.dbPath.setText("")
|
||||
self.dbPath.setObjectName("dbPath")
|
||||
self.verticalLayout.addWidget(self.dbPath)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
spacerItem = QtWidgets.QSpacerItem(88, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem)
|
||||
self.btnAdd = QtWidgets.QPushButton(Dialog)
|
||||
self.btnAdd.setDefault(True)
|
||||
self.btnAdd.setObjectName("btnAdd")
|
||||
self.horizontalLayout.addWidget(self.btnAdd)
|
||||
self.btnAddClose = QtWidgets.QPushButton(Dialog)
|
||||
self.btnAddClose.setObjectName("btnAddClose")
|
||||
self.horizontalLayout.addWidget(self.btnAddClose)
|
||||
self.btnClose = QtWidgets.QPushButton(Dialog)
|
||||
self.btnClose.setObjectName("btnClose")
|
||||
self.horizontalLayout.addWidget(self.btnClose)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
|
||||
self.retranslateUi(Dialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(Dialog)
|
||||
|
||||
def retranslateUi(self, Dialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
|
||||
self.label.setText(_translate("Dialog", "Title:"))
|
||||
self.btnAdd.setText(_translate("Dialog", "&Add"))
|
||||
self.btnAddClose.setText(_translate("Dialog", "A&dd and close"))
|
||||
self.btnClose.setText(_translate("Dialog", "&Close"))
|
||||
543
app/ui/main_window_ui.py
Normal file
543
app/ui/main_window_ui.py
Normal file
@ -0,0 +1,543 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/main_window.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.4
|
||||
#
|
||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
MainWindow.setObjectName("MainWindow")
|
||||
MainWindow.resize(1164, 857)
|
||||
MainWindow.setStyleSheet("")
|
||||
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName("centralwidget")
|
||||
self.gridLayout_3 = QtWidgets.QGridLayout(self.centralwidget)
|
||||
self.gridLayout_3.setObjectName("gridLayout_3")
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.verticalLayout_3 = QtWidgets.QVBoxLayout()
|
||||
self.verticalLayout_3.setObjectName("verticalLayout_3")
|
||||
self.previous_track_2 = QtWidgets.QLabel(self.centralwidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.previous_track_2.sizePolicy().hasHeightForWidth())
|
||||
self.previous_track_2.setSizePolicy(sizePolicy)
|
||||
self.previous_track_2.setMaximumSize(QtCore.QSize(230, 16777215))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Sans")
|
||||
font.setPointSize(20)
|
||||
self.previous_track_2.setFont(font)
|
||||
self.previous_track_2.setStyleSheet("background-color: #f8d7da;\n"
|
||||
"border: 1px solid rgb(85, 87, 83);")
|
||||
self.previous_track_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.previous_track_2.setObjectName("previous_track_2")
|
||||
self.verticalLayout_3.addWidget(self.previous_track_2)
|
||||
self.current_track_2 = QtWidgets.QLabel(self.centralwidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.current_track_2.sizePolicy().hasHeightForWidth())
|
||||
self.current_track_2.setSizePolicy(sizePolicy)
|
||||
self.current_track_2.setMaximumSize(QtCore.QSize(230, 16777215))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Sans")
|
||||
font.setPointSize(20)
|
||||
self.current_track_2.setFont(font)
|
||||
self.current_track_2.setStyleSheet("background-color: #d4edda;\n"
|
||||
"border: 1px solid rgb(85, 87, 83);")
|
||||
self.current_track_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.current_track_2.setObjectName("current_track_2")
|
||||
self.verticalLayout_3.addWidget(self.current_track_2)
|
||||
self.next_track_2 = QtWidgets.QLabel(self.centralwidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.next_track_2.sizePolicy().hasHeightForWidth())
|
||||
self.next_track_2.setSizePolicy(sizePolicy)
|
||||
self.next_track_2.setMaximumSize(QtCore.QSize(230, 16777215))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Sans")
|
||||
font.setPointSize(20)
|
||||
self.next_track_2.setFont(font)
|
||||
self.next_track_2.setStyleSheet("background-color: #fff3cd;\n"
|
||||
"border: 1px solid rgb(85, 87, 83);")
|
||||
self.next_track_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.next_track_2.setObjectName("next_track_2")
|
||||
self.verticalLayout_3.addWidget(self.next_track_2)
|
||||
self.horizontalLayout_3.addLayout(self.verticalLayout_3)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout()
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.hdrPreviousTrack = QtWidgets.QLabel(self.centralwidget)
|
||||
self.hdrPreviousTrack.setMinimumSize(QtCore.QSize(16, 0))
|
||||
self.hdrPreviousTrack.setMaximumSize(QtCore.QSize(16777215, 16777215))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Sans")
|
||||
font.setPointSize(20)
|
||||
self.hdrPreviousTrack.setFont(font)
|
||||
self.hdrPreviousTrack.setStyleSheet("background-color: #f8d7da;\n"
|
||||
"border: 1px solid rgb(85, 87, 83);")
|
||||
self.hdrPreviousTrack.setText("")
|
||||
self.hdrPreviousTrack.setObjectName("hdrPreviousTrack")
|
||||
self.verticalLayout.addWidget(self.hdrPreviousTrack)
|
||||
self.hdrCurrentTrack = QtWidgets.QLabel(self.centralwidget)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Sans")
|
||||
font.setPointSize(20)
|
||||
self.hdrCurrentTrack.setFont(font)
|
||||
self.hdrCurrentTrack.setStyleSheet("background-color: #d4edda;\n"
|
||||
"border: 1px solid rgb(85, 87, 83);")
|
||||
self.hdrCurrentTrack.setText("")
|
||||
self.hdrCurrentTrack.setObjectName("hdrCurrentTrack")
|
||||
self.verticalLayout.addWidget(self.hdrCurrentTrack)
|
||||
self.hdrNextTrack = QtWidgets.QLabel(self.centralwidget)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Sans")
|
||||
font.setPointSize(20)
|
||||
self.hdrNextTrack.setFont(font)
|
||||
self.hdrNextTrack.setStyleSheet("background-color: #fff3cd;\n"
|
||||
"border: 1px solid rgb(85, 87, 83);")
|
||||
self.hdrNextTrack.setText("")
|
||||
self.hdrNextTrack.setObjectName("hdrNextTrack")
|
||||
self.verticalLayout.addWidget(self.hdrNextTrack)
|
||||
self.horizontalLayout_3.addLayout(self.verticalLayout)
|
||||
self.frame_2 = QtWidgets.QFrame(self.centralwidget)
|
||||
self.frame_2.setMaximumSize(QtCore.QSize(230, 16777215))
|
||||
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||
self.frame_2.setObjectName("frame_2")
|
||||
self.gridLayout_2 = QtWidgets.QGridLayout(self.frame_2)
|
||||
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||
self.lblTOD = QtWidgets.QLabel(self.frame_2)
|
||||
self.lblTOD.setMinimumSize(QtCore.QSize(208, 109))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(35)
|
||||
self.lblTOD.setFont(font)
|
||||
self.lblTOD.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.lblTOD.setObjectName("lblTOD")
|
||||
self.gridLayout_2.addWidget(self.lblTOD, 0, 0, 1, 1)
|
||||
self.horizontalLayout_3.addWidget(self.frame_2)
|
||||
self.gridLayout_3.addLayout(self.horizontalLayout_3, 0, 0, 1, 1)
|
||||
self.frame_5 = QtWidgets.QFrame(self.centralwidget)
|
||||
self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||
self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||
self.frame_5.setObjectName("frame_5")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame_5)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.btnPlay = QtWidgets.QPushButton(self.frame_5)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/icons/play"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.btnPlay.setIcon(icon)
|
||||
self.btnPlay.setIconSize(QtCore.QSize(30, 30))
|
||||
self.btnPlay.setObjectName("btnPlay")
|
||||
self.horizontalLayout.addWidget(self.btnPlay)
|
||||
spacerItem = QtWidgets.QSpacerItem(68, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem)
|
||||
self.btnSongInfo = QtWidgets.QPushButton(self.frame_5)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/icons/wikipedia"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.btnSongInfo.setIcon(icon1)
|
||||
self.btnSongInfo.setIconSize(QtCore.QSize(30, 30))
|
||||
self.btnSongInfo.setObjectName("btnSongInfo")
|
||||
self.horizontalLayout.addWidget(self.btnSongInfo)
|
||||
spacerItem1 = QtWidgets.QSpacerItem(70, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem1)
|
||||
self.btnDatabase = QtWidgets.QPushButton(self.frame_5)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/icons/search_db"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.btnDatabase.setIcon(icon2)
|
||||
self.btnDatabase.setIconSize(QtCore.QSize(30, 30))
|
||||
self.btnDatabase.setObjectName("btnDatabase")
|
||||
self.horizontalLayout.addWidget(self.btnDatabase)
|
||||
self.btnAddFile = QtWidgets.QPushButton(self.frame_5)
|
||||
icon3 = QtGui.QIcon()
|
||||
icon3.addPixmap(QtGui.QPixmap(":/icons/open_file"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.btnAddFile.setIcon(icon3)
|
||||
self.btnAddFile.setIconSize(QtCore.QSize(30, 30))
|
||||
self.btnAddFile.setObjectName("btnAddFile")
|
||||
self.horizontalLayout.addWidget(self.btnAddFile)
|
||||
spacerItem2 = QtWidgets.QSpacerItem(68, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem2)
|
||||
self.btnAddNote = QtWidgets.QPushButton(self.frame_5)
|
||||
icon4 = QtGui.QIcon()
|
||||
icon4.addPixmap(QtGui.QPixmap(":/icons/note"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.btnAddNote.setIcon(icon4)
|
||||
self.btnAddNote.setIconSize(QtCore.QSize(30, 30))
|
||||
self.btnAddNote.setObjectName("btnAddNote")
|
||||
self.horizontalLayout.addWidget(self.btnAddNote)
|
||||
self.btnSetNext = QtWidgets.QPushButton(self.frame_5)
|
||||
icon5 = QtGui.QIcon()
|
||||
icon5.addPixmap(QtGui.QPixmap(":/icons/set_next"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.btnSetNext.setIcon(icon5)
|
||||
self.btnSetNext.setIconSize(QtCore.QSize(30, 30))
|
||||
self.btnSetNext.setObjectName("btnSetNext")
|
||||
self.horizontalLayout.addWidget(self.btnSetNext)
|
||||
spacerItem3 = QtWidgets.QSpacerItem(69, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem3)
|
||||
self.btnFade = QtWidgets.QPushButton(self.frame_5)
|
||||
icon6 = QtGui.QIcon()
|
||||
icon6.addPixmap(QtGui.QPixmap(":/icons/fade"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.btnFade.setIcon(icon6)
|
||||
self.btnFade.setIconSize(QtCore.QSize(30, 30))
|
||||
self.btnFade.setObjectName("btnFade")
|
||||
self.horizontalLayout.addWidget(self.btnFade)
|
||||
self.btnStop = QtWidgets.QPushButton(self.frame_5)
|
||||
icon7 = QtGui.QIcon()
|
||||
icon7.addPixmap(QtGui.QPixmap(":/icons/stopsign"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.btnStop.setIcon(icon7)
|
||||
self.btnStop.setIconSize(QtCore.QSize(30, 30))
|
||||
self.btnStop.setObjectName("btnStop")
|
||||
self.horizontalLayout.addWidget(self.btnStop)
|
||||
self.spnVolume = QtWidgets.QSpinBox(self.frame_5)
|
||||
self.spnVolume.setMaximum(100)
|
||||
self.spnVolume.setProperty("value", 100)
|
||||
self.spnVolume.setObjectName("spnVolume")
|
||||
self.horizontalLayout.addWidget(self.spnVolume)
|
||||
self.gridLayout_3.addWidget(self.frame_5, 1, 0, 1, 1)
|
||||
self.tabPlaylist = QtWidgets.QTabWidget(self.centralwidget)
|
||||
self.tabPlaylist.setDocumentMode(False)
|
||||
self.tabPlaylist.setTabsClosable(False)
|
||||
self.tabPlaylist.setMovable(True)
|
||||
self.tabPlaylist.setObjectName("tabPlaylist")
|
||||
self.gridLayout_3.addWidget(self.tabPlaylist, 2, 0, 1, 1)
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.frame = QtWidgets.QFrame(self.centralwidget)
|
||||
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||
self.frame.setObjectName("frame")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.frame)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.label_2 = QtWidgets.QLabel(self.frame)
|
||||
self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1)
|
||||
self.label_start_tod = QtWidgets.QLabel(self.frame)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("FreeSans")
|
||||
font.setPointSize(16)
|
||||
self.label_start_tod.setFont(font)
|
||||
self.label_start_tod.setScaledContents(False)
|
||||
self.label_start_tod.setObjectName("label_start_tod")
|
||||
self.gridLayout.addWidget(self.label_start_tod, 0, 1, 1, 1)
|
||||
self.label_3 = QtWidgets.QLabel(self.frame)
|
||||
self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
|
||||
self.label_silent_tod = QtWidgets.QLabel(self.frame)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("FreeSans")
|
||||
font.setPointSize(16)
|
||||
self.label_silent_tod.setFont(font)
|
||||
self.label_silent_tod.setScaledContents(False)
|
||||
self.label_silent_tod.setObjectName("label_silent_tod")
|
||||
self.gridLayout.addWidget(self.label_silent_tod, 1, 1, 1, 1)
|
||||
self.label_7 = QtWidgets.QLabel(self.frame)
|
||||
self.label_7.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_7.setObjectName("label_7")
|
||||
self.gridLayout.addWidget(self.label_7, 2, 0, 1, 1)
|
||||
self.label_fade_length = QtWidgets.QLabel(self.frame)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("FreeSans")
|
||||
font.setPointSize(16)
|
||||
self.label_fade_length.setFont(font)
|
||||
self.label_fade_length.setScaledContents(False)
|
||||
self.label_fade_length.setObjectName("label_fade_length")
|
||||
self.gridLayout.addWidget(self.label_fade_length, 2, 1, 1, 1)
|
||||
self.horizontalLayout_2.addWidget(self.frame)
|
||||
self.frame_elapsed = QtWidgets.QFrame(self.centralwidget)
|
||||
self.frame_elapsed.setStyleSheet("")
|
||||
self.frame_elapsed.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||
self.frame_elapsed.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||
self.frame_elapsed.setObjectName("frame_elapsed")
|
||||
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.frame_elapsed)
|
||||
self.verticalLayout_5.setObjectName("verticalLayout_5")
|
||||
self.label = QtWidgets.QLabel(self.frame_elapsed)
|
||||
self.label.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label.setObjectName("label")
|
||||
self.verticalLayout_5.addWidget(self.label)
|
||||
self.label_elapsed_timer = QtWidgets.QLabel(self.frame_elapsed)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("FreeSans")
|
||||
font.setPointSize(40)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
self.label_elapsed_timer.setFont(font)
|
||||
self.label_elapsed_timer.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_elapsed_timer.setObjectName("label_elapsed_timer")
|
||||
self.verticalLayout_5.addWidget(self.label_elapsed_timer)
|
||||
self.horizontalLayout_2.addWidget(self.frame_elapsed)
|
||||
self.frame_fade = QtWidgets.QFrame(self.centralwidget)
|
||||
self.frame_fade.setStyleSheet("")
|
||||
self.frame_fade.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||
self.frame_fade.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||
self.frame_fade.setObjectName("frame_fade")
|
||||
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.frame_fade)
|
||||
self.verticalLayout_6.setObjectName("verticalLayout_6")
|
||||
self.label_4 = QtWidgets.QLabel(self.frame_fade)
|
||||
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.verticalLayout_6.addWidget(self.label_4)
|
||||
self.label_fade_timer = QtWidgets.QLabel(self.frame_fade)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("FreeSans")
|
||||
font.setPointSize(40)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
self.label_fade_timer.setFont(font)
|
||||
self.label_fade_timer.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_fade_timer.setObjectName("label_fade_timer")
|
||||
self.verticalLayout_6.addWidget(self.label_fade_timer)
|
||||
self.horizontalLayout_2.addWidget(self.frame_fade)
|
||||
self.frame_silent = QtWidgets.QFrame(self.centralwidget)
|
||||
self.frame_silent.setStyleSheet("")
|
||||
self.frame_silent.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||
self.frame_silent.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||
self.frame_silent.setObjectName("frame_silent")
|
||||
self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.frame_silent)
|
||||
self.verticalLayout_7.setObjectName("verticalLayout_7")
|
||||
self.label_5 = QtWidgets.QLabel(self.frame_silent)
|
||||
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_5.setObjectName("label_5")
|
||||
self.verticalLayout_7.addWidget(self.label_5)
|
||||
self.label_silent_timer = QtWidgets.QLabel(self.frame_silent)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("FreeSans")
|
||||
font.setPointSize(40)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
self.label_silent_timer.setFont(font)
|
||||
self.label_silent_timer.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_silent_timer.setObjectName("label_silent_timer")
|
||||
self.verticalLayout_7.addWidget(self.label_silent_timer)
|
||||
self.horizontalLayout_2.addWidget(self.frame_silent)
|
||||
self.frame_end = QtWidgets.QFrame(self.centralwidget)
|
||||
self.frame_end.setStyleSheet("")
|
||||
self.frame_end.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||
self.frame_end.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||
self.frame_end.setObjectName("frame_end")
|
||||
self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.frame_end)
|
||||
self.verticalLayout_8.setObjectName("verticalLayout_8")
|
||||
self.label_6 = QtWidgets.QLabel(self.frame_end)
|
||||
self.label_6.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_6.setObjectName("label_6")
|
||||
self.verticalLayout_8.addWidget(self.label_6)
|
||||
self.label_end_timer = QtWidgets.QLabel(self.frame_end)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("FreeSans")
|
||||
font.setPointSize(40)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
self.label_end_timer.setFont(font)
|
||||
self.label_end_timer.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_end_timer.setObjectName("label_end_timer")
|
||||
self.verticalLayout_8.addWidget(self.label_end_timer)
|
||||
self.horizontalLayout_2.addWidget(self.frame_end)
|
||||
self.gridLayout_3.addLayout(self.horizontalLayout_2, 3, 0, 1, 1)
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QtWidgets.QMenuBar(MainWindow)
|
||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 1164, 29))
|
||||
self.menubar.setObjectName("menubar")
|
||||
self.menuFile = QtWidgets.QMenu(self.menubar)
|
||||
self.menuFile.setObjectName("menuFile")
|
||||
self.menuPlaylist = QtWidgets.QMenu(self.menubar)
|
||||
self.menuPlaylist.setObjectName("menuPlaylist")
|
||||
self.menu_Tracks = QtWidgets.QMenu(self.menubar)
|
||||
self.menu_Tracks.setObjectName("menu_Tracks")
|
||||
self.menuTest = QtWidgets.QMenu(self.menubar)
|
||||
self.menuTest.setObjectName("menuTest")
|
||||
MainWindow.setMenuBar(self.menubar)
|
||||
self.statusbar = QtWidgets.QStatusBar(MainWindow)
|
||||
self.statusbar.setEnabled(True)
|
||||
self.statusbar.setStyleSheet("background-color: rgb(211, 215, 207);")
|
||||
self.statusbar.setObjectName("statusbar")
|
||||
MainWindow.setStatusBar(self.statusbar)
|
||||
self.actionPlay_next = QtWidgets.QAction(MainWindow)
|
||||
icon8 = QtGui.QIcon()
|
||||
icon8.addPixmap(QtGui.QPixmap("ui/../../../../.designer/backup/icon-play.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionPlay_next.setIcon(icon8)
|
||||
self.actionPlay_next.setObjectName("actionPlay_next")
|
||||
self.actionSkip_next = QtWidgets.QAction(MainWindow)
|
||||
icon9 = QtGui.QIcon()
|
||||
icon9.addPixmap(QtGui.QPixmap(":/icons/next"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionSkip_next.setIcon(icon9)
|
||||
self.actionSkip_next.setObjectName("actionSkip_next")
|
||||
self.actionSearch_database = QtWidgets.QAction(MainWindow)
|
||||
icon10 = QtGui.QIcon()
|
||||
icon10.addPixmap(QtGui.QPixmap("ui/../../../../.designer/backup/icon_search_database.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionSearch_database.setIcon(icon10)
|
||||
self.actionSearch_database.setObjectName("actionSearch_database")
|
||||
self.actionAdd_file = QtWidgets.QAction(MainWindow)
|
||||
icon11 = QtGui.QIcon()
|
||||
icon11.addPixmap(QtGui.QPixmap("ui/../../../../.designer/backup/icon_open_file.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionAdd_file.setIcon(icon11)
|
||||
self.actionAdd_file.setObjectName("actionAdd_file")
|
||||
self.actionFade = QtWidgets.QAction(MainWindow)
|
||||
icon12 = QtGui.QIcon()
|
||||
icon12.addPixmap(QtGui.QPixmap("ui/../../../../.designer/backup/icon-fade.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionFade.setIcon(icon12)
|
||||
self.actionFade.setObjectName("actionFade")
|
||||
self.actionStop = QtWidgets.QAction(MainWindow)
|
||||
icon13 = QtGui.QIcon()
|
||||
icon13.addPixmap(QtGui.QPixmap(":/icons/stop"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.actionStop.setIcon(icon13)
|
||||
self.actionStop.setObjectName("actionStop")
|
||||
self.action_Clear_selection = QtWidgets.QAction(MainWindow)
|
||||
self.action_Clear_selection.setObjectName("action_Clear_selection")
|
||||
self.action_Resume_previous = QtWidgets.QAction(MainWindow)
|
||||
icon14 = QtGui.QIcon()
|
||||
icon14.addPixmap(QtGui.QPixmap(":/icons/previous"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.action_Resume_previous.setIcon(icon14)
|
||||
self.action_Resume_previous.setObjectName("action_Resume_previous")
|
||||
self.actionE_xit = QtWidgets.QAction(MainWindow)
|
||||
self.actionE_xit.setObjectName("actionE_xit")
|
||||
self.actionTest = QtWidgets.QAction(MainWindow)
|
||||
self.actionTest.setObjectName("actionTest")
|
||||
self.actionOpenPlaylist = QtWidgets.QAction(MainWindow)
|
||||
self.actionOpenPlaylist.setObjectName("actionOpenPlaylist")
|
||||
self.actionNewPlaylist = QtWidgets.QAction(MainWindow)
|
||||
self.actionNewPlaylist.setObjectName("actionNewPlaylist")
|
||||
self.actionTestFunction = QtWidgets.QAction(MainWindow)
|
||||
self.actionTestFunction.setObjectName("actionTestFunction")
|
||||
self.actionSkipToFade = QtWidgets.QAction(MainWindow)
|
||||
self.actionSkipToFade.setObjectName("actionSkipToFade")
|
||||
self.actionSkipToEnd = QtWidgets.QAction(MainWindow)
|
||||
self.actionSkipToEnd.setObjectName("actionSkipToEnd")
|
||||
self.actionClosePlaylist = QtWidgets.QAction(MainWindow)
|
||||
self.actionClosePlaylist.setEnabled(True)
|
||||
self.actionClosePlaylist.setObjectName("actionClosePlaylist")
|
||||
self.actionRenamePlaylist = QtWidgets.QAction(MainWindow)
|
||||
self.actionRenamePlaylist.setEnabled(False)
|
||||
self.actionRenamePlaylist.setObjectName("actionRenamePlaylist")
|
||||
self.actionDeletePlaylist = QtWidgets.QAction(MainWindow)
|
||||
self.actionDeletePlaylist.setEnabled(False)
|
||||
self.actionDeletePlaylist.setObjectName("actionDeletePlaylist")
|
||||
self.actionMoveSelected = QtWidgets.QAction(MainWindow)
|
||||
self.actionMoveSelected.setObjectName("actionMoveSelected")
|
||||
self.actionExport_playlist = QtWidgets.QAction(MainWindow)
|
||||
self.actionExport_playlist.setObjectName("actionExport_playlist")
|
||||
self.actionSetNext = QtWidgets.QAction(MainWindow)
|
||||
self.actionSetNext.setObjectName("actionSetNext")
|
||||
self.actionSelect_next_track = QtWidgets.QAction(MainWindow)
|
||||
self.actionSelect_next_track.setObjectName("actionSelect_next_track")
|
||||
self.actionSelect_previous_track = QtWidgets.QAction(MainWindow)
|
||||
self.actionSelect_previous_track.setObjectName("actionSelect_previous_track")
|
||||
self.actionSelect_played_tracks = QtWidgets.QAction(MainWindow)
|
||||
self.actionSelect_played_tracks.setObjectName("actionSelect_played_tracks")
|
||||
self.actionSelect_unplayed_tracks = QtWidgets.QAction(MainWindow)
|
||||
self.actionSelect_unplayed_tracks.setObjectName("actionSelect_unplayed_tracks")
|
||||
self.menuFile.addAction(self.actionE_xit)
|
||||
self.menuPlaylist.addAction(self.actionNewPlaylist)
|
||||
self.menuPlaylist.addAction(self.actionOpenPlaylist)
|
||||
self.menuPlaylist.addAction(self.actionClosePlaylist)
|
||||
self.menuPlaylist.addAction(self.actionRenamePlaylist)
|
||||
self.menuPlaylist.addAction(self.actionDeletePlaylist)
|
||||
self.menuPlaylist.addSeparator()
|
||||
self.menuPlaylist.addAction(self.actionSearch_database)
|
||||
self.menuPlaylist.addAction(self.actionAdd_file)
|
||||
self.menuPlaylist.addAction(self.action_Clear_selection)
|
||||
self.menuPlaylist.addSeparator()
|
||||
self.menuPlaylist.addAction(self.actionSelect_unplayed_tracks)
|
||||
self.menuPlaylist.addAction(self.actionSelect_played_tracks)
|
||||
self.menuPlaylist.addAction(self.actionMoveSelected)
|
||||
self.menuPlaylist.addSeparator()
|
||||
self.menuPlaylist.addAction(self.actionExport_playlist)
|
||||
self.menuPlaylist.addSeparator()
|
||||
self.menuPlaylist.addAction(self.actionSelect_next_track)
|
||||
self.menuPlaylist.addAction(self.actionSelect_previous_track)
|
||||
self.menu_Tracks.addAction(self.actionPlay_next)
|
||||
self.menu_Tracks.addAction(self.actionSkip_next)
|
||||
self.menu_Tracks.addAction(self.actionFade)
|
||||
self.menu_Tracks.addAction(self.actionStop)
|
||||
self.menu_Tracks.addAction(self.action_Resume_previous)
|
||||
self.menu_Tracks.addSeparator()
|
||||
self.menu_Tracks.addAction(self.actionSetNext)
|
||||
self.menuTest.addAction(self.actionTestFunction)
|
||||
self.menuTest.addSeparator()
|
||||
self.menuTest.addAction(self.actionSkipToFade)
|
||||
self.menuTest.addAction(self.actionSkipToEnd)
|
||||
self.menubar.addAction(self.menuFile.menuAction())
|
||||
self.menubar.addAction(self.menuPlaylist.menuAction())
|
||||
self.menubar.addAction(self.menu_Tracks.menuAction())
|
||||
self.menubar.addAction(self.menuTest.menuAction())
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
self.tabPlaylist.setCurrentIndex(-1)
|
||||
self.actionE_xit.triggered.connect(MainWindow.close)
|
||||
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MainWindow.setWindowTitle(_translate("MainWindow", "Music Muster"))
|
||||
self.previous_track_2.setText(_translate("MainWindow", "Last track:"))
|
||||
self.current_track_2.setText(_translate("MainWindow", "Current track:"))
|
||||
self.next_track_2.setText(_translate("MainWindow", "Next track:"))
|
||||
self.lblTOD.setText(_translate("MainWindow", "00:00:00"))
|
||||
self.btnPlay.setText(_translate("MainWindow", " Play"))
|
||||
self.btnSongInfo.setText(_translate("MainWindow", "Song info"))
|
||||
self.btnDatabase.setText(_translate("MainWindow", "Database"))
|
||||
self.btnAddFile.setText(_translate("MainWindow", "Add file"))
|
||||
self.btnAddNote.setText(_translate("MainWindow", "Add note"))
|
||||
self.btnSetNext.setText(_translate("MainWindow", "Set next"))
|
||||
self.btnFade.setText(_translate("MainWindow", "Fade"))
|
||||
self.btnStop.setText(_translate("MainWindow", "Stop"))
|
||||
self.label_2.setText(_translate("MainWindow", "Started at:"))
|
||||
self.label_start_tod.setText(_translate("MainWindow", "00:00:00"))
|
||||
self.label_3.setText(_translate("MainWindow", "Silent at:"))
|
||||
self.label_silent_tod.setText(_translate("MainWindow", "00:00:00"))
|
||||
self.label_7.setText(_translate("MainWindow", "Fade length:"))
|
||||
self.label_fade_length.setText(_translate("MainWindow", "0:00"))
|
||||
self.label.setText(_translate("MainWindow", "Elapsed time"))
|
||||
self.label_elapsed_timer.setText(_translate("MainWindow", "00:00"))
|
||||
self.label_4.setText(_translate("MainWindow", "Fade"))
|
||||
self.label_fade_timer.setText(_translate("MainWindow", "00:00"))
|
||||
self.label_5.setText(_translate("MainWindow", "Silent"))
|
||||
self.label_silent_timer.setText(_translate("MainWindow", "00:00"))
|
||||
self.label_6.setText(_translate("MainWindow", "End"))
|
||||
self.label_end_timer.setText(_translate("MainWindow", "00:00"))
|
||||
self.menuFile.setTitle(_translate("MainWindow", "Fi&le"))
|
||||
self.menuPlaylist.setTitle(_translate("MainWindow", "Pla&ylist"))
|
||||
self.menu_Tracks.setTitle(_translate("MainWindow", "&Tracks"))
|
||||
self.menuTest.setTitle(_translate("MainWindow", "TestMo&de"))
|
||||
self.actionPlay_next.setText(_translate("MainWindow", "&Play next"))
|
||||
self.actionPlay_next.setShortcut(_translate("MainWindow", "Return"))
|
||||
self.actionSkip_next.setText(_translate("MainWindow", "Skip to &next"))
|
||||
self.actionSkip_next.setShortcut(_translate("MainWindow", "Ctrl+Return"))
|
||||
self.actionSearch_database.setText(_translate("MainWindow", "Search &database"))
|
||||
self.actionSearch_database.setShortcut(_translate("MainWindow", "Ctrl+D"))
|
||||
self.actionAdd_file.setText(_translate("MainWindow", "Add &file"))
|
||||
self.actionAdd_file.setShortcut(_translate("MainWindow", "Ctrl+F"))
|
||||
self.actionFade.setText(_translate("MainWindow", "F&ade"))
|
||||
self.actionFade.setShortcut(_translate("MainWindow", "Ctrl+S"))
|
||||
self.actionStop.setText(_translate("MainWindow", "S&top"))
|
||||
self.action_Clear_selection.setText(_translate("MainWindow", "Clear &selection"))
|
||||
self.action_Clear_selection.setShortcut(_translate("MainWindow", "Esc"))
|
||||
self.action_Resume_previous.setText(_translate("MainWindow", "&Resume previous"))
|
||||
self.actionE_xit.setText(_translate("MainWindow", "E&xit"))
|
||||
self.actionTest.setText(_translate("MainWindow", "&Test"))
|
||||
self.actionOpenPlaylist.setText(_translate("MainWindow", "O&pen..."))
|
||||
self.actionNewPlaylist.setText(_translate("MainWindow", "&New..."))
|
||||
self.actionTestFunction.setText(_translate("MainWindow", "&Test function"))
|
||||
self.actionSkipToFade.setText(_translate("MainWindow", "&Skip to start of fade"))
|
||||
self.actionSkipToEnd.setText(_translate("MainWindow", "Skip to &end of track"))
|
||||
self.actionClosePlaylist.setText(_translate("MainWindow", "&Close"))
|
||||
self.actionRenamePlaylist.setText(_translate("MainWindow", "&Rename..."))
|
||||
self.actionDeletePlaylist.setText(_translate("MainWindow", "Dele&te..."))
|
||||
self.actionMoveSelected.setText(_translate("MainWindow", "Mo&ve selected tracks to..."))
|
||||
self.actionExport_playlist.setText(_translate("MainWindow", "E&xport playlist..."))
|
||||
self.actionSetNext.setText(_translate("MainWindow", "Set &next"))
|
||||
self.actionSetNext.setShortcut(_translate("MainWindow", "Ctrl+N"))
|
||||
self.actionSelect_next_track.setText(_translate("MainWindow", "Select next track"))
|
||||
self.actionSelect_next_track.setShortcut(_translate("MainWindow", "J"))
|
||||
self.actionSelect_previous_track.setText(_translate("MainWindow", "Select previous track"))
|
||||
self.actionSelect_previous_track.setShortcut(_translate("MainWindow", "K"))
|
||||
self.actionSelect_played_tracks.setText(_translate("MainWindow", "Select played tracks"))
|
||||
self.actionSelect_unplayed_tracks.setText(_translate("MainWindow", "Select unplayed tracks"))
|
||||
import icons_rc
|
||||
10
app/ui/playlist_ui.py
Normal file
10
app/ui/playlist_ui.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/playlist.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.4
|
||||
#
|
||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
80
audacity_control.py
Normal file
80
audacity_control.py
Normal file
@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Tests the audacity pipe.
|
||||
Keep pipe_test.py short!!
|
||||
You can make more complicated longer tests to test other functionality
|
||||
or to generate screenshots etc in other scripts.
|
||||
Make sure Audacity is running first and that mod-script-pipe is enabled
|
||||
before running this script.
|
||||
Requires Python 2.7 or later. Python 3 is strongly recommended.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
if sys.platform == 'win32':
|
||||
print("pipe-test.py, running on windows")
|
||||
TONAME = '\\\\.\\pipe\\ToSrvPipe'
|
||||
FROMNAME = '\\\\.\\pipe\\FromSrvPipe'
|
||||
EOL = '\r\n\0'
|
||||
else:
|
||||
print("pipe-test.py, running on linux or mac")
|
||||
TONAME = '/tmp/audacity_script_pipe.to.' + str(os.getuid())
|
||||
FROMNAME = '/tmp/audacity_script_pipe.from.' + str(os.getuid())
|
||||
EOL = '\n'
|
||||
|
||||
print("Write to \"" + TONAME + "\"")
|
||||
if not os.path.exists(TONAME):
|
||||
print(" does not exist. Ensure Audacity is running with mod-script-pipe.")
|
||||
sys.exit()
|
||||
|
||||
print("Read from \"" + FROMNAME + "\"")
|
||||
if not os.path.exists(FROMNAME):
|
||||
print(" does not exist. Ensure Audacity is running with mod-script-pipe.")
|
||||
sys.exit()
|
||||
|
||||
print("-- Both pipes exist. Good.")
|
||||
|
||||
TOFILE = open(TONAME, 'w')
|
||||
print("-- File to write to has been opened")
|
||||
FROMFILE = open(FROMNAME, 'rt')
|
||||
print("-- File to read from has now been opened too\r\n")
|
||||
|
||||
|
||||
def send_command(command):
|
||||
"""Send a single command."""
|
||||
print("Send: >>> \n"+command)
|
||||
TOFILE.write(command + EOL)
|
||||
TOFILE.flush()
|
||||
|
||||
|
||||
def get_response():
|
||||
"""Return the command response."""
|
||||
result = ''
|
||||
line = ''
|
||||
while True:
|
||||
result += line
|
||||
line = FROMFILE.readline()
|
||||
if line == '\n' and len(result) > 0:
|
||||
break
|
||||
return result
|
||||
|
||||
|
||||
def do_command(command):
|
||||
"""Send one command, and return the response."""
|
||||
send_command(command)
|
||||
response = get_response()
|
||||
print("Rcvd: <<< \n" + response)
|
||||
return response
|
||||
|
||||
|
||||
def quick_test():
|
||||
"""Example list of commands."""
|
||||
do_command('Help: Command=Help')
|
||||
do_command('Help: Command="GetInfo"')
|
||||
# do_command('SetPreference: Name=GUI/Theme Value=classic Reload=1')
|
||||
|
||||
|
||||
do_command('Import2: Filename=/home/kae/git/musicmuster/archive/boot.flac')
|
||||
4
run_prod.sh
Executable file
4
run_prod.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
MYSQL_CONNECT="mysql+mysqldb://musicmuster:musicmuster@localhost/musicmuster_prod"
|
||||
ROOT="/home/kae/music"
|
||||
./app/musicmuster.py
|
||||
Loading…
Reference in New Issue
Block a user