def SetStyleFromName(name):

    global CURRENT_STYLE_NAME

    if name == CURRENT_STYLE_NAME:

        return

    if name in GetAvailableStyles():

        try:

            QW.QApplication.instance().setStyle(name)

            CURRENT_STYLE_NAME = name

        except Exception as e:

            raise HydrusExceptions.DataMissing(
                'Style "{}" could not be generated/applied. If this is the default, perhaps a third-party custom style, you may have to restart the client to re-set it. Extra error info: {}'
                .format(name, e))

    else:

        raise HydrusExceptions.DataMissing(
            'Style "{}" does not exist! If this is the default, perhaps a third-party custom style, you may have to restart the client to re-set it.'
            .format(name))
Esempio n. 2
0
    def _GetListCtrlMenu( self ):
        
        selected_gallery_seeds = self._list_ctrl.GetData( only_selected = True )
        
        if len( selected_gallery_seeds ) == 0:
            
            raise HydrusExceptions.DataMissing()
            
        
        menu = QW.QMenu()

        ClientGUIMenus.AppendMenuItem( menu, 'copy urls', 'Copy all the selected urls to clipboard.', self._CopySelectedGalleryURLs )
        ClientGUIMenus.AppendMenuItem( menu, 'copy notes', 'Copy all the selected notes to clipboard.', self._CopySelectedNotes )
        
        ClientGUIMenus.AppendSeparator( menu )

        ClientGUIMenus.AppendMenuItem( menu, 'open urls', 'Open all the selected urls in your web browser.', self._OpenSelectedGalleryURLs )
        
        ClientGUIMenus.AppendSeparator( menu )
        
        if not self._read_only:
            
            ClientGUIMenus.AppendMenuItem( menu, 'try again (just this one page)', 'Schedule this url to occur again.', HydrusData.Call( self._TrySelectedAgain, False ) )
            
            if self._can_generate_more_pages:
                ClientGUIMenus.AppendMenuItem( menu, 'try again (and allow search to continue)', 'Schedule this url to occur again and continue.', HydrusData.Call( self._TrySelectedAgain, True ) )

        ClientGUIMenus.AppendMenuItem( menu, 'skip', 'Skip all the selected urls.', HydrusData.Call( self._SetSelected, CC.STATUS_SKIPPED ) )
        
        return menu
Esempio n. 3
0
    def GetHashIdFromExtraHash(self, hash_type, hash):

        if hash_type == 'md5':

            result = self._Execute(
                'SELECT hash_id FROM local_hashes WHERE md5 = ?;',
                (sqlite3.Binary(hash), )).fetchone()

        elif hash_type == 'sha1':

            result = self._Execute(
                'SELECT hash_id FROM local_hashes WHERE sha1 = ?;',
                (sqlite3.Binary(hash), )).fetchone()

        elif hash_type == 'sha512':

            result = self._Execute(
                'SELECT hash_id FROM local_hashes WHERE sha512 = ?;',
                (sqlite3.Binary(hash), )).fetchone()

        if result is None:

            raise HydrusExceptions.DataMissing(
                'Hash Id not found for {} hash {}!'.format(
                    hash_type, hash.hex()))

        (hash_id, ) = result

        return hash_id
Esempio n. 4
0
    def _GetListCtrlMenu( self ):
        
        selected_file_seeds = self._list_ctrl.GetData( only_selected = True )
        
        if len( selected_file_seeds ) == 0:
            
            raise HydrusExceptions.DataMissing()
            
        
        menu = QW.QMenu()
        
        can_show_files_in_new_page = True in ( file_seed.HasHash() for file_seed in selected_file_seeds )
        
        if can_show_files_in_new_page:
            
            ClientGUIMenus.AppendMenuItem( menu, 'open selected import files in a new page', 'Show all the known selected files in a new thumbnail page. This is complicated, so cannot always be guaranteed, even if the import says \'success\'.', self._ShowSelectionInNewPage )
            
            ClientGUIMenus.AppendSeparator( menu )

        ClientGUIMenus.AppendMenuItem( menu, 'copy sources', 'Copy all the selected sources to clipboard.', self._CopySelectedFileSeedData )
        ClientGUIMenus.AppendMenuItem( menu, 'copy notes', 'Copy all the selected notes to clipboard.', self._CopySelectedNotes )
        
        ClientGUIMenus.AppendSeparator( menu )

        ClientGUIMenus.AppendMenuItem( menu, 'open sources', 'Open all the selected sources in your file explorer or web browser.', self._OpenSelectedFileSeedData )
        
        ClientGUIMenus.AppendSeparator( menu )

        ClientGUIMenus.AppendMenuItem( menu, 'try again', 'Reset the progress of all the selected imports.', HydrusData.Call( self._SetSelected, CC.STATUS_UNKNOWN ) )
        ClientGUIMenus.AppendMenuItem( menu, 'skip', 'Skip all the selected imports.', HydrusData.Call( self._SetSelected, CC.STATUS_SKIPPED ) )
        ClientGUIMenus.AppendMenuItem( menu, 'delete from list', 'Remove all the selected imports.', self._DeleteSelected )
        
        return menu
