Пример #1
0
 def _showWebMenu(self, pos):
     """显示网页右键菜单
     :param pos:            点击位置
     """
     hit = self.webViewContent.page().currentFrame().hitTestContent(pos)
     url = hit.linkUrl()
     if url.isValid():
         path = url.toLocalFile().strip().replace('\\', '/')
         names = path.split('Markdown/')
         if len(names) == 1:
             return
         path = os.path.abspath(os.path.join(
             Constants.DirCurrent, names[1]))
         AppLog.debug('path: {}'.format(path))
         AppLog.debug('isdir: {}'.format(os.path.isdir(path)))
         self._webviewactRun.setData(path)
         self._webviewactView.setData(path)
         self._webviewactFolder.setData(path)
         if os.path.exists(path) and os.path.isdir(path):
             self._webviewactRun.setVisible(False)
             self._webviewactView.setVisible(False)
             self._webviewactFolder.setVisible(True)
         elif os.path.exists(path) and os.path.isfile(path):
             self._webviewactRun.setVisible(True)
             self._webviewactView.setVisible(True)
             self._webviewactFolder.setVisible(True)
         self._webviewMenu.exec_(QCursor.pos())
Пример #2
0
 def initCatalog(self):
     """初始化本地仓库结构树
     """
     AppLog.debug('')
     if not os.path.exists(Constants.DirProjects):
         return
     pitem = self._dmodel.invisibleRootItem()
     # 只遍历根目录
     for name in os.listdir(Constants.DirProjects):
         file = os.path.join(Constants.DirProjects, name).replace('\\', '/')
         if os.path.isfile(file):  # 跳过文件
             continue
         if name.startswith(
                 '.') or name == 'Donate' or name == 'Test':  # 不显示.开头的文件夹
             continue
         items = self.findItems(name)
         if items:
             item = items[0]
         else:
             item = QStandardItem(name)
             # 添加自定义的数据
             # 用于绘制进度条的item标识
             item.setData(True, Constants.RoleRoot)
             # 目录或者文件的绝对路径
             item.setData(
                 os.path.abspath(os.path.join(Constants.DirProjects, name)),
                 Constants.RolePath)
             pitem.appendRow(item)
         # 遍历子目录
         self.listSubDir(item, file)
     # 排序
     self._fmodel.sort(0, Qt.AscendingOrder)
Пример #3
0
 def onLoginErrored(self, message):
     AppLog.debug('onLoginErrored')
     self._isLogin = False
     self.buttonLogin.showWaiting(False)
     self.setEnabled(True)
     AppLog.error(message)
     if message:
         self.labelNotice.setText(message)
Пример #4
0
 def onReadChannelFinished(self):
     process = self.sender()
     message = process.readAllStandardError().data().decode()
     if process.exitCode() != 0 and len(message.strip()) > 0:
         file = str(process.property('file'))
         reqfile = os.path.abspath(os.path.join(
             os.path.dirname(file), 'requirements.txt'))
         AppLog.debug('reqfile: {}'.format(reqfile))
         dialog = ErrorDialog(message, self, reqfile=reqfile)
         dialog.exec_()
Пример #5
0
    def createRequest(self, op, originalReq, outgoingData):
        """创建请求
        :param op:           操作类型见http://doc.qt.io/qt-5/qnetworkaccessmanager.html#Operation-enum
        :param originalReq:  原始请求
        :param outgoingData: 输出数据
        """
        url = originalReq.url()
        surl = url.toString()
        AppLog.debug('access url: {}'.format(surl))

        if surl.endswith('Donate'):
            # 点击了打赏
            originalReq.setUrl(QUrl())
            return super(NetworkAccessManager,
                         self).createRequest(op, originalReq, outgoingData)
        elif surl.endswith('k=5QVVEdF'):
            # 点击了QQ群链接
            webbrowser.open(Constants.UrlGroup)
            originalReq.setUrl(QUrl())
            return super(NetworkAccessManager,
                         self).createRequest(op, originalReq, outgoingData)

        if url.scheme() == 'tencent':
            # 调用tx的app
            webbrowser.open(surl)
            originalReq.setUrl(QUrl())
        elif url.scheme() == 'file':
            # 本地文件,比如一些图片文件等
            names = surl.split('Markdown/')
            if len(names) > 1:
                rname = names[1]
                path = os.path.join(Constants.DirCurrent,
                                    rname).replace('\\', '/')
                if os.path.exists(path) and os.path.isfile(path):
                    if rname[-3:] == '.py':
                        originalReq.setUrl(QUrl())
                        # 运行py文件
                        Signals.runExampled.emit(path)
                    else:
                        originalReq.setUrl(QUrl.fromLocalFile(path))
                elif os.path.exists(path) and os.path.isdir(path):
                    if rname.count('/') == 0:
                        # 跳转到左侧目录树
                        originalReq.setUrl(QUrl())
                        Signals.itemJumped.emit(rname)
        else:
            # 只加载文件,不加载其它网页
            if not mimetypes.guess_type(url.fileName())[0]:
                originalReq.setUrl(QUrl())
                # 调用系统打开网页
                webbrowser.open_new_tab(surl)

        return super(NetworkAccessManager,
                     self).createRequest(op, originalReq, outgoingData)
