Exemplo n.º 1
0
class AddDownloads(QVBoxLayout):
    def __init__(self, downloads, parent=None):
        QVBoxLayout.__init__(self)
        self.setContentsMargins(0, 0, 0, 0)
        self.setSpacing(5)

        self.downloads = downloads
        self.parent = parent

        self.tree_view = QTreeView(parent)
        #
        self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view.customContextMenuRequested.connect(self.context_menu)
        #
        #listview look
        self.tree_view.setWordWrap(True)  #search textElideMode
        self.tree_view.setRootIsDecorated(False)
        self.tree_view.setIndentation(0)
        self.tree_view.setAlternatingRowColors(True)
        #
        self.items = []
        self.rows_buffer = {}  #{id_item: row_obj, }
        #self.items = [[True, "1", "11", "t5est", "t3est"], [True, "1", "11", "t5est", "t3est"], [True, "1", "11", "t5est", "t3est"]]
        bool_cols = [
            1,
        ]
        headers = [
            "hidden_id_item", "",
            _("Status"),
            _("File Name"),
            _("Host"),
            _("Size"),
            _("Status Message")
        ]
        #
        self.__model = SimpleListModel(headers, self.items, bool_cols)
        self.tree_view.setModel(self.__model)
        self.addWidget(self.tree_view)
        #
        self.tree_view.setColumnHidden(0, True)
        self.tree_view.setColumnWidth(1, 27)
        self.tree_view.header().setResizeMode(1, QHeaderView.Fixed)

        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(10)

        self.cb = QComboBox()
        #self.cb.setFixedWidth(100)
        self.cb.setEditable(True)
        self.cb.setFixedHeight(35)
        self.cb.setMinimumWidth(1)
        cb_view = self.cb.view()
        cb_view.setAlternatingRowColors(True)
        #
        self.paths_list = conf.get_save_dl_paths()
        if not self.paths_list:
            self.cb.addItem(cons.DLFOLDER_PATH)
        else:
            [self.cb.addItem(path) for path in reversed(self.paths_list)]
        #
        hbox.addWidget(self.cb)

        btn_examine = QPushButton('...')
        btn_examine.clicked.connect(self.on_examine)
        btn_examine.setFixedHeight(35)
        btn_examine.setMaximumWidth(80)
        hbox.addWidget(btn_examine)

        hbox.addSpacing(40)  #index, size

        btn_download = QPushButton()
        btn_download.setIcon(media.get_icon(media.DOWN, media.MEDIUM))
        btn_download.setIconSize(QSize(24, 24))
        btn_download.clicked.connect(self.on_download_selected)
        btn_download.setFixedHeight(35)
        btn_download.setMaximumWidth(40)
        hbox.addWidget(btn_download)

        btn_add = QPushButton()
        btn_add.setIcon(media.get_icon(media.ADD, media.MEDIUM))
        btn_add.setIconSize(QSize(24, 24))
        btn_add.clicked.connect(self.on_add_links)
        btn_add.setFixedHeight(35)
        btn_add.setMaximumWidth(40)
        hbox.addWidget(btn_add)

        self.menu = QMenu(parent)
        import_action = self.menu.addAction(_("Import Container"),
                                            self.on_import_container)
        self.menu.addSeparator()
        recheck_action = self.menu.addAction(_("Re-check"), self.on_recheck)
        clear_action = self.menu.addAction(_("Clear list"), self.on_clear_list)
        #
        btn_menu = QPushButton()
        btn_menu.setMenu(self.menu)
        btn_menu.setFixedHeight(35)
        btn_menu.setMaximumWidth(22)
        btn_menu.setFlat(True)
        hbox.addWidget(btn_menu)

        self.addLayout(hbox)

        #update list
        parent.idle_timeout(1000, self.update)

    def context_menu(self, position):
        menu = QMenu()
        #indexes = self.selectedIndexes()

        #sensitive = True if indexes else False

        #individual_items = [('Open destination folder', self.on_open_folder),]

        #[menu.addAction(title, callback).setEnabled(sensitive) for title, callback in individual_items]

        #menu.addSeparator()

        generic_items = [(_('Download Selected'), self.on_download_selected),
                         (None, None), (_('Select all'), self.on_select_all),
                         (_('Select none'), self.on_select_none),
                         (_('Select inverse'), self.on_select_inverse),
                         (None, None), (_('Re-check'), self.on_recheck),
                         (_('Clear list'), self.on_clear_list)]

        [
            menu.addAction(title, callback)
            if title is not None else menu.addSeparator()
            for title, callback in generic_items
        ]

        menu.exec_(self.tree_view.viewport().mapToGlobal(position))

    def on_clear_list(self):
        self.__model.clear()
        self.rows_buffer.clear()
        api.clear_pending()

    def on_recheck(self):
        api.recheck_items()

    def on_select_all(self):
        for row in self.items:
            row[1] = True

    def on_select_none(self):
        for row in self.items:
            row[1] = False

    def on_select_inverse(self):
        for row in self.items:
            row[1] = False if row[1] else True

    def on_import_container(self):
        file_name, filter = QFileDialog.getOpenFileName(
            filter='OCH Files (*.och)')
        if file_name:
            container = Container(file_name)
            container.extract_links()
            links_list = container.get_linklist()

            if links_list:
                self.links_checking(links_list, copy_link=False)

    def on_add_links(self):
        add_links = AddLinks(self.parent)
        result_code = add_links.result()
        links_list = add_links.links_list
        if result_code == QDialog.Accepted and links_list:
            self.links_checking(links_list)

    def on_examine(self):
        folder = QFileDialog.getExistingDirectory()
        if folder:
            self.cb.setEditText(folder)

    def cb_remove(self, text):
        index = self.cb.findText(text)
        if index >= 0:
            self.cb.removeItem(index)

    def on_download_selected(self):
        current_path = self.cb.currentText()
        self.cb_remove(current_path)
        self.cb.insertItem(0, current_path)
        if current_path in self.paths_list:
            self.paths_list.remove(current_path)
        self.paths_list.append(current_path)
        if len(self.paths_list) > 5:
            self.paths_list.pop(0)
            self.cb.removeItem(5)
        self.cb.setCurrentIndex(0)
        conf.set_save_dl_paths(self.paths_list)

        id_items_list = []
        iters = []
        for row in self.items:
            if row[1]:  # and row[4] != cons.UNSUPPORTED: #tmp
                iters.append(row)
                id_item = row[0]
                id_items_list.append(id_item)
                del self.rows_buffer[id_item]
        [self.__model.remove(self.items.index(iter)) for iter in iters]

        item_list = api.get_added_items(id_items_list)

        api.downloader_init(item_list,
                            current_path)  #iniciar threads de descarga.
        #TODO: use a signal.
        self.downloads.store_items(item_list)

    def links_checking(self, links_list, copy_link=True):
        for link in links_list:
            download_item = api.create_download_item(
                cons.UNKNOWN, 0, link, copy_link)  #return download_item object
            item = [
                download_item.id, True, cons.LINK_CHECKING, cons.UNKNOWN, None,
                None, None
            ]
            #self.items.append(item)
            self.__model.append(item)
            self.rows_buffer[item[0]] = item
        api.start_checking()

    def update(self):  #this method steals cycles, its not a new thread
        items_list = api.get_checking_update()
        for download_item in items_list:
            try:
                row = self.rows_buffer[download_item.id]
                row[1] = True if download_item.link_status != cons.LINK_DEAD else False
                row[2] = download_item.link_status
                row[3] = download_item.name
                row[4] = download_item.host
                row[5] = misc.size_format(download_item.size)
                row[6] = download_item.link_status_msg
            except KeyError as err:
                logger.debug(err)
        self.__model.refresh()
