# # Copyright (C) 2008 jerous # Copyright (C) 2009 Anton Khirnov # # Nephilim is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Nephilim is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Nephilim. If not, see . # from PyQt5 import QtCore, QtWidgets, QtGui import socket import logging import os import re from html.entities import name2codepoint as n2cp socket.setdefaulttimeout(8) appIcon = ':icons/nephilim_small.png' APPNAME = 'nephilim' ORGNAME = 'nephilim' # custom mimetypes used for drag&drop MIMETYPES = {'songs' : 'application/x-mpd-songlist', 'plistsongs' : 'application/x-mpd-playlistsonglist'} def sec2min(secs): """Converts seconds to min:sec.""" min=int(secs/60) sec=secs%60 if sec<10:sec='0'+str(sec) return str(min)+':'+str(sec) class Button(QtWidgets.QPushButton): iconSize=32 """A simple Button class which calls $onClick when clicked.""" def __init__(self, caption, onClick=None, iconPath=None, iconOnly=False, parent=None): QtWidgets.QPushButton.__init__(self, parent) if onClick: self.clicked.connect(onClick) if iconPath: self.changeIcon(iconPath) if not(iconPath and iconOnly): QtWidgets.QPushButton.setText(self, caption) self.setToolTip(caption) def setText(self, caption): self.setToolTip(caption) if self.icon()==None: self.setText(caption) def changeIcon(self, iconPath): icon=QtGui.QIcon() icon.addFile(iconPath, QtCore.QSize(self.iconSize, self.iconSize)) self.setIcon(icon) def expand_tags(string, expanders): for expander in expanders: string = expander.expand_tags(string) #remove unexpanded tags return re.sub('\$\{.*\}', '', string) def generate_metadata_path(song, dir_tag, file_tag): """Generate dirname and (db files only) full file path for reading/writing metadata files (cover, lyrics) from $tags in dir/filename.""" if QtCore.QDir.isAbsolutePath(song['file']): dirname = os.path.dirname(song['file']) filepath = '' elif '://' in song['file']: # we are streaming dirname = '' filepath = '' else: dirname = expand_tags(dir_tag, (QtWidgets.QApplication.instance(), song)) filepath = '%s/%s'%(dirname, expand_tags(file_tag, (QtWidgets.QApplication.instance(), song)).replace('/', '_')) return dirname, filepath def substitute_entity(match): ent = match.group(3) if match.group(1) == "#": if match.group(2) == '': return unichr(int(ent)) elif match.group(2) == 'x': return unichr(int('0x'+ent, 16)) else: cp = n2cp.get(ent) if cp: return unichr(cp) else: return match.group() def decode_htmlentities(string): entity_re = re.compile(r'&(#?)(x?)(\w+);') return entity_re.subn(substitute_entity, string)[0] class SongsMimeData(QtCore.QMimeData): # private __songs = None __plistsongs = None def set_songs(self, songs): self.__songs = songs def songs(self): return self.__songs def set_plistsongs(self, songs): self.__plistsongs = songs def plistsongs(self): return self.__plistsongs def formats(self): types = QtCore.QMimeData.formats(self) if self.__songs: types += MIMETYPES['songs'] if self.__plistsongs: types += MIMETYPES['plistsongs'] return types def hasFormat(self, format): if format == MIMETYPES['songs'] and self.__songs: return True elif format == MIMETYPES['plistsongs'] and self.__plistsongs: return True return QtCore.QMimeData.hasFormat(self, format)