Beispiel #1
0
    def __init__(self, bbclient, config, parent=None):
        super(HistoryWidget, self).__init__(parent)

        self.bbclient = bbclient
        self.config = config

        self.track_list = []

        self.list = QListWidget(self)
        self.list.setUniformItemSizes(True)
        self.list.setSelectionMode(QListWidget.ExtendedSelection)

        self.list.currentRowChanged.connect(self._onRowChanged)


        self.delete_btn = QPushButton(QIcon(resource_path('img/delete.png')), '', self)
        self.save_btn = QPushButton(QIcon(resource_path('img/save.png')), '', self)
        self.upload_btn = QPushButton(QIcon(resource_path('img/upload.png')), '', self)

        for i, w in enumerate((self.delete_btn, self.save_btn, self.upload_btn)):
            w.setIconSize(QSize(22, 22))

            if i < 1:
                w.setMinimumSize(32, 32)
                w.setMaximumSize(32, 32)
            else:
                w.setMinimumSize(58, 32)
                w.setMaximumSize(58, 32)

        save_menu = QMenu('Export tracks', self)
        act = save_menu.addAction('Save as TCX')
        act.triggered.connect(self._onSaveAsTCX)
        act = save_menu.addAction('Save as BDX (Bryton GPX extension)')
        act.triggered.connect(self._onSaveAsBDX)

        self.save_btn.setMenu(save_menu)


        upload_menu = QMenu('Upload tracks', self)
        act = upload_menu.addAction(QIcon(resource_path('img/strava-icon.png')), 'Upload to Strava.com')
        act.triggered.connect(self._onUploadStrava)
        act = upload_menu.addAction(QIcon(resource_path('img/bryton-icon.png')), 'Upload to Brytonsport.com')
        act.triggered.connect(self._onUploadBrytonSport)


        self.upload_btn.setMenu(upload_menu)


        self.delete_btn.clicked.connect(self._onDeleteTracks)


        self._createLayout()


        self.message_overlay = MessageWidget(self)
        self.message_overlay.setLoading('Loading tracklist')


        bbclient.refreshingTrackList.connect(self.message_overlay.show)
Beispiel #2
0
    def __init__(self, config, parent=None):
        super(MainWindow, self).__init__(parent)

        self.bbclient = BrytonClient(parent=self,
                server_host=config.get('server_host'))

        self.history_list_widget = HistoryWidget(self.bbclient, config, self)
        self.device_info_widget = DeviceInfoWidget(self)
        self.track_summary_widget = TrackSummaryWidget(self)


        self.track_tabs = QTabWidget(self)

        self.track_tabs.setMaximumWidth(200)

        self.track_tabs.addTab(self.history_list_widget, 'History')


        self.history_list_widget.currentTrackChanged.connect(self._onHistoryTrackChanged)


        self.bb_version = QLabel('', self)
        self.bb_version.setAlignment(Qt.AlignRight)
        self.bb_version.setContentsMargins(0, 0, 3, 0)

        self._createLayout()

        self.message_overlay = MessageWidget(self)
        self.message_overlay.setLoading('Connecting to BrytonBridge')

        self.message_overlay.retryClicked.connect(self._onRetry)



        self.bbclient.statusMessage.connect(self.message_overlay.setLoading)

        self.bbclient.connected.connect(self._onConnected)
        self.bbclient.deviceOffline.connect(self._onDeviceOffline)
        self.bbclient.deviceReady.connect(self._onDeviceReady)
        self.bbclient.trackListReady.connect(self._onTrackListReady)
        self.bbclient.error.connect(self._onError)
        self.bbclient.BBVersion.connect(self._onBBVersion)
        self.bbclient.start()
