def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainForm() self.ui.setupUi(self) self.lastFMHandle = UserLastApi() self.musicLibHandle = MusicLib() self.singletonDownloader = SingletonDownload(self) self.settings = QSettings() self.settings.beginGroup('app') self.lastFMUser = '' self.current_track = {} self.scrollLabelTimer = QTimer() self.scrollLabelTimer.setInterval(50) self.updatePlayNowTimer = QTimer() self.updatePlayNowTimer.setInterval(self.updatePlayNowInterval) self.loadingAnimGif = QMovie(":/animations/loading.gif") self.loadingAnimGif.setScaledSize(QSize(24, 24)) self.startAnimationSignal.connect(self.start_animation) self.stopAnimationSignal.connect(self.stop_animation) self.setStateDownloadButtonSignal.connect(self.setStateDownloadButton) self.setProgressBarValueSignal.connect(self.setProgressBarValue) self.setStatusLabelTextSignal.connect(self.setStatusLabelText) self.setStateAlreadyLabelSignal.connect(self.setStateAlreadyLabel) self.setPlayNowLabelTextSignal.connect(self.setPlayNowLabelText) self.abortAndShowErrorSignal.connect(self.abortAndShowError) self.scrollLabelTimer.timeout.connect(self.on_timer_timeout) self.updatePlayNowTimer.timeout.connect(self.mainthread_wrapper) self.setUpdatePlayNowIntervalSignal.connect(self.setUpdatePlayNowInterval) self.updatePlayNowTimer.timeout.emit() self.updatePlayNowTimer.start() QObject.installEventFilter(self, self)
class SettingsFormMusicLib(QWidget): def __init__(self): QWidget.__init__(self) self.ui = Ui_settingsFormMusicLib() self.ui.setupUi(self) self.musicLibHandle = MusicLib() self.settings = QSettings() self.settings.beginGroup('app/musiclib') if self.settings.contains('saveway'): _currentIndex, ok = self.settings.value('saveway').toInt() self.ui.comboBox.setCurrentIndex(_currentIndex) if self.settings.contains('musiclibpath'): self.ui.musiclibPathEdit.setText(self.settings.value('musiclibpath').toString()) else: pass if self.settings.contains('itunespath'): self.ui.iTunesMediaPathEdit.setText(self.settings.value('itunespath').toString()) else: pass @pyqtSlot(int) def on_comboBox_currentIndexChanged(self, index): self.ui.stackedWidget.setCurrentIndex(index) @pyqtSlot() def on_musiclibPathButton_clicked(self): musiclibPath = QFileDialog.getExistingDirectory(self, u"Укажите папку для сохранения файлов", self.ui.musiclibPathEdit.text(), QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks ) if musiclibPath: self.ui.musiclibPathEdit.setText(musiclibPath) @pyqtSlot() def on_iTunesMediaPathButton_clicked(self): iTunesMediaPath = QFileDialog.getExistingDirectory(self, u'Укажите папку iTunes Media', self.ui.iTunesMediaPathEdit.text(), QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks ) if iTunesMediaPath: if self.musicLibHandle.isItunesFolder(unicode(iTunesMediaPath)): self.ui.iTunesMediaPathEdit.setText(iTunesMediaPath) else: QMessageBox.warning(self, u'Ошибка', u'Папка не является библиотекой iTunes') def hideEvent(self, event): self.settings.setValue('saveway', self.ui.comboBox.currentIndex()) iTunesMediaPath = self.ui.iTunesMediaPathEdit.text() if iTunesMediaPath: self.settings.setValue('itunespath', iTunesMediaPath) musiclibPath = self.ui.musiclibPathEdit.text() if musiclibPath: self.settings.setValue('musiclibpath', musiclibPath)
def __init__(self, creator, *args, **kwargs): QThread.__init__(self) self.creator = creator self.args = args self.kwargs = kwargs self.settings = QSettings() self.settings.beginGroup('app') self.vkHandle = VK() self.musicLibHandle = MusicLib()
def __init__(self): QWidget.__init__(self) self.ui = Ui_settingsFormMusicLib() self.ui.setupUi(self) self.musicLibHandle = MusicLib() self.settings = QSettings() self.settings.beginGroup('app/musiclib') if self.settings.contains('saveway'): _currentIndex, ok = self.settings.value('saveway').toInt() self.ui.comboBox.setCurrentIndex(_currentIndex) if self.settings.contains('musiclibpath'): self.ui.musiclibPathEdit.setText(self.settings.value('musiclibpath').toString()) else: pass if self.settings.contains('itunespath'): self.ui.iTunesMediaPathEdit.setText(self.settings.value('itunespath').toString()) else: pass
class SingletonDownload(QThread): def __new__(cls, creator, *args, **kwargs): if not hasattr(cls, 'instance'): cls.instance = super(SingletonDownload, cls).__new__(cls) cls.instance.__init__(creator, *args, **kwargs) return cls.instance def __init__(self, creator, *args, **kwargs): QThread.__init__(self) self.creator = creator self.args = args self.kwargs = kwargs self.settings = QSettings() self.settings.beginGroup('app') self.vkHandle = VK() self.musicLibHandle = MusicLib() def run(self): try: current_track = self.creator.current_track if not 'artist' in current_track or not 'title' in current_track: return if not self.settings.contains('userVK/cookie'): self.setStatusLabelTextSignal.emit(u'Не авторизован ВКонтакте, проверьте настройки') return self.creator.setProgressBarValueSignal.emit(5) if not self.vkHandle.check_connection(): self.creator.setStatusLabelTextSignal.emit(u'Не удается соединиться с сервером ВКонтакте') return _cookie = self.settings.value('userVK/cookie').toString() self.vkHandle.set_cookie(_cookie) if not self.vkHandle.is_logged(): self.creator.setStatusLabelTextSignal.emit(u'Авторизационные данные ВКонтакте не корректны, проверьте настройки') return self.creator.setProgressBarValueSignal.emit(10) _song = self.vkHandle.search_best(current_track['artist'], current_track['title']) if not _song: self.creator.setStatusLabelTextSignal.emit(u'Трек не найден в базе ВКонтакте') else: recieved_bytes, filetmp_path = self.downloadtemp(_song['url']) if filetmp_path: try: file_tags = Tag(filetmp_path) except ValueError: pass else: file_tags.flush_tags() file_tags.set_tags(**current_track) song_title = u'{0} - {1}.mp3'.format(current_track['artist'], current_track['title']) save_path = self.musicLibHandle.get_path() if not os.path.exists(save_path): os.mkdir(save_path) shutil.move(filetmp_path, self.musicLibHandle.get_path() + '/' + song_title) self.creator.setStatusLabelTextSignal.emit(u'Загрузка файла завершена') else: self.creator.setStatusLabelTextSignal.emit(u'Не удалось загрузить файл') finally: self.creator.setProgressBarValueSignal.emit(0) self.creator.setStateDownloadButtonSignal.emit(True) def downloadfile(self, url, filename, dirname='.', fd=None): chunk_size = 40960 file_path = os.path.join(dirname, filename) file_url = urllib2.urlopen(url) total_size = file_url.info().getheader('Content-Length').strip() total_size = int(total_size) recieved_bytes = 0 if not fd: file_data = open(file_path, 'wb') else: file_data = os.fdopen(fd, 'wb') while True: chunk = file_url.read(chunk_size) if not chunk: if total_size == recieved_bytes: file_data.close() return recieved_bytes, file_path return None file_data.write(chunk) recieved_bytes += len(chunk) percent = (float(recieved_bytes) / float(total_size) * 90) + 10 self.creator.setProgressBarValueSignal.emit(percent) def downloadtemp(self, url): audio_file_fd, audio_file_path = mkstemp(prefix='vkaudio', suffix='.mp3') audio_file_dir = os.path.dirname(audio_file_path) audio_file_name = os.path.basename(audio_file_path) recieved_bytes, file_path = self.downloadfile(url, audio_file_name, dirname=audio_file_dir, fd=audio_file_fd) if recieved_bytes and file_path: return recieved_bytes, file_path return None
class MainWindowForm(QMainWindow): startAnimationSignal = pyqtSignal() stopAnimationSignal = pyqtSignal() setStateDownloadButtonSignal = pyqtSignal(bool) setStateAlreadyLabelSignal = pyqtSignal(bool) setProgressBarValueSignal = pyqtSignal(int) setStatusLabelTextSignal = pyqtSignal(unicode) setPlayNowLabelTextSignal = pyqtSignal(unicode) abortAndShowErrorSignal = pyqtSignal(unicode) setUpdatePlayNowIntervalSignal = pyqtSignal(int) updatePlayNowInterval = 15000 def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainForm() self.ui.setupUi(self) self.lastFMHandle = UserLastApi() self.musicLibHandle = MusicLib() self.singletonDownloader = SingletonDownload(self) self.settings = QSettings() self.settings.beginGroup('app') self.lastFMUser = '' self.current_track = {} self.scrollLabelTimer = QTimer() self.scrollLabelTimer.setInterval(50) self.updatePlayNowTimer = QTimer() self.updatePlayNowTimer.setInterval(self.updatePlayNowInterval) self.loadingAnimGif = QMovie(":/animations/loading.gif") self.loadingAnimGif.setScaledSize(QSize(24, 24)) self.startAnimationSignal.connect(self.start_animation) self.stopAnimationSignal.connect(self.stop_animation) self.setStateDownloadButtonSignal.connect(self.setStateDownloadButton) self.setProgressBarValueSignal.connect(self.setProgressBarValue) self.setStatusLabelTextSignal.connect(self.setStatusLabelText) self.setStateAlreadyLabelSignal.connect(self.setStateAlreadyLabel) self.setPlayNowLabelTextSignal.connect(self.setPlayNowLabelText) self.abortAndShowErrorSignal.connect(self.abortAndShowError) self.scrollLabelTimer.timeout.connect(self.on_timer_timeout) self.updatePlayNowTimer.timeout.connect(self.mainthread_wrapper) self.setUpdatePlayNowIntervalSignal.connect(self.setUpdatePlayNowInterval) self.updatePlayNowTimer.timeout.emit() self.updatePlayNowTimer.start() QObject.installEventFilter(self, self) @pyqtSlot() def mainthread_wrapper(self): self.thread = GenericThread(self.thread_func) self.thread.start() def thread_func(self): self.startAnimationSignal.emit() self.setStatusLabelTextSignal.emit(u' ') self.setStateAlreadyLabelSignal.emit(False) self.current_track = {} self.setStateDownloadButtonSignal.emit(False) self.check_current_lastfm_track() def check_current_lastfm_track(self): if not self.settings.contains('userLastFM/sessionkey'): self.abortAndShowErrorSignal.emit(u'Не авторизован в Last.FM, проверьте настройки') return try: if not self.lastFMUser: session_key = unicode(self.settings.value('userLastFM/sessionkey').toString()) self.lastFMUser = self.lastFMHandle.auth(session_key) except LastApiWSError: self.abortAndShowErrorSignal.emit(u'Не удалось авторизоваться в Last.FM') return except LastApiNetworkError: self.abortAndShowErrorSignal.emit(u'Не удалось установить соединение с сервером') return _current_track = self.lastFMHandle.get_playnow() #print _current_track if _current_track: self.current_track = _current_track song_title = self.current_track['artist'] + ' - ' + self.current_track['title'] self.stopAnimationSignal.emit() self.setPlayNowLabelTextSignal.emit(song_title) self.setUpdatePlayNowIntervalSignal.emit(self.updatePlayNowInterval) if self.musicLibHandle.isTrackExists(self.current_track['artist'], self.current_track['title']): self.setStateAlreadyLabelSignal.emit(True) else: self.setStateDownloadButtonSignal.emit(True) else: self.setUpdatePlayNowIntervalSignal.emit(self.updatePlayNowInterval / 4) self.stopAnimationSignal.emit() self.setStatusLabelTextSignal.emit(u'В данный момент нет проигрываемых треков') @pyqtSlot(unicode) def abortAndShowError(self, text): self.stopAnimationSignal.emit() self.current_track = {} self.setStatusLabelTextSignal.emit(text) @pyqtSlot() def start_animation(self): self.resetScrollArea() self.ui.playNowLabel.setMovie(self.loadingAnimGif) self.loadingAnimGif.start() @pyqtSlot() def stop_animation(self): self.loadingAnimGif.stop() self.loadingAnimGif.jumpToFrame(0) self.setPlayNowLabelTextSignal.emit(u' ') @pyqtSlot(unicode) def setPlayNowLabelText(self, text): self.ui.playNowLabel.setText(text) _font = self.ui.playNowLabel.font() _fm = QFontMetrics(_font) _str_width = _fm.width(self.ui.playNowLabel.text()) scrollAreaWidth = self.ui.scrollArea.width() if _str_width > scrollAreaWidth: self.startScrollArea(_str_width + 10) @pyqtSlot(unicode) def setStatusLabelText(self, text): self.ui.statusLabel.setText(text) @pyqtSlot(int) def setProgressBarValue(self, num): self.ui.downloadProgressBar.setValue(num) @pyqtSlot(bool) def setStateDownloadButton(self, state): self.ui.downloadButton.setEnabled(state) @pyqtSlot(bool) def setStateAlreadyLabel(self, state): if state: pixmap = QPixmap(':/icons/label/ok.png') self.ui.alreadyLabel.setPixmap(pixmap.scaled(24, 24)) self.ui.alreadyLabel.setToolTip(u'Трек уже есть в музыкальной библиотеке') else: pixmap = QPixmap(':/icons/label/ok_off.png') self.ui.alreadyLabel.setPixmap(pixmap.scaled(24, 24)) @pyqtSlot() def on_settingsButton_clicked(self): self.settingsForm = SettingsFormMain() self.settingsForm.show() @pyqtSlot() def on_actionPreferences_triggered(self): self.on_settingsButton_clicked() @pyqtSlot() def on_downloadButton_clicked(self): self.setStateDownloadButtonSignal.emit(False) self.singletonDownloader.start() @pyqtSlot() def on_exitButton_clicked(self): confirm_exit = QMessageBox.question(self, u'Подтверждение завершения LastVK', u"Вы действительно хотите завершить приложение LastVK?", QMessageBox.Ok | QMessageBox.Cancel ) if confirm_exit == QMessageBox.Ok: qApp.quit() @pyqtSlot() def on_timer_timeout(self): _value = self.ui.scrollArea.horizontalScrollBar().value() if _value >= self.__maxscroll: _value = -self.__scrollWidth self.ui.scrollArea.horizontalScrollBar().setValue(_value + 3) @pyqtSlot(int) def setUpdatePlayNowInterval(self, interval): self.updatePlayNowTimer.setInterval(interval) def resetScrollArea(self): self.scrollLabelTimer.stop() _scrollWidth = self.ui.scrollArea.width() self.ui.playNowLabel.setFixedWidth(_scrollWidth) self.ui.playNowLabel.setAlignment(Qt.AlignHCenter) self.ui.scrollArea.horizontalScrollBar().setValue(0) def startScrollArea(self, width): self.__scrollWidth = self.ui.scrollArea.width() self.__maxscroll = width self.ui.playNowLabel.setFixedWidth(width) self.ui.scrollArea.horizontalScrollBar().setMinimum(-self.__scrollWidth) self.ui.scrollArea.horizontalScrollBar().setMaximum(width) self.scrollLabelTimer.start() def eventFilter(self, obj, event): if event.type() == QEvent.WindowDeactivate: if QApplication.focusWidget() == self: self.close() return True else: return QObject.eventFilter(self, obj, event) def closeEvent(self, event): self.updatePlayNowTimer.stop() self.scrollLabelTimer.stop()