Esempio n. 1
0
def boot():

    args = sys.argv[1:]

    if len(args) > 0:

        only_run = args[0]

    else:

        only_run = None

    try:

        threading.Thread(target=reactor.run,
                         kwargs={
                             'installSignalHandlers': 0
                         }).start()

        QP.MonkeyPatchMissingMethods()
        app = QW.QApplication(sys.argv)

        app.call_after_catcher = QP.CallAfterEventCatcher(app)

        try:

            # we run the tests on the Qt thread atm
            # keep a window alive the whole time so the app doesn't finish its mainloop

            win = QW.QWidget(None)
            win.setWindowTitle('Running tests...')

            controller = TestController.Controller(win, only_run)

            def do_it():

                controller.Run(win)

            QP.CallAfter(do_it)

            app.exec_()

        except:

            HydrusData.DebugPrint(traceback.format_exc())

        finally:

            HG.view_shutdown = True

            controller.pubimmediate('wake_daemons')

            HG.model_shutdown = True

            controller.pubimmediate('wake_daemons')

            controller.TidyUp()

    except:

        HydrusData.DebugPrint(traceback.format_exc())

    finally:

        reactor.callFromThread(reactor.stop)

        print('This was version ' + str(HC.SOFTWARE_VERSION))

        input()
Esempio n. 2
0
    def __init__(self, parent, media):

        self._hashes = set()

        for m in media:

            self._hashes.update(m.GetHashes())

        ClientGUIDialogs.Dialog.__init__(
            self,
            parent,
            'manage ratings for ' + HydrusData.ToHumanInt(len(self._hashes)) +
            ' files',
            position='topleft')

        #

        like_services = HG.client_controller.services_manager.GetServices(
            (HC.LOCAL_RATING_LIKE, ))
        numerical_services = HG.client_controller.services_manager.GetServices(
            (HC.LOCAL_RATING_NUMERICAL, ))

        self._panels = []

        if len(like_services) > 0:

            self._panels.append(self._LikePanel(self, like_services, media))

        if len(numerical_services) > 0:

            self._panels.append(
                self._NumericalPanel(self, numerical_services, media))

        self._apply = QW.QPushButton('apply', self)
        self._apply.clicked.connect(self.EventOK)
        self._apply.setObjectName('HydrusAccept')

        self._cancel = QW.QPushButton('cancel', self)
        self._cancel.clicked.connect(self.reject)
        self._cancel.setObjectName('HydrusCancel')

        #

        buttonbox = QP.HBoxLayout()

        QP.AddToLayout(buttonbox, self._apply, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(buttonbox, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        for panel in self._panels:

            QP.AddToLayout(vbox, panel, CC.FLAGS_EXPAND_PERPENDICULAR)

        QP.AddToLayout(vbox, buttonbox, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        QP.SetInitialSize(self, size_hint)

        #

        self._my_shortcut_handler = ClientGUIShortcuts.ShortcutsHandler(
            self, ['global', 'media'])
Esempio n. 3
0
    def __init__(self, parent, service_key):

        Dialog.__init__(self, parent, 'configure new accounts')

        self._service_key = service_key

        self._num = QP.MakeQSpinBox(self, min=1, max=10000, width=80)

        self._account_types = ClientGUICommon.BetterChoice(self)

        self._lifetime = ClientGUICommon.BetterChoice(self)

        self._ok = QW.QPushButton('OK', self)
        self._ok.clicked.connect(self.EventOK)
        self._ok.setObjectName('HydrusAccept')

        self._cancel = QW.QPushButton('Cancel', self)
        self._cancel.clicked.connect(self.reject)
        self._cancel.setObjectName('HydrusCancel')

        #

        self._num.setValue(1)

        service = HG.client_controller.services_manager.GetService(service_key)

        response = service.Request(HC.GET, 'account_types')

        account_types = response['account_types']

        for account_type in account_types:

            self._account_types.addItem(account_type.GetTitle(), account_type)

        self._account_types.setCurrentIndex(0)

        for (s, value) in HC.lifetimes:

            self._lifetime.addItem(s, value)

        self._lifetime.setCurrentIndex(3)  # one year

        #

        ctrl_box = QP.HBoxLayout()

        QP.AddToLayout(ctrl_box,
                       ClientGUICommon.BetterStaticText(self, 'generate'),
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(ctrl_box, self._num, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(ctrl_box, self._account_types,
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(
            ctrl_box,
            ClientGUICommon.BetterStaticText(self, 'accounts, to expire in'),
            CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(ctrl_box, self._lifetime, CC.FLAGS_CENTER_PERPENDICULAR)

        b_box = QP.HBoxLayout()
        QP.AddToLayout(b_box, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(b_box, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, ctrl_box, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)
        QP.AddToLayout(vbox, b_box, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        QP.SetInitialSize(self, size_hint)

        ClientGUIFunctions.SetFocusLater(self._ok)
Esempio n. 4
0
    def __init__(self, parent, namespace='', regex=''):

        Dialog.__init__(self, parent, 'configure quick namespace')

        self._namespace = QW.QLineEdit(self)

        self._regex = QW.QLineEdit(self)

        self._shortcuts = ClientGUICommon.RegexButton(self)

        self._regex_intro_link = ClientGUICommon.BetterHyperLink(
            self, 'a good regex introduction',
            'https://www.aivosto.com/vbtips/regex.html')
        self._regex_practise_link = ClientGUICommon.BetterHyperLink(
            self, 'regex practice', 'https://regexr.com/3cvmf')

        self._ok = QW.QPushButton('OK', self)
        self._ok.clicked.connect(self.EventOK)
        self._ok.setObjectName('HydrusAccept')

        self._cancel = QW.QPushButton('Cancel', self)
        self._cancel.clicked.connect(self.reject)
        self._cancel.setObjectName('HydrusCancel')

        #

        self._namespace.setText(namespace)
        self._regex.setText(regex)

        #

        control_box = QP.HBoxLayout()

        QP.AddToLayout(control_box, self._namespace, CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(control_box,
                       ClientGUICommon.BetterStaticText(self, ':'),
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(control_box, self._regex, CC.FLAGS_EXPAND_BOTH_WAYS)

        b_box = QP.HBoxLayout()
        QP.AddToLayout(b_box, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(b_box, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        intro = r'Put the namespace (e.g. page) on the left.' + os.linesep + r'Put the regex (e.g. [1-9]+\d*(?=.{4}$)) on the right.' + os.linesep + r'All files will be tagged with "namespace:regex".'

        QP.AddToLayout(vbox, ClientGUICommon.BetterStaticText(self, intro),
                       CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, control_box, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)
        QP.AddToLayout(vbox, self._shortcuts, CC.FLAGS_ON_RIGHT)
        QP.AddToLayout(vbox, self._regex_intro_link, CC.FLAGS_ON_RIGHT)
        QP.AddToLayout(vbox, self._regex_practise_link, CC.FLAGS_ON_RIGHT)
        QP.AddToLayout(vbox, b_box, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        QP.SetInitialSize(self, size_hint)

        HG.client_controller.CallAfterQtSafe(self._ok, self._ok.setFocus,
                                             QC.Qt.OtherFocusReason)
Esempio n. 5
0
    def __init__(self, parent, external_port, protocol_type, internal_port,
                 description, duration):

        Dialog.__init__(self, parent, 'configure upnp mapping')

        self._external_port = QP.MakeQSpinBox(self, min=0, max=65535)

        self._protocol_type = ClientGUICommon.BetterChoice(self)
        self._protocol_type.addItem('TCP', 'TCP')
        self._protocol_type.addItem('UDP', 'UDP')

        self._internal_port = QP.MakeQSpinBox(self, min=0, max=65535)
        self._description = QW.QLineEdit(self)
        self._duration = QP.MakeQSpinBox(self, min=0, max=86400)

        self._ok = ClientGUICommon.BetterButton(self, 'OK', self.done,
                                                QW.QDialog.Accepted)
        self._ok.setObjectName('HydrusAccept')

        self._cancel = QW.QPushButton('Cancel', self)
        self._cancel.clicked.connect(self.reject)
        self._cancel.setObjectName('HydrusCancel')

        #

        self._external_port.setValue(external_port)

        if protocol_type == 'TCP': self._protocol_type.setCurrentIndex(0)
        elif protocol_type == 'UDP': self._protocol_type.setCurrentIndex(1)

        self._internal_port.setValue(internal_port)
        self._description.setText(description)
        self._duration.setValue(duration)

        #

        rows = []

        rows.append(('external port: ', self._external_port))
        rows.append(('protocol type: ', self._protocol_type))
        rows.append(('internal port: ', self._internal_port))
        rows.append(('description: ', self._description))
        rows.append(('duration (0 = indefinite): ', self._duration))

        gridbox = ClientGUICommon.WrapInGrid(self, rows)

        b_box = QP.HBoxLayout()
        QP.AddToLayout(b_box, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(b_box, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, gridbox, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS)
        QP.AddToLayout(vbox, b_box, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        QP.SetInitialSize(self, size_hint)

        HG.client_controller.CallAfterQtSafe(self._ok, self._ok.setFocus,
                                             QC.Qt.OtherFocusReason)
Esempio n. 6
0
 def __init__( self, parent, flat_media, do_export_and_then_quit = False ):
     
     ClientGUIScrolledPanels.ReviewPanel.__init__( self, parent )
     
     new_options = HG.client_controller.new_options
     
     self._media_to_paths = {}
     self._existing_filenames = set()
     self._last_phrase_used = ''
     self._last_dir_used = ''
     
     self._tags_box = ClientGUIListBoxes.StaticBoxSorterForListBoxTags( self, 'files\' tags' )
     
     services_manager = HG.client_controller.services_manager
     
     self._neighbouring_txt_tag_service_keys = services_manager.FilterValidServiceKeys( new_options.GetKeyList( 'default_neighbouring_txt_tag_service_keys' ) )
     
     t = ClientGUIListBoxes.ListBoxTagsMedia( self._tags_box, ClientTags.TAG_DISPLAY_ACTUAL, include_counts = True )
     
     self._tags_box.SetTagsBox( t )
     
     self._tags_box.setMinimumSize( QC.QSize( 220, 300 ) )
     
     self._paths = ClientGUIListCtrl.BetterListCtrl( self, CGLC.COLUMN_LIST_EXPORT_FILES.ID, 24, self._ConvertDataToListCtrlTuples, use_simple_delete = True )
     
     self._paths.Sort()
     
     self._export_path_box = ClientGUICommon.StaticBox( self, 'export path' )
     
     self._directory_picker = QP.DirPickerCtrl( self._export_path_box )
     self._directory_picker.dirPickerChanged.connect( self._RefreshPaths )
     
     self._open_location = QW.QPushButton( 'open this location', self._export_path_box )
     self._open_location.clicked.connect( self.EventOpenLocation )
     
     self._filenames_box = ClientGUICommon.StaticBox( self, 'filenames' )
     
     self._pattern = QW.QLineEdit( self._filenames_box )
     
     self._update = QW.QPushButton( 'update', self._filenames_box )
     self._update.clicked.connect( self._RefreshPaths )
     
     self._examples = ClientGUICommon.ExportPatternButton( self._filenames_box )
     
     self._delete_files_after_export = QW.QCheckBox( 'delete files from client after export?', self )
     self._delete_files_after_export.setObjectName( 'HydrusWarning' )
     
     self._export_symlinks = QW.QCheckBox( 'EXPERIMENTAL: export symlinks', self )
     self._export_symlinks.setObjectName( 'HydrusWarning' )
     
     text = 'This will export all the files\' tags, newline separated, into .txts beside the files themselves.'
     
     self._export_tag_txts_services_button = ClientGUICommon.BetterButton( self, 'set .txt services', self._SetTxtServices )
     
     self._export_tag_txts = QW.QCheckBox( 'export tags to .txt files?', self )
     self._export_tag_txts.setToolTip( text )
     self._export_tag_txts.clicked.connect( self.EventExportTagTxtsChanged )
     
     self._export = QW.QPushButton( 'export', self )
     self._export.clicked.connect( self._DoExport )
     
     #
     
     export_path = ClientExporting.GetExportPath()
     
     if export_path is not None:
         
         self._directory_picker.SetPath( export_path )
         
     
     phrase = new_options.GetString( 'export_phrase' )
     
     self._pattern.setText( phrase )
     
     if len( self._neighbouring_txt_tag_service_keys ) > 0:
         
         self._export_tag_txts.setChecked( True )
         
     
     self._paths.SetData( list( enumerate( flat_media ) ) )
     
     self._delete_files_after_export.setChecked( HG.client_controller.new_options.GetBoolean( 'delete_files_after_export' ) )
     self._delete_files_after_export.clicked.connect( self.EventDeleteFilesChanged )
     
     if not HG.client_controller.new_options.GetBoolean( 'advanced_mode' ):
         
         self._export_symlinks.setVisible( False )
         
     
     #
     
     top_hbox = QP.HBoxLayout()
     
     QP.AddToLayout( top_hbox, self._tags_box, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( top_hbox, self._paths, CC.FLAGS_EXPAND_BOTH_WAYS )
     
     hbox = QP.HBoxLayout()
     
     QP.AddToLayout( hbox, self._directory_picker, CC.FLAGS_EXPAND_BOTH_WAYS )
     QP.AddToLayout( hbox, self._open_location, CC.FLAGS_CENTER_PERPENDICULAR )
     
     self._export_path_box.Add( hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
     
     hbox = QP.HBoxLayout()
     
     QP.AddToLayout( hbox, self._pattern, CC.FLAGS_EXPAND_BOTH_WAYS )
     QP.AddToLayout( hbox, self._update, CC.FLAGS_CENTER_PERPENDICULAR )
     QP.AddToLayout( hbox, self._examples, CC.FLAGS_CENTER_PERPENDICULAR )
     
     self._filenames_box.Add( hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
     
     txt_hbox = QP.HBoxLayout()
     
     QP.AddToLayout( txt_hbox, self._export_tag_txts_services_button, CC.FLAGS_CENTER_PERPENDICULAR )
     QP.AddToLayout( txt_hbox, self._export_tag_txts, CC.FLAGS_CENTER_PERPENDICULAR )
     
     vbox = QP.VBoxLayout()
     
     QP.AddToLayout( vbox, top_hbox, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
     QP.AddToLayout( vbox, self._export_path_box, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, self._filenames_box, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, self._delete_files_after_export, CC.FLAGS_ON_RIGHT )
     QP.AddToLayout( vbox, self._export_symlinks, CC.FLAGS_ON_RIGHT )
     QP.AddToLayout( vbox, txt_hbox, CC.FLAGS_ON_RIGHT )
     QP.AddToLayout( vbox, self._export, CC.FLAGS_ON_RIGHT )
     
     self.widget().setLayout( vbox )
     
     self._RefreshTags()
     
     self._UpdateTxtButton()
     
     HG.client_controller.CallAfterQtSafe( self._export, self._export.setFocus, QC.Qt.OtherFocusReason)
     
     self._paths.itemSelectionChanged.connect( self._RefreshTags )
     
     if do_export_and_then_quit:
         
         QP.CallAfter( self._DoExport, True )
Esempio n. 7
0
    def __init__(self,
                 parent,
                 message,
                 default='',
                 placeholder=None,
                 allow_blank=False,
                 suggestions=None,
                 max_chars=None,
                 password_entry=False,
                 min_char_width=72):

        if suggestions is None:

            suggestions = []

        Dialog.__init__(self, parent, 'enter text', position='center')

        self._chosen_suggestion = None
        self._allow_blank = allow_blank
        self._max_chars = max_chars

        button_choices = []

        for text in suggestions:

            button_choices.append(
                ClientGUICommon.BetterButton(self, text, self.ButtonChoice,
                                             text))

        self._text = QW.QLineEdit(self)
        self._text.textChanged.connect(self.EventText)
        self._text.installEventFilter(
            ClientGUICommon.TextCatchEnterEventFilter(self._text,
                                                      self.EnterText))

        width = ClientGUIFunctions.ConvertTextToPixelWidth(
            self._text, min_char_width)

        self._text.setMinimumWidth(width)

        if password_entry:

            self._text.setEchoMode(QW.QLineEdit.Password)

        if self._max_chars is not None:

            self._text.setMaxLength(self._max_chars)

        self._ok = ClientGUICommon.BetterButton(self, 'ok', self.done,
                                                QW.QDialog.Accepted)
        self._ok.setObjectName('HydrusAccept')

        self._cancel = QW.QPushButton('cancel', self)
        self._cancel.clicked.connect(self.reject)
        self._cancel.setObjectName('HydrusCancel')

        #

        self._text.setText(default)

        if placeholder is not None:

            self._text.setPlaceholderText(placeholder)

        if len(default) > 0:

            self._text.setSelection(0, len(default))

        self._CheckText()

        #

        hbox = QP.HBoxLayout()

        QP.AddToLayout(hbox, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(hbox, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        st_message = ClientGUICommon.BetterStaticText(self, message)
        st_message.setWordWrap(True)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, st_message, CC.FLAGS_EXPAND_PERPENDICULAR)

        for button in button_choices:

            QP.AddToLayout(vbox, button, CC.FLAGS_EXPAND_PERPENDICULAR)

        QP.AddToLayout(vbox, self._text, CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(vbox, hbox, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        size_hint.setWidth(max(size_hint.width(), 250))

        QP.SetInitialSize(self, size_hint)
    def CallBlockingToQt(self, win, func, *args, **kwargs):
        def qt_code(win: QW.QWidget, job_key: ClientThreading.JobKey):

            try:

                if win is not None and not QP.isValid(win):

                    raise HydrusExceptions.QtDeadWindowException(
                        'Parent Window was destroyed before Qt command was called!'
                    )

                result = func(*args, **kwargs)

                job_key.SetVariable('result', result)

            except (HydrusExceptions.QtDeadWindowException,
                    HydrusExceptions.DBCredentialsException,
                    HydrusExceptions.ShutdownException) as e:

                job_key.SetErrorException(e)

            except Exception as e:

                job_key.SetErrorException(e)

                HydrusData.Print('CallBlockingToQt just caught this error:')
                HydrusData.DebugPrint(traceback.format_exc())

            finally:

                job_key.Finish()

        job_key = ClientThreading.JobKey()

        job_key.Begin()

        QP.CallAfter(qt_code, win, job_key)

        while not job_key.IsDone():

            if HG.model_shutdown:

                raise HydrusExceptions.ShutdownException(
                    'Application is shutting down!')

            time.sleep(0.05)

        if job_key.HasVariable('result'):

            # result can be None, for qt_code that has no return variable

            result = job_key.GetIfHasVariable('result')

            return result

        if job_key.HadError():

            e = job_key.GetErrorException()

            raise e

        raise HydrusExceptions.ShutdownException()
Esempio n. 9
0
    def SetControl(self, control):

        self._control = control

        QP.AddToLayout(self._vbox, control, CC.FLAGS_EXPAND_BOTH_WAYS)
Esempio n. 10
0
    def __init__(self, parent,
                 predicates: typing.Collection[ClientSearch.Predicate]):

        ClientGUIScrolledPanels.EditPanel.__init__(self, parent)

        predicates = list(predicates)

        predicates.sort(key=lambda p: p.ToString(with_count=False))

        self._uneditable_predicates = []

        self._invertible_pred_buttons = []
        self._editable_pred_panels = []

        rating_preds = []

        # I hate this pred comparison stuff, but let's hang in there until we split this stuff up by type mate
        # then we can just have a dict type->panel_class lookup or whatever
        # also it would be nice to have proper rating editing here, think about it

        AGE_DELTA_PRED = ClientSearch.Predicate(
            ClientSearch.PREDICATE_TYPE_SYSTEM_AGE,
            ('>', 'delta', (2000, 1, 1, 1)))
        MODIFIED_DELTA_PRED = ClientSearch.Predicate(
            ClientSearch.PREDICATE_TYPE_SYSTEM_MODIFIED_TIME,
            ('>', 'delta', (2000, 1, 1, 1)))
        KNOWN_URL_EXACT = ClientSearch.Predicate(
            ClientSearch.PREDICATE_TYPE_SYSTEM_KNOWN_URLS,
            (True, 'exact_match', '', ''))
        KNOWN_URL_DOMAIN = ClientSearch.Predicate(
            ClientSearch.PREDICATE_TYPE_SYSTEM_KNOWN_URLS,
            (True, 'domain', '', ''))
        KNOWN_URL_REGEX = ClientSearch.Predicate(
            ClientSearch.PREDICATE_TYPE_SYSTEM_KNOWN_URLS,
            (True, 'regex', '', ''))
        FILE_VIEWS_PRED = ClientSearch.Predicate(
            ClientSearch.PREDICATE_TYPE_SYSTEM_FILE_VIEWING_STATS,
            ('views', ('media', ), '>', 0))

        for predicate in predicates:

            predicate_type = predicate.GetType()

            if predicate_type == ClientSearch.PREDICATE_TYPE_OR_CONTAINER:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesOR.ORPredicateControl(self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_AGE:

                if predicate.IsUIEditable(AGE_DELTA_PRED):

                    self._editable_pred_panels.append(
                        ClientGUIPredicatesSingle.PanelPredicateSystemAgeDelta(
                            self, predicate))

                else:

                    self._editable_pred_panels.append(
                        ClientGUIPredicatesSingle.PanelPredicateSystemAgeDate(
                            self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_MODIFIED_TIME:

                if predicate.IsUIEditable(MODIFIED_DELTA_PRED):

                    self._editable_pred_panels.append(
                        ClientGUIPredicatesSingle.
                        PanelPredicateSystemModifiedDelta(self, predicate))

                else:

                    self._editable_pred_panels.append(
                        ClientGUIPredicatesSingle.
                        PanelPredicateSystemModifiedDate(self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_HEIGHT:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemHeight(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_WIDTH:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemWidth(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemRatio(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_PIXELS:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumPixels(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_DURATION:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemDuration(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_FRAMERATE:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemFramerate(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_FRAMES:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumFrames(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_FILE_SERVICE:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemFileService(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_KNOWN_URLS:

                if predicate.IsUIEditable(KNOWN_URL_EXACT):

                    self._editable_pred_panels.append(
                        ClientGUIPredicatesSingle.
                        PanelPredicateSystemKnownURLsExactURL(self, predicate))

                elif predicate.IsUIEditable(KNOWN_URL_DOMAIN):

                    self._editable_pred_panels.append(
                        ClientGUIPredicatesSingle.
                        PanelPredicateSystemKnownURLsDomain(self, predicate))

                elif predicate.IsUIEditable(KNOWN_URL_REGEX):

                    self._editable_pred_panels.append(
                        ClientGUIPredicatesSingle.
                        PanelPredicateSystemKnownURLsRegex(self, predicate))

                else:

                    self._editable_pred_panels.append(
                        ClientGUIPredicatesSingle.
                        PanelPredicateSystemKnownURLsURLClass(self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_HASH:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemHash(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_LIMIT:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemLimit(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_MIME:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemMime(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_TAGS:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumTags(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_NOTES:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumNotes(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_HAS_NOTE_NAME:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemHasNoteName(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_WORDS:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumWords(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_SIMILAR_TO:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemSimilarTo(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_SIZE:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemSize(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_TAG_AS_NUMBER:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.PanelPredicateSystemTagAsNumber(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_FILE_RELATIONSHIPS_COUNT:

                self._editable_pred_panels.append(
                    ClientGUIPredicatesSingle.
                    PanelPredicateSystemDuplicateRelationships(
                        self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_FILE_VIEWING_STATS:

                if predicate.IsUIEditable(FILE_VIEWS_PRED):

                    self._editable_pred_panels.append(
                        ClientGUIPredicatesSingle.
                        PanelPredicateSystemFileViewingStatsViews(
                            self, predicate))

                else:

                    self._editable_pred_panels.append(
                        ClientGUIPredicatesSingle.
                        PanelPredicateSystemFileViewingStatsViewtime(
                            self, predicate))

            elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_RATING:

                rating_preds.append(predicate)

            elif predicate.IsInvertible():

                self._invertible_pred_buttons.append(
                    ClientGUIPredicatesSingle.InvertiblePredicateButton(
                        self, predicate))

            else:

                self._uneditable_predicates.append(predicate)

        if len(rating_preds) > 0:

            self._editable_pred_panels.append(
                ClientGUIPredicatesMultiple.PanelPredicateSystemRating(
                    self, rating_preds))

        vbox = QP.VBoxLayout()

        for button in self._invertible_pred_buttons:

            QP.AddToLayout(vbox, button, CC.FLAGS_EXPAND_PERPENDICULAR)

        for panel in self._editable_pred_panels:

            QP.AddToLayout(vbox, panel, CC.FLAGS_EXPAND_PERPENDICULAR)

        self.widget().setLayout(vbox)
Esempio n. 11
0
    def __init__(self, parent, predicate: ClientSearch.Predicate):

        ClientGUIScrolledPanels.EditPanel.__init__(self, parent)

        predicate_type = predicate.GetType()

        self._predicates = []

        label = None
        editable_pred_panels = []
        static_pred_buttons = []

        recent_predicate_types = [predicate_type]

        if predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_AGE:

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_AGE,
                        ('<', 'delta', (0, 0, 1, 0))), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_AGE,
                        ('<', 'delta', (0, 0, 7, 0))), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_AGE,
                        ('<', 'delta', (0, 1, 0, 0))), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemAgeDelta,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemAgeDate,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_MODIFIED_TIME:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemModifiedDelta, predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemModifiedDate,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_DIMENSIONS:

            recent_predicate_types = [
                ClientSearch.PREDICATE_TYPE_SYSTEM_HEIGHT,
                ClientSearch.PREDICATE_TYPE_SYSTEM_WIDTH,
                ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO,
                ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_PIXELS
            ]

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO,
                        ('=', 16, 9)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO,
                        ('=', 9, 16)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO,
                        ('=', 4, 3)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO,
                        ('=', 1, 1)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self,
                    self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_WIDTH, ('=', 1920)),
                           ClientSearch.Predicate(
                               ClientSearch.PREDICATE_TYPE_SYSTEM_HEIGHT,
                               ('=', 1080))),
                    forced_label='1080p'))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self,
                    self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_WIDTH, ('=', 1280)),
                           ClientSearch.Predicate(
                               ClientSearch.PREDICATE_TYPE_SYSTEM_HEIGHT,
                               ('=', 720))),
                    forced_label='720p'))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self,
                    self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_WIDTH, ('=', 3840)),
                           ClientSearch.Predicate(
                               ClientSearch.PREDICATE_TYPE_SYSTEM_HEIGHT,
                               ('=', 2160))),
                    forced_label='4k'))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemHeight,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemWidth,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemRatio,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumPixels,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_DURATION:

            recent_predicate_types = [
                ClientSearch.PREDICATE_TYPE_SYSTEM_DURATION,
                ClientSearch.PREDICATE_TYPE_SYSTEM_FRAMERATE,
                ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_FRAMES
            ]

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_DURATION,
                        ('>', 0)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_DURATION,
                        ('=', 0)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_FRAMERATE,
                        ('=', 30)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_FRAMERATE,
                        ('=', 60)), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemDuration,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemFramerate,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumFrames,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_FILE_SERVICE:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemFileService,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_KNOWN_URLS:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemKnownURLsExactURL, predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemKnownURLsDomain, predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemKnownURLsRegex, predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemKnownURLsURLClass, predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_HAS_AUDIO:

            recent_predicate_types = []

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_HAS_AUDIO,
                        True), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_HAS_AUDIO,
                        False), )))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_HASH:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemHash,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_LIMIT:

            label = 'system:limit clips a large search result down to the given number of files. It is very useful for processing in smaller batches.'
            label += os.linesep * 2
            label += 'For all the simpler sorts (filesize, duration, etc...), it will select the n largest/smallest in the result set appropriate for that sort. For complicated sorts like tags, it will sample randomly.'

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_LIMIT, 64), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_LIMIT, 256), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_LIMIT, 1024), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemLimit,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_MIME:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemMime,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_TAGS:

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_TAGS,
                        (None, '>', 0)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_TAGS,
                        (None, '=', 0)), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumTags,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NOTES:

            recent_predicate_types = [
                ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_NOTES,
                ClientSearch.PREDICATE_TYPE_SYSTEM_HAS_NOTE_NAME
            ]

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_NOTES,
                        ('>', 0)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_NOTES,
                        ('=', 0)), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumNotes,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemHasNoteName,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_WORDS:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumWords,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_RATING:

            services_manager = HG.client_controller.services_manager

            ratings_services = services_manager.GetServices(
                (HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL))

            if len(ratings_services) > 0:

                editable_pred_panels.append(
                    self._PredOKPanel(
                        self,
                        ClientGUIPredicatesMultiple.PanelPredicateSystemRating,
                        (predicate, )))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_SIMILAR_TO:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemSimilarTo,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_SIZE:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemSize,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_TAG_AS_NUMBER:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemTagAsNumber,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_FILE_RELATIONSHIPS:

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.
                        PREDICATE_TYPE_SYSTEM_FILE_RELATIONSHIPS_KING,
                        False), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.
                        PREDICATE_TYPE_SYSTEM_FILE_RELATIONSHIPS_KING,
                        True), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemDuplicateRelationships, predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_FILE_VIEWING_STATS:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemFileViewingStatsViews, predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemFileViewingStatsViewtime, predicate))

        vbox = QP.VBoxLayout()

        if label is not None:

            st = ClientGUICommon.BetterStaticText(self, label=label)

            st.setWordWrap(True)

            QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)

        recent_predicates = []

        if len(recent_predicate_types) > 0:

            recent_predicates = HG.client_controller.new_options.GetRecentPredicates(
                recent_predicate_types)

            if len(recent_predicates) > 0:

                recent_predicates_box = ClientGUICommon.StaticBox(
                    self, 'recent')

                for recent_predicate in recent_predicates:

                    button = ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                        recent_predicates_box, self, (recent_predicate, ))

                    recent_predicates_box.Add(button,
                                              CC.FLAGS_EXPAND_PERPENDICULAR)

                QP.AddToLayout(vbox, recent_predicates_box,
                               CC.FLAGS_EXPAND_PERPENDICULAR)

        for button in static_pred_buttons:

            QP.AddToLayout(vbox, button, CC.FLAGS_EXPAND_PERPENDICULAR)

        for panel in editable_pred_panels:

            QP.AddToLayout(vbox, panel, CC.FLAGS_EXPAND_PERPENDICULAR)

        if len(static_pred_buttons) > 0 and len(editable_pred_panels) == 0:

            HG.client_controller.CallAfterQtSafe(
                static_pred_buttons[0], static_pred_buttons[0].setFocus,
                QC.Qt.OtherFocusReason)

        self.widget().setLayout(vbox)
Esempio n. 12
0
 def __init__( self, parent ):
     
     QW.QWidget.__init__( self, parent )
     
     self.setWindowFlags( QC.Qt.Tool | QC.Qt.FramelessWindowHint )
     
     self.setAttribute( QC.Qt.WA_ShowWithoutActivating )
     
     self.setSizePolicy( QW.QSizePolicy.MinimumExpanding, QW.QSizePolicy.Preferred )
     
     self._last_best_size_i_fit_on = ( 0, 0 )
     
     self._max_messages_to_display = 10
     
     vbox = QP.VBoxLayout()
     
     self._message_panel = QW.QWidget( self )
     
     self._message_vbox = QP.VBoxLayout( margin = 0 )
     
     vbox.setSizeConstraint( QW.QLayout.SetFixedSize )
     
     self._message_panel.setLayout( self._message_vbox )
     self._message_panel.setSizePolicy( QW.QSizePolicy.MinimumExpanding, QW.QSizePolicy.Preferred )
     
     self._summary_bar = PopupMessageSummaryBar( self, self )
     self._summary_bar.setSizePolicy( QW.QSizePolicy.MinimumExpanding, QW.QSizePolicy.Preferred )
     
     QP.AddToLayout( vbox, self._message_panel )
     QP.AddToLayout( vbox, self._summary_bar )
     
     self.setLayout( vbox )
     
     self._pending_job_keys = []
     
     self._gui_event_filter = QP.WidgetEventFilter( parent )
     self._gui_event_filter.EVT_SIZE( self.EventParentMovedOrResized )
     self._gui_event_filter.EVT_MOVE( self.EventParentMovedOrResized )
     
     HG.client_controller.sub( self, 'AddMessage', 'message' )
     
     self._old_excepthook = sys.excepthook
     self._old_show_exception = HydrusData.ShowException
     self._old_show_exception_tuple = HydrusData.ShowExceptionTuple
     self._old_show_text = HydrusData.ShowText
     
     sys.excepthook = ClientData.CatchExceptionClient
     HydrusData.ShowException = ClientData.ShowExceptionClient
     HydrusData.ShowExceptionTuple = ClientData.ShowExceptionTupleClient
     HydrusData.ShowText = ClientData.ShowTextClient
     
     job_key = ClientThreading.JobKey()
     
     job_key.SetVariable( 'popup_text_1', 'initialising popup message manager\u2026' )
     
     self._update_job = HG.client_controller.CallRepeatingQtSafe( self, 0.25, 0.5, 'repeating popup message update', self.REPEATINGUpdate )
     
     self._summary_bar.expandCollapse.connect( self.ExpandCollapse )
     
     HG.client_controller.CallLaterQtSafe( self, 0.5, 'initialise message', self.AddMessage, job_key )
     
     HG.client_controller.CallLaterQtSafe( self, 1.0, 'delete initial message', job_key.Delete )
Esempio n. 13
0
 def __init__( self, parent, manager, job_key: ClientThreading.JobKey ):
     
     PopupWindow.__init__( self, parent, manager )
     
     self.setSizePolicy( QW.QSizePolicy.MinimumExpanding, QW.QSizePolicy.Fixed )
     
     self._job_key = job_key
     
     vbox = QP.VBoxLayout()
     
     self._title = ClientGUICommon.BetterStaticText( self )
     self._title.setAlignment( QC.Qt.AlignHCenter | QC.Qt.AlignVCenter )
     
     font = self._title.font()
     font.setBold( True )
     self._title.setFont( font )
     
     popup_message_character_width = HG.client_controller.new_options.GetInteger( 'popup_message_character_width' )
     
     popup_char_width = ClientGUIFunctions.ConvertTextToPixelWidth( self._title, popup_message_character_width )
     
     if HG.client_controller.new_options.GetBoolean( 'popup_message_force_min_width' ):
         
         #QP.SetMinClientSize( self, ( wrap_width, -1 ) )
         self.setFixedWidth( popup_char_width )
         
     else:
         
         self.setMaximumWidth( popup_char_width )
         
     
     self._title.setWordWrap( True )
     self._title_ev = QP.WidgetEventFilter( self._title )
     self._title_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._title.hide()
     
     self._text_1 = ClientGUICommon.BetterStaticText( self )
     self._text_1.setWordWrap( True )
     self._text_1_ev = QP.WidgetEventFilter( self._text_1 )
     self._text_1_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._text_1.hide()
     
     self._gauge_1 = ClientGUICommon.Gauge( self )
     self._gauge_1_ev = QP.WidgetEventFilter( self._gauge_1 )
     self._gauge_1_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._gauge_1.setMinimumWidth( int( popup_char_width * 0.9 ) )
     self._gauge_1.hide()
     
     self._text_2 = ClientGUICommon.BetterStaticText( self )
     self._text_2.setWordWrap( True )
     self._text_2_ev = QP.WidgetEventFilter( self._text_2 )
     self._text_2_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._text_2.hide()
     
     self._gauge_2 = ClientGUICommon.Gauge( self )
     self._gauge_2_ev = QP.WidgetEventFilter( self._gauge_2 )
     self._gauge_2_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._gauge_2.setMinimumWidth( int( popup_char_width * 0.9 ) )
     self._gauge_2.hide()
     
     self._text_yes_no = ClientGUICommon.BetterStaticText( self )
     self._text_yes_no_ev = QP.WidgetEventFilter( self._text_yes_no )
     self._text_yes_no_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._text_yes_no.hide()
     
     self._yes = ClientGUICommon.BetterButton( self, 'yes', self._YesButton )
     self._yes.hide()
     
     self._no = ClientGUICommon.BetterButton( self, 'no', self._NoButton )
     self._no.hide()
     
     self._network_job_ctrl = ClientGUINetworkJobControl.NetworkJobControl( self )
     self._network_job_ctrl.hide()
     
     self._copy_to_clipboard_button = ClientGUICommon.BetterButton( self, 'copy to clipboard', self.CopyToClipboard )
     self._copy_to_clipboard_button_ev = QP.WidgetEventFilter( self._copy_to_clipboard_button )
     self._copy_to_clipboard_button_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._copy_to_clipboard_button.hide()
     
     self._show_files_button = ClientGUICommon.BetterButton( self, 'show files', self.ShowFiles )
     self._show_files_button_ev = QP.WidgetEventFilter( self._show_files_button )
     self._show_files_button_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._show_files_button.hide()
     
     self._user_callable_button = ClientGUICommon.BetterButton( self, 'run command', self.CallUserCallable )
     self._user_callable_button_ev = QP.WidgetEventFilter( self._user_callable_button )
     self._user_callable_button_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._user_callable_button.hide()
     
     self._show_tb_button = ClientGUICommon.BetterButton( self, 'show traceback', self.ShowTB )
     self._show_tb_button_ev = QP.WidgetEventFilter( self._show_tb_button )
     self._show_tb_button_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._show_tb_button.hide()
     
     self._tb_text = ClientGUICommon.BetterStaticText( self )
     self._tb_text_ev = QP.WidgetEventFilter( self._tb_text )
     self._tb_text_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._tb_text.setWordWrap( True )
     self._tb_text.hide()
     
     self._copy_tb_button = ClientGUICommon.BetterButton( self, 'copy traceback information', self.CopyTB )
     self._copy_tb_button_ev = QP.WidgetEventFilter( self._copy_tb_button )
     self._copy_tb_button_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._copy_tb_button.hide()
     
     self._pause_button = ClientGUICommon.BetterBitmapButton( self, CC.global_pixmaps().pause, self.PausePlay )
     self._pause_button_ev = QP.WidgetEventFilter( self._pause_button )
     self._pause_button_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._pause_button.hide()
     
     self._cancel_button = ClientGUICommon.BetterBitmapButton( self, CC.global_pixmaps().stop, self.Cancel )
     self._cancel_button_ev = QP.WidgetEventFilter( self._cancel_button )
     self._cancel_button_ev.EVT_RIGHT_DOWN( self.EventDismiss )
     self._cancel_button.hide()
     
     hbox = QP.HBoxLayout()
     
     QP.AddToLayout( hbox, self._pause_button, CC.FLAGS_CENTER_PERPENDICULAR )
     QP.AddToLayout( hbox, self._cancel_button, CC.FLAGS_CENTER_PERPENDICULAR )
     
     yes_no_hbox = QP.HBoxLayout()
     
     QP.AddToLayout( yes_no_hbox, self._yes, CC.FLAGS_CENTER_PERPENDICULAR )
     QP.AddToLayout( yes_no_hbox, self._no, CC.FLAGS_CENTER_PERPENDICULAR )
     
     QP.AddToLayout( vbox, self._title, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, self._text_1, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, self._gauge_1, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, self._text_2, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, self._gauge_2, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, self._text_yes_no, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, yes_no_hbox )
     QP.AddToLayout( vbox, self._network_job_ctrl )
     QP.AddToLayout( vbox, self._copy_to_clipboard_button )
     QP.AddToLayout( vbox, self._show_files_button )
     QP.AddToLayout( vbox, self._user_callable_button )
     QP.AddToLayout( vbox, self._show_tb_button )
     QP.AddToLayout( vbox, self._tb_text )
     QP.AddToLayout( vbox, self._copy_tb_button )
     QP.AddToLayout( vbox, hbox, CC.FLAGS_ON_RIGHT )
     
     self.setLayout( vbox )
Esempio n. 14
0
def CreateTopImage(width, title, payload_description, text):

    text_extent_qt_image = HG.client_controller.bitmap_manager.GetQtImage(
        20, 20, 24)

    painter = QG.QPainter(text_extent_qt_image)

    text_font = QW.QApplication.font()

    basic_font_size = text_font.pointSize()

    payload_description_font = QW.QApplication.font()

    payload_description_font.setPointSize(int(basic_font_size * 1.4))

    title_font = QW.QApplication.font()

    title_font.setPointSize(int(basic_font_size * 2.0))

    texts_to_draw = []

    current_y = 6

    for (t, f) in ((title, title_font), (payload_description,
                                         payload_description_font),
                   (text, text_font)):

        painter.setFont(f)

        wrapped_texts = WrapText(painter, t, width - 20)
        line_height = painter.fontMetrics().height()

        wrapped_texts_with_ys = []

        if len(wrapped_texts) > 0:

            current_y += 10

            for wrapped_text in wrapped_texts:

                wrapped_texts_with_ys.append((wrapped_text, current_y))

                current_y += line_height + 4

        texts_to_draw.append((wrapped_texts_with_ys, f))

    current_y += 6

    top_height = current_y

    del painter
    del text_extent_qt_image

    #

    top_qt_image = HG.client_controller.bitmap_manager.GetQtImage(
        width, top_height, 24)

    painter = QG.QPainter(top_qt_image)

    painter.setBackground(QG.QBrush(QC.Qt.white))

    painter.eraseRect(painter.viewport())

    #

    painter.drawPixmap(width - 16 - 5, 5, CC.global_pixmaps().file_repository)

    #

    for (wrapped_texts_with_ys, f) in texts_to_draw:

        painter.setFont(f)

        for (wrapped_text, y) in wrapped_texts_with_ys:

            text_size = painter.fontMetrics().size(QC.Qt.TextSingleLine,
                                                   wrapped_text)

            QP.DrawText(painter, (width - text_size.width()) // 2, y,
                        wrapped_text)

    del painter

    data_bytearray = top_qt_image.bits()

    if QP.qtpy.PYSIDE2:

        data_bytes = bytes(data_bytearray)

    elif QP.qtpy.PYQT5:

        data_bytes = data_bytearray.asstring(top_height * width * 3)

    top_image_rgb = numpy.fromstring(data_bytes, dtype='uint8').reshape(
        (top_height, width, 3))

    top_image = cv2.cvtColor(top_image_rgb, cv2.COLOR_RGB2GRAY)

    top_height_header = struct.pack('!H', top_height)

    byte0 = top_height_header[0:1]
    byte1 = top_height_header[1:2]

    top_image[0][0] = ord(byte0)
    top_image[0][1] = ord(byte1)

    return top_image
Esempio n. 15
0
    def __init__(self,
                 parent,
                 payload_obj,
                 title=None,
                 description=None,
                 payload_description=None):

        ClientGUIScrolledPanels.ReviewPanel.__init__(self, parent)

        self._payload_obj = payload_obj

        self._filepicker = QP.FilePickerCtrl(self, wildcard='PNG (*.png)')
        self._filepicker.SetSaveMode(True)

        flp_width = ClientGUIFunctions.ConvertTextToPixelWidth(
            self._filepicker, 64)

        self._filepicker.setMinimumWidth(flp_width)

        self._title = QW.QLineEdit(self)

        self._payload_description = QW.QLineEdit(self)

        self._text = QW.QLineEdit(self)

        self._width = ClientGUICommon.BetterSpinBox(self, min=100, max=4096)

        self._export = ClientGUICommon.BetterButton(self, 'export',
                                                    self.Export)

        #

        if payload_description is None:

            (payload_description,
             payload_bytes) = ClientSerialisable.GetPayloadDescriptionAndBytes(
                 self._payload_obj)

        else:

            (payload_bytes,
             payload_length) = ClientSerialisable.GetPayloadBytesAndLength(
                 self._payload_obj)

            payload_description += ' - {}'.format(
                HydrusData.ToHumanBytes(payload_length))

        self._payload_description.setText(payload_description)

        self._payload_description.setEnabled(False)

        self._width.setValue(512)

        last_png_export_dir = HG.client_controller.new_options.GetNoneableString(
            'last_png_export_dir')

        if title is not None:

            name = title

        elif isinstance(self._payload_obj,
                        HydrusSerialisable.SerialisableBaseNamed):

            name = self._payload_obj.GetName()

        else:

            name = payload_description

        self._title.setText(name)

        if description is not None:

            self._text.setText(description)

        if last_png_export_dir is not None:

            filename = name + '.png'

            filename = HydrusPaths.SanitizeFilename(filename)

            path = os.path.join(last_png_export_dir, filename)

            self._filepicker.SetPath(path)

        self._Update()

        #

        rows = []

        rows.append(('export path: ', self._filepicker))
        rows.append(('title: ', self._title))
        rows.append(('payload description: ', self._payload_description))
        rows.append(('your description (optional): ', self._text))
        rows.append(('png width: ', self._width))
        rows.append(('', self._export))

        gridbox = ClientGUICommon.WrapInGrid(self, rows)

        self.widget().setLayout(gridbox)

        self._filepicker.filePickerChanged.connect(self._Update)
        self._title.textChanged.connect(self._Update)
Esempio n. 16
0
    def __init__(self, parent, checker_options):

        ClientGUIScrolledPanels.EditPanel.__init__(self, parent)

        help_button = ClientGUICommon.BetterBitmapButton(
            self,
            CC.global_pixmaps().help, self._ShowHelp)
        help_button.setToolTip('Show help regarding these checker options.')

        help_hbox = ClientGUICommon.WrapInText(
            help_button,
            self,
            'help for this panel -->',
            object_name='HydrusIndeterminate')

        from hydrus.client import ClientDefaults

        defaults_panel = ClientGUICommon.StaticBox(self, 'reasonable defaults')

        defaults_1 = ClientGUICommon.BetterButton(
            defaults_panel, 'thread', self.SetValue,
            ClientDefaults.GetDefaultCheckerOptions('thread'))
        defaults_2 = ClientGUICommon.BetterButton(
            defaults_panel, 'slow thread', self.SetValue,
            ClientDefaults.GetDefaultCheckerOptions('slow thread'))
        defaults_3 = ClientGUICommon.BetterButton(
            defaults_panel, 'faster tag subscription', self.SetValue,
            ClientDefaults.GetDefaultCheckerOptions('fast tag subscription'))
        defaults_4 = ClientGUICommon.BetterButton(
            defaults_panel, 'medium tag/artist subscription', self.SetValue,
            ClientDefaults.GetDefaultCheckerOptions('artist subscription'))
        defaults_5 = ClientGUICommon.BetterButton(
            defaults_panel, 'slower tag subscription', self.SetValue,
            ClientDefaults.GetDefaultCheckerOptions('slow tag subscription'))

        #

        # add statictext or whatever that will update on any updates above to say 'given velocity of blah and last check at blah, next check in 5 mins'
        # or indeed this could just take the file_seed cache and last check of the caller, if there is one
        # this would be more useful to the user, to know 'right, on ok, it'll refresh in 30 mins'
        # this is actually more complicated--it also needs last check time to calc a fresh file velocity based on new death_file_velocity

        #

        min_unit_value = 0
        max_unit_value = 1000
        min_time_delta = 60

        self._death_file_velocity = VelocityCtrl(self,
                                                 min_unit_value,
                                                 max_unit_value,
                                                 min_time_delta,
                                                 days=True,
                                                 hours=True,
                                                 minutes=True,
                                                 per_phrase='in',
                                                 unit='files')

        self._flat_check_period_checkbox = QW.QCheckBox(self)

        #

        if HG.client_controller.new_options.GetBoolean('advanced_mode'):

            never_faster_than_min = 1
            never_slower_than_min = 1

            flat_check_period_min = 1

        else:

            never_faster_than_min = 30
            never_slower_than_min = 600

            flat_check_period_min = 180

        self._reactive_check_panel = ClientGUICommon.StaticBox(
            self, 'reactive checking')

        self._intended_files_per_check = QP.MakeQSpinBox(
            self._reactive_check_panel, min=1, max=1000)
        self._intended_files_per_check.setToolTip(
            'How many new files you want the checker to find on each check. If a source is producing about 2 files a day, and this is set to 6, you will probably get a check every three days. You probably want this to be a low number, like 1-4.'
        )

        self._never_faster_than = TimeDeltaCtrl(self._reactive_check_panel,
                                                min=never_faster_than_min,
                                                days=True,
                                                hours=True,
                                                minutes=True,
                                                seconds=True)
        self._never_faster_than.setToolTip(
            'Even if the download source produces many new files, the checker will never ask for a check more often than this. This is a safety measure.'
        )

        self._never_slower_than = TimeDeltaCtrl(self._reactive_check_panel,
                                                min=never_slower_than_min,
                                                days=True,
                                                hours=True,
                                                minutes=True,
                                                seconds=True)
        self._never_slower_than.setToolTip(
            'Even if the download source slows down significantly, the checker will make sure it checks at least this often anyway, just to catch a future wave in time.'
        )

        #

        self._static_check_panel = ClientGUICommon.StaticBox(
            self, 'static checking')

        self._flat_check_period = TimeDeltaCtrl(self._static_check_panel,
                                                min=flat_check_period_min,
                                                days=True,
                                                hours=True,
                                                minutes=True,
                                                seconds=True)
        self._flat_check_period.setToolTip(
            'Always use the same check delay. It is based on the time the last check completed, not the time the last check was due. If you want once a day with no skips, try setting this to 23 hours.'
        )

        #

        self.SetValue(checker_options)

        #

        defaults_panel.Add(defaults_1, CC.FLAGS_EXPAND_PERPENDICULAR)
        defaults_panel.Add(defaults_2, CC.FLAGS_EXPAND_PERPENDICULAR)
        defaults_panel.Add(defaults_3, CC.FLAGS_EXPAND_PERPENDICULAR)
        defaults_panel.Add(defaults_4, CC.FLAGS_EXPAND_PERPENDICULAR)
        defaults_panel.Add(defaults_5, CC.FLAGS_EXPAND_PERPENDICULAR)

        #

        #

        label = 'This checks more or less frequently based on how fast the download source is producing new files.'

        st = ClientGUICommon.BetterStaticText(self._reactive_check_panel,
                                              label=label)

        st.setWordWrap(True)

        rows = []

        rows.append(
            ('intended new files per check: ', self._intended_files_per_check))
        rows.append(
            ('never check faster than once per: ', self._never_faster_than))
        rows.append(
            ('never check slower than once per: ', self._never_slower_than))

        gridbox = ClientGUICommon.WrapInGrid(self._reactive_check_panel, rows)

        self._reactive_check_panel.Add(st, CC.FLAGS_EXPAND_PERPENDICULAR)
        self._reactive_check_panel.Add(gridbox,
                                       CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        #

        rows = []

        rows.append(('check period: ', self._flat_check_period))

        gridbox = ClientGUICommon.WrapInGrid(self._static_check_panel, rows)

        self._static_check_panel.Add(gridbox,
                                     CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        #

        rows = []

        rows.append(('stop checking if new files found falls below: ',
                     self._death_file_velocity))
        rows.append(('just check at a static, regular interval: ',
                     self._flat_check_period_checkbox))

        gridbox = ClientGUICommon.WrapInGrid(self, rows)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, help_hbox, CC.FLAGS_EXPAND_PERPENDICULAR)

        label = 'If you do not understand this panel, use the buttons! The defaults are fine for most purposes!'

        st = ClientGUICommon.BetterStaticText(self._reactive_check_panel,
                                              label=label)

        st.setWordWrap(True)
        st.setObjectName('HydrusWarning')

        QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, defaults_panel, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        if HG.client_controller.new_options.GetBoolean('advanced_mode'):

            label = 'As you are in advanced mode, these options have extremely low limits. This is intended only for testing and small scale private network tasks. Do not use very fast check times for real world use on public websites, as it is wasteful and rude, hydrus will be overloaded with high-CPU parsing work, and you may get your IP banned.'

            st = ClientGUICommon.BetterStaticText(self, label=label)
            st.setObjectName('HydrusWarning')

            st.setWordWrap(True)

            QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)

        QP.AddToLayout(vbox, self._reactive_check_panel,
                       CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._static_check_panel,
                       CC.FLAGS_EXPAND_PERPENDICULAR)

        vbox.addStretch(1)

        self.widget().setLayout(vbox)

        #

        self._flat_check_period_checkbox.clicked.connect(
            self.EventFlatPeriodCheck)
Esempio n. 17
0
    def __init__( self, parent, export_folder: ClientExporting.ExportFolder ):
        
        ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
        
        self._export_folder = export_folder
        
        ( name, path, export_type, delete_from_client_after_export, file_search_context, run_regularly, period, phrase, self._last_checked, paused, run_now ) = self._export_folder.ToTuple()
        
        self._path_box = ClientGUICommon.StaticBox( self, 'name and location' )
        
        self._name = QW.QLineEdit( self._path_box )
        
        self._path = QP.DirPickerCtrl( self._path_box )
        
        #
        
        self._type_box = ClientGUICommon.StaticBox( self, 'type of export' )
        
        self._type = ClientGUICommon.BetterChoice( self._type_box )
        self._type.addItem( 'regular', HC.EXPORT_FOLDER_TYPE_REGULAR )
        self._type.addItem( 'synchronise', HC.EXPORT_FOLDER_TYPE_SYNCHRONISE )
        
        self._delete_from_client_after_export = QW.QCheckBox( self._type_box )
        
        #
        
        self._query_box = ClientGUICommon.StaticBox( self, 'query to export' )
        
        self._page_key = 'export folders placeholder'
        
        self._tag_autocomplete = ClientGUIACDropdown.AutoCompleteDropdownTagsRead( self._query_box, self._page_key, file_search_context, allow_all_known_files = False, force_system_everything = True )
        
        #
        
        self._period_box = ClientGUICommon.StaticBox( self, 'export period' )
        
        self._period = ClientGUITime.TimeDeltaButton( self._period_box, min = 3 * 60, days = True, hours = True, minutes = True )
        
        self._run_regularly = QW.QCheckBox( self._period_box )
        
        self._paused = QW.QCheckBox( self._period_box )
        
        self._run_now = QW.QCheckBox( self._period_box )
        
        #
        
        self._phrase_box = ClientGUICommon.StaticBox( self, 'filenames' )
        
        self._pattern = QW.QLineEdit( self._phrase_box )
        
        self._examples = ClientGUICommon.ExportPatternButton( self._phrase_box )
        
        #
        
        self._name.setText( name )
        
        self._path.SetPath( path )
        
        self._type.SetValue( export_type )
        
        self._delete_from_client_after_export.setChecked( delete_from_client_after_export )
        
        self._period.SetValue( period )
        
        self._run_regularly.setChecked( run_regularly )
        
        self._paused.setChecked( paused )
        
        self._run_now.setChecked( run_now )
        
        self._pattern.setText( phrase )
        
        #
        
        rows = []
        
        rows.append( ( 'name: ', self._name ) )
        rows.append( ( 'folder path: ', self._path ) )
        
        gridbox = ClientGUICommon.WrapInGrid( self._path_box, rows )
        
        self._path_box.Add( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
        
        #
        
        text = '''regular - try to export the files to the directory, overwriting if the filesize if different

synchronise - try to export the files to the directory, overwriting if the filesize if different, and delete anything else in the directory

If you select synchronise, be careful!'''
        
        st = ClientGUICommon.BetterStaticText( self._type_box, label = text )
        st.setWordWrap( True )
        
        self._type_box.Add( st, CC.FLAGS_EXPAND_PERPENDICULAR )
        self._type_box.Add( self._type, CC.FLAGS_EXPAND_PERPENDICULAR )
        
        rows = []
        
        rows.append( ( 'delete files from client after export: ', self._delete_from_client_after_export ) )
        
        gridbox = ClientGUICommon.WrapInGrid( self._type_box, rows )
        
        self._type_box.Add( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
        
        self._query_box.Add( self._tag_autocomplete )
        
        self._period_box.Add( self._period, CC.FLAGS_EXPAND_PERPENDICULAR )
        
        rows = []
        
        rows.append( ( 'run regularly?: ', self._run_regularly ) )
        rows.append( ( 'paused: ', self._paused ) )
        rows.append( ( 'run on dialog ok: ', self._run_now ) )
        
        gridbox = ClientGUICommon.WrapInGrid( self._period_box, rows )
        
        self._period_box.Add( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
        
        phrase_hbox = QP.HBoxLayout()
        
        QP.AddToLayout( phrase_hbox, self._pattern, CC.FLAGS_EXPAND_BOTH_WAYS )
        QP.AddToLayout( phrase_hbox, self._examples, CC.FLAGS_CENTER_PERPENDICULAR )
        
        self._phrase_box.Add( phrase_hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
        
        vbox = QP.VBoxLayout()
        
        QP.AddToLayout( vbox, self._path_box, CC.FLAGS_EXPAND_PERPENDICULAR )
        QP.AddToLayout( vbox, self._type_box, CC.FLAGS_EXPAND_PERPENDICULAR )
        QP.AddToLayout( vbox, self._query_box, CC.FLAGS_EXPAND_BOTH_WAYS )
        QP.AddToLayout( vbox, self._period_box, CC.FLAGS_EXPAND_PERPENDICULAR )
        QP.AddToLayout( vbox, self._phrase_box, CC.FLAGS_EXPAND_PERPENDICULAR )
        
        self.widget().setLayout( vbox )
        
        self._UpdateTypeDeleteUI()
        
        self._type.currentIndexChanged.connect( self._UpdateTypeDeleteUI )
        self._delete_from_client_after_export.clicked.connect( self.EventDeleteFilesAfterExport )
Esempio n. 18
0
    def __init__(self, parent, api_permissions):

        ClientGUIScrolledPanels.EditPanel.__init__(self, parent)

        self._original_api_permissions = api_permissions

        self._access_key = QW.QLineEdit()

        self._access_key.setReadOnly(True)

        width = ClientGUIFunctions.ConvertTextToPixelWidth(
            self._access_key, 66)

        self.setMinimumWidth(width)

        self._name = QW.QLineEdit(self)

        self._basic_permissions = QP.CheckListBox(self)

        for permission in ClientAPI.ALLOWED_PERMISSIONS:

            self._basic_permissions.Append(
                ClientAPI.basic_permission_to_str_lookup[permission],
                permission)

        search_tag_filter = api_permissions.GetSearchTagFilter()

        message = 'The API will only permit searching for tags that pass through this filter.'
        message += os.linesep * 2
        message += 'If you want to allow all tags, just leave it as is, permitting everything. If you want to limit it to just one tag, such as "do waifu2x on this", set up a whitelist with only that tag allowed.'

        self._search_tag_filter = ClientGUITags.TagFilterButton(
            self, message, search_tag_filter, label_prefix='permitted tags: ')

        #

        access_key = api_permissions.GetAccessKey()

        self._access_key.setText(access_key.hex())

        name = api_permissions.GetName()

        self._name.setText(name)

        basic_permissions = api_permissions.GetBasicPermissions()

        self._basic_permissions.SetCheckedData(basic_permissions)

        #

        rows = []

        rows.append(('access key: ', self._access_key))
        rows.append(('name: ', self._name))
        rows.append(('permissions: ', self._basic_permissions))
        rows.append(('tag search permissions: ', self._search_tag_filter))

        gridbox = ClientGUICommon.WrapInGrid(self, rows)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        self.widget().setLayout(vbox)

        #

        self._UpdateEnabled()

        self._basic_permissions.checkListBoxChanged.connect(
            self._UpdateEnabled)
Esempio n. 19
0
 def do_it( directory, neighbouring_txt_tag_service_keys, delete_afterwards, export_symlinks, quit_afterwards ):
     
     pauser = HydrusData.BigJobPauser()
     
     for ( index, ( ordering_index, media ) ) in enumerate( to_do ):
         
         try:
             
             QP.CallAfter( qt_update_label, HydrusData.ConvertValueRangeToPrettyString(index+1,num_to_do) )
             
             hash = media.GetHash()
             mime = media.GetMime()
             
             path = self._GetPath( media )
             
             path = os.path.normpath( path )
             
             if not path.startswith( directory ):
                 
                 raise Exception( 'It seems a destination path was above the main export directory! The file was "{}" and its destination path was "{}".'.format( hash.hex(), path ) )
                 
             
             path_dir = os.path.dirname( path )
             
             HydrusPaths.MakeSureDirectoryExists( path_dir )
             
             if export_tag_txts:
                 
                 tags_manager = media.GetTagsManager()
                 
                 tags = set()
                 
                 for service_key in neighbouring_txt_tag_service_keys:
                     
                     current_tags = tags_manager.GetCurrent( service_key, ClientTags.TAG_DISPLAY_ACTUAL )
                     
                     tags.update( current_tags )
                     
                 
                 tags = sorted( tags )
                 
                 txt_path = path + '.txt'
                 
                 with open( txt_path, 'w', encoding = 'utf-8' ) as f:
                     
                     f.write( os.linesep.join( tags ) )
                     
                 
             
             source_path = client_files_manager.GetFilePath( hash, mime, check_file_exists = False )
             
             if export_symlinks:
                 
                 os.symlink( source_path, path )
                 
             else:
                 
                 HydrusPaths.MirrorFile( source_path, path )
                 
                 HydrusPaths.MakeFileWriteable( path )
                 
             
         except:
             
             QP.CallAfter( QW.QMessageBox.information, self, 'Information', 'Encountered a problem while attempting to export file with index '+str(ordering_index+1)+':'+os.linesep*2+traceback.format_exc() )
             
             break
             
         
         pauser.Pause()
         
     
     if delete_afterwards:
         
         QP.CallAfter( qt_update_label, 'deleting' )
         
         delete_lock_for_archived_files = HG.client_controller.new_options.GetBoolean( 'delete_lock_for_archived_files' )
         
         if delete_lock_for_archived_files:
             
             deletee_hashes = { media.GetHash() for ( ordering_index, media ) in to_do if not media.HasArchive() }
             
         else:
             
             deletee_hashes = { media.GetHash() for ( ordering_index, media ) in to_do }
             
         
         chunks_of_hashes = HydrusData.SplitListIntoChunks( deletee_hashes, 64 )
         
         reason = 'Deleted after manual export to "{}".'.format( directory )
         
         content_updates = [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_DELETE, chunk_of_hashes, reason = reason ) for chunk_of_hashes in chunks_of_hashes ]
         
         for content_update in content_updates:
             
             HG.client_controller.WriteSynchronous( 'content_updates', { CC.LOCAL_FILE_SERVICE_KEY : [ content_update ] } )
             
         
     
     QP.CallAfter( qt_update_label, 'done!' )
     
     time.sleep( 1 )
     
     QP.CallAfter( qt_update_label, 'export' )
     
     QP.CallAfter( qt_done, quit_afterwards )
Esempio n. 20
0
 def __init__( self, parent, service_key, media, activate_callable ):
     
     QW.QWidget.__init__( self, parent )
     
     self._service_key = service_key
     self._media = media
     
     self._new_options = HG.client_controller.new_options
     
     layout_mode = self._new_options.GetNoneableString( 'suggested_tags_layout' )
     
     self._notebook = None
     
     if layout_mode == 'notebook':
         
         self._notebook = ClientGUICommon.BetterNotebook( self )
         
         panel_parent = self._notebook
         
     else:
         
         panel_parent = self
         
     
     panels = []
     
     self._favourite_tags = None
     
     favourites = HG.client_controller.new_options.GetSuggestedTagsFavourites( self._service_key )
     
     if len( favourites ) > 0:
         
         self._favourite_tags = FavouritesTagsPanel( panel_parent, service_key, media, activate_callable )
         
         self._favourite_tags.mouseActivationOccurred.connect( self.mouseActivationOccurred )
         
         panels.append( ( 'favourites', self._favourite_tags ) )
         
     
     self._related_tags = None
     
     if self._new_options.GetBoolean( 'show_related_tags' ) and len( media ) == 1:
         
         self._related_tags = RelatedTagsPanel( panel_parent, service_key, media, activate_callable )
         
         self._related_tags.mouseActivationOccurred.connect( self.mouseActivationOccurred )
         
         panels.append( ( 'related', self._related_tags ) )
         
     
     self._file_lookup_script_tags = None
     
     if self._new_options.GetBoolean( 'show_file_lookup_script_tags' ) and len( media ) == 1:
         
         self._file_lookup_script_tags = FileLookupScriptTagsPanel( panel_parent, service_key, media, activate_callable )
         
         self._file_lookup_script_tags.mouseActivationOccurred.connect( self.mouseActivationOccurred )
         
         panels.append( ( 'file lookup scripts', self._file_lookup_script_tags ) )
         
     
     self._recent_tags = None
     
     if self._new_options.GetNoneableInteger( 'num_recent_tags' ) is not None:
         
         self._recent_tags = RecentTagsPanel( panel_parent, service_key, media, activate_callable )
         
         self._recent_tags.mouseActivationOccurred.connect( self.mouseActivationOccurred )
         
         panels.append( ( 'recent', self._recent_tags ) )
         
     
     hbox = QP.HBoxLayout()
     
     if layout_mode == 'notebook':
         
         for ( name, panel ) in panels:
             
             self._notebook.addTab( panel, name )
             
         
         QP.AddToLayout( hbox, self._notebook, CC.FLAGS_EXPAND_BOTH_WAYS )
         
     elif layout_mode == 'columns':
         
         for ( name, panel ) in panels:
             
             QP.AddToLayout( hbox, panel, CC.FLAGS_EXPAND_PERPENDICULAR )
             
         
     
     self.setLayout( hbox )
     
     if len( panels ) == 0:
         
         self.hide()
Esempio n. 21
0
    def EventText(self, text):

        QP.CallAfter(self._CheckText)
Esempio n. 22
0
    if len(args) > 0:

        only_run = args[0]

    else:

        only_run = None

    try:

        threading.Thread(target=reactor.run,
                         kwargs={
                             'installSignalHandlers': 0
                         }).start()

        QP.MonkeyPatchMissingMethods()
        app = QW.QApplication(sys.argv)

        app.call_after_catcher = QP.CallAfterEventCatcher(app)

        try:

            # we run the tests on the Qt thread atm
            # keep a window alive the whole time so the app doesn't finish its mainloop

            win = QW.QWidget(None)
            win.setWindowTitle('Running tests...')

            controller = TestController.Controller(win, only_run)

            def do_it():
Esempio n. 23
0
    def __init__(self,
                 parent,
                 service_key,
                 tags,
                 expand_parents=True,
                 message=''):

        Dialog.__init__(self, parent, 'input tags')

        self._service_key = service_key

        self._tags = ClientGUIListBoxes.ListBoxTagsStringsAddRemove(
            self, service_key=service_key)

        self._expand_parents = expand_parents

        self._tag_autocomplete = ClientGUIACDropdown.AutoCompleteDropdownTagsWrite(
            self,
            self.EnterTags,
            self._expand_parents,
            CC.LOCAL_FILE_SERVICE_KEY,
            service_key,
            null_entry_callable=self.OK,
            show_paste_button=True)

        self._ok = ClientGUICommon.BetterButton(self, 'OK', self.done,
                                                QW.QDialog.Accepted)
        self._ok.setObjectName('HydrusAccept')

        self._cancel = QW.QPushButton('Cancel', self)
        self._cancel.clicked.connect(self.reject)
        self._cancel.setObjectName('HydrusCancel')

        #

        self._tags.SetTags(tags)

        #

        b_box = QP.HBoxLayout()

        QP.AddToLayout(b_box, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(b_box, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        if message != '':

            st = ClientGUICommon.BetterStaticText(self, message)

            st.setWordWrap(True)

            QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)

        QP.AddToLayout(vbox, self._tags, CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(vbox, self._tag_autocomplete)
        QP.AddToLayout(vbox, b_box, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        size_hint.setWidth(max(size_hint.width(), 300))

        QP.SetInitialSize(self, size_hint)

        HG.client_controller.CallAfterQtSafe(self._tag_autocomplete,
                                             self._tag_autocomplete.setFocus,
                                             QC.Qt.OtherFocusReason)
Esempio n. 24
0
    def __init__(self, parent, existing_folders_to_names, foldername, name,
                 file_search_context, synchronised, media_sort, media_collect):

        ClientGUIScrolledPanels.EditPanel.__init__(self, parent)

        self._existing_folders_to_names = existing_folders_to_names
        self._original_folder_and_name = (foldername, name)

        self._foldername = QW.QLineEdit(self)
        self._name = QW.QLineEdit(self)

        self._media_sort = ClientGUIResultsSortCollect.MediaSortControl(self)
        self._media_collect = ClientGUIResultsSortCollect.MediaCollectControl(
            self, silent=True)

        page_key = HydrusData.GenerateKey()

        from hydrus.client.gui.search import ClientGUIACDropdown

        self._tag_autocomplete = ClientGUIACDropdown.AutoCompleteDropdownTagsRead(
            self,
            page_key,
            file_search_context,
            media_sort_widget=self._media_sort,
            media_collect_widget=self._media_collect,
            synchronised=synchronised,
            hide_favourites_edit_actions=True)

        self._include_media_sort = QW.QCheckBox(self)
        self._include_media_collect = QW.QCheckBox(self)

        width = ClientGUIFunctions.ConvertTextToPixelWidth(
            self._include_media_collect, 48)

        self._include_media_collect.setMinimumWidth(width)

        self._include_media_sort.stateChanged.connect(self._UpdateWidgets)
        self._include_media_collect.stateChanged.connect(self._UpdateWidgets)

        #

        if foldername is not None:

            self._foldername.setText(foldername)

        self._name.setText(name)

        if media_sort is not None:

            self._include_media_sort.setChecked(True)

            self._media_sort.SetSort(media_sort)

        if media_collect is not None:

            self._include_media_collect.setChecked(True)

            self._media_collect.SetCollect(media_collect)

        #

        rows = []

        rows.append(('folder (blank for none): ', self._foldername))
        rows.append(('name: ', self._name))

        top_gridbox = ClientGUICommon.WrapInGrid(self, rows)

        rows = []

        rows.append(('save sort: ', self._include_media_sort))
        rows.append(('sort: ', self._media_sort))
        rows.append(('save collect: ', self._include_media_collect))
        rows.append(('collect: ', self._media_collect))

        bottom_gridbox = ClientGUICommon.WrapInGrid(self, rows)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, top_gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)
        QP.AddToLayout(vbox, self._tag_autocomplete, CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(vbox, bottom_gridbox,
                       CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        self.widget().setLayout(vbox)
Esempio n. 25
0
    def __init__(self, parent, service_key, subject_identifiers):

        Dialog.__init__(self, parent, 'modify account')

        self._service = HG.client_controller.services_manager.GetService(
            service_key)
        self._subject_identifiers = list(subject_identifiers)

        #

        self._account_info_panel = ClientGUICommon.StaticBox(
            self, 'account info')

        self._subject_text = QW.QLabel(self._account_info_panel)

        #

        self._account_types_panel = ClientGUICommon.StaticBox(
            self, 'account types')

        self._account_types = QW.QComboBox(self._account_types_panel)

        self._account_types_ok = QW.QPushButton('OK',
                                                self._account_types_panel)
        self._account_types_ok.clicked.connect(self.EventChangeAccountType)

        #

        self._expiration_panel = ClientGUICommon.StaticBox(
            self, 'change expiration')

        self._add_to_expires = QW.QComboBox(self._expiration_panel)

        self._add_to_expires_ok = QW.QPushButton('OK', self._expiration_panel)
        self._add_to_expires.clicked.connect(self.EventAddToExpires)

        self._set_expires = QW.QComboBox(self._expiration_panel)

        self._set_expires_ok = QW.QPushButton('OK', self._expiration_panel)
        self._set_expires_ok.clicked.connect(self.EventSetExpires)

        #

        self._ban_panel = ClientGUICommon.StaticBox(self, 'bans')

        self._ban = QW.QPushButton('ban user', self._ban_panel)
        self._ban.clicked.connect(self.EventBan)
        QP.SetBackgroundColour(self._ban, (255, 0, 0))
        QP.SetForegroundColour(self._ban, (255, 255, 0))

        self._superban = QW.QPushButton(
            'ban user and delete every contribution they have ever made',
            self._ban_panel)
        self._superban.clicked.connect(self.EventSuperban)
        QP.SetBackgroundColour(self._superban, (255, 0, 0))
        QP.SetForegroundColour(self._superban, (255, 255, 0))

        self._exit = QW.QPushButton('Exit', self)
        self._exit.clicked.connect(self.reject)

        #

        if len(self._subject_identifiers) == 1:

            (subject_identifier, ) = self._subject_identifiers

            response = self._service.Request(
                HC.GET, 'account_info',
                {'subject_identifier': subject_identifier})

            subject_string = str(response['account_info'])

        else:

            subject_string = 'modifying ' + HydrusData.ToHumanInt(
                len(self._subject_identifiers)) + ' accounts'

        self._subject_text.setText(subject_string)

        #

        response = self._service.Request(HC.GET, 'account_types')

        account_types = response['account_types']

        for account_type in account_types:
            self._account_types.addItem(account_type.ConvertToString(),
                                        account_type)

        self._account_types.setCurrentIndex(0)

        #

        for (label, value) in HC.lifetimes:

            if value is not None:

                self._add_to_expires.addItem(
                    label, value)  # don't want 'add no limit'

        self._add_to_expires.setCurrentIndex(1)  # three months

        for (label, value) in HC.lifetimes:

            self._set_expires.addItem(label, value)

        self._set_expires.setCurrentIndex(1)  # three months

        #

        self._account_info_panel.Add(self._subject_text,
                                     CC.FLAGS_EXPAND_PERPENDICULAR)

        account_types_hbox = QP.HBoxLayout()

        QP.AddToLayout(account_types_hbox, self._account_types,
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(account_types_hbox, self._account_types_ok,
                       CC.FLAGS_CENTER_PERPENDICULAR)

        self._account_types_panel.Add(account_types_hbox,
                                      CC.FLAGS_EXPAND_PERPENDICULAR)

        add_to_expires_box = QP.HBoxLayout()

        QP.AddToLayout(add_to_expires_box,
                       QW.QLabel('add to expires: ', self._expiration_panel),
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(add_to_expires_box, self._add_to_expires,
                       CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(add_to_expires_box, self._add_to_expires_ok,
                       CC.FLAGS_CENTER_PERPENDICULAR)

        set_expires_box = QP.HBoxLayout()

        QP.AddToLayout(set_expires_box,
                       QW.QLabel('set expires to: ', self._expiration_panel),
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(set_expires_box, self._set_expires,
                       CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(set_expires_box, self._set_expires_ok,
                       CC.FLAGS_CENTER_PERPENDICULAR)

        self._expiration_panel.Add(add_to_expires_box,
                                   CC.FLAGS_EXPAND_PERPENDICULAR)
        self._expiration_panel.Add(set_expires_box,
                                   CC.FLAGS_EXPAND_PERPENDICULAR)

        self._ban_panel.Add(self._ban, CC.FLAGS_EXPAND_PERPENDICULAR)
        self._ban_panel.Add(self._superban, CC.FLAGS_EXPAND_PERPENDICULAR)

        vbox = QP.VBoxLayout()
        QP.AddToLayout(vbox, self._account_info_panel,
                       CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._account_types_panel,
                       CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._expiration_panel,
                       CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._ban_panel, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._exit, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        QP.SetInitialSize(self, size_hint)

        HG.client_controller.CallAfterQtSafe(self._exit, self._exit.setFocus,
                                             QC.Qt.OtherFocusReason)
 def __init__( self, parent, checker_options ):
     
     ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
     
     help_button = ClientGUICommon.BetterBitmapButton( self, CC.global_pixmaps().help, self._ShowHelp )
     help_button.setToolTip( 'Show help regarding these checker options.' )
     
     help_hbox = ClientGUICommon.WrapInText( help_button, self, 'help for this panel -->', QG.QColor( 0, 0, 255 ) )
     
     from hydrus.client import ClientDefaults
     
     defaults_panel = ClientGUICommon.StaticBox( self, 'reasonable defaults' )
     
     defaults_1 = ClientGUICommon.BetterButton( defaults_panel, 'thread', self.SetValue, ClientDefaults.GetDefaultCheckerOptions( 'thread' ) )
     defaults_2 = ClientGUICommon.BetterButton( defaults_panel, 'slow thread', self.SetValue, ClientDefaults.GetDefaultCheckerOptions( 'slow thread' ) )
     defaults_3 = ClientGUICommon.BetterButton( defaults_panel, 'faster tag subscription', self.SetValue, ClientDefaults.GetDefaultCheckerOptions( 'fast tag subscription' ) )
     defaults_4 = ClientGUICommon.BetterButton( defaults_panel, 'medium tag/artist subscription', self.SetValue, ClientDefaults.GetDefaultCheckerOptions( 'artist subscription' ) )
     defaults_5 = ClientGUICommon.BetterButton( defaults_panel, 'slower tag subscription', self.SetValue, ClientDefaults.GetDefaultCheckerOptions( 'slow tag subscription' ) )
     
     #
     
     # add statictext or whatever that will update on any updates above to say 'given velocity of blah and last check at blah, next check in 5 mins'
     # or indeed this could just take the file_seed cache and last check of the caller, if there is one
     # this would be more useful to the user, to know 'right, on ok, it'll refresh in 30 mins'
     # this is actually more complicated--it also needs last check time to calc a fresh file velocity based on new death_file_velocity
     
     #
     
     min_unit_value = 0
     max_unit_value = 1000
     min_time_delta = 60
     
     self._death_file_velocity = VelocityCtrl( self, min_unit_value, max_unit_value, min_time_delta, days = True, hours = True, minutes = True, per_phrase = 'in', unit = 'files' )
     
     self._flat_check_period_checkbox = QW.QCheckBox( self )
     
     #
     
     if HG.client_controller.new_options.GetBoolean( 'advanced_mode' ):
         
         never_faster_than_min = 1
         never_slower_than_min = 1
         
         flat_check_period_min = 1
         
     else:
         
         never_faster_than_min = 30
         never_slower_than_min = 600
         
         flat_check_period_min = 180
         
     
     self._reactive_check_panel = ClientGUICommon.StaticBox( self, 'reactive checking' )
     
     self._intended_files_per_check = QP.MakeQSpinBox( self._reactive_check_panel, min=1, max=1000 )
     
     self._never_faster_than = TimeDeltaCtrl( self._reactive_check_panel, min = never_faster_than_min, days = True, hours = True, minutes = True, seconds = True )
     
     self._never_slower_than = TimeDeltaCtrl( self._reactive_check_panel, min = never_slower_than_min, days = True, hours = True, minutes = True, seconds = True )
     
     #
     
     self._static_check_panel = ClientGUICommon.StaticBox( self, 'static checking' )
     
     self._flat_check_period = TimeDeltaCtrl( self._static_check_panel, min = flat_check_period_min, days = True, hours = True, minutes = True, seconds = True )
     
     #
     
     self.SetValue( checker_options )
     
     #
     
     defaults_panel.Add( defaults_1, CC.FLAGS_EXPAND_PERPENDICULAR )
     defaults_panel.Add( defaults_2, CC.FLAGS_EXPAND_PERPENDICULAR )
     defaults_panel.Add( defaults_3, CC.FLAGS_EXPAND_PERPENDICULAR )
     defaults_panel.Add( defaults_4, CC.FLAGS_EXPAND_PERPENDICULAR )
     defaults_panel.Add( defaults_5, CC.FLAGS_EXPAND_PERPENDICULAR )
     
     #
     
     #
     
     rows = []
     
     rows.append( ( 'intended new files per check: ', self._intended_files_per_check ) )
     rows.append( ( 'never check faster than once per: ', self._never_faster_than ) )
     rows.append( ( 'never check slower than once per: ', self._never_slower_than ) )
     
     gridbox = ClientGUICommon.WrapInGrid( self._reactive_check_panel, rows )
     
     self._reactive_check_panel.Add( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
     
     #
     
     rows = []
     
     rows.append( ( 'check period: ', self._flat_check_period ) )
     
     gridbox = ClientGUICommon.WrapInGrid( self._static_check_panel, rows )
     
     self._static_check_panel.Add( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
     
     #
     
     rows = []
     
     rows.append( ( 'stop checking if new files found falls below: ', self._death_file_velocity ) )
     rows.append( ( 'just check at a static, regular interval: ', self._flat_check_period_checkbox ) )
     
     gridbox = ClientGUICommon.WrapInGrid( self, rows )
     
     vbox = QP.VBoxLayout()
     
     QP.AddToLayout( vbox, help_hbox, CC.FLAGS_ON_RIGHT )
     QP.AddToLayout( vbox, defaults_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
     
     if HG.client_controller.new_options.GetBoolean( 'advanced_mode' ):
         
         label = 'As you are in advanced mode, these options have extremely low limits. This is intended only for testing and small scale private network tasks. Do not use very fast check times for real world use on public websites, as it is wasteful and rude, hydrus will be overloaded with high-CPU parsing work, and you may get your IP banned.'
         
         st = ClientGUICommon.BetterStaticText( self, label = label )
         st.setObjectName( 'HydrusWarning' )
         
         st.setWordWrap( True )
         
         QP.AddToLayout( vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR )
         
     
     QP.AddToLayout( vbox, self._reactive_check_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, self._static_check_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
     
     self.widget().setLayout( vbox )
     
     #
     
     self._flat_check_period_checkbox.clicked.connect( self.EventFlatPeriodCheck )
Esempio n. 27
0
    def __init__(self, parent):

        title = 'manage local upnp'

        ClientGUIDialogs.Dialog.__init__(self, parent, title)

        self._status_st = ClientGUICommon.BetterStaticText(self)

        self._mappings_listctrl_panel = ClientGUIListCtrl.BetterListCtrlPanel(
            self)

        self._mappings_list = ClientGUIListCtrl.BetterListCtrl(
            self._mappings_listctrl_panel,
            CGLC.COLUMN_LIST_MANAGE_UPNP_MAPPINGS.ID,
            12,
            self._ConvertDataToListCtrlTuples,
            delete_key_callback=self._Remove,
            activation_callback=self._Edit)

        self._mappings_listctrl_panel.SetListCtrl(self._mappings_list)

        self._mappings_listctrl_panel.AddButton('add custom mapping',
                                                self._Add)
        self._mappings_listctrl_panel.AddButton(
            'edit mapping', self._Edit, enabled_only_on_single_selection=True)
        self._mappings_listctrl_panel.AddButton('remove mapping',
                                                self._Remove,
                                                enabled_only_on_selection=True)

        self._ok = QW.QPushButton('ok', self)
        self._ok.clicked.connect(self.EventOK)
        self._ok.setObjectName('HydrusAccept')

        #

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, self._status_st, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._mappings_listctrl_panel,
                       CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(vbox, self._ok, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        size_hint.setWidth(max(size_hint.width(), 760))

        QP.SetInitialSize(self, size_hint)

        #

        self._mappings_lookup = set()

        self._mappings_list.Sort()

        self._external_ip = None

        self._started_external_ip_fetch = False

        self._RefreshMappings()
 def __init__( self, parent, min = 1, days = False, hours = False, minutes = False, seconds = False, monthly_allowed = False, monthly_label = 'monthly' ):
     
     QW.QWidget.__init__( self, parent )
     
     self._min = min
     self._show_days = days
     self._show_hours = hours
     self._show_minutes = minutes
     self._show_seconds = seconds
     self._monthly_allowed = monthly_allowed
     
     hbox = QP.HBoxLayout( margin = 0 )
     
     if self._show_days:
         
         self._days = QP.MakeQSpinBox( self, min=0, max=3653, width = 50 )
         self._days.valueChanged.connect( self.EventChange )
         
         QP.AddToLayout( hbox, self._days, CC.FLAGS_CENTER_PERPENDICULAR )
         QP.AddToLayout( hbox, ClientGUICommon.BetterStaticText(self,'days'), CC.FLAGS_CENTER_PERPENDICULAR )
         
     
     if self._show_hours:
         
         self._hours = QP.MakeQSpinBox( self, min=0, max=23, width = 45 )
         self._hours.valueChanged.connect( self.EventChange )
         
         QP.AddToLayout( hbox, self._hours, CC.FLAGS_CENTER_PERPENDICULAR )
         QP.AddToLayout( hbox, ClientGUICommon.BetterStaticText(self,'hours'), CC.FLAGS_CENTER_PERPENDICULAR )
         
     
     if self._show_minutes:
         
         self._minutes = QP.MakeQSpinBox( self, min=0, max=59, width = 45 )
         self._minutes.valueChanged.connect( self.EventChange )
         
         QP.AddToLayout( hbox, self._minutes, CC.FLAGS_CENTER_PERPENDICULAR )
         QP.AddToLayout( hbox, ClientGUICommon.BetterStaticText(self,'minutes'), CC.FLAGS_CENTER_PERPENDICULAR )
         
     
     if self._show_seconds:
         
         self._seconds = QP.MakeQSpinBox( self, min=0, max=59, width = 45 )
         self._seconds.valueChanged.connect( self.EventChange )
         
         QP.AddToLayout( hbox, self._seconds, CC.FLAGS_CENTER_PERPENDICULAR )
         QP.AddToLayout( hbox, ClientGUICommon.BetterStaticText(self,'seconds'), CC.FLAGS_CENTER_PERPENDICULAR )
         
     
     if self._monthly_allowed:
         
         self._monthly = QW.QCheckBox( self )
         self._monthly.clicked.connect( self.EventChange )
         
         QP.AddToLayout( hbox, self._monthly, CC.FLAGS_CENTER_PERPENDICULAR )
         QP.AddToLayout( hbox, ClientGUICommon.BetterStaticText(self,monthly_label), CC.FLAGS_CENTER_PERPENDICULAR )
         
     
     self.setLayout( hbox )
Esempio n. 29
0
    def __init__(self,
                 parent,
                 share_key,
                 name,
                 text,
                 timeout,
                 hashes,
                 new_share=False):

        Dialog.__init__(self, parent, 'configure local booru share')

        self._name = QW.QLineEdit(self)

        self._text = QW.QPlainTextEdit(self)
        self._text.setMinimumHeight(100)

        message = 'expires in'

        self._timeout_number = ClientGUICommon.NoneableSpinCtrl(
            self,
            message,
            none_phrase='no expiration',
            max=1000000,
            multiplier=1)

        self._timeout_multiplier = ClientGUICommon.BetterChoice(self)
        self._timeout_multiplier.addItem('minutes', 60)
        self._timeout_multiplier.addItem('hours', 60 * 60)
        self._timeout_multiplier.addItem('days', 60 * 60 * 24)

        self._copy_internal_share_link = QW.QPushButton(
            'copy internal share link', self)
        self._copy_internal_share_link.clicked.connect(
            self.EventCopyInternalShareURL)

        self._copy_external_share_link = QW.QPushButton(
            'copy external share link', self)
        self._copy_external_share_link.clicked.connect(
            self.EventCopyExternalShareURL)

        self._ok = QW.QPushButton('ok', self)
        self._ok.clicked.connect(self.accept)
        self._ok.setObjectName('HydrusAccept')

        self._cancel = QW.QPushButton('cancel', self)
        self._cancel.clicked.connect(self.reject)
        self._cancel.setObjectName('HydrusCancel')

        #

        self._share_key = share_key
        self._name.setText(name)
        self._text.setPlainText(text)

        if timeout is None:

            self._timeout_number.SetValue(None)

            self._timeout_multiplier.SetValue(60)

        else:

            time_left = HydrusData.GetTimeDeltaUntilTime(timeout)

            if time_left < 60 * 60 * 12: time_value = 60
            elif time_left < 60 * 60 * 24 * 7: time_value = 60 * 60
            else: time_value = 60 * 60 * 24

            self._timeout_number.SetValue(time_left // time_value)

            self._timeout_multiplier.SetValue(time_value)

        self._hashes = hashes

        self._service = HG.client_controller.services_manager.GetService(
            CC.LOCAL_BOORU_SERVICE_KEY)

        internal_port = self._service.GetPort()

        if internal_port is None:

            self._copy_internal_share_link.setEnabled(False)
            self._copy_external_share_link.setEnabled(False)

        #

        rows = []

        rows.append(('share name: ', self._name))
        rows.append(('share text: ', self._text))

        gridbox = ClientGUICommon.WrapInGrid(self, rows)

        timeout_box = QP.HBoxLayout()
        QP.AddToLayout(timeout_box, self._timeout_number,
                       CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(timeout_box, self._timeout_multiplier,
                       CC.FLAGS_EXPAND_BOTH_WAYS)

        link_box = QP.HBoxLayout()
        QP.AddToLayout(link_box, self._copy_internal_share_link,
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(link_box, self._copy_external_share_link,
                       CC.FLAGS_CENTER_PERPENDICULAR)

        b_box = QP.HBoxLayout()
        QP.AddToLayout(b_box, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(b_box, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        intro = 'Sharing ' + HydrusData.ToHumanInt(len(
            self._hashes)) + ' files.'
        intro += os.linesep + 'Title and text are optional.'

        if new_share:
            intro += os.linesep + 'The link will not work until you ok this dialog.'

        QP.AddToLayout(vbox, ClientGUICommon.BetterStaticText(self, intro),
                       CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)
        QP.AddToLayout(vbox, timeout_box, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)
        QP.AddToLayout(vbox, link_box, CC.FLAGS_ON_RIGHT)
        QP.AddToLayout(vbox, b_box, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        size_hint.setWidth(max(size_hint.width(), 350))

        QP.SetInitialSize(self, size_hint)

        ClientGUIFunctions.SetFocusLater(self._ok)
Esempio n. 30
0
    def EventShowMenu(self):

        QP.CallAfter(self._ShowMenu)