Exemplo n.º 2
0
class ConfigAccounts(QDialog):
    def __init__(self, parent):
        QDialog.__init__(self, parent, Qt.WindowSystemMenuHint | Qt.WindowTitleHint)
        self.setWindowTitle(_('Host Accounts'))
        self.resize(500, 450)
        
        vbox = QVBoxLayout()
        self.setLayout(vbox)
        
        # ####################### #
        
        vbox_accounts = QVBoxLayout()
        group_accounts = QGroupBox(_('Accounts:'))
        group_accounts.setLayout(vbox_accounts)
        
        self.tree_view = QTreeView()
        #
        #listview look
        self.tree_view.setWordWrap(True) #search textElideMode
        self.tree_view.setRootIsDecorated(False)
        self.tree_view.setIndentation(0)
        self.tree_view.setAlternatingRowColors(True)
        #
        self.items = []
        headers = ["hidden_id_account", _("Host"), _("Status"), _("Username"), _("Password"), _("Enable")]
        bool_cols = [ENABLE, ]
        #
        self.__model = SimpleListModel(headers, self.items, bool_cols)
        self.tree_view.setModel(self.__model)
        vbox_accounts.addWidget(self.tree_view)
        
        self.tree_view.setColumnHidden(0, True)
        
        hbox_accounts = QHBoxLayout()
        hbox_accounts.addStretch(0) #stretch/align widget to right.
        vbox_accounts.addLayout(hbox_accounts)
        
        self.btn_remove = QPushButton(_('Remove'))
        self.btn_remove.clicked.connect(self.on_remove)
        self.btn_remove.setFixedHeight(35)
        self.btn_remove.setMaximumWidth(80)
        self.btn_remove.setEnabled(False)
        hbox_accounts.addWidget(self.btn_remove)
        
        self.btn_check = QPushButton(_('Check'))
        self.btn_check.clicked.connect(self.on_check)
        self.btn_check.setFixedHeight(35)
        self.btn_check.setMaximumWidth(80)
        self.btn_check.setEnabled(False)
        hbox_accounts.addWidget(self.btn_check)
        
        vbox.addWidget(group_accounts)
        
        # ####################### #
        
        vbox_login = QVBoxLayout()
        group_login = QGroupBox(_('Login:'******'Server:'))
        #label_server.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        label_user = QLabel(_('Username:'******'Password:'******'Add'))
        btn_add.clicked.connect(self.on_add)
        btn_add.setFixedHeight(35)
        btn_add.setMaximumWidth(80)
        if not self.cb.count():
            btn_add.setEnabled(False)
        hbox_add.addStretch(0)
        hbox_add.addWidget(btn_add)
        vbox_login.addLayout(hbox_add)
        
        vbox.addWidget(group_login)
        
        # ####################### #
        
        vbox.addSpacing(20)
        
        hbox_btns = QHBoxLayout()
        hbox_btns.addStretch()
        
        btn_accept = QPushButton(_('Close'))
        btn_accept.clicked.connect(self.accept)
        btn_accept.setDefault(True)
        btn_accept.setFixedHeight(35)
        btn_accept.setMaximumWidth(80)
        hbox_btns.addWidget(btn_accept)
        
        vbox.addLayout(hbox_btns)
        
        # ####################### #

        #self.tree_view.selectionModel().selectionChanged.connect(self.on_selected)
        
        self.load_accounts()
        
        self.timer = parent.idle_timeout(1000, self.update_)
        
        #self.show()
        self.exec_()
        self.deleteLater()
    
    def get_selected_row(self):
        """"""
        selected_row = self.tree_view.selectionModel().selectedRows()[0].row()
        return selected_row
    
    #def on_selected(self, selected, unselected):
        #""""""
        #todo: heredar treeView y subclass selectionChanged
        #row = self.get_selected_row()
        #self.btn_remove.setEnabled(True)
        #self.btn_check.setEnabled(True)
    
    def load_accounts(self):
        accounts_list = [account
                        for service, accounts in sorted(accounts_manager.accounts_dict.iteritems())
                        for account in accounts.itervalues()]
        for account in accounts_list:
            password = "".join(["*" for _ in account.password])
            self.__model.append([account.id_account, account.host, account.status, account.username, password, account.enable])
            #TODO: Automatic accounts checking on load.
    
    def on_add(self):
        username = self.entry_user.text()
        password = self.entry_pass.text()
        if username and password:
            accounts_manager.new_account(self.cb.currentText(), username, password)
            self.__model.clear()
            self.load_accounts()
    
    def on_remove(self):
        row = self.get_selected_row()
        accounts_manager.remove_account(self.items[row][HOST], self.items[row][ACCOUNT_ID])
        self.__model.remove(row)
    
    def on_check(self):
        row = self.get_selected_row()
        accounts_manager.manual_checking(self.items[row][HOST], self.items[row][ACCOUNT_ID])
    
    def update_(self):
        account_list = accounts_manager.update()
        for account_item in account_list:
            for row in self.items:
                if row[ACCOUNT_ID] == account_item.id_account:
                    row[STATUS] = account_item.status

    def save(self):
        for row in self.items:
            if row[ENABLE]:
                accounts_manager.enable_account(row[HOST], row[ACCOUNT_ID])
            else:
                accounts_manager.disable_account(row[HOST], row[ACCOUNT_ID])

    def accept(self, *args, **kwargs):
        self.timer.stop()
        self.save()
        self.hide()
        QDialog.accept(self, *args, **kwargs)

    def reject(self, *args, **kwargs):
        self.timer.stop()
        self.save()
        self.hide()
        QDialog.reject(self, *args, **kwargs)
