Exemple #1
0
 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
Exemple #6
0
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()