Beispiel #3
0
class MainWindow(QWidget):


    def __init__(self, config, parent=None):
        super(MainWindow, self).__init__(parent)

        self.bbclient = BrytonClient(parent=self,
                server_host=config.get('server_host'))

        self.history_list_widget = HistoryWidget(self.bbclient, config, self)
        self.device_info_widget = DeviceInfoWidget(self)
        self.track_summary_widget = TrackSummaryWidget(self)


        self.track_tabs = QTabWidget(self)

        self.track_tabs.setMaximumWidth(200)

        self.track_tabs.addTab(self.history_list_widget, 'History')


        self.history_list_widget.currentTrackChanged.connect(self._onHistoryTrackChanged)


        self.bb_version = QLabel('', self)
        self.bb_version.setAlignment(Qt.AlignRight)
        self.bb_version.setContentsMargins(0, 0, 3, 0)

        self._createLayout()

        self.message_overlay = MessageWidget(self)
        self.message_overlay.setLoading('Connecting to BrytonBridge')

        self.message_overlay.retryClicked.connect(self._onRetry)



        self.bbclient.statusMessage.connect(self.message_overlay.setLoading)

        self.bbclient.connected.connect(self._onConnected)
        self.bbclient.deviceOffline.connect(self._onDeviceOffline)
        self.bbclient.deviceReady.connect(self._onDeviceReady)
        self.bbclient.trackListReady.connect(self._onTrackListReady)
        self.bbclient.error.connect(self._onError)
        self.bbclient.BBVersion.connect(self._onBBVersion)
        self.bbclient.start()

        # self.message_overlay.hide()


    def _onConnected(self):
        self.message_overlay.setMessage('Searching for device')

    def _onDeviceReady(self):
        self.device_info_widget.setDeviceInfo(self.bbclient.dev_state)
        self.message_overlay.hide()

    def _onDeviceOffline(self):
        self.message_overlay.setDisconnected('Please connect your device')
        self.message_overlay.show()

    def _onError(self, msg):
        self.message_overlay.setError(msg)
        self.message_overlay.retry.show()
        self.message_overlay.show()

    def _onRetry(self):
        self.message_overlay.retry.hide()
        self.bbclient.reset()
        self.bbclient.start()

    def _onBBVersion(self, version):
        if version in TESTED_VERSIONS:
            self.bb_version.hide()
            self.bb_version.setText('BrytonBridge version <font color="green">{}</font>'.format(version))
        else:
            self.bb_version.show()
            self.bb_version.setText('BrytonBridge version <font color="red"><b>{}</b></font>'.format(version))
            self.bb_version.setToolTip('You are using an untested version of BrytonBridge')


    def _onTrackListReady(self):
        self.tracks = tracks = self.bbclient.track_list

        self.history_list_widget.setTrackList(tracks, self.bbclient.dev_state)

    def _onHistoryTrackChanged(self, track):

        self.track_summary_widget.setTrack(track)


    def resizeEvent(self, event):

        self.message_overlay.resize(event.size())

        super(MainWindow, self).resizeEvent(event)

    def _createLayout(self):

        la = QVBoxLayout()


        la.addWidget(self.bb_version)


        l = QHBoxLayout()

        l.addWidget(self.track_tabs, 0)

        v = QVBoxLayout()


        group = QGroupBox('Device', self)
        l2 = QHBoxLayout()
        l2.addWidget(self.device_info_widget)
        group.setLayout(l2)


        v.addWidget(group)


        group = QGroupBox('Track Summary', self)
        l2 = QHBoxLayout()
        l2.addWidget(self.track_summary_widget)
        group.setLayout(l2)


        v.addWidget(group, 1)


        l.addLayout(v, 1)


        la.addLayout(l)

        self.setLayout(la)