Esempio n. 5
0
 def GetYAMLDump( self, dump_type, dump_name = None ):
     
     if dump_name is None:
         
         result = { dump_name : data for ( dump_name, data ) in self._c.execute( 'SELECT dump_name, dump FROM yaml_dumps WHERE dump_type = ?;', ( dump_type, ) ) }
         
         if dump_type == YAML_DUMP_ID_LOCAL_BOORU:
             
             result = { bytes.fromhex( dump_name ) : data for ( dump_name, data ) in list(result.items()) }
             
         
     else:
         
         if dump_type == YAML_DUMP_ID_LOCAL_BOORU: dump_name = dump_name.hex()
         
         result = self._c.execute( 'SELECT dump FROM yaml_dumps WHERE dump_type = ? AND dump_name = ?;', ( dump_type, dump_name ) ).fetchone()
         
         if result is None:
             
             if result is None:
                 
                 raise HydrusExceptions.DataMissing( dump_name + ' was not found!' )
                 
             
         else:
             
             ( result, ) = result
             
         
     
     return result
Esempio n. 6
0
def GetICCProfileBytes(pil_image: PILImage.Image) -> bytes:

    if HasICCProfile(pil_image):

        return pil_image.info['icc_profile']

    raise HydrusExceptions.DataMissing('This image has no ICC profile!')
Esempio n. 7
0
 def GetServiceId( self, service_key: bytes ) -> int:
     
     if service_key in self._service_keys_to_service_ids:
         
         return self._service_keys_to_service_ids[ service_key ]
         
     
     raise HydrusExceptions.DataMissing( 'Service id error in database: key "{}" does not exist!'.format( service_key.hex() ) )
    def GetPageData(self, hash) -> "GUISessionPageData":

        if hash not in self._hashes_to_page_data:

            raise HydrusExceptions.DataMissing(
                'The page hash "{}" was not found!'.format(hash.hex()))

        return self._hashes_to_page_data[hash]
Esempio n. 9
0
 def GetServiceType( self, service_id ) -> ClientServices.Service:
     
     if service_id in self._service_ids_to_services:
         
         return self._service_ids_to_services[ service_id ].GetServiceType()
         
     
     raise HydrusExceptions.DataMissing( 'Service id error in database: id "{}" does not exist!'.format( service_id ) )
Esempio n. 10
0
 def GetNote( self, name: str ):
     
     if name in self._names_to_notes:
         
         return self._names_to_notes[ name ]
         
     else:
         
         raise HydrusExceptions.DataMissing( 'Note "{}" does not exist!'.format( name ) )
Esempio n. 11
0
    def _GetService(self, service_key: bytes):

        try:

            return self._keys_to_services[service_key]

        except KeyError:

            raise HydrusExceptions.DataMissing('That service was not found!')
Esempio n. 12
0
 def GetPermissions( self, access_key ):
     
     with self._lock:
         
         if access_key not in self._access_keys_to_permissions:
             
             raise HydrusExceptions.DataMissing( 'Did not find an entry for that access key!' )
             
         
         return self._access_keys_to_permissions[ access_key ]
Esempio n. 13
0
    def GetText(self, text_id):

        result = self._Execute('SELECT text FROM texts WHERE text_id = ?;',
                               (text_id, )).fetchone()

        if result is None:

            raise HydrusExceptions.DataMissing('Text lookup error in database')

        (text, ) = result

        return text