Exemplo n.º 3
0
class AddDownloads(QVBoxLayout):
    def __init__(self, parent):
        QVBoxLayout.__init__(self)
        self.setContentsMargins(0, 0, 0, 0)
        self.setSpacing(5)

        self.weak_parent = weakref.ref(parent)
        
        self.tree_view = QTreeView()

        self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view.customContextMenuRequested.connect(self.context_menu)

        #listview look
        self.tree_view.setWordWrap(True) #search textElideMode
        self.tree_view.setRootIsDecorated(False)
        self.tree_view.setIndentation(0)
        self.tree_view.setAlternatingRowColors(True)

        self.icons_dict = self.get_icons()
        self.items = []
        self.rows_buffer = {} #{id_item: row_obj, }

        bool_cols = [1, ]
        image_cols = [2, ]
        headers = ["hidden_id_item", "", "", _("File Name"), _("Host"), _("Size"), _("Status Message")]

        self.__model = SimpleListModel(headers, self.items, bool_cols, image_cols)
        self.tree_view.setModel(self.__model)
        self.addWidget(self.tree_view)

        self.tree_view.setColumnHidden(0, True)
        self.tree_view.setColumnWidth(1, 27)
        self.tree_view.setColumnWidth(2, 27)
        self.tree_view.header().setResizeMode(1, QHeaderView.Fixed)
        
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(10)
        
        self.cb = QComboBox()
        #self.cb.setFixedWidth(100)
        self.cb.setEditable(True)
        self.cb.setFixedHeight(35)
        self.cb.setMinimumWidth(1)
        cb_view = self.cb.view()
        cb_view.setAlternatingRowColors(True)

        self.paths_list = conf.get_save_dl_paths()

        if not self.paths_list:
            self.cb.addItem(cons.DLFOLDER_PATH)
        else:
            [self.cb.addItem(path) for path in reversed(self.paths_list)]

        hbox.addWidget(self.cb)
        
        btn_examine = QPushButton('...')
        btn_examine.clicked.connect(self.on_examine)
        btn_examine.setFixedHeight(35)
        btn_examine.setMaximumWidth(80)
        hbox.addWidget(btn_examine)
        
        hbox.addSpacing(40) #index, size
        
        btn_download = QPushButton()
        btn_download.setIcon(media.get_icon(media.DOWN, media.MEDIUM))
        btn_download.setIconSize(QSize(24, 24))
        btn_download.clicked.connect(self.on_download_selected)
        btn_download.setFixedHeight(35)
        btn_download.setMaximumWidth(40)
        hbox.addWidget(btn_download)
        
        btn_add = QPushButton()
        btn_add.setIcon(media.get_icon(media.ADD, media.MEDIUM))
        btn_add.setIconSize(QSize(24, 24))
        btn_add.clicked.connect(self.on_add_links)
        btn_add.setFixedHeight(35)
        btn_add.setMaximumWidth(40)
        hbox.addWidget(btn_add)
        
        self.menu = QMenu()
        import_action = self.menu.addAction(_("Import Container"), self.on_import_container)
        self.menu.addSeparator()
        recheck_action = self.menu.addAction(_("Re-check"), self.on_recheck)
        clear_action = self.menu.addAction(_("Clear list"), self.on_clear_list)

        btn_menu = QPushButton()
        btn_menu.setMenu(self.menu)
        btn_menu.setFixedHeight(35)
        btn_menu.setMaximumWidth(22)
        btn_menu.setFlat(True)
        hbox.addWidget(btn_menu)
        
        self.addLayout(hbox)

        #custom signals
        signals.add_downloads_to_check.connect(self.add_downloads_to_check)
        
        #update list
        self.timer = parent.idle_timeout(1000, self.update_)

    @property
    def parent(self):
        return self.weak_parent()

    def get_selected_rows(self):
        """"""
        selected_rows = [index.row() for index in self.tree_view.selectionModel().selectedRows()]
        selected_rows.sort()
        return selected_rows

    def context_menu(self, position):
        rows = self.get_selected_rows()

        is_single_row = True if len(rows) == 1 else False

        options = [(_('Save as...'), self.on_save_as, is_single_row),
                    None,
                    (_('Download Selected'), self.on_download_selected, True),
                    None,
                    (_('Select all'), self.on_select_all, True),
                    (_('Select none'), self.on_select_none, True),
                    (_('Select inverse'), self.on_select_inverse, True),
                    None,
                    (_('Re-check'), self.on_recheck, True),
                    (_('Clear list'), self.on_clear_list, True)]

        menu = Menu(options)
        
        menu.exec_(self.tree_view.viewport().mapToGlobal(position))

    def on_save_as(self):
        rows = self.get_selected_rows()
        row = self.items[rows[0]]
        item_id = row[0]
        download_item = api.get_checking_download_item(item_id)
        widget = QLineEdit()

        # set the line entry file name if we have one.
        if download_item.save_as:
            widget.setText(download_item.save_as)
        elif download_item.name != cons.UNKNOWN:
            widget.setText(download_item.name)

        dialog = Dialog(self.parent, "Save as", widget)
        if dialog.result() == QDialog.Accepted:
            save_as = widget.text()
            # change the file name in treeview and DownloadItem
            if save_as:
                api.save_download_as(download_item, save_as)
                api.set_download_name(download_item, save_as)
                row[3] = save_as

    def on_clear_list(self):
        self.__model.clear()
        self.rows_buffer.clear()
        api.clear_pending()
    
    def on_recheck(self):
        api.recheck_items()

    def on_select_all(self):
        for row in self.items:
            row[1] = True

    def on_select_none(self):
        for row in self.items:
            row[1] = False

    def on_select_inverse(self):
        for row in self.items:
            row[1] = False if row[1] else True
    
    def on_import_container(self):
        file_name, filter = QFileDialog.getOpenFileName(filter='OCH Files (*.och)')
        if file_name:
            container = Container(file_name)
            container.extract_links()
            links_list = container.get_linklist()
            
            if links_list:
                self.add_downloads_to_check(links_list, copy_link=False)
    
    def on_add_links(self):
        dialog = AddLinks(self.parent)
        result_code = dialog.result()
        links_list = dialog.links_list
        if result_code == QDialog.Accepted and links_list:
            self.add_downloads_to_check(links_list)
    
    def on_examine(self):
        folder = QFileDialog.getExistingDirectory()
        if folder:
            self.cb.setEditText(folder)
    
    def cb_remove(self, text):
        index = self.cb.findText(text)
        if index >= 0:
            self.cb.removeItem(index)
    
    def on_download_selected(self):
        # save the selected path
        current_path = self.cb.currentText()
        self.cb_remove(current_path)
        self.cb.insertItem(0, current_path)

        if current_path in self.paths_list:
            self.paths_list.remove(current_path)

        self.paths_list.append(current_path)

        if len(self.paths_list) > 5:
            self.paths_list.pop(0)
            self.cb.removeItem(5)

        self.cb.setCurrentIndex(0)
        conf.set_save_dl_paths(self.paths_list)

        # move selected items to downloads tab
        id_items_list = []
        iters = []

        for row in self.items:
            if row[1]:
                iters.append(row)
                id_item = row[0]
                id_items_list.append(id_item)
                del self.rows_buffer[id_item]

        [self.__model.remove(self.items.index(iter)) for iter in iters]
        
        item_list = api.pop_checking_items(id_items_list)
        for download_item in item_list:
            download_item.path = current_path

        signals.add_to_downloader.emit(item_list)

    def add_downloads_to_check(self, links_list, copy_link=True):
        for link in links_list:
            download_item = api.create_download_item(cons.UNKNOWN, link, copy_link=copy_link)
            api.add_to_checker(download_item)
            item = [download_item.id, True, self.icons_dict[cons.LINK_CHECKING], cons.UNKNOWN, None, None, None]
            #self.items.append(item)
            self.__model.append(item)
            self.rows_buffer[item[0]] = item
        api.start_checking()
    
    def update_(self):
        checking_downloads = api.get_checking_downloads()
        api.update_checking_downloads()
        for download_item in checking_downloads.itervalues():
            row = self.rows_buffer[download_item.id]
            if download_item.link_status == cons.LINK_DEAD:
                row[1] = False
            row[2] = self.icons_dict[download_item.link_status]
            row[3] = download_item.name
            if not download_item.host == cons.UNSUPPORTED:
                row[4] = download_item.host
            if download_item.size:
                row[5] = utils.size_format(download_item.size)
            row[6] = download_item.link_status_msg
        self.__model.refresh()

    def get_icons(self):
        alive = media.get_pixmap(media.ALIVE, media.SMALL)
        dead = media.get_pixmap(media.DEAD, media.SMALL)
        error = media.get_pixmap(media.ERROR, media.SMALL)
        checking = media.get_pixmap(media.CHECKING, media.SMALL)
        #unavailable = media.get_pixmap(media.ERROR, media.SMALL)

        return {cons.LINK_ALIVE: alive, cons.LINK_DEAD: dead,
                cons.LINK_UNAVAILABLE: error, cons.LINK_ERROR: error,
                cons.LINK_CHECKING: checking}
