Version 210
This commit is contained in:
parent
b063f24298
commit
eccf03aaa4
|
@ -27,7 +27,9 @@ try:
|
|||
from include import HydrusLogger
|
||||
import traceback
|
||||
|
||||
with HydrusLogger.HydrusLogger( 'client.log' ) as logger:
|
||||
log_path = os.path.join( HC.DB_DIR, 'client.log' )
|
||||
|
||||
with HydrusLogger.HydrusLogger( log_path ) as logger:
|
||||
|
||||
try:
|
||||
|
||||
|
|
|
@ -8,6 +8,26 @@
|
|||
<div class="content">
|
||||
<h3>changelog</h3>
|
||||
<ul>
|
||||
<li><h3>version 210</h3></li>
|
||||
<ul>
|
||||
<li>manage tags dialog now launches much faster when thousands of thumbs are selected</li>
|
||||
<li>manage tags dialog now has a prototype 'do this for all' checkbox to make mass selected-tag editing a bit quicker</li>
|
||||
<li>polished the new disk cache turbo mode, added free memory limits and more options</li>
|
||||
<li>a bit of disk cache population now runs on client boot, just to kick things off</li>
|
||||
<li>a full disk cache population now runs before repo sync</li>
|
||||
<li>the client now keeps about 200MB of itself in the disk cache during idle maintenance</li>
|
||||
<li>the update files in client_updates are now stored compressed</li>
|
||||
<li>the log files and 'already running' files are now stored in the db folder, meaning hydrus shouldn't have to write to anything but db dir and temp dir</li>
|
||||
<li>'already running' files now delete themselves on program close if they can</li>
|
||||
<li>the log directory is no longer needed</li>
|
||||
<li>if there is only one booru to select, it will be auto-selected</li>
|
||||
<li>client failed exit is less likely to hang, more likely to log error</li>
|
||||
<li>client won't bother to save lest session regularly or on exit if this is not the default startup session</li>
|
||||
<li>hotfixed an auto-vacuum bug</li>
|
||||
<li>added a catch for any future vacuum mess-ups to save the db from collapse</li>
|
||||
<li>added other catches for other close/reinit db calls</li>
|
||||
<li>misc cleanup</li>
|
||||
</ul>
|
||||
<li><h3>version 209</h3></li>
|
||||
<ul>
|
||||
<li>the advanced content update dialog can now be !aunched from manage tags, and will only affect the files the dialog was launched for</li>
|
||||
|
|
|
@ -139,7 +139,7 @@ class Controller( HydrusController.HydrusController ):
|
|||
|
||||
def CheckAlreadyRunning( self ):
|
||||
|
||||
while HydrusData.IsAlreadyRunning( 'client' ):
|
||||
while HydrusData.IsAlreadyRunning( HC.DB_DIR, 'client' ):
|
||||
|
||||
self.pub( 'splash_set_status_text', 'client already running' )
|
||||
|
||||
|
@ -162,7 +162,7 @@ class Controller( HydrusController.HydrusController ):
|
|||
|
||||
for i in range( 10, 0, -1 ):
|
||||
|
||||
if not HydrusData.IsAlreadyRunning( 'client' ):
|
||||
if not HydrusData.IsAlreadyRunning( HC.DB_DIR, 'client' ):
|
||||
|
||||
break
|
||||
|
||||
|
@ -616,6 +616,8 @@ class Controller( HydrusController.HydrusController ):
|
|||
|
||||
|
||||
|
||||
loaded_into_disk_cache = HydrusGlobals.client_controller.Read( 'load_into_disk_cache', stop_time = stop_time, caller_limit = 200 * 1024 * 1024 )
|
||||
|
||||
self.WriteInterruptable( 'vacuum', stop_time = stop_time )
|
||||
|
||||
self.pub( 'splash_set_status_text', 'analyzing' )
|
||||
|
@ -1038,7 +1040,7 @@ class Controller( HydrusController.HydrusController ):
|
|||
|
||||
self.CheckAlreadyRunning()
|
||||
|
||||
HydrusData.RecordRunningStart( 'client' )
|
||||
HydrusData.RecordRunningStart( HC.DB_DIR, 'client' )
|
||||
|
||||
self.InitModel()
|
||||
|
||||
|
@ -1085,6 +1087,8 @@ class Controller( HydrusController.HydrusController ):
|
|||
|
||||
self.ShutdownModel()
|
||||
|
||||
HydrusData.CleanRunningFile( HC.DB_DIR, 'client' )
|
||||
|
||||
except HydrusExceptions.PermissionException: pass
|
||||
except HydrusExceptions.ShutdownException: pass
|
||||
except:
|
||||
|
|
|
@ -27,6 +27,7 @@ import HydrusThreading
|
|||
import ClientConstants as CC
|
||||
import lz4
|
||||
import os
|
||||
import psutil
|
||||
import Queue
|
||||
import random
|
||||
import shutil
|
||||
|
@ -3963,14 +3964,13 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
current_file_service_keys_to_timestamps = { service_ids_to_service_keys[ service_id ] : timestamp for ( service_id, timestamp ) in hash_ids_to_current_file_service_ids_and_timestamps[ hash_id ] }
|
||||
|
||||
file_service_keys_cdpp = ClientMedia.LocationsManager( current_file_service_keys, deleted_file_service_keys, pending_file_service_keys, petitioned_file_service_keys, urls = urls, service_keys_to_filenames = service_keys_to_filenames, current_to_timestamps = current_file_service_keys_to_timestamps )
|
||||
locations_manager = ClientMedia.LocationsManager( current_file_service_keys, deleted_file_service_keys, pending_file_service_keys, petitioned_file_service_keys, urls = urls, service_keys_to_filenames = service_keys_to_filenames, current_to_timestamps = current_file_service_keys_to_timestamps )
|
||||
|
||||
#
|
||||
|
||||
local_ratings = { service_ids_to_service_keys[ service_id ] : rating for ( service_id, rating ) in hash_ids_to_local_ratings[ hash_id ] }
|
||||
|
||||
local_ratings = ClientRatings.LocalRatingsManager( local_ratings )
|
||||
remote_ratings = {}
|
||||
ratings_manager = ClientRatings.RatingsManager( local_ratings )
|
||||
|
||||
#
|
||||
|
||||
|
@ -3983,7 +3983,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
( size, mime, width, height, duration, num_frames, num_words ) = ( None, HC.APPLICATION_UNKNOWN, None, None, None, None, None )
|
||||
|
||||
|
||||
media_results.append( ClientMedia.MediaResult( ( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, file_service_keys_cdpp, local_ratings, remote_ratings ) ) )
|
||||
media_results.append( ClientMedia.MediaResult( ( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager ) ) )
|
||||
|
||||
|
||||
return media_results
|
||||
|
@ -5036,6 +5036,11 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
archives_dir = os.path.join( self._db_dir, 'client_archives' )
|
||||
|
||||
if not os.path.exists( archives_dir ):
|
||||
|
||||
os.makedirs( archives_dir )
|
||||
|
||||
|
||||
for filename in os.listdir( archives_dir ):
|
||||
|
||||
if filename.endswith( '.db' ):
|
||||
|
@ -5061,6 +5066,14 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _InitCaches( self ):
|
||||
|
||||
HydrusGlobals.client_controller.pub( 'splash_set_status_text', 'preparing disk cache' )
|
||||
|
||||
stop_time = HydrusData.GetNow() + 10
|
||||
|
||||
self._LoadIntoDiskCache( stop_time = stop_time )
|
||||
|
||||
HydrusGlobals.client_controller.pub( 'splash_set_status_text', 'preparing db caches' )
|
||||
|
||||
self._local_file_service_id = self._GetServiceId( CC.LOCAL_FILE_SERVICE_KEY )
|
||||
self._trash_service_id = self._GetServiceId( CC.TRASH_SERVICE_KEY )
|
||||
self._local_tag_service_id = self._GetServiceId( CC.LOCAL_TAG_SERVICE_KEY )
|
||||
|
@ -5127,24 +5140,61 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
|
||||
|
||||
def _LoadIntoDiskCache( self ):
|
||||
def _LoadIntoDiskCache( self, stop_time = None, caller_limit = None ):
|
||||
|
||||
self._CloseDBCursor()
|
||||
|
||||
for filename in self._db_filenames.values():
|
||||
try:
|
||||
|
||||
path = os.path.join( self._db_dir, filename )
|
||||
approx_disk_cache_size = psutil.virtual_memory().available * 4 / 5
|
||||
|
||||
with open( path, 'rb' ) as f:
|
||||
|
||||
while f.read( HC.READ_BLOCK_SIZE ) != '':
|
||||
|
||||
pass
|
||||
|
||||
|
||||
disk_cache_limit = approx_disk_cache_size * 2 / 3
|
||||
|
||||
except psutil.Error:
|
||||
|
||||
disk_cache_limit = 1024 * 1024 * 1024
|
||||
|
||||
|
||||
self._InitDBCursor()
|
||||
so_far_read = 0
|
||||
|
||||
try:
|
||||
|
||||
paths = [ os.path.join( HC.DB_DIR, filename ) for filename in self._db_filenames.values() ]
|
||||
|
||||
paths.sort( key = os.path.getsize )
|
||||
|
||||
for path in paths:
|
||||
|
||||
with open( path, 'rb' ) as f:
|
||||
|
||||
while f.read( HC.READ_BLOCK_SIZE ) != '':
|
||||
|
||||
if stop_time is not None and HydrusData.TimeHasPassed( stop_time ):
|
||||
|
||||
return False
|
||||
|
||||
|
||||
so_far_read += HC.READ_BLOCK_SIZE
|
||||
|
||||
if so_far_read > disk_cache_limit:
|
||||
|
||||
return True
|
||||
|
||||
|
||||
if caller_limit is not None and so_far_read > caller_limit:
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
finally:
|
||||
|
||||
self._InitDBCursor()
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _MaintenanceDue( self ):
|
||||
|
@ -6436,214 +6486,6 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._controller.pub( 'splash_set_title_text', 'updating db to v' + str( version + 1 ) )
|
||||
|
||||
if version == 150:
|
||||
|
||||
options = self._GetOptions()
|
||||
|
||||
options[ 'file_system_predicates' ][ 'hamming_distance' ] = 5
|
||||
|
||||
self._c.execute( 'UPDATE options SET options = ?;', ( options, ) )
|
||||
|
||||
|
||||
if version == 151:
|
||||
|
||||
results = self._c.execute( 'SELECT * FROM yaml_dumps WHERE dump_type = ?;', ( YAML_DUMP_ID_SUBSCRIPTION, ) ).fetchall()
|
||||
|
||||
for ( dump_type, dump_name, dump ) in results:
|
||||
|
||||
dump[ 'initial_limit' ] = 500
|
||||
|
||||
self._c.execute( 'UPDATE yaml_dumps SET dump = ? WHERE dump_type = ? and dump_name = ?;', ( dump, dump_type, dump_name ) )
|
||||
|
||||
|
||||
|
||||
if version == 152:
|
||||
|
||||
options = self._GetOptions()
|
||||
|
||||
options[ 'file_system_predicates' ][ 'num_pixels' ] = ( 1, 2, 2 )
|
||||
|
||||
self._c.execute( 'UPDATE options SET options = ?;', ( options, ) )
|
||||
|
||||
|
||||
if version == 153:
|
||||
|
||||
options = self._GetOptions()
|
||||
|
||||
options[ 'file_system_predicates' ] = ClientDefaults.GetClientDefaultOptions()[ 'file_system_predicates' ]
|
||||
|
||||
self._c.execute( 'UPDATE options SET options = ?;', ( options, ) )
|
||||
|
||||
#
|
||||
|
||||
self._c.execute( 'CREATE TABLE json_dumps ( dump_type INTEGER PRIMARY KEY, version INTEGER, dump BLOB_BYTES );' )
|
||||
self._c.execute( 'CREATE TABLE json_dumps_named ( dump_type INTEGER, dump_name TEXT, version INTEGER, dump BLOB_BYTES, PRIMARY KEY ( dump_type, dump_name ) );' )
|
||||
|
||||
#
|
||||
|
||||
results = self._c.execute( 'SELECT * FROM yaml_dumps WHERE dump_type = ?;', ( YAML_DUMP_ID_FAVOURITE_CUSTOM_FILTER_ACTIONS, ) ).fetchall()
|
||||
|
||||
objs = []
|
||||
|
||||
for ( dump_type, dump_name, dump ) in results:
|
||||
|
||||
shortcuts = ClientData.Shortcuts( dump_name )
|
||||
|
||||
actions = dump
|
||||
|
||||
for ( modifier, key, service_key, data ) in actions:
|
||||
|
||||
if isinstance( service_key, ClientData.ClientServiceIdentifier ): service_key = service_key.GetServiceKey()
|
||||
|
||||
action = ( service_key, data )
|
||||
|
||||
shortcuts.SetKeyboardAction( modifier, key, action )
|
||||
|
||||
|
||||
objs.append( shortcuts )
|
||||
|
||||
|
||||
for obj in objs:
|
||||
|
||||
( dump_type, dump_name, dump_version, serialisable_info ) = obj.GetSerialisableTuple()
|
||||
|
||||
dump = json.dumps( serialisable_info )
|
||||
|
||||
self._c.execute( 'INSERT INTO json_dumps_named ( dump_type, dump_name, version, dump ) VALUES ( ?, ?, ?, ? );', ( dump_type, dump_name, dump_version, sqlite3.Binary( dump ) ) )
|
||||
|
||||
|
||||
self._c.execute( 'DELETE FROM yaml_dumps WHERE dump_type = ?;', ( YAML_DUMP_ID_FAVOURITE_CUSTOM_FILTER_ACTIONS, ) )
|
||||
|
||||
|
||||
if version == 156:
|
||||
|
||||
results = self._c.execute( 'SELECT dump_type, dump_name, dump FROM json_dumps_named;' ).fetchall()
|
||||
|
||||
for ( dump_type, dump_name, dump ) in results:
|
||||
|
||||
try:
|
||||
|
||||
dump = lz4.loads( dump )
|
||||
|
||||
self._c.execute( 'UPDATE json_dumps_named SET dump = ? WHERE dump_type = ? AND dump_name = ?;', ( sqlite3.Binary( dump ), dump_type, dump_name ) )
|
||||
|
||||
except:
|
||||
|
||||
continue
|
||||
|
||||
|
||||
|
||||
|
||||
if version == 157:
|
||||
|
||||
results = self._c.execute( 'SELECT * FROM yaml_dumps WHERE dump_type = ?;', ( YAML_DUMP_ID_SUBSCRIPTION, ) ).fetchall()
|
||||
|
||||
for ( dump_type, dump_name, dump ) in results:
|
||||
|
||||
dump[ 'get_tags_if_redundant' ] = False
|
||||
|
||||
a_i_o = dump[ 'advanced_import_options' ]
|
||||
|
||||
if 'auto_archive' not in a_i_o:
|
||||
|
||||
a_i_o[ 'auto_archive' ] = False
|
||||
|
||||
|
||||
if 'exclude_deleted_files' not in a_i_o:
|
||||
|
||||
a_i_o[ 'exclude_deleted_files' ] = False
|
||||
|
||||
|
||||
if 'min_resolution' not in a_i_o:
|
||||
|
||||
a_i_o[ 'min_resolution' ] = None
|
||||
|
||||
|
||||
if 'min_size' not in a_i_o:
|
||||
|
||||
a_i_o[ 'min_size' ] = None
|
||||
|
||||
|
||||
self._c.execute( 'UPDATE yaml_dumps SET dump = ? WHERE dump_type = ? and dump_name = ?;', ( dump, dump_type, dump_name ) )
|
||||
|
||||
|
||||
#
|
||||
|
||||
results = self._c.execute( 'SELECT service_id, service_type, info FROM services WHERE service_type IN ( ?, ? );', ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ) ).fetchall()
|
||||
|
||||
for ( service_id, service_type, info ) in results:
|
||||
|
||||
if service_type == HC.LOCAL_RATING_LIKE:
|
||||
|
||||
del info[ 'like' ]
|
||||
del info[ 'dislike' ]
|
||||
|
||||
info[ 'colours' ] = ClientRatings.default_like_colours
|
||||
|
||||
else:
|
||||
|
||||
upper = info[ 'upper' ]
|
||||
lower = info[ 'lower' ]
|
||||
|
||||
del info[ 'upper' ]
|
||||
del info[ 'lower' ]
|
||||
|
||||
info[ 'num_stars' ] = upper - lower
|
||||
|
||||
info[ 'colours' ] = ClientRatings.default_numerical_colours
|
||||
|
||||
|
||||
info[ 'shape' ] = ClientRatings.CIRCLE
|
||||
|
||||
self._c.execute( 'UPDATE services SET info = ? WHERE service_id = ?;', ( info, service_id ) )
|
||||
|
||||
|
||||
#
|
||||
|
||||
results = self._c.execute( 'SELECT * FROM yaml_dumps WHERE dump_type = ?;', ( YAML_DUMP_ID_EXPORT_FOLDER, ) ).fetchall()
|
||||
|
||||
for ( dump_type, dump_name, dump ) in results:
|
||||
|
||||
details = dump
|
||||
|
||||
details[ 'type' ] = HC.EXPORT_FOLDER_TYPE_REGULAR
|
||||
|
||||
self._c.execute( 'UPDATE yaml_dumps SET dump = ? WHERE dump_type = ? and dump_name = ?;', ( dump, dump_type, dump_name ) )
|
||||
|
||||
|
||||
|
||||
if version == 158:
|
||||
|
||||
results = self._c.execute( 'SELECT service_id, service_type, info FROM services WHERE service_type IN ( ?, ? );', ( HC.TAG_REPOSITORY, HC.FILE_REPOSITORY ) ).fetchall()
|
||||
|
||||
for ( service_id, service_type, info ) in results:
|
||||
|
||||
info[ 'first_timestamp' ] = None
|
||||
info[ 'next_download_timestamp' ] = 0
|
||||
|
||||
self._c.execute( 'UPDATE services SET info = ? WHERE service_id = ?;', ( info, service_id ) )
|
||||
|
||||
|
||||
for filename in os.listdir( HC.CLIENT_UPDATES_DIR ):
|
||||
|
||||
path = os.path.join( HC.CLIENT_UPDATES_DIR, filename )
|
||||
|
||||
ClientData.DeletePath( path )
|
||||
|
||||
|
||||
|
||||
if version == 159:
|
||||
|
||||
results = self._c.execute( 'SELECT service_id, service_type, info FROM services WHERE service_type = ?;', ( HC.LOCAL_RATING_NUMERICAL, ) ).fetchall()
|
||||
|
||||
for ( service_id, service_type, info ) in results:
|
||||
|
||||
info[ 'allow_zero' ] = True
|
||||
|
||||
self._c.execute( 'UPDATE services SET info = ? WHERE service_id = ?;', ( info, service_id ) )
|
||||
|
||||
|
||||
|
||||
if version == 160:
|
||||
|
||||
self._c.execute( 'REPLACE INTO yaml_dumps VALUES ( ?, ?, ? );', ( YAML_DUMP_ID_REMOTE_BOORU, 'e621', ClientDefaults.GetDefaultBoorus()[ 'e621' ] ) )
|
||||
|
@ -7509,29 +7351,34 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._CloseDBCursor()
|
||||
|
||||
for filename in self._db_filenames.values():
|
||||
try:
|
||||
|
||||
self._controller.pub( 'splash_set_status_text', 'vacuuming ' + filename )
|
||||
|
||||
db_path = os.path.join( self._db_dir, filename )
|
||||
|
||||
try:
|
||||
for filename in self._db_filenames.values():
|
||||
|
||||
if HydrusDB.CanVacuum( db_path ):
|
||||
self._controller.pub( 'splash_set_status_text', 'vacuuming ' + filename )
|
||||
|
||||
db_path = os.path.join( self._db_dir, filename )
|
||||
|
||||
try:
|
||||
|
||||
HydrusDB.VacuumDB( db_path )
|
||||
if HydrusDB.CanVacuum( db_path ):
|
||||
|
||||
HydrusDB.VacuumDB( db_path )
|
||||
|
||||
|
||||
except Exception as e:
|
||||
|
||||
HydrusData.Print( 'Vacuum failed!' )
|
||||
HydrusData.PrintException( e )
|
||||
|
||||
|
||||
except Exception as e:
|
||||
|
||||
HydrusData.Print( 'Vacuum failed!' )
|
||||
HydrusData.PrintException( e )
|
||||
|
||||
|
||||
|
||||
self._InitDBCursor()
|
||||
|
||||
self._c.execute( 'BEGIN IMMEDIATE;' )
|
||||
finally:
|
||||
|
||||
self._InitDBCursor()
|
||||
|
||||
self._c.execute( 'BEGIN IMMEDIATE;' )
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -7787,29 +7634,34 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._CloseDBCursor()
|
||||
|
||||
for filename in self._db_filenames.values():
|
||||
try:
|
||||
|
||||
self._controller.pub( 'splash_set_status_text', 'vacuuming ' + filename )
|
||||
|
||||
db_path = os.path.join( self._db_dir, filename )
|
||||
|
||||
try:
|
||||
for filename in self._db_filenames.values():
|
||||
|
||||
if HydrusDB.CanVacuum( db_path ):
|
||||
self._controller.pub( 'splash_set_status_text', 'vacuuming ' + filename )
|
||||
|
||||
db_path = os.path.join( self._db_dir, filename )
|
||||
|
||||
try:
|
||||
|
||||
HydrusDB.VacuumDB( db_path )
|
||||
if HydrusDB.CanVacuum( db_path ):
|
||||
|
||||
HydrusDB.VacuumDB( db_path )
|
||||
|
||||
|
||||
except Exception as e:
|
||||
|
||||
HydrusData.Print( 'Vacuum failed!' )
|
||||
HydrusData.PrintException( e )
|
||||
|
||||
|
||||
except Exception as e:
|
||||
|
||||
HydrusData.Print( 'Vacuum failed!' )
|
||||
HydrusData.PrintException( e )
|
||||
|
||||
|
||||
|
||||
self._InitDBCursor()
|
||||
|
||||
self._c.execute( 'BEGIN IMMEDIATE;' )
|
||||
finally:
|
||||
|
||||
self._InitDBCursor()
|
||||
|
||||
self._c.execute( 'BEGIN IMMEDIATE;' )
|
||||
|
||||
|
||||
|
||||
if version == 204:
|
||||
|
@ -7913,6 +7765,47 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
|
||||
|
||||
if version == 209:
|
||||
|
||||
update_dirnames = os.listdir( HC.CLIENT_UPDATES_DIR )
|
||||
|
||||
for update_dirname in update_dirnames:
|
||||
|
||||
update_dir = os.path.join( HC.CLIENT_UPDATES_DIR, update_dirname )
|
||||
|
||||
if os.path.isdir( update_dir ):
|
||||
|
||||
update_filenames = os.listdir( update_dir )
|
||||
|
||||
for update_filename in update_filenames:
|
||||
|
||||
update_path = os.path.join( update_dir, update_filename )
|
||||
|
||||
try:
|
||||
|
||||
with open( update_path, 'rb' ) as f:
|
||||
|
||||
content = f.read()
|
||||
|
||||
|
||||
obj = HydrusSerialisable.CreateFromString( content )
|
||||
|
||||
compressed_content = obj.DumpToNetworkString()
|
||||
|
||||
with open( update_path, 'wb' ) as f:
|
||||
|
||||
f.write( compressed_content )
|
||||
|
||||
|
||||
except:
|
||||
|
||||
HydrusData.Print( 'The path ' + update_path + ' failed to convert to a network string.' )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
self._controller.pub( 'splash_set_title_text', 'updated db to v' + str( version + 1 ) )
|
||||
|
||||
self._c.execute( 'UPDATE version SET version = ?;', ( version + 1, ) )
|
||||
|
|
|
@ -728,7 +728,7 @@ class Imageboard( HydrusData.HydrusYAMLBase ):
|
|||
|
||||
def IsOkToPost( self, media_result ):
|
||||
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, local_ratings, remote_ratings ) = media_result.ToTuple()
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager ) = media_result.ToTuple()
|
||||
|
||||
if CC.RESTRICTION_MIN_RESOLUTION in self._restrictions:
|
||||
|
||||
|
@ -1529,7 +1529,7 @@ class ServiceRepository( ServiceRestricted ):
|
|||
|
||||
content_update_package = self.Request( HC.GET, 'content_update_package', { 'begin' : begin, 'subindex' : subindex } )
|
||||
|
||||
obj_string = content_update_package.DumpToString()
|
||||
obj_string = content_update_package.DumpToNetworkString()
|
||||
|
||||
job_key.SetVariable( 'popup_text_1', update_index_string + subupdate_index_string + 'saving to disk' )
|
||||
|
||||
|
@ -1541,7 +1541,7 @@ class ServiceRepository( ServiceRestricted ):
|
|||
|
||||
path = ClientFiles.GetExpectedServiceUpdatePackagePath( self._service_key, begin )
|
||||
|
||||
obj_string = service_update_package.DumpToString()
|
||||
obj_string = service_update_package.DumpToNetworkString()
|
||||
|
||||
with open( path, 'wb' ) as f: f.write( obj_string )
|
||||
|
||||
|
@ -1578,6 +1578,33 @@ class ServiceRepository( ServiceRestricted ):
|
|||
|
||||
|
||||
|
||||
if self.CanProcessUpdate():
|
||||
|
||||
HydrusGlobals.client_controller.pub( 'splash_set_status_text', 'preparing disk cache' )
|
||||
job_key.SetVariable( 'popup_text_1', 'preparing disk cache' )
|
||||
|
||||
loaded_into_disk_cache = False
|
||||
|
||||
while not loaded_into_disk_cache:
|
||||
|
||||
if options[ 'pause_repo_sync' ]:
|
||||
|
||||
break
|
||||
|
||||
|
||||
( i_paused, should_quit ) = job_key.WaitIfNeeded()
|
||||
|
||||
if should_quit:
|
||||
|
||||
break
|
||||
|
||||
|
||||
stop_time = HydrusData.GetNow() + 15
|
||||
|
||||
loaded_into_disk_cache = HydrusGlobals.client_controller.Read( 'load_into_disk_cache', stop_time = stop_time )
|
||||
|
||||
|
||||
|
||||
while self.CanProcessUpdate():
|
||||
|
||||
if options[ 'pause_repo_sync' ]:
|
||||
|
@ -1618,7 +1645,7 @@ class ServiceRepository( ServiceRestricted ):
|
|||
|
||||
try:
|
||||
|
||||
service_update_package = HydrusSerialisable.CreateFromString( obj_string )
|
||||
service_update_package = HydrusSerialisable.CreateFromNetworkString( obj_string )
|
||||
|
||||
if not isinstance( service_update_package, HydrusData.ServerToClientServiceUpdatePackage ):
|
||||
|
||||
|
@ -1673,7 +1700,7 @@ class ServiceRepository( ServiceRestricted ):
|
|||
|
||||
try:
|
||||
|
||||
content_update_package = HydrusSerialisable.CreateFromString( obj_string )
|
||||
content_update_package = HydrusSerialisable.CreateFromNetworkString( obj_string )
|
||||
|
||||
if not isinstance( content_update_package, HydrusData.ServerToClientContentUpdatePackage ):
|
||||
|
||||
|
@ -2304,32 +2331,4 @@ def GetShortcutFromEvent( event ):
|
|||
key = event.KeyCode
|
||||
|
||||
return ( modifier, key )
|
||||
|
||||
class ClientServiceIdentifier( HydrusData.HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ClientServiceIdentifier'
|
||||
|
||||
def __init__( self, service_key, service_type, name ):
|
||||
|
||||
HydrusData.HydrusYAMLBase.__init__( self )
|
||||
|
||||
self._service_key = service_key
|
||||
self._type = service_type
|
||||
self._name = name
|
||||
|
||||
|
||||
def __eq__( self, other ): return self.__hash__() == other.__hash__()
|
||||
|
||||
def __hash__( self ): return self._service_key.__hash__()
|
||||
|
||||
def __ne__( self, other ): return self.__hash__() != other.__hash__()
|
||||
|
||||
def __repr__( self ): return 'Client Service Identifier: ' + HydrusData.ToUnicode( ( self._name, HC.service_string_lookup[ self._type ] ) )
|
||||
|
||||
def GetInfo( self ): return ( self._service_key, self._type, self._name )
|
||||
|
||||
def GetName( self ): return self._name
|
||||
|
||||
def GetServiceKey( self ): return self._service_key
|
||||
|
||||
def GetServiceType( self ): return self._type
|
||||
|
|
|
@ -1163,7 +1163,7 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
debug.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'debug_garbage' ), p( 'Garbage' ) )
|
||||
debug.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'clear_caches' ), p( '&Clear Preview/Fullscreen Caches' ) )
|
||||
debug.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'delete_service_info' ), p( '&Clear DB Service Info Cache' ), p( 'Delete all cached service info, in case it has become desynchronised.' ) )
|
||||
debug.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'load_into_disk_cache' ), p( 'Engage Turbo Mode (testing)' ) )
|
||||
debug.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'load_into_disk_cache' ), p( 'Load db into disk cache' ) )
|
||||
|
||||
menu.AppendMenu( wx.ID_NONE, p( 'Debug' ), debug )
|
||||
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'help_shortcuts' ), p( '&Shortcuts' ) )
|
||||
|
@ -2134,7 +2134,7 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
|
||||
service.Request( HC.POST, 'file', { 'file' : file } )
|
||||
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, local_ratings, remote_ratings ) = media_result.ToTuple()
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager ) = media_result.ToTuple()
|
||||
|
||||
timestamp = HydrusData.GetNow()
|
||||
|
||||
|
@ -2353,7 +2353,7 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
elif command == 'load_gui_session': self._LoadGUISession( data )
|
||||
elif command == 'load_into_disk_cache':
|
||||
|
||||
self._controller.Read( 'load_into_disk_cache' )
|
||||
self._controller.CallToThread( self._controller.Read, 'load_into_disk_cache' )
|
||||
|
||||
elif command == 'manage_account_types': self._ManageAccountTypes( data )
|
||||
elif command == 'manage_boorus': self._ManageBoorus()
|
||||
|
@ -2530,25 +2530,32 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
HydrusGlobals.restart = True
|
||||
|
||||
|
||||
if not self._loading_session:
|
||||
try:
|
||||
|
||||
self._SaveGUISession( 'last session' )
|
||||
if HC.options[ 'default_gui_session' ] == 'last session' and not self._loading_session:
|
||||
|
||||
self._SaveGUISession( 'last session' )
|
||||
|
||||
|
||||
|
||||
self._message_manager.CleanBeforeDestroy()
|
||||
|
||||
self._message_manager.Hide()
|
||||
|
||||
for page in [ self._notebook.GetPage( i ) for i in range( self._notebook.GetPageCount() ) ]: page.CleanBeforeDestroy()
|
||||
|
||||
page = self._notebook.GetCurrentPage()
|
||||
|
||||
if page is not None:
|
||||
self._message_manager.CleanBeforeDestroy()
|
||||
|
||||
( HC.options[ 'hpos' ], HC.options[ 'vpos' ] ) = page.GetSashPositions()
|
||||
self._message_manager.Hide()
|
||||
|
||||
for page in [ self._notebook.GetPage( i ) for i in range( self._notebook.GetPageCount() ) ]: page.CleanBeforeDestroy()
|
||||
|
||||
page = self._notebook.GetCurrentPage()
|
||||
|
||||
if page is not None:
|
||||
|
||||
( HC.options[ 'hpos' ], HC.options[ 'vpos' ] ) = page.GetSashPositions()
|
||||
|
||||
|
||||
self._controller.WriteSynchronous( 'save_options', HC.options )
|
||||
|
||||
except Exception as e:
|
||||
|
||||
HydrusData.PrintException( e )
|
||||
|
||||
|
||||
self._controller.WriteSynchronous( 'save_options', HC.options )
|
||||
|
||||
self.Hide()
|
||||
|
||||
|
@ -2714,8 +2721,14 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
|
||||
old_menu_index = self._menubar.FindMenu( old_label )
|
||||
|
||||
if show: self._menubar.Replace( old_menu_index, menu, label )
|
||||
else: self._menubar.Remove( old_menu_index )
|
||||
if show:
|
||||
|
||||
self._menubar.Replace( old_menu_index, menu, label )
|
||||
|
||||
else:
|
||||
|
||||
self._menubar.Remove( old_menu_index )
|
||||
|
||||
|
||||
else:
|
||||
|
||||
|
@ -2729,7 +2742,10 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
|
||||
( temp_menu, temp_label, temp_show ) = self._menus[ temp_name ]
|
||||
|
||||
if temp_show: insert_index += 1
|
||||
if temp_show:
|
||||
|
||||
insert_index += 1
|
||||
|
||||
|
||||
|
||||
self._menubar.Insert( insert_index, menu, label )
|
||||
|
@ -2745,7 +2761,10 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
|
||||
def SaveLastSession( self ):
|
||||
|
||||
self._SaveGUISession( 'last session' )
|
||||
if HC.options[ 'default_gui_session' ] == 'last session':
|
||||
|
||||
self._SaveGUISession( 'last session' )
|
||||
|
||||
|
||||
wx.CallLater( 5 * 60 * 1000, self.SaveLastSession )
|
||||
|
||||
|
|
|
@ -1431,8 +1431,6 @@ class CanvasWithDetails( Canvas ):
|
|||
|
||||
# ratings
|
||||
|
||||
( local_ratings, remote_ratings ) = self._current_display_media.GetRatings()
|
||||
|
||||
services_manager = HydrusGlobals.client_controller.GetServicesManager()
|
||||
|
||||
like_services = services_manager.GetServices( ( HC.LOCAL_RATING_LIKE, ), randomised = False )
|
||||
|
@ -1454,7 +1452,6 @@ class CanvasWithDetails( Canvas ):
|
|||
|
||||
if len( like_services ) > 0: current_y += 20
|
||||
|
||||
|
||||
numerical_services = services_manager.GetServices( ( HC.LOCAL_RATING_NUMERICAL, ), randomised = False )
|
||||
|
||||
for numerical_service in numerical_services:
|
||||
|
|
|
@ -580,7 +580,7 @@ class DialogAdvancedContentUpdate( Dialog ):
|
|||
|
||||
class DialogButtonChoice( Dialog ):
|
||||
|
||||
def __init__( self, parent, intro, choices ):
|
||||
def __init__( self, parent, intro, choices, show_always_checkbox = False ):
|
||||
|
||||
Dialog.__init__( self, parent, 'choose what to do', position = 'center' )
|
||||
|
||||
|
@ -600,11 +600,23 @@ class DialogButtonChoice( Dialog ):
|
|||
i += 1
|
||||
|
||||
|
||||
self._always_do_checkbox = wx.CheckBox( self, label = 'do this for all' )
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
vbox.AddF( wx.StaticText( self, label = intro ), CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
for button in self._buttons: vbox.AddF( button, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
for button in self._buttons:
|
||||
|
||||
vbox.AddF( button, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
|
||||
vbox.AddF( self._always_do_checkbox, CC.FLAGS_LONE_BUTTON )
|
||||
|
||||
if not show_always_checkbox:
|
||||
|
||||
self._always_do_checkbox.Hide()
|
||||
|
||||
|
||||
self.SetSizer( vbox )
|
||||
|
||||
|
@ -630,7 +642,10 @@ class DialogButtonChoice( Dialog ):
|
|||
|
||||
|
||||
|
||||
def GetData( self ): return self._data
|
||||
def GetData( self ):
|
||||
|
||||
return ( self._always_do_checkbox.GetValue(), self._data )
|
||||
|
||||
|
||||
class DialogChooseNewServiceMethod( Dialog ):
|
||||
|
||||
|
@ -3877,7 +3892,16 @@ class DialogSelectBooru( Dialog ):
|
|||
|
||||
self.SetInitialSize( ( x, y ) )
|
||||
|
||||
wx.CallAfter( self._ok.SetFocus )
|
||||
if len( boorus ) == 1:
|
||||
|
||||
self._boorus.Select( 0 )
|
||||
|
||||
wx.CallAfter( self.EventOK, None )
|
||||
|
||||
else:
|
||||
|
||||
wx.CallAfter( self._ok.SetFocus )
|
||||
|
||||
|
||||
|
||||
def EventDoubleClick( self, event ): self.EndModal( wx.ID_OK )
|
||||
|
@ -4166,7 +4190,10 @@ class DialogSelectFromListOfStrings( Dialog ):
|
|||
|
||||
selection = self._strings.GetSelection()
|
||||
|
||||
if selection != wx.NOT_FOUND: self.EndModal( wx.ID_OK )
|
||||
if selection != wx.NOT_FOUND:
|
||||
|
||||
self.EndModal( wx.ID_OK )
|
||||
|
||||
|
||||
|
||||
def EventSelect( self, event ): self.EndModal( wx.ID_OK )
|
||||
|
|
|
@ -9010,13 +9010,18 @@ class DialogManageTags( ClientGUIDialogs.Dialog ):
|
|||
|
||||
self._file_service_key = file_service_key
|
||||
|
||||
self._hashes = set()
|
||||
|
||||
self._canvas_key = canvas_key
|
||||
|
||||
self._current_media = media
|
||||
media = ClientMedia.FlattenMedia( media )
|
||||
|
||||
for m in media: self._hashes.update( m.GetHashes() )
|
||||
self._current_media = [ m.Duplicate() for m in media ]
|
||||
|
||||
self._hashes = set()
|
||||
|
||||
for m in self._current_media:
|
||||
|
||||
self._hashes.update( m.GetHashes() )
|
||||
|
||||
|
||||
( remember, position ) = HC.options[ 'tag_dialog_position' ]
|
||||
|
||||
|
@ -9065,7 +9070,7 @@ class DialogManageTags( ClientGUIDialogs.Dialog ):
|
|||
service_type = service.GetServiceType()
|
||||
name = service.GetName()
|
||||
|
||||
page = self._Panel( self._tag_repositories, self._file_service_key, service.GetServiceKey(), media )
|
||||
page = self._Panel( self._tag_repositories, self._file_service_key, service.GetServiceKey(), self._current_media )
|
||||
|
||||
self._tag_repositories.AddPage( name, service_key, page )
|
||||
|
||||
|
@ -9531,30 +9536,61 @@ class DialogManageTags( ClientGUIDialogs.Dialog ):
|
|||
|
||||
|
||||
|
||||
forced_choice_actions = []
|
||||
|
||||
for choices in sets_of_choices:
|
||||
|
||||
always_do = False
|
||||
|
||||
if len( choices ) == 1:
|
||||
|
||||
[ ( text_gumpf, choice ) ] = choices
|
||||
|
||||
else:
|
||||
|
||||
intro = 'What would you like to do?'
|
||||
choice = None
|
||||
|
||||
with ClientGUIDialogs.DialogButtonChoice( self, intro, choices ) as dlg:
|
||||
for forced_choice_action in forced_choice_actions:
|
||||
|
||||
result = dlg.ShowModal()
|
||||
for possible_choice in choices:
|
||||
|
||||
( text_gumpf, ( choice_action, choice_tag ) ) = possible_choice
|
||||
|
||||
if choice_action == forced_choice_action:
|
||||
|
||||
choice = ( choice_action, choice_tag )
|
||||
|
||||
break
|
||||
|
||||
|
||||
|
||||
if result == wx.ID_OK:
|
||||
|
||||
choice = dlg.GetData()
|
||||
|
||||
else:
|
||||
if choice is not None:
|
||||
|
||||
break
|
||||
|
||||
|
||||
|
||||
if choice is None:
|
||||
|
||||
intro = 'What would you like to do?'
|
||||
|
||||
show_always_checkbox = len( sets_of_choices ) > 1
|
||||
|
||||
with ClientGUIDialogs.DialogButtonChoice( self, intro, choices, show_always_checkbox = show_always_checkbox ) as dlg:
|
||||
|
||||
result = dlg.ShowModal()
|
||||
|
||||
if result == wx.ID_OK:
|
||||
|
||||
( always_do, choice ) = dlg.GetData()
|
||||
|
||||
else:
|
||||
|
||||
break
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if choice is None:
|
||||
|
||||
|
@ -9563,6 +9599,11 @@ class DialogManageTags( ClientGUIDialogs.Dialog ):
|
|||
|
||||
( choice_action, choice_tag ) = choice
|
||||
|
||||
if always_do:
|
||||
|
||||
forced_choice_actions.append( choice_action )
|
||||
|
||||
|
||||
if choice_action == HC.CONTENT_UPDATE_ADD: media_to_affect = ( m for m in self._media if choice_tag not in m.GetTagsManager().GetCurrent( self._tag_service_key ) )
|
||||
elif choice_action == HC.CONTENT_UPDATE_DELETE: media_to_affect = ( m for m in self._media if choice_tag in m.GetTagsManager().GetCurrent( self._tag_service_key ) )
|
||||
elif choice_action == HC.CONTENT_UPDATE_PEND: media_to_affect = ( m for m in self._media if choice_tag not in m.GetTagsManager().GetCurrent( self._tag_service_key ) and choice_tag not in m.GetTagsManager().GetPending( self._tag_service_key ) )
|
||||
|
@ -9745,15 +9786,12 @@ class DialogManageTags( ClientGUIDialogs.Dialog ):
|
|||
|
||||
self._content_updates = []
|
||||
|
||||
if media is None: media = []
|
||||
if media is None:
|
||||
|
||||
media = []
|
||||
|
||||
|
||||
hashes = { hash for hash in itertools.chain.from_iterable( ( m.GetHashes() for m in media ) ) }
|
||||
|
||||
if len( hashes ) > 0: media_results = HydrusGlobals.client_controller.Read( 'media_results', hashes )
|
||||
else: media_results = []
|
||||
|
||||
# this should now be a nice clean copy of the original media
|
||||
self._media = [ ClientMedia.MediaSingleton( media_result ) for media_result in media_results ]
|
||||
self._media = media
|
||||
|
||||
self._tags_box.SetTagsByMedia( self._media )
|
||||
|
||||
|
|
|
@ -18,6 +18,24 @@ import HydrusExceptions
|
|||
import HydrusGlobals
|
||||
import itertools
|
||||
|
||||
def FlattenMedia( media_list ):
|
||||
|
||||
flat_media = []
|
||||
|
||||
for media in media_list:
|
||||
|
||||
if media.IsCollection():
|
||||
|
||||
flat_media.extend( media.GetFlatMedia() )
|
||||
|
||||
else:
|
||||
|
||||
flat_media.append( media )
|
||||
|
||||
|
||||
|
||||
return flat_media
|
||||
|
||||
def MergeTagsManagers( tags_managers ):
|
||||
|
||||
def CurrentAndPendingFilter( items ):
|
||||
|
@ -99,6 +117,19 @@ class LocationsManager( object ):
|
|||
self._petitioned.discard( service_key )
|
||||
|
||||
|
||||
def Duplicate( self ):
|
||||
|
||||
current = set( self._current )
|
||||
deleted = set( self._deleted )
|
||||
pending = set( self._pending )
|
||||
petitioned = set( self._petitioned )
|
||||
urls = list( self._urls )
|
||||
service_keys_to_filenames = dict( self._service_keys_to_filenames )
|
||||
current_to_timestamps = dict( self._current_to_timestamps )
|
||||
|
||||
return LocationsManager( current, deleted, pending, petitioned, urls = urls, service_keys_to_filenames = service_keys_to_filenames, current_to_timestamps = current_to_timestamps )
|
||||
|
||||
|
||||
def GetCDPP( self ): return ( self._current, self._deleted, self._pending, self._petitioned )
|
||||
|
||||
def GetCurrent( self ): return self._current
|
||||
|
@ -298,29 +329,27 @@ class MediaList( object ):
|
|||
|
||||
services_manager = HydrusGlobals.client_controller.GetServicesManager()
|
||||
|
||||
local_ratings_to_collect_by = [ service_key for service_key in ratings_to_collect_by if services_manager.GetService( service_key ).GetServiceType() in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ) ]
|
||||
remote_ratings_to_collect_by = [ service_key for service_key in ratings_to_collect_by if services_manager.GetService( service_key ).GetServiceType() in ( HC.RATING_LIKE_REPOSITORY, HC.RATING_NUMERICAL_REPOSITORY ) ]
|
||||
|
||||
keys_to_medias = collections.defaultdict( list )
|
||||
|
||||
for media in medias:
|
||||
|
||||
if len( namespaces_to_collect_by ) > 0: namespace_key = media.GetTagsManager().GetNamespaceSlice( namespaces_to_collect_by, collapse_siblings = True )
|
||||
else: namespace_key = None
|
||||
if len( namespaces_to_collect_by ) > 0:
|
||||
|
||||
namespace_key = media.GetTagsManager().GetNamespaceSlice( namespaces_to_collect_by, collapse_siblings = True )
|
||||
|
||||
else:
|
||||
|
||||
namespace_key = None
|
||||
|
||||
|
||||
if len( ratings_to_collect_by ) > 0:
|
||||
|
||||
( local_ratings, remote_ratings ) = media.GetRatings()
|
||||
rating_key = media.GetRatingsManager().GetRatingSlice( ratings_to_collect_by )
|
||||
|
||||
if len( local_ratings_to_collect_by ) > 0: local_rating_key = local_ratings.GetRatingSlice( local_ratings_to_collect_by )
|
||||
else: local_rating_key = None
|
||||
else:
|
||||
|
||||
if len( remote_ratings_to_collect_by ) > 0: remote_rating_key = remote_ratings.GetRatingSlice( remote_ratings_to_collect_by )
|
||||
else: remote_rating_key = None
|
||||
rating_key = None
|
||||
|
||||
rating_key = ( local_rating_key, remote_rating_key )
|
||||
|
||||
else: rating_key = None
|
||||
|
||||
keys_to_medias[ ( namespace_key, rating_key ) ].append( media )
|
||||
|
||||
|
@ -566,9 +595,12 @@ class MediaList( object ):
|
|||
|
||||
if unrated is not None:
|
||||
|
||||
( local_ratings, remote_ratings ) = media.GetRatings()
|
||||
ratings_manager = media.GetRatingsManager()
|
||||
|
||||
if local_ratings.GetRating( unrated ) is not None: continue
|
||||
if ratings_manager.GetRating( unrated ) is not None:
|
||||
|
||||
continue
|
||||
|
||||
|
||||
|
||||
if for_media_viewer:
|
||||
|
@ -731,14 +763,14 @@ class MediaList( object ):
|
|||
|
||||
def ratings_sort_function( service_key, reverse, x ):
|
||||
|
||||
( x_local_ratings, x_remote_ratings ) = x.GetRatings()
|
||||
x_ratings_manager = x.GetRatingsManager()
|
||||
|
||||
service = HydrusGlobals.client_controller.GetServicesManager().GetService( service_key )
|
||||
rating = deal_with_none( x_ratings_manager.GetRating( service_key ) )
|
||||
|
||||
if service.GetServiceType() in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ): rating = deal_with_none( x_local_ratings.GetRating( service_key ) )
|
||||
else: rating = deal_with_none( x_remote_ratings.GetScore( service_key ) )
|
||||
|
||||
if reverse: rating *= -1
|
||||
if reverse:
|
||||
|
||||
rating *= -1
|
||||
|
||||
|
||||
return rating
|
||||
|
||||
|
@ -830,8 +862,14 @@ class MediaCollection( MediaList, Media ):
|
|||
self._tags_manager = MergeTagsManagers( tags_managers )
|
||||
|
||||
# horrible compromise
|
||||
if len( self._sorted_media ) > 0: self._ratings = self._sorted_media[0].GetRatings()
|
||||
else: self._ratings = ( ClientRatings.LocalRatingsManager( {} ), ClientRatings.CPRemoteRatingsServiceKeys( {} ) )
|
||||
if len( self._sorted_media ) > 0:
|
||||
|
||||
self._ratings_manager = self._sorted_media[0].GetRatingsManager()
|
||||
|
||||
else:
|
||||
|
||||
self._ratings_manager = ClientRatings.RatingsManager( {} )
|
||||
|
||||
|
||||
all_locations_managers = [ media.GetLocationsManager() for media in self._sorted_media ]
|
||||
|
||||
|
@ -916,7 +954,10 @@ class MediaCollection( MediaList, Media ):
|
|||
return [ info_string ]
|
||||
|
||||
|
||||
def GetRatings( self ): return self._ratings
|
||||
def GetRatingsManager( self ):
|
||||
|
||||
return self._ratings_manager
|
||||
|
||||
|
||||
def GetResolution( self ): return ( self._width, self._height )
|
||||
|
||||
|
@ -974,6 +1015,11 @@ class MediaSingleton( Media ):
|
|||
self._media_result = media_result
|
||||
|
||||
|
||||
def Duplicate( self ):
|
||||
|
||||
return MediaSingleton( self._media_result.Duplicate() )
|
||||
|
||||
|
||||
def GetDisplayMedia( self ): return self
|
||||
|
||||
def GetDuration( self ): return self._media_result.GetDuration()
|
||||
|
@ -1070,7 +1116,7 @@ class MediaSingleton( Media ):
|
|||
|
||||
def GetPrettyInfoLines( self ):
|
||||
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, local_ratings, remote_ratings ) = self._media_result.ToTuple()
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager ) = self._media_result.ToTuple()
|
||||
|
||||
info_string = HydrusData.ConvertIntToBytes( size ) + ' ' + HC.mime_string_lookup[ mime ]
|
||||
|
||||
|
@ -1130,7 +1176,7 @@ class MediaSingleton( Media ):
|
|||
return lines
|
||||
|
||||
|
||||
def GetRatings( self ): return self._media_result.GetRatings()
|
||||
def GetRatingsManager( self ): return self._media_result.GetRatingsManager()
|
||||
|
||||
def GetResolution( self ):
|
||||
|
||||
|
@ -1275,14 +1321,14 @@ class MediaResult( object ):
|
|||
|
||||
def __init__( self, tuple ):
|
||||
|
||||
# hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, local_ratings, remote_ratings
|
||||
# hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager
|
||||
|
||||
self._tuple = tuple
|
||||
|
||||
|
||||
def DeletePending( self, service_key ):
|
||||
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, local_ratings, remote_ratings ) = self._tuple
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager ) = self._tuple
|
||||
|
||||
service = HydrusGlobals.client_controller.GetServicesManager().GetService( service_key )
|
||||
|
||||
|
@ -1292,6 +1338,19 @@ class MediaResult( object ):
|
|||
elif service_type in ( HC.FILE_REPOSITORY, HC.LOCAL_FILE ): locations_manager.DeletePending( service_key )
|
||||
|
||||
|
||||
def Duplicate( self ):
|
||||
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager ) = self._tuple
|
||||
|
||||
tags_manager = tags_manager.Duplicate()
|
||||
locations_manager = locations_manager.Duplicate()
|
||||
ratings_manager = ratings_manager.Duplicate()
|
||||
|
||||
tuple = ( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager )
|
||||
|
||||
return MediaResult( tuple )
|
||||
|
||||
|
||||
def GetHash( self ): return self._tuple[0]
|
||||
|
||||
def GetDuration( self ): return self._tuple[6]
|
||||
|
@ -1306,7 +1365,7 @@ class MediaResult( object ):
|
|||
|
||||
def GetNumWords( self ): return self._tuple[8]
|
||||
|
||||
def GetRatings( self ): return ( self._tuple[11], self._tuple[12] )
|
||||
def GetRatingsManager( self ): return self._tuple[11]
|
||||
|
||||
def GetResolution( self ): return ( self._tuple[4], self._tuple[5] )
|
||||
|
||||
|
@ -1318,19 +1377,28 @@ class MediaResult( object ):
|
|||
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, local_ratings, remote_ratings ) = self._tuple
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager ) = self._tuple
|
||||
|
||||
service = HydrusGlobals.client_controller.GetServicesManager().GetService( service_key )
|
||||
|
||||
service_type = service.GetServiceType()
|
||||
|
||||
if service_type in HC.TAG_SERVICES: tags_manager.ProcessContentUpdate( service_key, content_update )
|
||||
if service_type in HC.TAG_SERVICES:
|
||||
|
||||
tags_manager.ProcessContentUpdate( service_key, content_update )
|
||||
|
||||
elif service_type in ( HC.FILE_REPOSITORY, HC.LOCAL_FILE, HC.IPFS ):
|
||||
|
||||
if service_type == HC.LOCAL_FILE:
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ARCHIVE: inbox = False
|
||||
elif action == HC.CONTENT_UPDATE_INBOX: inbox = True
|
||||
if action == HC.CONTENT_UPDATE_ARCHIVE:
|
||||
|
||||
inbox = False
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_INBOX:
|
||||
|
||||
inbox = True
|
||||
|
||||
|
||||
if service_key == CC.LOCAL_FILE_SERVICE_KEY:
|
||||
|
||||
|
@ -1347,21 +1415,20 @@ class MediaResult( object ):
|
|||
|
||||
|
||||
|
||||
self._tuple = ( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, local_ratings, remote_ratings )
|
||||
self._tuple = ( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager )
|
||||
|
||||
|
||||
locations_manager.ProcessContentUpdate( service_key, content_update )
|
||||
|
||||
elif service_type in HC.RATINGS_SERVICES:
|
||||
|
||||
if service_type in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ): local_ratings.ProcessContentUpdate( service_key, content_update )
|
||||
else: remote_ratings.ProcessContentUpdate( service_key, content_update )
|
||||
ratings_manager.ProcessContentUpdate( service_key, content_update )
|
||||
|
||||
|
||||
|
||||
def ResetService( self, service_key ):
|
||||
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, local_ratings, remote_ratings ) = self._tuple
|
||||
( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager ) = self._tuple
|
||||
|
||||
tags_manager.ResetService( service_key )
|
||||
locations_manager.ResetService( service_key )
|
||||
|
@ -1502,6 +1569,25 @@ class TagsManagerSimple( object ):
|
|||
self._combined_namespaces_cache = None
|
||||
|
||||
|
||||
def Duplicate( self ):
|
||||
|
||||
dupe_service_keys_to_statuses_to_tags = collections.defaultdict( HydrusData.default_dict_set )
|
||||
|
||||
for ( service_key, statuses_to_tags ) in self._service_keys_to_statuses_to_tags.items():
|
||||
|
||||
dupe_statuses_to_tags = HydrusData.default_dict_set()
|
||||
|
||||
for ( status, tags ) in statuses_to_tags.items():
|
||||
|
||||
dupe_statuses_to_tags[ status ] = set( tags )
|
||||
|
||||
|
||||
dupe_service_keys_to_statuses_to_tags[ service_key ] = dupe_statuses_to_tags
|
||||
|
||||
|
||||
return TagsManagerSimple( dupe_service_keys_to_statuses_to_tags )
|
||||
|
||||
|
||||
def GetCombinedNamespaces( self, namespaces ):
|
||||
|
||||
if self._combined_namespaces_cache is None:
|
||||
|
@ -1612,6 +1698,25 @@ class TagsManager( TagsManagerSimple ):
|
|||
|
||||
|
||||
|
||||
def Duplicate( self ):
|
||||
|
||||
dupe_service_keys_to_statuses_to_tags = collections.defaultdict( HydrusData.default_dict_set )
|
||||
|
||||
for ( service_key, statuses_to_tags ) in self._service_keys_to_statuses_to_tags.items():
|
||||
|
||||
dupe_statuses_to_tags = HydrusData.default_dict_set()
|
||||
|
||||
for ( status, tags ) in statuses_to_tags.items():
|
||||
|
||||
dupe_statuses_to_tags[ status ] = set( tags )
|
||||
|
||||
|
||||
dupe_service_keys_to_statuses_to_tags[ service_key ] = dupe_statuses_to_tags
|
||||
|
||||
|
||||
return TagsManager( dupe_service_keys_to_statuses_to_tags )
|
||||
|
||||
|
||||
def GetCurrent( self, service_key = CC.COMBINED_TAG_SERVICE_KEY ):
|
||||
|
||||
statuses_to_tags = self._service_keys_to_statuses_to_tags[ service_key ]
|
||||
|
|
|
@ -100,13 +100,22 @@ def GetLikeStateFromMedia( media, service_key ):
|
|||
|
||||
for m in media:
|
||||
|
||||
( local_ratings, remote_ratings ) = m.GetRatings()
|
||||
ratings_manager = m.GetRatingsManager()
|
||||
|
||||
rating = local_ratings.GetRating( service_key )
|
||||
rating = ratings_manager.GetRating( service_key )
|
||||
|
||||
if rating == 1: on_exists = True
|
||||
elif rating == 0: off_exists = True
|
||||
elif rating is None: null_exists = True
|
||||
if rating == 1:
|
||||
|
||||
on_exists = True
|
||||
|
||||
elif rating == 0:
|
||||
|
||||
off_exists = True
|
||||
|
||||
elif rating is None:
|
||||
|
||||
null_exists = True
|
||||
|
||||
|
||||
|
||||
if len( [ b for b in ( on_exists, off_exists, null_exists ) if b ] ) == 1:
|
||||
|
@ -130,9 +139,9 @@ def GetNumericalStateFromMedia( media, service_key ):
|
|||
|
||||
for m in media:
|
||||
|
||||
( local_ratings, remote_ratings ) = m.GetRatings()
|
||||
ratings_manager = m.GetRatingsManager()
|
||||
|
||||
rating = local_ratings.GetRating( service_key )
|
||||
rating = ratings_manager.GetRating( service_key )
|
||||
|
||||
if rating is None:
|
||||
|
||||
|
@ -248,83 +257,28 @@ def GetStars( service_key, rating_state, rating ):
|
|||
|
||||
return ( shape, stars )
|
||||
|
||||
class CPRemoteRatingsServiceKeys( object ):
|
||||
|
||||
def __init__( self, service_keys_to_cp ):
|
||||
|
||||
self._service_keys_to_cp = service_keys_to_cp
|
||||
|
||||
|
||||
def GetCP( self, service_key ):
|
||||
|
||||
if service_key in self._service_keys_to_cp: return self._service_keys_to_cp[ service_key ]
|
||||
else: return ( None, None )
|
||||
|
||||
|
||||
def GetRatingSlice( self, service_keys ):
|
||||
|
||||
# this doesn't work yet. it should probably use self.GetScore( service_key ) like I think Sort by remote rating does
|
||||
|
||||
return frozenset( { self._service_keys_to_cp[ service_key ] for service_key in service_keys if service_key in self._service_keys_to_cp } )
|
||||
|
||||
|
||||
def GetServiceKeysToRatingsCP( self ): return self._service_keys_to_cp
|
||||
|
||||
def ProcessContentUpdate( self, service_key, content_update ):
|
||||
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
if service_key in self._service_keys_to_cp: ( current, pending ) = self._service_keys_to_cp[ service_key ]
|
||||
else:
|
||||
|
||||
( current, pending ) = ( None, None )
|
||||
|
||||
self._service_keys_to_cp[ service_key ] = ( current, pending )
|
||||
|
||||
|
||||
# this may well need work; need to figure out how to set the pending back to None after an upload. rescind seems ugly
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ADD:
|
||||
|
||||
rating = content_update.GetInfo()
|
||||
|
||||
current = rating
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_DELETE:
|
||||
|
||||
current = None
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PEND:
|
||||
|
||||
pending = None
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_DELETE:
|
||||
|
||||
rating = content_update.GetInfo()
|
||||
|
||||
pending = rating
|
||||
|
||||
|
||||
|
||||
def ResetService( self, service_key ):
|
||||
|
||||
if service_key in self._service_keys_to_cp:
|
||||
|
||||
( current, pending ) = self._service_keys_to_cp[ service_key ]
|
||||
|
||||
self._service_keys_to_cp[ service_key ] = ( None, None )
|
||||
|
||||
class LocalRatingsManager( object ):
|
||||
class RatingsManager( object ):
|
||||
|
||||
def __init__( self, service_keys_to_ratings ):
|
||||
|
||||
self._service_keys_to_ratings = service_keys_to_ratings
|
||||
|
||||
|
||||
def Duplicate( self ):
|
||||
|
||||
return RatingsManager( dict( self._service_keys_to_ratings ) )
|
||||
|
||||
|
||||
def GetRating( self, service_key ):
|
||||
|
||||
if service_key in self._service_keys_to_ratings: return self._service_keys_to_ratings[ service_key ]
|
||||
else: return None
|
||||
if service_key in self._service_keys_to_ratings:
|
||||
|
||||
return self._service_keys_to_ratings[ service_key ]
|
||||
|
||||
else:
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
||||
def GetRatingSlice( self, service_keys ): return frozenset( { self._service_keys_to_ratings[ service_key ] for service_key in service_keys if service_key in self._service_keys_to_ratings } )
|
||||
|
|
|
@ -27,7 +27,6 @@ CLIENT_UPDATES_DIR = os.path.join( DB_DIR, 'client_updates' )
|
|||
SERVER_UPDATES_DIR = os.path.join( DB_DIR, 'server_updates' )
|
||||
HELP_DIR = os.path.join( BASE_DIR, 'help' )
|
||||
INCLUDE_DIR = os.path.join( BASE_DIR, 'include' )
|
||||
LOGS_DIR = os.path.join( BASE_DIR, 'logs' )
|
||||
STATIC_DIR = os.path.join( BASE_DIR, 'static' )
|
||||
|
||||
#
|
||||
|
@ -49,7 +48,7 @@ options = {}
|
|||
# Misc
|
||||
|
||||
NETWORK_VERSION = 17
|
||||
SOFTWARE_VERSION = 209
|
||||
SOFTWARE_VERSION = 210
|
||||
|
||||
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )
|
||||
|
||||
|
|
|
@ -56,6 +56,19 @@ def CalculateScoreFromRating( count, rating ):
|
|||
|
||||
return score
|
||||
|
||||
def CleanRunningFile( db_path, instance ):
|
||||
|
||||
path = os.path.join( db_path, instance + '_running' )
|
||||
|
||||
try:
|
||||
|
||||
os.remove( path )
|
||||
|
||||
except:
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def ConvertContentsToClientToServerContentUpdatePackage( action, contents, reason = None ):
|
||||
|
||||
hashes_to_hash_ids = {}
|
||||
|
@ -636,9 +649,9 @@ def GetNowPrecise():
|
|||
if HC.PLATFORM_WINDOWS: return time.clock()
|
||||
else: return time.time()
|
||||
|
||||
def GetSiblingProcessPorts( instance ):
|
||||
def GetSiblingProcessPorts( db_path, instance ):
|
||||
|
||||
path = os.path.join( HC.BASE_DIR, instance + '_running' )
|
||||
path = os.path.join( db_path, instance + '_running' )
|
||||
|
||||
if os.path.exists( path ):
|
||||
|
||||
|
@ -727,9 +740,9 @@ def IntelligentMassIntersect( sets_to_reduce ):
|
|||
if answer is None: return set()
|
||||
else: return answer
|
||||
|
||||
def IsAlreadyRunning( instance ):
|
||||
def IsAlreadyRunning( db_path, instance ):
|
||||
|
||||
path = os.path.join( HC.BASE_DIR, instance + '_running' )
|
||||
path = os.path.join( db_path, instance + '_running' )
|
||||
|
||||
if os.path.exists( path ):
|
||||
|
||||
|
@ -870,9 +883,9 @@ def Profile( code, g, l ):
|
|||
|
||||
DebugPrint( output.read() )
|
||||
|
||||
def RecordRunningStart( instance ):
|
||||
def RecordRunningStart( db_path, instance ):
|
||||
|
||||
path = os.path.join( HC.BASE_DIR, instance + '_running' )
|
||||
path = os.path.join( db_path, instance + '_running' )
|
||||
|
||||
record_string = ''
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ import time
|
|||
# I guess I am sending bad characters or something to the 'windowised' environment of pythonw
|
||||
class HydrusLogger( object ):
|
||||
|
||||
def __init__( self, log_filename ):
|
||||
def __init__( self, log_path ):
|
||||
|
||||
self._log_filename = log_filename
|
||||
self._log_path = log_path
|
||||
|
||||
|
||||
def __enter__( self ):
|
||||
|
@ -23,7 +23,7 @@ class HydrusLogger( object ):
|
|||
sys.stdout = self
|
||||
sys.stderr = self
|
||||
|
||||
self._log_file = open( os.path.join( HC.LOGS_DIR, self._log_filename ), 'a' )
|
||||
self._log_file = open( self._log_path, 'a' )
|
||||
|
||||
return self
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ def GetStartingAction():
|
|||
|
||||
else:
|
||||
|
||||
already_running = HydrusData.IsAlreadyRunning( 'server' )
|
||||
already_running = HydrusData.IsAlreadyRunning( HC.DB_DIR, 'server' )
|
||||
|
||||
if command == 'start':
|
||||
|
||||
|
@ -77,7 +77,7 @@ def GetStartingAction():
|
|||
|
||||
else:
|
||||
|
||||
already_running = HydrusData.IsAlreadyRunning( 'server' )
|
||||
already_running = HydrusData.IsAlreadyRunning( HC.DB_DIR, 'server' )
|
||||
|
||||
if not already_running:
|
||||
|
||||
|
@ -111,7 +111,7 @@ def ShutdownSiblingInstance():
|
|||
|
||||
port_found = False
|
||||
|
||||
ports = HydrusData.GetSiblingProcessPorts( 'server' )
|
||||
ports = HydrusData.GetSiblingProcessPorts( HC.DB_DIR, 'server' )
|
||||
|
||||
if ports is None:
|
||||
|
||||
|
@ -164,7 +164,7 @@ def ShutdownSiblingInstance():
|
|||
|
||||
time_waited = 0
|
||||
|
||||
while HydrusData.IsAlreadyRunning( 'server' ):
|
||||
while HydrusData.IsAlreadyRunning( HC.DB_DIR, 'server' ):
|
||||
|
||||
time.sleep( 1 )
|
||||
|
||||
|
@ -300,6 +300,8 @@ class Controller( HydrusController.HydrusController ):
|
|||
|
||||
self.ShutdownModel()
|
||||
|
||||
HydrusData.CleanRunningFile( HC.DB_DIR, 'server' )
|
||||
|
||||
|
||||
def GetServerSessionManager( self ):
|
||||
|
||||
|
@ -356,7 +358,7 @@ class Controller( HydrusController.HydrusController ):
|
|||
|
||||
def Run( self ):
|
||||
|
||||
HydrusData.RecordRunningStart( 'server' )
|
||||
HydrusData.RecordRunningStart( HC.DB_DIR, 'server' )
|
||||
|
||||
HydrusData.Print( 'Initialising db...' )
|
||||
|
||||
|
|
|
@ -152,13 +152,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
dest_path = ServerFiles.GetExpectedFilePath( hash )
|
||||
|
||||
with open( source_path, 'rb' ) as f_source:
|
||||
|
||||
with open( dest_path, 'wb' ) as f_dest:
|
||||
|
||||
HydrusPaths.CopyFileLikeToFileLike( f_source, f_dest )
|
||||
|
||||
|
||||
HydrusPaths.MirrorFile( source_path, dest_path )
|
||||
|
||||
if 'thumbnail' in file_dict:
|
||||
|
||||
|
@ -2308,39 +2302,6 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
HydrusData.Print( 'The server is updating to version ' + str( version + 1 ) )
|
||||
|
||||
if version == 155:
|
||||
|
||||
results = self._c.execute( 'SELECT service_id, account_type_id, account_type FROM account_types;' ).fetchall()
|
||||
|
||||
for ( service_id, account_type_id, account_type ) in results:
|
||||
|
||||
title = account_type.GetTitle()
|
||||
|
||||
self._c.execute( 'UPDATE account_types SET title = ? WHERE service_id = ? AND account_type_id = ?;', ( title, service_id, account_type_id ) )
|
||||
|
||||
|
||||
|
||||
if version == 158:
|
||||
|
||||
first_ends = self._c.execute( 'SELECT service_id, end FROM update_cache WHERE begin = ?;', ( 0, ) ).fetchall()
|
||||
|
||||
self._c.execute( 'DELETE FROM update_cache;' )
|
||||
|
||||
for filename in os.listdir( HC.SERVER_UPDATES_DIR ):
|
||||
|
||||
path = os.path.join( HC.SERVER_UPDATES_DIR, filename )
|
||||
|
||||
HydrusPaths.RecyclePath( path )
|
||||
|
||||
|
||||
for ( service_id, end ) in first_ends:
|
||||
|
||||
service_key = self._GetServiceKey( service_id )
|
||||
|
||||
self._CreateUpdate( service_key, 0, end )
|
||||
|
||||
|
||||
|
||||
if version == 161:
|
||||
|
||||
for filename in os.listdir( HC.SERVER_UPDATES_DIR ):
|
||||
|
@ -2555,21 +2516,26 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._CloseDBCursor()
|
||||
|
||||
for filename in self._db_filenames.values():
|
||||
try:
|
||||
|
||||
HydrusData.Print( 'vacuuming ' + filename )
|
||||
|
||||
db_path = os.path.join( self._db_dir, filename )
|
||||
|
||||
if HydrusDB.CanVacuum( db_path ):
|
||||
for filename in self._db_filenames.values():
|
||||
|
||||
HydrusDB.VacuumDB( db_path )
|
||||
HydrusData.Print( 'vacuuming ' + filename )
|
||||
|
||||
db_path = os.path.join( self._db_dir, filename )
|
||||
|
||||
if HydrusDB.CanVacuum( db_path ):
|
||||
|
||||
HydrusDB.VacuumDB( db_path )
|
||||
|
||||
|
||||
|
||||
|
||||
self._InitDBCursor()
|
||||
|
||||
self._c.execute( 'BEGIN IMMEDIATE;' )
|
||||
finally:
|
||||
|
||||
self._InitDBCursor()
|
||||
|
||||
self._c.execute( 'BEGIN IMMEDIATE;' )
|
||||
|
||||
|
||||
|
||||
if version == 202:
|
||||
|
|
|
@ -654,7 +654,7 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
( media_result, ) = self._read( 'media_results', ( written_hash, ) )
|
||||
|
||||
( mr_hash, mr_inbox, mr_size, mr_mime, mr_width, mr_height, mr_duration, mr_num_frames, mr_num_words, mr_tags_manager, mr_locations_manager, mr_local_ratings, mr_remote_ratings ) = media_result.ToTuple()
|
||||
( mr_hash, mr_inbox, mr_size, mr_mime, mr_width, mr_height, mr_duration, mr_num_frames, mr_num_words, mr_tags_manager, mr_locations_manager, mr_ratings_manager ) = media_result.ToTuple()
|
||||
|
||||
now = HydrusData.GetNow()
|
||||
|
||||
|
@ -788,7 +788,7 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
( media_result, ) = self._read( 'media_results', ( hash, ) )
|
||||
|
||||
( mr_hash, mr_inbox, mr_size, mr_mime, mr_width, mr_height, mr_duration, mr_num_frames, mr_num_words, mr_tags_manager, mr_locations_manager, mr_local_ratings, mr_remote_ratings ) = media_result.ToTuple()
|
||||
( mr_hash, mr_inbox, mr_size, mr_mime, mr_width, mr_height, mr_duration, mr_num_frames, mr_num_words, mr_tags_manager, mr_locations_manager, mr_ratings_manager ) = media_result.ToTuple()
|
||||
|
||||
now = HydrusData.GetNow()
|
||||
|
||||
|
@ -805,7 +805,7 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
( media_result, ) = self._read( 'media_results_from_ids', ( 1, ) )
|
||||
|
||||
( mr_hash, mr_inbox, mr_size, mr_mime, mr_width, mr_height, mr_duration, mr_num_frames, mr_num_words, mr_tags_manager, mr_locations_manager, mr_local_ratings, mr_remote_ratings ) = media_result.ToTuple()
|
||||
( mr_hash, mr_inbox, mr_size, mr_mime, mr_width, mr_height, mr_duration, mr_num_frames, mr_num_words, mr_tags_manager, mr_locations_manager, mr_ratings_manager ) = media_result.ToTuple()
|
||||
|
||||
now = HydrusData.GetNow()
|
||||
|
||||
|
|
|
@ -270,9 +270,9 @@ class TestServer( unittest.TestCase ):
|
|||
info[ 'timeout' ] = 0
|
||||
info[ 'hashes' ] = hashes
|
||||
|
||||
# hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, local_ratings, remote_ratings
|
||||
# hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager
|
||||
|
||||
media_results = [ ClientMedia.MediaResult( ( hash, True, 500, HC.IMAGE_JPEG, 640, 480, None, None, None, None, None, None, None ) ) for hash in hashes ]
|
||||
media_results = [ ClientMedia.MediaResult( ( hash, True, 500, HC.IMAGE_JPEG, 640, 480, None, None, None, None, None, None ) ) for hash in hashes ]
|
||||
|
||||
HydrusGlobals.test_controller.SetRead( 'local_booru_share_keys', [ share_key ] )
|
||||
HydrusGlobals.test_controller.SetRead( 'local_booru_share', info )
|
||||
|
|
Loading…
Reference in New Issue