Esempio n. 14
0
 def GetExtraHash( self, hash_type, hash_id ) -> bytes:
     
     result = self._c.execute( 'SELECT {} FROM local_hashes WHERE hash_id = ?;'.format( hash_type ), ( hash_id, ) ).fetchone()
     
     if result is None:
         
         raise HydrusExceptions.DataMissing( '{} not available for file {}!'.format( hash_type, hash_id ) )
         
     
     ( hash, ) = result
     
     return hash
Esempio n. 15
0
    def GetServiceKeyFromName(self, allowed_types: typing.Iterable[int],
                              service_name: str):

        with self._lock:

            for service in self._services_sorted:

                if service.GetServiceType(
                ) in allowed_types and service.GetName() == service_name:

                    return service.GetServiceKey()

            raise HydrusExceptions.DataMissing()
    def GetMime(self, hash_id: int) -> int:

        result = self._Execute(
            'SELECT mime FROM files_info WHERE hash_id = ?;',
            (hash_id, )).fetchone()

        if result is None:

            raise HydrusExceptions.DataMissing(
                'Did not have mime information for that file!')

        (mime, ) = result

        return mime
def GetCookie(cookies, search_domain, cookie_name_string_match):

    for cookie in cookies:

        if CookieDomainMatches(
                cookie, search_domain) and cookie_name_string_match.Matches(
                    cookie.name):

            return cookie

    raise HydrusExceptions.DataMissing('Cookie "' +
                                       cookie_name_string_match.ToString() +
                                       '" not found for domain ' +
                                       search_domain + '!')
def SetStylesheetFromPath(filename):

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

    if not os.path.exists(path):

        raise HydrusExceptions.DataMissing(
            'Stylesheet "{}" does not exist!'.format(path))

    with open(path, 'r', encoding='utf-8') as f:

        qss = f.read()

    SetStyleSheet(qss)
def GetAvailableStylesheets():

    if not os.path.exists(STYLESHEET_DIR) or not os.path.isdir(STYLESHEET_DIR):

        raise HydrusExceptions.DataMissing(
            'Stylesheet dir "{}" is missing or not a directory!'.format(
                STYLESHEET_DIR))

    stylesheet_filenames = []

    extensions = ['.qss', '.css']

    for filename in os.listdir(STYLESHEET_DIR):

        if True in (filename.endswith(ext) for ext in extensions):

            stylesheet_filenames.append(filename)

    return stylesheet_filenames
Esempio n. 20
0
 def GetAccessKey( self, session_key ):
     
     with self._lock:
         
         if session_key not in self._session_keys_to_access_keys_and_expirys:
             
             raise HydrusExceptions.DataMissing( 'Did not find an entry for that session key!' )
             
         
         ( access_key, session_expiry ) = self._session_keys_to_access_keys_and_expirys[ session_key ]
         
         if HydrusData.TimeHasPassed( session_expiry ):
             
             del self._session_keys_to_access_keys_and_expirys[ session_expiry ]
             
             raise HydrusExceptions.SessionException( 'That session key has expired!' )
             
         
         self._session_keys_to_access_keys_and_expirys[ session_key ] = ( access_key, HydrusData.GetNow() + SESSION_EXPIRY )
         
     
     return access_key
    def GetJSONDumpNamed(self, dump_type, dump_name=None, timestamp=None):

        if dump_name is None:

            results = self._c.execute(
                'SELECT dump_name, version, dump, timestamp FROM json_dumps_named WHERE dump_type = ?;',
                (dump_type, )).fetchall()

            objs = []

            for (dump_name, version, dump, object_timestamp) in results:

                try:

                    if isinstance(dump, bytes):

                        dump = str(dump, 'utf-8')

                    serialisable_info = json.loads(dump)

                    objs.append(
                        HydrusSerialisable.CreateFromSerialisableTuple(
                            (dump_type, dump_name, version,
                             serialisable_info)))

                except:

                    self._c.execute(
                        'DELETE FROM json_dumps_named WHERE dump_type = ? AND dump_name = ? AND timestamp = ?;',
                        (dump_type, dump_name, object_timestamp))

                    self._cursor_transaction_wrapper.CommitAndBegin()

                    DealWithBrokenJSONDump(
                        self._db_dir, dump,
                        'dump_type {} dump_name {} timestamp {}'.format(
                            dump_type, dump_name[:10], timestamp))

            return objs

        else:

            if timestamp is None:

                result = self._c.execute(
                    'SELECT version, dump, timestamp FROM json_dumps_named WHERE dump_type = ? AND dump_name = ? ORDER BY timestamp DESC;',
                    (dump_type, dump_name)).fetchone()

            else:

                result = self._c.execute(
                    'SELECT version, dump, timestamp FROM json_dumps_named WHERE dump_type = ? AND dump_name = ? AND timestamp = ?;',
                    (dump_type, dump_name, timestamp)).fetchone()

            if result is None:

                raise HydrusExceptions.DataMissing(
                    'Could not find the object of type "{}" and name "{}" and timestamp "{}".'
                    .format(dump_type, dump_name, str(timestamp)))

            (version, dump, object_timestamp) = result

            try:

                if isinstance(dump, bytes):

                    dump = str(dump, 'utf-8')

                serialisable_info = json.loads(dump)

            except:

                self._c.execute(
                    'DELETE FROM json_dumps_named WHERE dump_type = ? AND dump_name = ? AND timestamp = ?;',
                    (dump_type, dump_name, object_timestamp))

                self._cursor_transaction_wrapper.CommitAndBegin()

                DealWithBrokenJSONDump(
                    self._db_dir, dump,
                    'dump_type {} dump_name {} timestamp {}'.format(
                        dump_type, dump_name[:10], object_timestamp))

            return HydrusSerialisable.CreateFromSerialisableTuple(
                (dump_type, dump_name, version, serialisable_info))