Exemplo n.º 4
0
class ConfigAccounts(QDialog):
    def __init__(self, parent):
        QDialog.__init__(self, parent,
                         Qt.WindowSystemMenuHint | Qt.WindowTitleHint)
        self.setWindowTitle(_('Host Accounts'))
        self.resize(500, 450)

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        # ####################### #

        vbox_accounts = QVBoxLayout()
        group_accounts = QGroupBox(_('Accounts:'))
        group_accounts.setLayout(vbox_accounts)

        self.tree_view = QTreeView()
        #
        #listview look
        self.tree_view.setWordWrap(True)  #search textElideMode
        self.tree_view.setRootIsDecorated(False)
        self.tree_view.setIndentation(0)
        self.tree_view.setAlternatingRowColors(True)
        #
        self.items = []
        headers = [
            "hidden_id_account",
            _("Host"),
            _("Status"),
            _("Username"),
            _("Password"),
            _("Enable")
        ]
        bool_cols = [
            ENABLE,
        ]
        #
        self.__model = SimpleListModel(headers, self.items, bool_cols)
        self.tree_view.setModel(self.__model)
        vbox_accounts.addWidget(self.tree_view)

        self.tree_view.setColumnHidden(0, True)

        hbox_accounts = QHBoxLayout()
        hbox_accounts.addStretch(0)  #stretch/align widget to right.
        vbox_accounts.addLayout(hbox_accounts)

        self.btn_remove = QPushButton(_('Remove'))
        self.btn_remove.clicked.connect(self.on_remove)
        self.btn_remove.setFixedHeight(35)
        self.btn_remove.setMaximumWidth(80)
        self.btn_remove.setEnabled(False)
        hbox_accounts.addWidget(self.btn_remove)

        self.btn_check = QPushButton(_('Check'))
        self.btn_check.clicked.connect(self.on_check)
        self.btn_check.setFixedHeight(35)
        self.btn_check.setMaximumWidth(80)
        self.btn_check.setEnabled(False)
        hbox_accounts.addWidget(self.btn_check)

        vbox.addWidget(group_accounts)

        # ####################### #

        vbox_login = QVBoxLayout()
        group_login = QGroupBox(_('Login:'******'Server:'))
        #label_server.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        label_user = QLabel(_('Username:'******'Password:'******'Add'))
        btn_add.clicked.connect(self.on_add)
        btn_add.setFixedHeight(35)
        btn_add.setMaximumWidth(80)
        if not self.cb.count():
            btn_add.setEnabled(False)
        hbox_add.addStretch(0)
        hbox_add.addWidget(btn_add)
        vbox_login.addLayout(hbox_add)

        vbox.addWidget(group_login)

        # ####################### #

        vbox.addSpacing(20)

        hbox_btns = QHBoxLayout()
        hbox_btns.addStretch()

        btn_accept = QPushButton(_('Close'))
        btn_accept.clicked.connect(self.accept)
        btn_accept.setDefault(True)
        btn_accept.setFixedHeight(35)
        btn_accept.setMaximumWidth(80)
        hbox_btns.addWidget(btn_accept)

        vbox.addLayout(hbox_btns)

        # ####################### #

        #self.tree_view.selectionModel().selectionChanged.connect(self.on_selected)

        self.load_accounts()

        self.timer = parent.idle_timeout(1000, self.update_)

        #self.show()
        self.exec_()
        self.deleteLater()

    def get_selected_row(self):
        """"""
        selected_row = self.tree_view.selectionModel().selectedRows()[0].row()
        return selected_row

    #def on_selected(self, selected, unselected):
    #""""""
    #todo: heredar treeView y subclass selectionChanged
    #row = self.get_selected_row()
    #self.btn_remove.setEnabled(True)
    #self.btn_check.setEnabled(True)

    def load_accounts(self):
        accounts_list = [
            account for service, accounts in sorted(
                accounts_manager.accounts_dict.iteritems())
            for account in accounts.itervalues()
        ]
        for account in accounts_list:
            password = "".join(["*" for _ in account.password])
            self.__model.append([
                account.id_account, account.host, account.status,
                account.username, password, account.enable
            ])
            #TODO: Automatic accounts checking on load.

    def on_add(self):
        username = self.entry_user.text()
        password = self.entry_pass.text()
        if username and password:
            accounts_manager.new_account(self.cb.currentText(), username,
                                         password)
            self.__model.clear()
            self.load_accounts()

    def on_remove(self):
        row = self.get_selected_row()
        accounts_manager.remove_account(self.items[row][HOST],
                                        self.items[row][ACCOUNT_ID])
        self.__model.remove(row)

    def on_check(self):
        row = self.get_selected_row()
        accounts_manager.manual_checking(self.items[row][HOST],
                                         self.items[row][ACCOUNT_ID])

    def update_(self):
        account_list = accounts_manager.update()
        for account_item in account_list:
            for row in self.items:
                if row[ACCOUNT_ID] == account_item.id_account:
                    row[STATUS] = account_item.status

    def save(self):
        for row in self.items:
            if row[ENABLE]:
                accounts_manager.enable_account(row[HOST], row[ACCOUNT_ID])
            else:
                accounts_manager.disable_account(row[HOST], row[ACCOUNT_ID])

    def accept(self, *args, **kwargs):
        self.timer.stop()
        self.save()
        self.hide()
        QDialog.accept(self, *args, **kwargs)

    def reject(self, *args, **kwargs):
        self.timer.stop()
        self.save()
        self.hide()
        QDialog.reject(self, *args, **kwargs)