Beispiel #4
0
class HistoryWidget(QWidget):

    currentTrackChanged = pyqtSignal(dict)

    def __init__(self, bbclient, config, parent=None):
        super(HistoryWidget, self).__init__(parent)

        self.bbclient = bbclient
        self.config = config

        self.track_list = []

        self.list = QListWidget(self)
        self.list.setUniformItemSizes(True)
        self.list.setSelectionMode(QListWidget.ExtendedSelection)

        self.list.currentRowChanged.connect(self._onRowChanged)


        self.delete_btn = QPushButton(QIcon(resource_path('img/delete.png')), '', self)
        self.save_btn = QPushButton(QIcon(resource_path('img/save.png')), '', self)
        self.upload_btn = QPushButton(QIcon(resource_path('img/upload.png')), '', self)

        for i, w in enumerate((self.delete_btn, self.save_btn, self.upload_btn)):
            w.setIconSize(QSize(22, 22))

            if i < 1:
                w.setMinimumSize(32, 32)
                w.setMaximumSize(32, 32)
            else:
                w.setMinimumSize(58, 32)
                w.setMaximumSize(58, 32)

        save_menu = QMenu('Export tracks', self)
        act = save_menu.addAction('Save as TCX')
        act.triggered.connect(self._onSaveAsTCX)
        act = save_menu.addAction('Save as BDX (Bryton GPX extension)')
        act.triggered.connect(self._onSaveAsBDX)

        self.save_btn.setMenu(save_menu)


        upload_menu = QMenu('Upload tracks', self)
        act = upload_menu.addAction(QIcon(resource_path('img/strava-icon.png')), 'Upload to Strava.com')
        act.triggered.connect(self._onUploadStrava)
        act = upload_menu.addAction(QIcon(resource_path('img/bryton-icon.png')), 'Upload to Brytonsport.com')
        act.triggered.connect(self._onUploadBrytonSport)


        self.upload_btn.setMenu(upload_menu)


        self.delete_btn.clicked.connect(self._onDeleteTracks)


        self._createLayout()


        self.message_overlay = MessageWidget(self)
        self.message_overlay.setLoading('Loading tracklist')


        bbclient.refreshingTrackList.connect(self.message_overlay.show)


    def setTrackList(self, track_list, device_info):

        self.list.clear()
        self.device_info = device_info
        self.track_list = track_list

        for track in track_list:

            item = QListWidgetItem(track['name'])
            item.setData(TRACK_ITEM_ROLE, track['id'])
            self.list.addItem(item)

        self.message_overlay.hide()


    def resizeEvent(self, event):

        self.message_overlay.resize(event.size())

        super(HistoryWidget, self).resizeEvent(event)


    def _onDeleteTracks(self):

        tracks = self._getSelectedTracks()

        if not tracks:
            tracks = self.track_list


        ids = map(lambda t: t['id'], tracks)
        names = map(lambda t: t['name'], tracks)

        msg = 'Are you sure you want to delete the following {} track(s):'.format(len(tracks))

        msg += '\n' + '\n'.join(names)


        res = QMessageBox.question(self, 'Delete tracks?',
                msg,
                QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Cancel)

        print res

        if res == QMessageBox.Ok:
            print ids
            # self.bbclient._refreshTrackList()

            d = ProgressDialog('Finalizing', "Don't close this window\n(It may stall for a little while on 93%)", self)
            d.progress.setRange(0, 100)
            d.resize(250, 80)

            self.bbclient.finalizingProgress.connect(d.progress.setValue)
            self.bbclient.tracksDeleted.connect(d.accept)

            def _onFail():

                QMessageBox.warning(self, 'Delete failed')
                d.accept()

            self.bbclient.deleteFailed.connect(_onFail)

            self.bbclient.deleteTracks(ids)
            d.exec_()



    def _onUploadStrava(self):


        tracks = self._getSelectedTracks()

        if not tracks:
            tracks = self.track_list

        strava.upload_to_strava(tracks, self.device_info, self,
                auth_token=self.config.get('strava_auth_token'),
                password=self.config.get('strava_password'),
                username=self.config.get('strava_email'))


    def _onUploadBrytonSport(self):

        brytonsport.upload_to_brytonsport(self.bbclient, self,
                username=self.config.get('bryton_email'),
                password=self.config.get('bryton_password'),
                session_id=self.config.get('bryton_session_id'))

    def _onSaveAsTCX(self):

        tracks = self._getSelectedTracks()

        if not tracks:
            tracks = self.track_list
            # QMessageBox.information(self, 'No tracks selected', 'You need to select the tracks you want to save.')

        if not tracks:
            return

        if len(tracks) == 1:
            name = QFileDialog.getSaveFileName(self,
                'Save file %s' % tracks[0]['name'],
                self._trackFilename(tracks[0]['name'], 'tcx'),
                filter='TCX (*.tcx)')

            if name:

                self._saveContent(name, tcx.bryton_gpx_to_tcx(tracks[0]['gpx'], pretty=True, device=self.device_info))

        else:
            dir = QFileDialog.getExistingDirectory(self,
                'Open Directory', '', QFileDialog.ShowDirsOnly)

            if not dir:
                return
            for t in tracks:
                name = path.join(str(dir), self._trackFilename(t['name'], 'tcx'))
                self._saveContent(name, tcx.bryton_gpx_to_tcx(t['gpx'], pretty=True, device=self.device_info))




    def _onSaveAsBDX(self):
        tracks = self._getSelectedTracks()

        if not tracks:
            tracks = self.track_list

        if not tracks:
            return

        if len(tracks) == 1:
            name = QFileDialog.getSaveFileName(self,
                'Save file %s' % tracks[0]['name'],
                self._trackFilename(tracks[0]['name'], 'bdx'),
                filter='BDX (*.bdx)')

            if name:

                self._saveContent(name, tracks[0]['gpx'].toString(pretty=True))

        else:
            dir = QFileDialog.getExistingDirectory(self,
                'Open Directory', '', QFileDialog.ShowDirsOnly)

            if not dir:
                return
            for t in tracks:
                name = path.join(str(dir), self._trackFilename(t['name'], 'gpx'))
                self._saveContent(name, t['gpx'].toString(pretty=True))

    def _saveContent(self, filename, content):

        with open(filename, 'w') as f:
            f.write(content)


    def _trackFilename(self, name, ext):

        return name.replace('/', '').replace(' ', '-').replace(':', '') + '.' + ext



    def _getSelectedTracks(self):

        items = self.list.selectedItems()

        tracks = []

        for item in items:

            index = self.list.row(item)

            tracks.append(self.track_list[index])

        return tracks


    def _onRowChanged(self, row):

        track = self.track_list[row]

        self.currentTrackChanged.emit(track)


    def _createLayout(self):

        l = QVBoxLayout()

        l.addWidget(self.list)


        h = QHBoxLayout()

        h.addWidget(self.delete_btn)
        h.addStretch()
        h.addWidget(self.save_btn)
        h.addWidget(self.upload_btn)

        l.addLayout(h)

        self.setLayout(l)