Esempio n. 22
0
    def _PopulateHashIdsToHashesCache(self,
                                      hash_ids,
                                      exception_on_error=False):

        if len(self._hash_ids_to_hashes_cache) > 100000:

            if not isinstance(hash_ids, set):

                hash_ids = set(hash_ids)

            self._hash_ids_to_hashes_cache = {
                hash_id: hash
                for (hash_id, hash) in self._hash_ids_to_hashes_cache.items()
                if hash_id in hash_ids
            }

        uncached_hash_ids = {
            hash_id
            for hash_id in hash_ids
            if hash_id not in self._hash_ids_to_hashes_cache
        }

        if len(uncached_hash_ids) > 0:

            pubbed_error = False

            if len(uncached_hash_ids) == 1:

                (uncached_hash_id, ) = uncached_hash_ids

                rows = self._Execute(
                    'SELECT hash_id, hash FROM hashes WHERE hash_id = ?;',
                    (uncached_hash_id, )).fetchall()

            else:

                with self._MakeTemporaryIntegerTable(
                        uncached_hash_ids, 'hash_id') as temp_table_name:

                    # temp hash_ids to actual hashes
                    rows = self._Execute(
                        'SELECT hash_id, hash FROM {} CROSS JOIN hashes USING ( hash_id );'
                        .format(temp_table_name)).fetchall()

            uncached_hash_ids_to_hashes = dict(rows)

            if len(uncached_hash_ids_to_hashes) < len(uncached_hash_ids):

                for hash_id in uncached_hash_ids:

                    if hash_id not in uncached_hash_ids_to_hashes:

                        if exception_on_error:

                            raise HydrusExceptions.DataMissing(
                                'Did not find all entries for those hash ids!')

                        HydrusData.DebugPrint('Database hash error: hash_id ' +
                                              str(hash_id) + ' was missing!')
                        HydrusData.PrintException(
                            Exception('Missing file identifier stack trace.'))

                        if not pubbed_error:

                            HydrusData.ShowText(
                                'A file identifier was missing! This is a serious error that means your client database has an orphan file id! Think about contacting hydrus dev!'
                            )

                            pubbed_error = True

                        hash = bytes.fromhex('aaaaaaaaaaaaaaaa') + os.urandom(
                            16)

                        uncached_hash_ids_to_hashes[hash_id] = hash

            self._hash_ids_to_hashes_cache.update(uncached_hash_ids_to_hashes)