Пример #6
0
 def onDoubleClicked(self, modelIndex):
     """Item双击
     :param modelIndex:        此处是代理模型中的QModelIndex, 并不是真实的
     """
     root = modelIndex.data(Constants.RoleRoot)
     path = modelIndex.data(Constants.RolePath)
     AppLog.debug('is root: {}'.format(root))
     AppLog.debug('path: {}'.format(path))
     if not root and os.path.isfile(path):
         # 运行代码
         Signals.runExampled.emit(path)
Пример #7
0
 def renderReadme(self, path=''):
     """加载README.md并显示
     """
     path = path.replace('\\', '/')
     if not path:
         path = os.path.join(Constants.DirProjects, 'README.md')
         Constants.CurrentReadme = ''
     elif path.count('/') == 0:
         path = os.path.join(Constants.DirCurrent, path, 'README.md')
         Constants.CurrentReadme = path
     elif not path.endswith('README.md'):
         path = path + '/README.md'
         Constants.CurrentReadme = path
     if not os.path.exists(path):
         AppLog.debug('{} not exists'.format(path))
         self._runJs('updateText("");')
         return
     if not os.path.isfile(path):
         AppLog.warn('file {} not exists'.format(path))
         return
     Constants.DirCurrent = os.path.dirname(path).replace('\\', '/')
     AppLog.debug('DirCurrent change to: {}'.format(Constants.DirCurrent))
     AppLog.debug('render: {}'.format(path))
     Constants.CurrentReadme = path      # 记录打开的路径防止重复加载
     AppLog.debug('readme dir: {}'.format(Constants.DirCurrent))
     content = repr(open(path, 'rb').read().decode())
     self._runJs("updateText({});".format(content))
Пример #8
0
    def run(self):
        try:
            req = requests.get(
                UrlGetAppsByCategory.format(category=self.category,
                                            pageno=1,
                                            count=20,
                                            time=time()))
            content = req.json()
            errno = content.get('errno', 0)
            AppLog.debug('errno: %s', errno)
            AppLog.debug('msg: %s', content.get('msg', ''))
            if errno != 0:
                return

            content = content.get('data', {})
            AppLog.debug('total_count: %s', content.get('total_count', ''))
            AppLog.debug('total_page: %s', content.get('total_page', ''))
            items = content.get('list', [])

            for i, item in enumerate(items):
                title = item.get('title', '')
                url = item.get('image', None)
                if not url:
                    continue
                self.download(i, title, url)
                QThread.msleep(200)
                QThread.yieldCurrentThread()
        except Exception as e:
            AppLog.exception(e)
        Signals.pictureDownFinished.emit(self.widget)
Пример #9
0
    def run(self):
        AppLog.info('start login github')
        try:
            req = requests.get(self.Url, auth=HTTPBasicAuth(
                self.account, self.password))
            retval = req.json()
            if retval.get('message', '') == 'Bad credentials':
                Signals.loginErrored.emit(QCoreApplication.translate(
                    'Repository', 'Incorrect account or password'))
                AppLog.warn('Incorrect account or password')
                LoginThread.quit()
                return
            if 'login' not in retval:
                Signals.loginErrored.emit(QCoreApplication.translate(
                    'Repository', 'Login failed, Unknown reason'))
                AppLog.warn('Login failed, Unknown reason')
                LoginThread.quit()
                return
            # 用户ID
            uid = retval.get('id', 0)
            AppLog.debug('user id: {}'.format(uid))
            # 用户昵称
            name = retval.get('name', 'Unknown')
            AppLog.debug('user name: {}'.format(name))
            # 用户头像地址
            avatar_url = retval.get('avatar_url', '')
            if avatar_url:
                # 获取头像
                self.get_avatar(uid, avatar_url)
            Signals.loginSuccessed.emit(str(uid), name)
        except ConnectTimeout as e:
            Signals.loginErrored.emit(QCoreApplication.translate(
                'Repository', 'Connect Timeout'))
            AppLog.exception(e)
        except ConnectionError as e:
            Signals.loginErrored.emit(QCoreApplication.translate(
                'Repository', 'Connection Error'))
            AppLog.exception(e)
        except Exception as e:
            Signals.loginErrored.emit(QCoreApplication.translate(
                'Repository', 'Unknown Error'))
            AppLog.exception(e)

        AppLog.info('login thread end')
        LoginThread.quit()