Exemplo n.º 5
0
class AddDownloads(QVBoxLayout):
    def __init__(self, downloads, parent=None):
        QVBoxLayout.__init__(self)
        self.setContentsMargins(0, 0, 0, 0)
        self.setSpacing(5)
        
        self.downloads = downloads
        self.parent = parent
        
        self.tree_view = QTreeView(parent)
        #
        self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view.customContextMenuRequested.connect(self.context_menu)
        #
        #listview look
        self.tree_view.setWordWrap(True) #search textElideMode
        self.tree_view.setRootIsDecorated(False)
        self.tree_view.setIndentation(0)
        self.tree_view.setAlternatingRowColors(True)
        #
        self.items = []
        self.rows_buffer = {} #{id_item: row_obj, }
        #self.items = [[True, "1", "11", "t5est", "t3est"], [True, "1", "11", "t5est", "t3est"], [True, "1", "11", "t5est", "t3est"]]
        bool_cols = [1, ]
        headers = ["hidden_id_item", "", _("Status"), _("File Name"), _("Host"), _("Size"), _("Status Message")]
        #
        self.__model = SimpleListModel(headers, self.items, bool_cols)
        self.tree_view.setModel(self.__model)
        self.addWidget(self.tree_view)
        #
        self.tree_view.setColumnHidden(0, True)
        self.tree_view.setColumnWidth(1, 27)
        self.tree_view.header().setResizeMode(1, QHeaderView.Fixed)
        
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(10)
        
        self.cb = QComboBox()
        #self.cb.setFixedWidth(100)
        self.cb.setEditable(True)
        self.cb.setFixedHeight(35)
        self.cb.setMinimumWidth(1)
        cb_view = self.cb.view()
        cb_view.setAlternatingRowColors(True)
        #
        self.paths_list = conf.get_save_dl_paths()
        if not self.paths_list:
            self.cb.addItem(cons.DLFOLDER_PATH)
        else:
            [self.cb.addItem(path) for path in reversed(self.paths_list)]
        #
        hbox.addWidget(self.cb)
        
        btn_examine = QPushButton('...')
        btn_examine.clicked.connect(self.on_examine)
        btn_examine.setFixedHeight(35)
        btn_examine.setMaximumWidth(80)
        hbox.addWidget(btn_examine)
        
        hbox.addSpacing(40) #index, size
        
        btn_download = QPushButton()
        btn_download.setIcon(media.get_icon(media.DOWN, media.MEDIUM))
        btn_download.setIconSize(QSize(24, 24))
        btn_download.clicked.connect(self.on_download_selected)
        btn_download.setFixedHeight(35)
        btn_download.setMaximumWidth(40)
        hbox.addWidget(btn_download)
        
        btn_add = QPushButton()
        btn_add.setIcon(media.get_icon(media.ADD, media.MEDIUM))
        btn_add.setIconSize(QSize(24, 24))
        btn_add.clicked.connect(self.on_add_links)
        btn_add.setFixedHeight(35)
        btn_add.setMaximumWidth(40)
        hbox.addWidget(btn_add)
        
        self.menu = QMenu(parent)
        import_action = self.menu.addAction(_("Import Container"), self.on_import_container)
        self.menu.addSeparator()
        recheck_action = self.menu.addAction(_("Re-check"), self.on_recheck)
        clear_action = self.menu.addAction(_("Clear list"), self.on_clear_list)
        #
        btn_menu = QPushButton()
        btn_menu.setMenu(self.menu)
        btn_menu.setFixedHeight(35)
        btn_menu.setMaximumWidth(22)
        btn_menu.setFlat(True)
        hbox.addWidget(btn_menu)
        
        
        self.addLayout(hbox)
        
        #update list
        parent.idle_timeout(1000, self.update)
    
    def context_menu(self, position):
        menu = QMenu()
        #indexes = self.selectedIndexes()
        
        #sensitive = True if indexes else False
        
        #individual_items = [('Open destination folder', self.on_open_folder),]
        
        #[menu.addAction(title, callback).setEnabled(sensitive) for title, callback in individual_items]

        #menu.addSeparator()
        
        generic_items = [(_('Download Selected'), self.on_download_selected),
                        (None, None),
                        (_('Select all'), self.on_select_all),
                        (_('Select none'), self.on_select_none),
                        (_('Select inverse'), self.on_select_inverse),
                        (None, None),
                        (_('Re-check'), self.on_recheck),
                        (_('Clear list'), self.on_clear_list)]
        
        [menu.addAction(title, callback) if title is not None else menu.addSeparator()
        for title, callback in generic_items]
        
        menu.exec_(self.tree_view.viewport().mapToGlobal(position))
    
    def on_clear_list(self):
        self.__model.clear()
        self.rows_buffer.clear()
        api.clear_pending()
    
    def on_recheck(self):
        api.recheck_items()

    def on_select_all(self):
        for row in self.items:
            row[1] = True

    def on_select_none(self):
        for row in self.items:
            row[1] = False

    def on_select_inverse(self):
        for row in self.items:
            row[1] = False if row[1] else True
    
    def on_import_container(self):
        file_name, filter = QFileDialog.getOpenFileName(filter='OCH Files (*.och)')
        if file_name:
            container = Container(file_name)
            container.extract_links()
            links_list = container.get_linklist()
            
            if links_list:
                self.links_checking(links_list, copy_link=False)
    
    def on_add_links(self):
        add_links = AddLinks(self.parent)
        result_code = add_links.result()
        links_list = add_links.links_list
        if result_code == QDialog.Accepted and links_list:
            self.links_checking(links_list)
    
    def on_examine(self):
        folder = QFileDialog.getExistingDirectory()
        if folder:
            self.cb.setEditText(folder)
    
    def cb_remove(self, text):
        index = self.cb.findText(text)
        if index >= 0:
            self.cb.removeItem(index)
    
    def on_download_selected(self):
        current_path = self.cb.currentText()
        self.cb_remove(current_path)
        self.cb.insertItem(0, current_path)
        if current_path in self.paths_list:
            self.paths_list.remove(current_path)
        self.paths_list.append(current_path)
        if len(self.paths_list) > 5:
            self.paths_list.pop(0)
            self.cb.removeItem(5)
        self.cb.setCurrentIndex(0)
        conf.set_save_dl_paths(self.paths_list)
        
        id_items_list = []
        iters = []
        for row in self.items:
            if row[1]: # and row[4] != cons.UNSUPPORTED: #tmp
                iters.append(row)
                id_item = row[0]
                id_items_list.append(id_item)
                del self.rows_buffer[id_item]
        [self.__model.remove(self.items.index(iter)) for iter in iters]
        
        item_list = api.get_added_items(id_items_list)
        
        api.downloader_init(item_list, current_path) #iniciar threads de descarga.
        #TODO: use a signal.
        self.downloads.store_items(item_list)

    def links_checking(self, links_list, copy_link=True):
        for link in links_list:
            download_item = api.create_download_item(cons.UNKNOWN, 0, link, copy_link) #return download_item object
            item = [download_item.id, True, cons.LINK_CHECKING, cons.UNKNOWN, None, None, None]
            #self.items.append(item)
            self.__model.append(item)
            self.rows_buffer[item[0]] = item
        api.start_checking()
    
    def update(self): #this method steals cycles, its not a new thread
        items_list = api.get_checking_update()
        for download_item in items_list:
            try:
                row = self.rows_buffer[download_item.id]
                row[1] = True if download_item.link_status != cons.LINK_DEAD else False
                row[2] = download_item.link_status
                row[3] = download_item.name
                row[4] = download_item.host
                row[5] = misc.size_format(download_item.size)
                row[6] = download_item.link_status_msg
            except KeyError as err:
                logger.debug(err)
        self.__model.refresh()