Esempio n. 23
0
def GetFFMPEGInfoLines( path, count_frames_manually = False, only_first_second = False ):
    
    # open the file in a pipe, provoke an error, read output
    
    cmd = [ FFMPEG_PATH, "-i", path ]
    
    if only_first_second:
        
        cmd.insert( 1, '-t' )
        cmd.insert( 2, '1' )
        
    
    if count_frames_manually:
        
        # added -an here to remove audio component, which was sometimes causing convert fails on single-frame music webms
        
        if HC.PLATFORM_WINDOWS:
            
            cmd += [ "-vf", "scale=-2:120", "-an", "-f", "null", "NUL" ]
            
        else:
            
            cmd += [ "-vf", "scale=-2:120", "-an", "-f", "null", "/dev/null" ]
            
        
    
    sbp_kwargs = HydrusData.GetSubprocessKWArgs()
    
    HydrusData.CheckProgramIsNotShuttingDown()
    
    try:
        
        process = subprocess.Popen( cmd, bufsize = 10**5, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, **sbp_kwargs )
        
    except FileNotFoundError as e:
        
        global FFMPEG_MISSING_ERROR_PUBBED
        
        if not FFMPEG_MISSING_ERROR_PUBBED:
            
            message = 'FFMPEG, which hydrus uses to parse and render video, was not found! This may be due to it not being available on your system, or hydrus being unable to find it.'
            message += os.linesep * 2
            
            if HC.PLATFORM_WINDOWS:
                
                message += 'You are on Windows, so there should be a copy of ffmpeg.exe in your install_dir/bin folder. If not, please check if your anti-virus has removed it and restore it through a new install.'
                
            else:
                
                message += 'If you are certain that FFMPEG is installed on your OS and accessible in your PATH, please let hydrus_dev know, as this problem is likely due to an environment problem. You may be able to solve this problem immediately by putting a static build of the ffmpeg executable in your install_dir/bin folder.'
                
            
            message += os.linesep * 2
            message += 'You can check your current FFMPEG status through help->about.'
            
            HydrusData.ShowText( message )
            
            FFMPEG_MISSING_ERROR_PUBBED = True
            
        
        raise FileNotFoundError( 'Cannot interact with video because FFMPEG not found--are you sure it is installed? Full error: ' + str( e ) )
        
    
    ( stdout, stderr ) = HydrusThreading.SubprocessCommunicate( process )
    
    data_bytes = stderr
    
    if len( data_bytes ) == 0:
        
        global FFMPEG_NO_CONTENT_ERROR_PUBBED
        
        if not FFMPEG_NO_CONTENT_ERROR_PUBBED:
            
            message = 'FFMPEG, which hydrus uses to parse and render video, did not return any data on a recent file metadata check! More debug info has been written to the log.'
            message += os.linesep * 2
            message += 'You can check this info again through help->about.'
            
            HydrusData.ShowText( message )
            
            message += os.linesep * 2
            message += str( sbp_kwargs )
            message += os.linesep * 2
            message += str( os.environ )
            message += os.linesep * 2
            message += 'STDOUT Response: {}'.format( stdout )
            message += os.linesep * 2
            message += 'STDERR Response: {}'.format( stderr )
            
            HydrusData.DebugPrint( message )
            
            FFMPEG_NO_CONTENT_ERROR_PUBBED = True
            
        
        raise HydrusExceptions.DataMissing( 'Cannot interact with video because FFMPEG did not return any content.' )
        
    
    del process
    
    ( text, encoding ) = HydrusText.NonFailingUnicodeDecode( data_bytes, 'utf-8' )
    
    lines = text.splitlines()
    
    CheckFFMPEGError( lines )
    
    return lines