Пример #10
0
 def _initUi(self):
     """初始UI"""
     self.setupUi(self)
     # 隐藏还原按钮
     self.buttonNormal.setVisible(False)
     # 隐藏目录树的滑动条
     self.treeViewCatalogs.verticalScrollBar().setVisible(False)
     # 加载鼠标样式
     ThemeManager.loadCursor(self.widgetMain)
     ThemeManager.setPointerCursors([
         self.buttonHead,            # 主界面头像
         self.buttonClear,           # 主界面清空按钮
         self.buttonGithub,          # Github按钮
         self.buttonQQ,              # QQ按钮
         self.buttonGroup,           # 群按钮
         self.buttonBackToUp,        # 返回顶部按钮
         self.buttonHome             # 显示主页readme
     ])
     # 安装事件过滤器用于还原鼠标样式
     self.widgetMain.installEventFilter(self)
     # 绑定返回顶部提示框
     ToolTip.bind(self.buttonBackToUp)
     ToolTip.bind(self.buttonHome)
     # 头像提示控件
     ToolTip.bind(self.buttonHead)
     # 加载主题
     colourful = Setting.value('colourful')
     picture = Setting.value('picture', '', str)
     AppLog.debug('colourful: %s', str(colourful))
     AppLog.debug('picture: %s', picture)
     if picture:
         ThemeManager.loadFont()
         ThemeManager.loadPictureTheme(picture)
     elif colourful:
         ThemeManager.loadFont()
         if isinstance(picture, QColor):
             ThemeManager.loadColourfulTheme(colourful)
         else:
             # json数据转渐变
             ThemeManager.loadColourfulTheme(
                 GradientUtils.toGradient(colourful))
     else:
         ThemeManager.loadTheme()
Пример #11
0
 def onClicked(self, modelIndex):
     """Item单击
     :param modelIndex:        此处是代理模型中的QModelIndex, 并不是真实的
     """
     root = modelIndex.data(Constants.RoleRoot)
     path = modelIndex.data(Constants.RolePath)
     code = modelIndex.data(Constants.RoleCode)
     AppLog.debug('is root: {}'.format(root))
     AppLog.debug('path: {}'.format(path))
     if not root and os.path.isfile(path) and code:
         # 右侧显示代码
         Signals.showCoded.emit(code)
     if root and os.path.isdir(path):
         if self.isExpanded(modelIndex):
             self.collapse(modelIndex)
         else:
             self.expand(modelIndex)
         # 显示readme
         Signals.showReadmed.emit(os.path.join(path, 'README.md'))
Пример #12
0
 def onLoginSuccessed(self, uid, name):
     AppLog.debug('onLoginSuccessed')
     self._isLogin = False
     self.buttonLogin.showWaiting(False)
     self.setEnabled(True)
     # 用账号密码实例化github访问对象
     account = self.lineEditAccount.text().strip()
     password = self.lineEditPassword.text().strip()
     Constants._Account = account
     Constants._Password = password
     Constants._Username = name
     # 储存账号密码
     Setting.setValue('account', account)
     if account not in self._accounts:
         # 更新账号数组
         self._accounts[account] = [
             uid, base64.b85encode(password.encode()).decode()]
         Setting.setValue('accounts', self._accounts)
     self.accept()
Пример #13
0
    def get_avatar(self, uid, avatar_url):
        try:
            req = requests.get(avatar_url)
            if req.status_code == 200:
                imgformat = req.headers.get(
                    'content-type', 'image/jpg').split('/')[1]
                Constants.ImageAvatar = os.path.join(
                    Constants.ImageDir, str(uid)).replace('\\', '/') + '.jpg'
                AppLog.debug('image type: {}'.format(imgformat))
                AppLog.debug(
                    'content length: {}'.format(len(req.content)))

                image = QImage()
                if image.loadFromData(req.content):
                    # 缩放图片
                    if not image.isNull():
                        image = image.scaled(130, 130, Qt.IgnoreAspectRatio,
                                             Qt.SmoothTransformation)
                        AppLog.debug('save to: {}'.format(
                            Constants.ImageAvatar))
                        image.save(Constants.ImageAvatar)
                    else:
                        AppLog.warn('avatar image is null')
                else:
                    AppLog.warn('can not load from image data')
        except Exception as e:
            AppLog.exception(e)
Пример #14
0
 def download(self, file, url):
     AppLog.debug('start download {}'.format(url))
     with closing(requests.get(url, stream=True)) as response:
         # 单次请求最大值
         chunk_size = 1024
         # 内容体总大小
         content_size = int(response.headers['content-length'])
         data_count = 0
         Signals.updateProgressChanged.emit(0, 0, content_size)
         AppLog.debug('content_size: {}'.format(content_size))
         with open(file, 'wb') as fp:
             for data in response.iter_content(chunk_size=chunk_size):
                 fp.write(data)
                 data_count = data_count + len(data)
                 if content_size > 0:
                     Signals.updateProgressChanged.emit(
                         data_count, 0, content_size)
         # 解压
         self.unzip(file)
     AppLog.debug('download {} end'.format(file))
Пример #15
0
 def transfer_progress(self, stats):
     Signals.progressUpdated.emit(
         stats.received_objects, stats.total_objects)
     AppLog.debug('total: {}, received: {}'.format(
         stats.total_objects, stats.received_objects))