Esempio n. 24
0
    def _GetListCtrlMenu(self):

        selected_file_seeds = self._list_ctrl.GetData(only_selected=True)

        if len(selected_file_seeds) == 0:

            raise HydrusExceptions.DataMissing()

        menu = QW.QMenu()

        can_show_files_in_new_page = True in (
            file_seed.HasHash() for file_seed in selected_file_seeds)

        if can_show_files_in_new_page:

            ClientGUIMenus.AppendMenuItem(
                menu, 'open selected import files in a new page',
                'Show all the known selected files in a new thumbnail page. This is complicated, so cannot always be guaranteed, even if the import says \'success\'.',
                self._ShowSelectionInNewPage)

            ClientGUIMenus.AppendSeparator(menu)

        ClientGUIMenus.AppendMenuItem(
            menu, 'copy sources',
            'Copy all the selected sources to clipboard.',
            self._CopySelectedFileSeedData)
        ClientGUIMenus.AppendMenuItem(
            menu, 'copy notes', 'Copy all the selected notes to clipboard.',
            self._CopySelectedNotes)

        if len(selected_file_seeds) == 1:

            ClientGUIMenus.AppendSeparator(menu)

            (selected_file_seed, ) = selected_file_seeds

            hash_types_to_hashes = selected_file_seed.GetHashTypesToHashes()

            if len(hash_types_to_hashes) == 0:

                ClientGUIMenus.AppendMenuLabel(menu, 'no hashes yet')

            else:

                hash_submenu = QW.QMenu(menu)

                for hash_type in ('sha256', 'md5', 'sha1', 'sha512'):

                    if hash_type in hash_types_to_hashes:

                        h = hash_types_to_hashes[hash_type]

                        ClientGUIMenus.AppendMenuLabel(
                            hash_submenu, '{}:{}'.format(hash_type, h.hex()))

                ClientGUIMenus.AppendMenu(menu, hash_submenu, 'hashes')

            #

            if selected_file_seed.IsURLFileImport():

                referral_url = selected_file_seed.GetReferralURL()
                primary_urls = sorted(selected_file_seed.GetPrimaryURLs())
                source_urls = sorted(selected_file_seed.GetSourceURLs())

                if referral_url is None and len(primary_urls) + len(
                        source_urls) == 0:

                    ClientGUIMenus.AppendMenuLabel(menu, 'no additional urls')

                else:

                    url_submenu = QW.QMenu(menu)

                    if referral_url is not None:

                        ClientGUIMenus.AppendMenuLabel(url_submenu,
                                                       'referral url:')
                        ClientGUIMenus.AppendMenuLabel(url_submenu,
                                                       referral_url)

                    if len(primary_urls) > 0:

                        ClientGUIMenus.AppendSeparator(url_submenu)

                        ClientGUIMenus.AppendMenuLabel(url_submenu,
                                                       'primary urls:')

                        for url in primary_urls:

                            ClientGUIMenus.AppendMenuLabel(url_submenu, url)

                    if len(source_urls) > 0:

                        ClientGUIMenus.AppendSeparator(url_submenu)

                        ClientGUIMenus.AppendMenuLabel(url_submenu,
                                                       'source urls:')

                        for url in source_urls:

                            ClientGUIMenus.AppendMenuLabel(url_submenu, url)

                    ClientGUIMenus.AppendMenu(menu, url_submenu,
                                              'additional urls')

                #

                tags = list(selected_file_seed.GetExternalTags())

                tag_sort = ClientTagSorting.TagSort(
                    sort_type=ClientTagSorting.SORT_BY_HUMAN_TAG,
                    sort_order=CC.SORT_ASC)

                ClientTagSorting.SortTags(tag_sort, tags)

                if len(tags) == 0:

                    ClientGUIMenus.AppendMenuLabel(menu, 'no parsed tags')

                else:

                    tag_submenu = QW.QMenu(menu)

                    for tag in tags:

                        ClientGUIMenus.AppendMenuLabel(tag_submenu, tag)

                    ClientGUIMenus.AppendMenu(menu, tag_submenu, 'parsed tags')

        ClientGUIMenus.AppendSeparator(menu)

        ClientGUIMenus.AppendMenuItem(
            menu, 'open sources',
            'Open all the selected sources in your file explorer or web browser.',
            self._OpenSelectedFileSeedData)

        ClientGUIMenus.AppendSeparator(menu)

        ClientGUIMenus.AppendMenuItem(
            menu, 'try again',
            'Reset the progress of all the selected imports.',
            HydrusData.Call(self._SetSelected, CC.STATUS_UNKNOWN))

        ClientGUIMenus.AppendMenuItem(
            menu, 'skip', 'Skip all the selected imports.',
            HydrusData.Call(self._SetSelected, CC.STATUS_SKIPPED))

        ClientGUIMenus.AppendMenuItem(menu, 'delete from list',
                                      'Remove all the selected imports.',
                                      HydrusData.Call(self._DeleteSelected))

        return menu