Version 126
|
@ -8,6 +8,24 @@
|
|||
<div class="content">
|
||||
<h3>changelog</h3>
|
||||
<ul>
|
||||
<li><h3>version 126</h3></li>
|
||||
<ul>
|
||||
<li>restored a dll that I thought was no longer needed, but was actually doing some weirder gif rendering</li>
|
||||
<li>added 'remove' to fullscreen menu</li>
|
||||
<li>harmonised thumbnail and fullscreen right click menus a bit more</li>
|
||||
<li>added pause button to popup messages for repo update and subscription processing</li>
|
||||
<li>moved service_identifier switchover forward</li>
|
||||
<li>moved all service fetching to streamlined and non-laggy manager</li>
|
||||
<li>changed client options to store default tag repository in a better way</li>
|
||||
<li>changed subscriptions to store their advanced tag options in a better way</li>
|
||||
<li>fixed a 'missing service' bug in advanced tag options</li>
|
||||
<li>remade idle calculation into a much better gui-based rather than db-based test</li>
|
||||
<li>fiddled more with maintenance timing, hopefully for the good</li>
|
||||
<li>new screenshots in the help index pages!</li>
|
||||
<li>improved how auto repo and server setup work and report their status</li>
|
||||
<li>the client's UPnP daemon will no longer spam errors if your IGD doesn't support UPnP</li>
|
||||
<li>fixed a bad db call in server's UPnP daemon</li>
|
||||
</ul>
|
||||
<li><h3>version 125</h3></li>
|
||||
<ul>
|
||||
<li>moved client splash screen and client boot to application event loop (i.e. your mouse won't hourglass over it now)</li>
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
<p>Because hydrus stores everything inside itself, it is entirely portable. You can extract it to a usb stick, move it from one place to another, have multiple installs for multiple purposes, wrap it all up inside a truecrypt volume, whatever you like. The .exe installer will write some unavoidable uninstall registry stuff to windows that'll mess with this, but the client itself will run fine in a different location.</p>
|
||||
<h3>updating</h3>
|
||||
<p>You don't <i>have</i> to update every week, but I generally recommend it. The different versions of client and server can talk with each other until I increment the private <i>network protocol version</i> (which happens every couple of months), at which point you will get polite error messages if you try to connect to a newer server with an older client or <i>vice versa</i>. Read my tumblr posts and judge for yourself what you want to do.</p>
|
||||
<p>All your files and settings and synchronisation progress will be remembered after the update. Unless the update specifically disables something, nothing will be deleted or lost.</p>
|
||||
<p>Whenever you start the client, it checks the version of its database. If the database is old, it makes the appropriate changes, in sequential order (i.e. to do v70->v75, the client would first apply v70->v71, then v71->v72 and so on), until the database is caught up.</p>
|
||||
<p>If the client you want to update is running, remember to close it first!</p>
|
||||
<p>If you use the installer, just download the new installer and run it. It should detect where the last install was and overwrite everything automatically.</p>
|
||||
<p>If you extract, then just extract right on top of your current install and overwrite manually. Then run client.exe as normal.</p>
|
||||
<p>All your files and settings and synchronisation progress will be remembered after the update. Unless the update specifically disables something, nothing will be deleted or lost.</p>
|
||||
<p>Whenever you start the client, it checks the version of its database. If the database is old, it makes the appropriate changes, in sequential order (i.e. to do v70->v75, the client would first apply v70->v71, then v71->v72 and so on), until the database is caught up. If this process will take a while (like an hour, sometimes!) I will say so in my tumblr post.</p>
|
||||
<h3>backing up</h3>
|
||||
<p>You <i>do</i> backup, right? <i>Right</i>?</p>
|
||||
<p>I run a backup every week so that if my computer blows up, I'll at worst have lost a few days' work. Before I had a backup regime, I once lost an entire drive with tens of thousands of files, and it didn't feel great at all. I only push backups so hard so you might avoid what I felt. ;_;</p>
|
||||
|
@ -30,7 +30,7 @@
|
|||
<p>If you want to backup hydrus, you can either go <i>database->create database backup</i> or just shut the client down and copy the entire install directory somewhere.</p>
|
||||
<p>I recommend you do it before you update, just in case there is a problem with my code that breaks your database. If that happens, please <a href="contact.html">contact me</a>, describing the problem, and revert to the functioning older version. I'll get on any problems like that immediately.</p>
|
||||
<h3>linux and os x</h3>
|
||||
<p>I now make an OS X release, although it is very prototype. A linux release should follow in a few weeks.</p>
|
||||
<p>I now make OS X and Linux releases. They are not as good as the Windows releases because I am not as experienced in their OSs' weirdnesses. When I find time, I improve them.</p>
|
||||
<p class="right"><a href="getting_started_files.html">Let's import some files! ----></a></p>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
<link href="style.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<a class="screenshot" href="client_empty.png" title="the main screen, just after you start up"><img src="client_empty_small.png" /></a>
|
||||
<a class="screenshot" href="client_autism.png" title="an example search"><img src="client_autism_small.png" /></a>
|
||||
<a class="screenshot" href="lib_gc.png" title="a well-tagged webcomic, sorted and viewed by chapter"><img src="lib_gc_small.png" /></a>
|
||||
<a class="screenshot" href="client_fullscreen.png" title="reading the webcomic in fullscreen"><img src="client_fullscreen_small.png" /></a>
|
||||
<a class="screenshot" href="lib_rec.png" title="file repository view, with some files local and some not"><img src="lib_rec_small.png" /></a>
|
||||
<a class="screenshot" href="lib_party_hard.png" title="now with swf support!"><img src="lib_party_hard_small.png" /></a>
|
||||
<a class="screenshot" href="client_auto.png" title="an example of tag-autocomplete, which only displays results applicable to the current query"><img src="client_auto_small.png" /></a>
|
||||
<a class="screenshot" href="screenshot_empty.png" title="an empty page. you can search in many ways, not just tags"><img src="screenshot_empty_thumb.png" /></a>
|
||||
<a class="screenshot" href="screenshot_general_search.png" title="a normal tag search"><img src="screenshot_general_search_thumb.png" /></a>
|
||||
<a class="screenshot" href="screenshot_big_search.png" title="the client can easily search, display and manage thousands of files"><img src="screenshot_big_search_thumb.png" /></a>
|
||||
<a class="screenshot" href="screenshot_gunnerkrigg_collect.png" title="files can be sorted and collected by their tags"><img src="screenshot_gunnerkrigg_collect_thumb.png" /></a>
|
||||
<a class="screenshot" href="screenshot_fullscreen_blame.png" title="fullscreen view is clean and fast"><img src="screenshot_fullscreen_blame_thumb.png" /></a>
|
||||
<a class="screenshot" href="screenshot_video.png" title="many file formats are supported"><img src="screenshot_video_thumb.png" /></a>
|
||||
<a class="screenshot" href="screenshot_booru.png" title="you can run your own (simple!) booru"><img src="screenshot_booru_thumb.png" /></a>
|
||||
<a class="screenshot" href="screenshot_advanced_autocomplete.png" title="the tag autocomplete is a powerful tool that can get complicated if you want it to. this screenshot shows a tag sibling, where one tag is immediately swapped with another, and a non-local search, where results that are known but not on the computer are shown"><img src="screenshot_advanced_autocomplete_thumb.png" /></a>
|
||||
<h3>hydrus help</h3>
|
||||
<p>Although I've tried to make hydrus's interface simple, its underlying concepts are not. Please read the introduction and skim the getting started guide at the least, and if you want to get started with my server, you'll probably want to check out the access keys section.</p>
|
||||
<ul>
|
||||
|
|
|
@ -8,23 +8,23 @@
|
|||
<div class="content">
|
||||
<h3>on being anonymous</h3>
|
||||
<p>I am convinced that having the option of anonymous speech is extremely valuable to the modern development of free culture and society.</p>
|
||||
<p>When people have no fear of personal repercussion, they can reveal corruptions and admit truths they otherwise never would. Their words are insightful and stupid, convincing and hurtful, hilarious and ridiculous. Try it; it's fun!</p>
|
||||
<p>Nearly all forums and social networking platforms use the same pseudonymous username/password archetype, and nearly all of them have the same problems with drama, sockpuppets, and egotistical mods. Sometimes the price is worth it, and sometimes it is not.</p>
|
||||
<p>When people do not have to fear personal repercussion, they can reveal corruptions and admit truths they otherwise never would. Their words are insightful and stupid, convincing and hurtful, hilarious and ridiculous. It's fun!</p>
|
||||
<p>Nearly all forums and social networking platforms use the same pseudonymous username/password system, and nearly all of them have the same problems with drama, sockpuppets, and egotistical mods. Sometimes the price is worth it, and sometimes it is not.</p>
|
||||
<p>I think people should have the <i>option</i> to interact with others anonymously if they wish, and further should always have the choice to filter or entirely block anonymously submitted content (or anything else!). I want people to decide for themselves what they see, not anyone else.</p>
|
||||
<p>There are several online platforms that support anonymity, usually through a web browser, but most have terribly inefficient code, and their actual anonymity is often impotent window dressing, an afterthought. Logs of IP addresses are kept routinely, available for any admin (or anyone else who gains access to the server) to peruse.</p>
|
||||
<p>There are several online platforms that support anonymity, usually through a web browser, but most have terribly inefficient code, and their actual anonymity is unreliable. Logs of IP addresses are kept routinely, available for any admin (or anyone else who gains access to the server) to peruse.</p>
|
||||
<p>I think we can do better.</p>
|
||||
<h3>the hydrus network</h3>
|
||||
<p>So! I'm developing a program that helps people manage their files together anonymously. My primary concern is in enabling you to do what you want with your stuff, and that's it. You can share tags and files with other people, but you don't have to connect to anything if you don't want to. I don't plan to ever record metrics on users, nor serve ads, nor charge for my software.</p>
|
||||
<p>So! I'm developing a program that helps people manage their files together anonymously. I want to help you do what you want with your stuff, and that's it. You can share tags and files with other people, but you don't have to connect to anything if you don't want to. The default is <b>no sharing</b>. I don't plan to ever record metrics on users, nor serve ads, nor charge for my software.</p>
|
||||
<p>There are a number of new concepts involved, and it can get as complicated as you like. If you are totally new to the idea of personal media collections and tagging, I advise you start slow, walk through the getting started guides, and experiment doing different things. You'll be importing thousands of files and applying <i>tens</i> of thousands of tags in no time.</p>
|
||||
<p>The client is chiefly a file database. It manages your media far better than an explorer window. Here's a screenshot of one of my test installs with a very general search:</p>
|
||||
<p>The client is chiefly a file database. It manages your media far better than an explorer window or some online gallery. Here's a screenshot of one of my test installs with a very general search:</p>
|
||||
<p><a href="example_client.png"><img src="example_client.png" width="960" height="540" title="WELCOME TO INTERNET" /></a></p>
|
||||
<p>There is also a server that anyone can run to store files or tags for sharing between many users. I run a tag service with several million tags that you are welcome to access and contribute to.</p>
|
||||
<p>As well as the client, there is also a server that anyone can run to store files or tags for sharing between many users. I run a tag service with several million tags that you are welcome to access and contribute to.</p>
|
||||
<p>I'm working on adding peer-to-peer anonymous communication.</p>
|
||||
<h3>statement of principles</h3>
|
||||
<ul class="bulletpoint">
|
||||
<li>No speech should be outlawed.</li>
|
||||
<li>Everyone should be able to control their own media diet.</li>
|
||||
<li>The data on someone's computer and the logs of their network activity should be absolutely private.</li>
|
||||
<li>Computer data and network logs should be absolutely private.</li>
|
||||
</ul>
|
||||
<p>None of the above are currently true, but I would love to live in a world where they were. My software is an attempt to move us a little closer.</p>
|
||||
<p>I try to side with the person over the authority, the distributed over the centralised. I still use gmail and youtube just like pretty much everyone, but I would rather be using different systems, especially in ten years. No one seemed to be making what I wanted, so I decided to do it myself, and here we are.</p>
|
||||
|
|
After Width: | Height: | Size: 409 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 2.0 MiB |
After Width: | Height: | Size: 133 KiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 123 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 107 KiB |
After Width: | Height: | Size: 1.8 MiB |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 324 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 411 KiB |
After Width: | Height: | Size: 49 KiB |
|
@ -283,7 +283,7 @@ CLIENT_DEFAULT_OPTIONS[ 'shortcuts' ] = shortcuts
|
|||
|
||||
CLIENT_DEFAULT_OPTIONS[ 'confirm_client_exit' ] = False
|
||||
|
||||
CLIENT_DEFAULT_OPTIONS[ 'default_tag_repository' ] = HC.LOCAL_TAG_SERVICE_IDENTIFIER
|
||||
CLIENT_DEFAULT_OPTIONS[ 'default_tag_repository' ] = HC.LOCAL_TAG_SERVICE_KEY
|
||||
CLIENT_DEFAULT_OPTIONS[ 'default_tag_sort' ] = SORT_BY_LEXICOGRAPHIC_ASC
|
||||
|
||||
CLIENT_DEFAULT_OPTIONS[ 'pause_export_folders_sync' ] = False
|
||||
|
@ -1160,7 +1160,7 @@ class LocalBooruCache( object ):
|
|||
|
||||
def _RefreshShares( self ):
|
||||
|
||||
self._local_booru_service = HC.app.Read( 'service', HC.LOCAL_BOORU_SERVICE_IDENTIFIER )
|
||||
self._local_booru_service = HC.app.GetManager( 'services' ).GetService( HC.LOCAL_BOORU_SERVICE_IDENTIFIER.GetServiceKey() )
|
||||
|
||||
self._keys_to_infos = {}
|
||||
|
||||
|
@ -2293,6 +2293,8 @@ class Service( HC.HydrusYAMLBase ):
|
|||
self._name = name
|
||||
self._info = info
|
||||
|
||||
self._lock = threading.Lock()
|
||||
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdates', 'service_updates_data' )
|
||||
|
||||
|
||||
|
@ -2565,29 +2567,14 @@ class ServiceManager( object ):
|
|||
HC.pubsub.sub( self, 'RefreshServices', 'notify_new_services_data' )
|
||||
|
||||
|
||||
def GetName( self, service_key ):
|
||||
|
||||
with self._lock:
|
||||
|
||||
service = self._keys_to_services[ service_key ]
|
||||
|
||||
return service.GetName()
|
||||
|
||||
|
||||
|
||||
def GetService( self, service_key ):
|
||||
|
||||
with self._lock: return self._keys_to_services[ service_key ]
|
||||
|
||||
|
||||
def GetType( self, service_key ):
|
||||
def GetServices( self, types = HC.ALL_SERVICES ):
|
||||
|
||||
with self._lock:
|
||||
|
||||
service = self._keys_to_services[ service_key ]
|
||||
|
||||
return service.GetType()
|
||||
|
||||
with self._lock: return [ service for service in self._keys_to_services.values() if service.GetType() in types ]
|
||||
|
||||
|
||||
def RefreshServices( self ):
|
||||
|
|
|
@ -31,7 +31,7 @@ from twisted.internet import defer
|
|||
ID_ANIMATED_EVENT_TIMER = wx.NewId()
|
||||
ID_MAINTENANCE_EVENT_TIMER = wx.NewId()
|
||||
|
||||
MAINTENANCE_PERIOD = 12 * 60
|
||||
MAINTENANCE_PERIOD = 5 * 60
|
||||
|
||||
class Controller( wx.App ):
|
||||
|
||||
|
@ -112,7 +112,7 @@ The database will be locked while the backup occurs, which may lock up your gui
|
|||
|
||||
|
||||
|
||||
def CurrentlyIdle( self ): return HC.GetNow() - self._timestamps[ 'last_user_db_use' ] > 30 * 60 # 30 mins since last user-initiated media_results query
|
||||
def CurrentlyIdle( self ): return HC.GetNow() - self._timestamps[ 'last_user_action' ] > 30 * 60 # 30 mins since last canvas media swap
|
||||
|
||||
def EventPubSub( self, event ):
|
||||
|
||||
|
@ -208,9 +208,10 @@ The database will be locked while the backup occurs, which may lock up your gui
|
|||
|
||||
self._managers = {}
|
||||
|
||||
self._managers[ 'services' ] = CC.ServiceManager()
|
||||
|
||||
self._managers[ 'hydrus_sessions' ] = HydrusSessions.HydrusSessionManagerClient()
|
||||
self._managers[ 'local_booru' ] = CC.LocalBooruCache()
|
||||
self._managers[ 'services' ] = CC.ServiceManager()
|
||||
self._managers[ 'tag_censorship' ] = HydrusTags.TagCensorshipManager()
|
||||
self._managers[ 'tag_siblings' ] = HydrusTags.TagSiblingsManager()
|
||||
self._managers[ 'tag_parents' ] = HydrusTags.TagParentsManager()
|
||||
|
@ -265,9 +266,9 @@ The database will be locked while the backup occurs, which may lock up your gui
|
|||
|
||||
HC.pubsub.pub( 'set_splash_text', 'fattening service info' )
|
||||
|
||||
service_identifiers = self.Read( 'service_identifiers' )
|
||||
services = self.GetManager( 'services' ).GetServices()
|
||||
|
||||
for service_identifier in service_identifiers: self.Read( 'service_info', service_identifier )
|
||||
for service in services: self.Read( 'service_info', service.GetKey() )
|
||||
|
||||
self._timestamps[ 'service_info_cache_fatten' ] = HC.GetNow()
|
||||
|
||||
|
@ -314,12 +315,7 @@ The database will be locked while the backup occurs, which may lock up your gui
|
|||
else: return text.lower()
|
||||
|
||||
|
||||
def Read( self, action, *args, **kwargs ):
|
||||
|
||||
if action == 'media_results': self._timestamps[ 'last_user_db_use' ] = HC.GetNow()
|
||||
|
||||
return self._Read( action, *args, **kwargs )
|
||||
|
||||
def Read( self, action, *args, **kwargs ): return self._Read( action, *args, **kwargs )
|
||||
|
||||
def ReadDaemon( self, action, *args, **kwargs ):
|
||||
|
||||
|
@ -330,9 +326,11 @@ The database will be locked while the backup occurs, which may lock up your gui
|
|||
return result
|
||||
|
||||
|
||||
def ResetIdleTimer( self ): self._timestamps[ 'last_user_action' ] = HC.GetNow()
|
||||
|
||||
def RestartBooru( self ):
|
||||
|
||||
service = self.Read( 'service', HC.LOCAL_BOORU_SERVICE_IDENTIFIER )
|
||||
service = self.GetManager( 'services' ).GetService( HC.LOCAL_BOORU_SERVICE_IDENTIFIER.GetServiceKey() )
|
||||
|
||||
info = service.GetInfo()
|
||||
|
||||
|
@ -506,7 +504,7 @@ Once it is done, the client will restart.'''
|
|||
|
||||
try:
|
||||
|
||||
query_hash_ids = HC.app.Read( 'file_query_ids', search_context )
|
||||
query_hash_ids = self.Read( 'file_query_ids', search_context )
|
||||
|
||||
query_hash_ids = list( query_hash_ids )
|
||||
|
||||
|
@ -537,13 +535,13 @@ Once it is done, the client will restart.'''
|
|||
|
||||
sub_query_hash_ids = query_hash_ids[ last_i : i ]
|
||||
|
||||
more_media_results = HC.app.Read( 'media_results_from_ids', file_service_identifier, sub_query_hash_ids )
|
||||
more_media_results = self.Read( 'media_results_from_ids', file_service_identifier, sub_query_hash_ids )
|
||||
|
||||
media_results.extend( more_media_results )
|
||||
|
||||
HC.pubsub.pub( 'set_num_query_results', len( media_results ), len( query_hash_ids ) )
|
||||
|
||||
HC.app.WaitUntilGoodTimeToUseGUIThread()
|
||||
self.WaitUntilGoodTimeToUseGUIThread()
|
||||
|
||||
|
||||
HC.pubsub.pub( 'file_query_done', query_key, media_results )
|
||||
|
@ -558,7 +556,7 @@ Once it is done, the client will restart.'''
|
|||
self._timestamps[ 'last_check_idle_time' ] = HC.GetNow()
|
||||
|
||||
# this tests if we probably just woke up from a sleep
|
||||
if HC.GetNow() - last_time_this_ran > MAINTENANCE_PERIOD * 1.2: return
|
||||
if HC.GetNow() - last_time_this_ran > MAINTENANCE_PERIOD + ( 5 * 60 ): return
|
||||
|
||||
if self.CurrentlyIdle(): self.MaintainDB()
|
||||
|
||||
|
|
|
@ -1316,11 +1316,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
c.execute( 'REPLACE INTO hydrus_sessions ( service_id, session_key, expiry ) VALUES ( ?, ?, ? );', ( service_id, sqlite3.Binary( session_key ), expiry ) )
|
||||
|
||||
|
||||
def _AddService( self, c, service_identifier, info ):
|
||||
|
||||
service_key = service_identifier.GetServiceKey()
|
||||
service_type = service_identifier.GetType()
|
||||
name = service_identifier.GetName()
|
||||
def _AddService( self, c, service_key, service_type, name, info ):
|
||||
|
||||
if service_type in HC.LOCAL_SERVICES:
|
||||
|
||||
|
@ -2497,10 +2493,6 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
service_type = service_identifier.GetType()
|
||||
|
||||
repository = self._GetService( c, service_id )
|
||||
|
||||
account = repository.GetInfo( 'account' )
|
||||
|
||||
if service_type == HC.TAG_REPOSITORY:
|
||||
|
||||
updates = []
|
||||
|
@ -2657,57 +2649,30 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
return reason_id
|
||||
|
||||
|
||||
def _GetService( self, c, parameter ):
|
||||
|
||||
try:
|
||||
|
||||
if type( parameter ) == int: service_id = parameter
|
||||
elif type( parameter ) == HC.ClientServiceIdentifier: service_id = self._GetServiceId( c, parameter )
|
||||
|
||||
except: raise Exception( 'Service error in database.' )
|
||||
|
||||
result = c.execute( 'SELECT service_key, service_type, name, info FROM services WHERE service_id = ?;', ( service_id, ) ).fetchone()
|
||||
|
||||
if result is None: raise Exception( 'Service error in database.' )
|
||||
|
||||
( service_key, service_type, name, info ) = result
|
||||
|
||||
service = CC.Service( service_key, service_type, name, info )
|
||||
|
||||
return service
|
||||
|
||||
|
||||
def _GetServices( self, c, limited_types = HC.ALL_SERVICES ):
|
||||
|
||||
service_ids = [ service_id for ( service_id, ) in c.execute( 'SELECT service_id FROM services WHERE service_type IN ' + HC.SplayListForDB( limited_types ) + ';' ) ]
|
||||
services = []
|
||||
|
||||
services = [ self._GetService( c, service_id ) for service_id in service_ids ]
|
||||
for result in c.execute( 'SELECT service_key, service_type, name, info FROM services WHERE service_type IN ' + HC.SplayListForDB( limited_types ) + ';' ):
|
||||
|
||||
( service_key, service_type, name, info ) = result
|
||||
|
||||
services.append( CC.Service( service_key, service_type, name, info ) )
|
||||
|
||||
|
||||
return services
|
||||
|
||||
|
||||
def _GetServiceId( self, c, parameter ):
|
||||
|
||||
if type( parameter ) in ( str, unicode ):
|
||||
|
||||
result = c.execute( 'SELECT service_id FROM services WHERE name = ?;', ( parameter, ) ).fetchone()
|
||||
|
||||
if result is None: raise Exception( 'Service id error in database' )
|
||||
|
||||
( service_id, ) = result
|
||||
|
||||
elif type( parameter ) == HC.ClientServiceIdentifier:
|
||||
|
||||
service_type = parameter.GetType()
|
||||
|
||||
service_key = parameter.GetServiceKey()
|
||||
|
||||
result = c.execute( 'SELECT service_id FROM services WHERE service_key = ?;', ( sqlite3.Binary( service_key ), ) ).fetchone()
|
||||
|
||||
if result is None: raise Exception( 'Service id error in database' )
|
||||
|
||||
( service_id, ) = result
|
||||
|
||||
if type( parameter ) == HC.ClientServiceIdentifier: service_key = parameter.GetServiceKey()
|
||||
else: service_key = parameter
|
||||
|
||||
result = c.execute( 'SELECT service_id FROM services WHERE service_key = ?;', ( sqlite3.Binary( service_key ), ) ).fetchone()
|
||||
|
||||
if result is None: raise Exception( 'Service id error in database' )
|
||||
|
||||
( service_id, ) = result
|
||||
|
||||
return service_id
|
||||
|
||||
|
@ -2727,11 +2692,11 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
def _GetServiceIdentifiers( self, c, limited_types = HC.ALL_SERVICES ): return { HC.ClientServiceIdentifier( service_key, service_type, name ) for ( service_key, service_type, name ) in c.execute( 'SELECT service_key, service_type, name FROM services WHERE service_type IN ' + HC.SplayListForDB( limited_types ) + ';' ) }
|
||||
|
||||
def _GetServiceInfo( self, c, service_identifier ):
|
||||
def _GetServiceInfo( self, c, service_key ):
|
||||
|
||||
service_id = self._GetServiceId( c, service_identifier )
|
||||
service_id = self._GetServiceId( c, service_key )
|
||||
|
||||
service_type = service_identifier.GetType()
|
||||
service_type = self._GetServiceType( c, service_id )
|
||||
|
||||
if service_type == HC.LOCAL_FILE: info_types = { HC.SERVICE_INFO_NUM_FILES, HC.SERVICE_INFO_TOTAL_SIZE, HC.SERVICE_INFO_NUM_DELETED_FILES }
|
||||
elif service_type == HC.FILE_REPOSITORY: info_types = { HC.SERVICE_INFO_NUM_FILES, HC.SERVICE_INFO_TOTAL_SIZE, HC.SERVICE_INFO_NUM_DELETED_FILES, HC.SERVICE_INFO_NUM_THUMBNAILS, HC.SERVICE_INFO_NUM_THUMBNAILS_LOCAL }
|
||||
|
@ -3022,14 +2987,6 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
result = { dump_name.decode( 'hex' ) : data for ( dump_name, data ) in result.items() }
|
||||
|
||||
|
||||
if dump_type == YAML_DUMP_ID_SUBSCRIPTION:
|
||||
|
||||
for ( dump_name, data ) in result.items():
|
||||
|
||||
data[ 'advanced_tag_options' ] = dict( data[ 'advanced_tag_options' ] )
|
||||
|
||||
|
||||
|
||||
else:
|
||||
|
||||
if dump_type == YAML_DUMP_ID_LOCAL_BOORU: dump_name = dump_name.encode( 'hex' )
|
||||
|
@ -3046,15 +3003,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
if result is None: raise Exception( dump_name + ' was not found!' )
|
||||
|
||||
else:
|
||||
|
||||
( result, ) = result
|
||||
|
||||
if dump_type == YAML_DUMP_ID_SUBSCRIPTION:
|
||||
|
||||
result[ 'advanced_tag_options' ] = dict( result[ 'advanced_tag_options' ] )
|
||||
|
||||
|
||||
else: ( result, ) = result
|
||||
|
||||
|
||||
return result
|
||||
|
@ -3827,14 +3776,12 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
def _ResetService( self, c, service_identifier ):
|
||||
|
||||
service_name = service_identifier.GetName()
|
||||
name = service_identifier.GetName()
|
||||
service_type = service_identifier.GetType()
|
||||
|
||||
service_id = self._GetServiceId( c, service_identifier )
|
||||
|
||||
service = self._GetService( c, service_id )
|
||||
|
||||
info = service.GetInfo()
|
||||
( info, ) = c.execute( 'SELECT info FROM services WHERE service_id = ?;', ( service_id, ) ).fetchone()
|
||||
|
||||
c.execute( 'DELETE FROM services WHERE service_id = ?;', ( service_id, ) )
|
||||
|
||||
|
@ -3852,14 +3799,16 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
self.pub_after_commit( 'notify_restart_repo_sync_daemon' )
|
||||
|
||||
|
||||
self._AddService( c, service_identifier, info )
|
||||
service_key = service_identifier.GetServiceKey()
|
||||
|
||||
self._AddService( c, service_key, service_type, name, info )
|
||||
|
||||
self.pub_service_updates_after_commit( { service_identifier : [ HC.ServiceUpdate( HC.SERVICE_UPDATE_RESET ) ] } )
|
||||
self.pub_after_commit( 'notify_new_pending' )
|
||||
self.pub_after_commit( 'notify_new_services_data' )
|
||||
self.pub_after_commit( 'notify_new_services_gui' )
|
||||
self.pub_after_commit( 'permissions_are_stale' )
|
||||
HC.ShowText( 'reset ' + service_name )
|
||||
HC.ShowText( 'reset ' + name )
|
||||
|
||||
|
||||
def _SetTagCensorship( self, c, info ):
|
||||
|
@ -3901,8 +3850,6 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
c.execute( 'DELETE FROM yaml_dumps WHERE dump_type = ? AND dump_name = ?;', ( dump_type, dump_name ) )
|
||||
|
||||
if dump_type == YAML_DUMP_ID_SUBSCRIPTION: data[ 'advanced_tag_options' ] = data[ 'advanced_tag_options' ].items()
|
||||
|
||||
try: c.execute( 'INSERT INTO yaml_dumps ( dump_type, dump_name, dump ) VALUES ( ?, ?, ? );', ( dump_type, dump_name, data ) )
|
||||
except:
|
||||
|
||||
|
@ -4290,11 +4237,10 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
server_admin_service_id = self._GetServiceId( c, server_admin_service_identifier )
|
||||
|
||||
server_admin = self._GetService( c, server_admin_service_id )
|
||||
( server_admin_info, ) = c.execute( 'SELECT info FROM services WHERE service_id = ?;', ( server_admin_service_id, ) ).fetchone()
|
||||
|
||||
server_admin_credentials = server_admin.GetCredentials()
|
||||
|
||||
( host, server_admin_port ) = server_admin_credentials.GetAddress()
|
||||
host = server_admin_info[ 'host' ]
|
||||
server_admin_port = server_admin_info[ 'port' ]
|
||||
|
||||
recalc_combined_mappings = False
|
||||
|
||||
|
@ -4315,9 +4261,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
name = HC.service_string_lookup[ service_type ] + ' at ' + host + ':' + HC.u( info[ 'port' ] )
|
||||
|
||||
client_service_identifier = HC.ClientServiceIdentifier( service_key, service_type, name )
|
||||
|
||||
self._AddService( c, client_service_identifier, info )
|
||||
self._AddService( c, service_key, service_type, name, info )
|
||||
|
||||
elif action == HC.DELETE:
|
||||
|
||||
|
@ -4406,7 +4350,11 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
|
|||
|
||||
( service_identifier, info ) = details
|
||||
|
||||
self._AddService( c, service_identifier, info )
|
||||
service_key = service_identifier.GetServiceKey()
|
||||
service_type = service_identifier.GetType()
|
||||
name = service_identifier.GetName()
|
||||
|
||||
self._AddService( c, service_key, service_type, name, info )
|
||||
|
||||
elif action == HC.DELETE:
|
||||
|
||||
|
@ -4570,10 +4518,10 @@ class DB( ServiceDB ):
|
|||
raise
|
||||
|
||||
|
||||
self._local_file_service_id = self._GetServiceId( c, HC.LOCAL_FILE_SERVICE_IDENTIFIER )
|
||||
self._local_tag_service_id = self._GetServiceId( c, HC.LOCAL_TAG_SERVICE_IDENTIFIER )
|
||||
self._combined_file_service_id = self._GetServiceId( c, HC.COMBINED_FILE_SERVICE_IDENTIFIER )
|
||||
self._combined_tag_service_id = self._GetServiceId( c, HC.COMBINED_TAG_SERVICE_IDENTIFIER )
|
||||
self._local_file_service_id = self._GetServiceId( c, HC.LOCAL_FILE_SERVICE_KEY )
|
||||
self._local_tag_service_id = self._GetServiceId( c, HC.LOCAL_TAG_SERVICE_KEY )
|
||||
self._combined_file_service_id = self._GetServiceId( c, HC.COMBINED_FILE_SERVICE_KEY )
|
||||
self._combined_tag_service_id = self._GetServiceId( c, HC.COMBINED_TAG_SERVICE_KEY )
|
||||
|
||||
options = self._GetOptions( c )
|
||||
|
||||
|
@ -4820,9 +4768,12 @@ class DB( ServiceDB ):
|
|||
|
||||
for init_service_identifier in init_service_identifiers:
|
||||
|
||||
service_key = init_service_identifier.GetServiceKey()
|
||||
service_type = init_service_identifier.GetType()
|
||||
name = init_service_identifier.GetName()
|
||||
info = {}
|
||||
|
||||
self._AddService( c, init_service_identifier, info )
|
||||
self._AddService( c, service_key, service_type, name, info )
|
||||
|
||||
|
||||
c.executemany( 'INSERT INTO yaml_dumps VALUES ( ?, ?, ? );', ( ( YAML_DUMP_ID_REMOTE_BOORU, name, booru ) for ( name, booru ) in CC.DEFAULT_BOORUS.items() ) )
|
||||
|
@ -4940,6 +4891,9 @@ class DB( ServiceDB ):
|
|||
|
||||
if version == 114:
|
||||
|
||||
service_key = HC.LOCAL_BOORU_SERVICE_IDENTIFIER.GetServiceKey()
|
||||
service_type = HC.LOCAL_BOORU_SERVICE_IDENTIFIER.GetType()
|
||||
name = HC.LOCAL_BOORU_SERVICE_IDENTIFIER.GetName()
|
||||
info = {}
|
||||
|
||||
self._AddService( c, HC.LOCAL_BOORU_SERVICE_IDENTIFIER, info )
|
||||
|
@ -5064,6 +5018,35 @@ class DB( ServiceDB ):
|
|||
c.execute( 'UPDATE services SET info = ? WHERE service_id = ?;', ( info, service_id ) )
|
||||
|
||||
|
||||
if version == 125:
|
||||
|
||||
( HC.options, ) = c.execute( 'SELECT options FROM options;' ).fetchone()
|
||||
|
||||
HC.options[ 'default_tag_repository' ] = HC.options[ 'default_tag_repository' ].GetServiceKey()
|
||||
|
||||
c.execute( 'UPDATE options SET options = ?;', ( HC.options, ) )
|
||||
|
||||
#
|
||||
|
||||
results = c.execute( 'SELECT * FROM yaml_dumps WHERE dump_type = ?;', ( YAML_DUMP_ID_SUBSCRIPTION, ) ).fetchall()
|
||||
|
||||
for ( dump_type, dump_name, dump ) in results:
|
||||
|
||||
advanced_tag_options = dump[ 'advanced_tag_options' ]
|
||||
|
||||
new_advanced_tag_options = {}
|
||||
|
||||
for ( service_identifier, namespaces ) in advanced_tag_options:
|
||||
|
||||
new_advanced_tag_options[ service_identifier.GetServiceKey() ] = namespaces
|
||||
|
||||
|
||||
dump[ 'advanced_tag_options' ] = new_advanced_tag_options
|
||||
|
||||
c.execute( 'UPDATE yaml_dumps SET dump = ? WHERE dump_type = ? and dump_name = ?;', ( dump, dump_type, dump_name ) )
|
||||
|
||||
|
||||
|
||||
c.execute( 'UPDATE version SET version = ?;', ( version + 1, ) )
|
||||
|
||||
HC.is_db_updated = True
|
||||
|
@ -7096,7 +7079,6 @@ class DB( ServiceDB ):
|
|||
elif action == 'ratings_media_result': result = self._GetRatingsMediaResult( c, *args, **kwargs )
|
||||
elif action == 'remote_booru': result = self._GetYAMLDump( c, YAML_DUMP_ID_REMOTE_BOORU, *args, **kwargs )
|
||||
elif action == 'remote_boorus': result = self._GetYAMLDump( c, YAML_DUMP_ID_REMOTE_BOORU )
|
||||
elif action == 'service': result = self._GetService( c, *args, **kwargs )
|
||||
elif action == 'service_identifiers': result = self._GetServiceIdentifiers( c, *args, **kwargs )
|
||||
elif action == 'service_info': result = self._GetServiceInfo( c, *args, **kwargs )
|
||||
elif action == 'services': result = self._GetServices( c, *args, **kwargs )
|
||||
|
@ -7557,7 +7539,7 @@ def DAEMONDownloadFiles():
|
|||
|
||||
if service_identifier == HC.LOCAL_FILE_SERVICE_IDENTIFIER: break
|
||||
|
||||
try: file_repository = HC.app.ReadDaemon( 'service', service_identifier )
|
||||
try: file_repository = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
except: continue
|
||||
|
||||
HC.pubsub.pub( 'downloads_status', HC.ConvertIntToPrettyString( num_downloads ) + ' file downloads' )
|
||||
|
@ -7611,7 +7593,7 @@ def DAEMONDownloadThumbnails():
|
|||
|
||||
if len( thumbnail_hashes_i_need ) > 0:
|
||||
|
||||
try: file_repository = HC.app.ReadDaemon( 'service', service_identifier )
|
||||
try: file_repository = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
except: continue
|
||||
|
||||
if file_repository.CanDownload():
|
||||
|
@ -7711,7 +7693,7 @@ def DAEMONResizeThumbnails():
|
|||
|
||||
def DAEMONSynchroniseAccounts():
|
||||
|
||||
services = HC.app.ReadDaemon( 'services', HC.RESTRICTED_SERVICES )
|
||||
services = HC.app.GetManager( 'services' ).GetServices( HC.RESTRICTED_SERVICES )
|
||||
|
||||
do_notify = False
|
||||
|
||||
|
@ -7771,7 +7753,7 @@ def DAEMONSynchroniseMessages():
|
|||
|
||||
service_type = service_identifier.GetType()
|
||||
|
||||
try: service = HC.app.ReadDaemon( 'service', service_identifier )
|
||||
try: service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
except: continue
|
||||
|
||||
if service.CanCheck():
|
||||
|
@ -7794,7 +7776,7 @@ def DAEMONSynchroniseMessages():
|
|||
|
||||
HC.app.WriteSynchronous( 'contact_associated', service_identifier )
|
||||
|
||||
service = HC.app.ReadDaemon( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
contact = service.GetContact()
|
||||
|
||||
|
@ -7893,7 +7875,7 @@ def DAEMONSynchroniseMessages():
|
|||
my_public_key = contact_from.GetPublicKey()
|
||||
my_contact_key = contact_from.GetContactKey()
|
||||
|
||||
my_message_depot = HC.app.ReadDaemon( 'service', contact_from )
|
||||
my_message_depot = HC.app.GetManager( 'services' ).GetService( contact_from.GetServiceKey() )
|
||||
|
||||
from_connection = my_message_depot.GetConnection()
|
||||
|
||||
|
@ -7957,7 +7939,7 @@ def DAEMONSynchroniseRepositories():
|
|||
service_type = service_identifier.GetType()
|
||||
service_key = service_identifier.GetServiceKey()
|
||||
|
||||
try: service = HC.app.ReadDaemon( 'service', service_identifier )
|
||||
try: service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
except: continue
|
||||
|
||||
info = service.GetInfo()
|
||||
|
@ -7966,19 +7948,34 @@ def DAEMONSynchroniseRepositories():
|
|||
|
||||
if service.CanDownloadUpdate():
|
||||
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, 'checking ' + name + ' repository' )
|
||||
job_key = HC.JobKey( pausable = True, cancellable = False )
|
||||
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, 'checking ' + name + ' repository', job_key )
|
||||
|
||||
HC.pubsub.pub( 'message', message )
|
||||
|
||||
while service.CanDownloadUpdate():
|
||||
|
||||
while job_key.IsPaused():
|
||||
|
||||
message.SetInfo( 'text', 'paused' )
|
||||
|
||||
time.sleep( 1 )
|
||||
|
||||
if HC.shutdown: raise Exception( 'application shutting down!' )
|
||||
|
||||
if message.IsClosed(): return
|
||||
|
||||
|
||||
while HC.options[ 'pause_repo_sync' ]:
|
||||
|
||||
message.SetInfo( 'text', 'Repository synchronisation paused' )
|
||||
message.SetInfo( 'text', 'repository synchronisation paused' )
|
||||
|
||||
time.sleep( 5 )
|
||||
|
||||
if HC.shutdown: raise Exception( 'Application shutting down!' )
|
||||
if HC.shutdown: raise Exception( 'application shutting down!' )
|
||||
|
||||
if message.IsClosed(): return
|
||||
|
||||
if HC.repos_changed:
|
||||
|
||||
|
@ -7990,7 +7987,7 @@ def DAEMONSynchroniseRepositories():
|
|||
|
||||
|
||||
|
||||
if HC.shutdown: raise Exception( 'Application shutting down!' )
|
||||
if HC.shutdown: raise Exception( 'application shutting down!' )
|
||||
|
||||
now = HC.GetNow()
|
||||
|
||||
|
@ -8036,7 +8033,7 @@ def DAEMONSynchroniseRepositories():
|
|||
|
||||
time.sleep( 0.10 )
|
||||
|
||||
try: service = HC.app.ReadDaemon( 'service', service_identifier )
|
||||
try: service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
except: break
|
||||
|
||||
|
||||
|
@ -8045,19 +8042,34 @@ def DAEMONSynchroniseRepositories():
|
|||
|
||||
if service.CanProcessUpdate():
|
||||
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, 'processing ' + name + ' repository' )
|
||||
job_key = HC.JobKey( pausable = True, cancellable = False )
|
||||
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, 'processing ' + name + ' repository', job_key )
|
||||
|
||||
HC.pubsub.pub( 'message', message )
|
||||
|
||||
while service.CanProcessUpdate():
|
||||
|
||||
while job_key.IsPaused():
|
||||
|
||||
message.SetInfo( 'text', 'paused' )
|
||||
|
||||
time.sleep( 1 )
|
||||
|
||||
if HC.shutdown: raise Exception( 'application shutting down!' )
|
||||
|
||||
if message.IsClosed(): return
|
||||
|
||||
|
||||
while HC.options[ 'pause_repo_sync' ]:
|
||||
|
||||
message.SetInfo( 'text', 'Repository synchronisation paused' )
|
||||
message.SetInfo( 'text', 'repository synchronisation paused' )
|
||||
|
||||
time.sleep( 5 )
|
||||
|
||||
if HC.shutdown: raise Exception( 'Application shutting down!' )
|
||||
if HC.shutdown: raise Exception( 'application shutting down!' )
|
||||
|
||||
if message.IsClosed(): return
|
||||
|
||||
if HC.repos_changed:
|
||||
|
||||
|
@ -8069,7 +8081,7 @@ def DAEMONSynchroniseRepositories():
|
|||
|
||||
|
||||
|
||||
if HC.shutdown: raise Exception( 'Application shutting down!' )
|
||||
if HC.shutdown: raise Exception( 'application shutting down!' )
|
||||
|
||||
now = HC.GetNow()
|
||||
|
||||
|
@ -8168,7 +8180,7 @@ def DAEMONSynchroniseRepositories():
|
|||
|
||||
time.sleep( 0.10 )
|
||||
|
||||
try: service = HC.app.ReadDaemon( 'service', service_identifier )
|
||||
try: service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
except: break
|
||||
|
||||
|
||||
|
@ -8225,7 +8237,9 @@ def DAEMONSynchroniseSubscriptions():
|
|||
|
||||
try:
|
||||
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, 'checking ' + name + ' subscription' )
|
||||
job_key = HC.JobKey( pausable = True, cancellable = False )
|
||||
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, 'checking ' + name + ' subscription', job_key )
|
||||
|
||||
HC.pubsub.pub( 'message', message )
|
||||
|
||||
|
@ -8291,6 +8305,17 @@ def DAEMONSynchroniseSubscriptions():
|
|||
|
||||
while True:
|
||||
|
||||
while job_key.IsPaused():
|
||||
|
||||
message.SetInfo( 'text', 'paused' )
|
||||
|
||||
time.sleep( 1 )
|
||||
|
||||
if HC.shutdown: return
|
||||
|
||||
if message.IsClosed(): return
|
||||
|
||||
|
||||
while HC.options[ 'pause_subs_sync' ]:
|
||||
|
||||
message.SetInfo( 'text', 'subscriptions paused' )
|
||||
|
@ -8299,6 +8324,8 @@ def DAEMONSynchroniseSubscriptions():
|
|||
|
||||
if HC.shutdown: return
|
||||
|
||||
if message.IsClosed(): return
|
||||
|
||||
if HC.subs_changed:
|
||||
|
||||
message.Close()
|
||||
|
@ -8467,6 +8494,8 @@ def DAEMONSynchroniseSubscriptions():
|
|||
message.SetInfo( 'hashes', successful_hashes )
|
||||
message.SetInfo( 'mode', 'files' )
|
||||
|
||||
job_key.SetPausable( False )
|
||||
|
||||
else: message.Close()
|
||||
|
||||
last_checked = now
|
||||
|
@ -8504,13 +8533,17 @@ def DAEMONSynchroniseSubscriptions():
|
|||
|
||||
def DAEMONUPnP():
|
||||
|
||||
local_ip = HydrusNATPunch.GetLocalIP()
|
||||
try:
|
||||
|
||||
local_ip = HydrusNATPunch.GetLocalIP()
|
||||
|
||||
current_mappings = HydrusNATPunch.GetUPnPMappings()
|
||||
|
||||
our_mappings = { ( internal_client, internal_port ) : external_port for ( description, internal_client, internal_port, external_ip_address, external_port, protocol, enabled ) in current_mappings }
|
||||
|
||||
except: return # This IGD probably doesn't support UPnP, so don't spam the user with errors they can't fix!
|
||||
|
||||
current_mappings = HydrusNATPunch.GetUPnPMappings()
|
||||
|
||||
our_mappings = { ( internal_client, internal_port ) : external_port for ( description, internal_client, internal_port, external_ip_address, external_port, protocol, enabled ) in current_mappings }
|
||||
|
||||
services = HC.app.ReadDaemon( 'services', ( HC.LOCAL_BOORU, ) )
|
||||
services = HC.app.GetManager( 'services' ).GetServices( ( HC.LOCAL_BOORU, ) )
|
||||
|
||||
for service in services:
|
||||
|
||||
|
|
|
@ -144,17 +144,17 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
try:
|
||||
|
||||
job_key = HC.JobKey()
|
||||
job_key = HC.JobKey( pausable = False, cancellable = False )
|
||||
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, 'gathering pending and petitioned' )
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, 'gathering pending and petitioned', job_key )
|
||||
|
||||
HC.pubsub.pub( 'message', message )
|
||||
|
||||
result = HC.app.Read( 'pending', service_identifier )
|
||||
|
||||
service_type = service_identifier.GetType()
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service_type = service.GetType()
|
||||
|
||||
if service_type == HC.FILE_REPOSITORY:
|
||||
|
||||
|
@ -172,7 +172,6 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
i = 1
|
||||
|
||||
message.SetInfo( 'job_key', job_key )
|
||||
message.SetInfo( 'range', gauge_range )
|
||||
message.SetInfo( 'value', i )
|
||||
message.SetInfo( 'text', 'connecting to repository' )
|
||||
|
@ -325,7 +324,7 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
subject_access_key = dlg.GetValue().decode( 'hex' )
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
response = service.Request( HC.GET, 'account_info', { 'subject_access_key' : subject_access_key.encode( 'hex' ) } )
|
||||
|
||||
|
@ -338,178 +337,193 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
def _AutoRepoSetup( self ):
|
||||
|
||||
def do_it():
|
||||
|
||||
edit_log = []
|
||||
|
||||
tag_repo_identifier = HC.ClientServiceIdentifier( os.urandom( 32 ), HC.TAG_REPOSITORY, 'public tag repository' )
|
||||
|
||||
tag_repo_info = {}
|
||||
|
||||
tag_repo_info[ 'host' ] = 'hydrus.no-ip.org'
|
||||
tag_repo_info[ 'port' ] = 45871
|
||||
tag_repo_info[ 'access_key' ] = '4a285629721ca442541ef2c15ea17d1f7f7578b0c3f4f5f2a05f8f0ab297786f'.decode( 'hex' )
|
||||
|
||||
edit_log.append( ( HC.ADD, ( tag_repo_identifier, tag_repo_info ) ) )
|
||||
|
||||
file_repo_identifier = HC.ClientServiceIdentifier( os.urandom( 32 ), HC.FILE_REPOSITORY, 'read-only art file repository' )
|
||||
|
||||
file_repo_info = {}
|
||||
|
||||
file_repo_info[ 'host' ] = 'hydrus.no-ip.org'
|
||||
file_repo_info[ 'port' ] = 45872
|
||||
file_repo_info[ 'access_key' ] = '8f8a3685abc19e78a92ba61d84a0482b1cfac176fd853f46d93fe437a95e40a5'.decode( 'hex' )
|
||||
|
||||
edit_log.append( ( HC.ADD, ( file_repo_identifier, file_repo_info ) ) )
|
||||
|
||||
HC.app.Write( 'update_services', edit_log )
|
||||
|
||||
HC.ShowText( 'Auto repo setup done! Check services->review services to see your new services.' )
|
||||
|
||||
|
||||
message = 'This will attempt to set up your client with my repositories\' credentials, letting you tag on the public tag repository and see some files.'
|
||||
|
||||
with ClientGUIDialogs.DialogYesNo( self, message ) as dlg:
|
||||
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
|
||||
edit_log = []
|
||||
|
||||
tag_repo_identifier = HC.ClientServiceIdentifier( os.urandom( 32 ), HC.TAG_REPOSITORY, 'public tag repository' )
|
||||
|
||||
tag_repo_info = {}
|
||||
|
||||
tag_repo_info[ 'host' ] = 'hydrus.no-ip.org'
|
||||
tag_repo_info[ 'port' ] = 45871
|
||||
tag_repo_info[ 'access_key' ] = '4a285629721ca442541ef2c15ea17d1f7f7578b0c3f4f5f2a05f8f0ab297786f'.decode( 'hex' )
|
||||
|
||||
edit_log.append( ( HC.ADD, ( tag_repo_identifier, tag_repo_info ) ) )
|
||||
|
||||
file_repo_identifier = HC.ClientServiceIdentifier( os.urandom( 32 ), HC.FILE_REPOSITORY, 'read-only art file repository' )
|
||||
|
||||
file_repo_info = {}
|
||||
|
||||
file_repo_info[ 'host' ] = 'hydrus.no-ip.org'
|
||||
file_repo_info[ 'port' ] = 45872
|
||||
file_repo_info[ 'access_key' ] = '8f8a3685abc19e78a92ba61d84a0482b1cfac176fd853f46d93fe437a95e40a5'.decode( 'hex' )
|
||||
|
||||
edit_log.append( ( HC.ADD, ( file_repo_identifier, file_repo_info ) ) )
|
||||
|
||||
HC.app.Write( 'update_services', edit_log )
|
||||
|
||||
HC.ShowText( 'Auto repo setup done!' )
|
||||
|
||||
if dlg.ShowModal() == wx.ID_YES: HydrusThreading.CallToThread( do_it )
|
||||
|
||||
|
||||
|
||||
def _AutoServerSetup( self ):
|
||||
|
||||
host = '127.0.0.1'
|
||||
port = HC.DEFAULT_SERVER_ADMIN_PORT
|
||||
def do_it():
|
||||
|
||||
host = '127.0.0.1'
|
||||
port = HC.DEFAULT_SERVER_ADMIN_PORT
|
||||
|
||||
try:
|
||||
|
||||
connection = httplib.HTTPConnection( '127.0.0.1', HC.DEFAULT_SERVER_ADMIN_PORT, timeout = 20 )
|
||||
|
||||
connection.connect()
|
||||
|
||||
connection.close()
|
||||
|
||||
already_running = True
|
||||
|
||||
except:
|
||||
|
||||
already_running = False
|
||||
|
||||
|
||||
if already_running:
|
||||
|
||||
HC.ShowText( 'The server appears to be already running. Either that, or something else is using port ' + HC.u( HC.DEFAULT_SERVER_ADMIN_PORT ) + '.' )
|
||||
|
||||
return
|
||||
|
||||
else:
|
||||
|
||||
try:
|
||||
|
||||
HC.ShowText( 'starting server' )
|
||||
|
||||
my_scriptname = sys.argv[0]
|
||||
|
||||
if my_scriptname.endswith( 'pyw' ): subprocess.Popen( [ 'pythonw', HC.BASE_DIR + os.path.sep + 'server.pyw' ] )
|
||||
else:
|
||||
|
||||
# The problem here is that, for mystical reasons, a PyInstaller exe can't launch another using subprocess, so we do it via explorer.
|
||||
|
||||
subprocess.Popen( [ 'explorer', HC.BASE_DIR + os.path.sep + 'server.exe' ] )
|
||||
|
||||
|
||||
time.sleep( 10 ) # give it time to init its db
|
||||
|
||||
except:
|
||||
|
||||
HC.ShowText( 'I tried to start the server, but something failed!' )
|
||||
HC.ShowText( traceback.format_exc() )
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
HC.ShowText( 'creating admin service' )
|
||||
|
||||
edit_log = []
|
||||
|
||||
admin_service_identifier = HC.ClientServiceIdentifier( os.urandom( 32 ), HC.SERVER_ADMIN, 'local server admin' )
|
||||
|
||||
admin_service_info = {}
|
||||
|
||||
admin_service_info[ 'host' ] = host
|
||||
admin_service_info[ 'port' ] = port
|
||||
admin_service_info[ 'access_key' ] = ''
|
||||
|
||||
edit_log.append( ( HC.ADD, ( admin_service_identifier, admin_service_info ) ) )
|
||||
|
||||
HC.app.Write( 'update_services', edit_log )
|
||||
|
||||
time.sleep( 5 )
|
||||
|
||||
i = 0
|
||||
|
||||
while True:
|
||||
|
||||
time.sleep( i + 1 )
|
||||
|
||||
try:
|
||||
|
||||
service = HC.app.GetManager( 'services' ).GetService( admin_service_identifier.GetServiceKey() )
|
||||
|
||||
break
|
||||
|
||||
except: pass
|
||||
|
||||
i += 1
|
||||
|
||||
if i > 5:
|
||||
|
||||
HC.ShowText( 'For some reason, I could not add the new server to the db! Perhaps it is very busy. Please email the hydrus developer, or sort it out yourself!' )
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
#
|
||||
|
||||
response = service.Request( HC.GET, 'init' )
|
||||
|
||||
access_key = response[ 'access_key' ]
|
||||
|
||||
update = { 'access_key' : access_key }
|
||||
|
||||
edit_log = [ ( HC.EDIT, ( admin_service_identifier, ( admin_service_identifier, update ) ) ) ]
|
||||
|
||||
HC.app.Write( 'update_services', edit_log )
|
||||
|
||||
HC.ShowText( 'admin service initialised' )
|
||||
|
||||
wx.CallAfter( ClientGUICommon.ShowKeys, 'access', ( access_key, ) )
|
||||
|
||||
time.sleep( 5 )
|
||||
|
||||
service = HC.app.GetManager( 'services' ).GetService( admin_service_identifier.GetServiceKey() )
|
||||
|
||||
#
|
||||
|
||||
HC.ShowText( 'creating tag and file services' )
|
||||
|
||||
tag_server_service_identifier = HC.ServerServiceIdentifier( os.urandom( 32 ), HC.TAG_REPOSITORY )
|
||||
|
||||
tag_options = HC.DEFAULT_OPTIONS[ HC.TAG_REPOSITORY ]
|
||||
tag_options[ 'port' ] = HC.DEFAULT_SERVICE_PORT
|
||||
|
||||
file_server_service_identifier = HC.ServerServiceIdentifier( os.urandom( 32 ), HC.FILE_REPOSITORY )
|
||||
|
||||
file_options = HC.DEFAULT_OPTIONS[ HC.FILE_REPOSITORY ]
|
||||
file_options[ 'port' ] = HC.DEFAULT_SERVICE_PORT + 1
|
||||
|
||||
edit_log = []
|
||||
|
||||
edit_log.append( ( HC.ADD, ( tag_server_service_identifier, tag_options ) ) )
|
||||
edit_log.append( ( HC.ADD, ( file_server_service_identifier, file_options ) ) )
|
||||
|
||||
response = service.Request( HC.POST, 'services', { 'edit_log' : edit_log } )
|
||||
|
||||
service_identifiers_to_access_keys = dict( response[ 'service_identifiers_to_access_keys' ] )
|
||||
|
||||
HC.app.Write( 'update_server_services', admin_service_identifier, edit_log, service_identifiers_to_access_keys )
|
||||
|
||||
HC.ShowText( 'Done! Check services->review services to see your new server and its services.' )
|
||||
|
||||
|
||||
message = 'This will attempt to start the server in the same install directory as this client, initialise it, and store the resultant admin accounts in the client.'
|
||||
|
||||
with ClientGUIDialogs.DialogYesNo( self, message ) as dlg:
|
||||
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
|
||||
try:
|
||||
|
||||
connection = httplib.HTTPConnection( '127.0.0.1', HC.DEFAULT_SERVER_ADMIN_PORT, timeout = 20 )
|
||||
|
||||
connection.connect()
|
||||
|
||||
connection.close()
|
||||
|
||||
already_running = True
|
||||
|
||||
except:
|
||||
|
||||
already_running = False
|
||||
|
||||
|
||||
if already_running:
|
||||
|
||||
message = 'The server appears to be already running. Either that, or something else is using port ' + HC.u( HC.DEFAULT_SERVER_ADMIN_PORT ) + '.' + os.linesep + 'Would you like to try to initialise the server that is already running?'
|
||||
|
||||
with ClientGUIDialogs.DialogYesNo( self, message ) as dlg:
|
||||
|
||||
if dlg.ShowModal() != wx.ID_YES: return
|
||||
|
||||
|
||||
else:
|
||||
|
||||
try:
|
||||
|
||||
my_scriptname = sys.argv[0]
|
||||
|
||||
if my_scriptname.endswith( 'pyw' ): subprocess.Popen( [ 'pythonw', HC.BASE_DIR + os.path.sep + 'server.pyw' ] )
|
||||
else:
|
||||
|
||||
# The problem here is that, for mystical reasons, a PyInstaller exe can't launch another using subprocess, so we do it via explorer.
|
||||
|
||||
subprocess.Popen( [ 'explorer', HC.BASE_DIR + os.path.sep + 'server.exe' ] )
|
||||
|
||||
|
||||
time.sleep( 10 ) # give it time to init its db
|
||||
|
||||
except:
|
||||
|
||||
wx.MessageBox( 'I tried to start the server, but something failed!' )
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
edit_log = []
|
||||
|
||||
admin_service_identifier = HC.ClientServiceIdentifier( os.urandom( 32 ), HC.SERVER_ADMIN, 'local server admin' )
|
||||
|
||||
admin_service_info = {}
|
||||
|
||||
admin_service_info[ 'host' ] = host
|
||||
admin_service_info[ 'port' ] = port
|
||||
admin_service_info[ 'access_key' ] = ''
|
||||
|
||||
edit_log.append( ( HC.ADD, ( admin_service_identifier, admin_service_info ) ) )
|
||||
|
||||
HC.app.Write( 'update_services', edit_log )
|
||||
|
||||
i = 0
|
||||
|
||||
while True:
|
||||
|
||||
time.sleep( i + 1 )
|
||||
|
||||
try:
|
||||
|
||||
service = HC.app.Read( 'service', admin_service_identifier )
|
||||
|
||||
break
|
||||
|
||||
except: pass
|
||||
|
||||
i += 1
|
||||
|
||||
if i > 5:
|
||||
|
||||
wx.MessageBox( 'For some reason, I could not add the new server to the db! Perhaps it is very busy. Please contact the administrator, or sort it out yourself!' )
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
#
|
||||
|
||||
response = service.Request( HC.GET, 'init' )
|
||||
|
||||
access_key = response[ 'access_key' ]
|
||||
|
||||
update = { 'access_key' : access_key }
|
||||
|
||||
edit_log = [ ( HC.EDIT, ( admin_service_identifier, ( admin_service_identifier, update ) ) ) ]
|
||||
|
||||
HC.app.Write( 'update_services', edit_log )
|
||||
|
||||
ClientGUICommon.ShowKeys( 'access', ( access_key, ) )
|
||||
|
||||
#
|
||||
|
||||
tag_server_service_identifier = HC.ServerServiceIdentifier( os.urandom( 32 ), HC.TAG_REPOSITORY )
|
||||
|
||||
tag_options = HC.DEFAULT_OPTIONS[ HC.TAG_REPOSITORY ]
|
||||
tag_options[ 'port' ] = HC.DEFAULT_SERVICE_PORT
|
||||
|
||||
file_server_service_identifier = HC.ServerServiceIdentifier( os.urandom( 32 ), HC.FILE_REPOSITORY )
|
||||
|
||||
file_options = HC.DEFAULT_OPTIONS[ HC.FILE_REPOSITORY ]
|
||||
file_options[ 'port' ] = HC.DEFAULT_SERVICE_PORT + 1
|
||||
|
||||
edit_log = []
|
||||
|
||||
edit_log.append( ( HC.ADD, ( tag_server_service_identifier, tag_options ) ) )
|
||||
edit_log.append( ( HC.ADD, ( file_server_service_identifier, file_options ) ) )
|
||||
|
||||
response = service.Request( HC.POST, 'services', { 'edit_log' : edit_log } )
|
||||
|
||||
service_identifiers_to_access_keys = dict( response[ 'service_identifiers_to_access_keys' ] )
|
||||
|
||||
HC.app.Write( 'update_server_services', admin_service_identifier, edit_log, service_identifiers_to_access_keys )
|
||||
|
||||
wx.MessageBox( 'Done! Check services->review services to see your new server and its services.' )
|
||||
|
||||
if dlg.ShowModal() == wx.ID_YES: HydrusThreading.CallToThread( do_it )
|
||||
|
||||
|
||||
|
||||
|
@ -521,7 +535,7 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
with wx.BusyCursor(): service.Request( HC.POST, 'backup' )
|
||||
|
||||
|
@ -611,7 +625,7 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
hash = dlg.GetValue().decode( 'hex' )
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
with wx.BusyCursor(): response = service.Request( HC.GET, 'ip', { 'hash' : hash.encode( 'hex' ) } )
|
||||
|
||||
|
@ -746,13 +760,13 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
def view():
|
||||
|
||||
services = HC.app.Read( 'services' )
|
||||
services = HC.app.GetManager( 'services' ).GetServices()
|
||||
|
||||
tag_repositories = [ service for service in services if service.GetServiceIdentifier().GetType() == HC.TAG_REPOSITORY ]
|
||||
tag_repositories = [ service for service in services if service.GetType() == HC.TAG_REPOSITORY ]
|
||||
|
||||
petition_resolve_tag_service_identifiers = [ repository.GetServiceIdentifier() for repository in tag_repositories if repository.GetInfo( 'account' ).HasPermission( HC.RESOLVE_PETITIONS ) ]
|
||||
|
||||
file_repositories = [ service for service in services if service.GetServiceIdentifier().GetType() == HC.FILE_REPOSITORY ]
|
||||
file_repositories = [ service for service in services if service.GetType() == HC.FILE_REPOSITORY ]
|
||||
|
||||
file_service_identifiers = [ repository.GetServiceIdentifier() for repository in file_repositories ]
|
||||
petition_resolve_file_service_identifiers = [ repository.GetServiceIdentifier() for repository in file_repositories if repository.GetInfo( 'account' ).HasPermission( HC.RESOLVE_PETITIONS ) ]
|
||||
|
@ -897,15 +911,15 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
def admin():
|
||||
|
||||
services = HC.app.Read( 'services' )
|
||||
services = HC.app.GetManager( 'services' ).GetServices()
|
||||
|
||||
tag_repositories = [ service for service in services if service.GetServiceIdentifier().GetType() == HC.TAG_REPOSITORY ]
|
||||
tag_repositories = [ service for service in services if service.GetType() == HC.TAG_REPOSITORY ]
|
||||
admin_tag_service_identifiers = [ repository.GetServiceIdentifier() for repository in tag_repositories if repository.GetInfo( 'account' ).HasPermission( HC.GENERAL_ADMIN ) ]
|
||||
|
||||
file_repositories = [ service for service in services if service.GetServiceIdentifier().GetType() == HC.FILE_REPOSITORY ]
|
||||
file_repositories = [ service for service in services if service.GetType() == HC.FILE_REPOSITORY ]
|
||||
admin_file_service_identifiers = [ repository.GetServiceIdentifier() for repository in file_repositories if repository.GetInfo( 'account' ).HasPermission( HC.GENERAL_ADMIN ) ]
|
||||
|
||||
servers_admin = [ service for service in services if service.GetServiceIdentifier().GetType() == HC.SERVER_ADMIN ]
|
||||
servers_admin = [ service for service in services if service.GetType() == HC.SERVER_ADMIN ]
|
||||
server_admin_identifiers = [ service.GetServiceIdentifier() for service in servers_admin if service.GetInfo( 'account' ).HasPermission( HC.GENERAL_ADMIN ) ]
|
||||
|
||||
if len( admin_tag_service_identifiers ) > 0 or len( admin_file_service_identifiers ) > 0 or len( server_admin_identifiers ) > 0:
|
||||
|
@ -1227,7 +1241,7 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
def _ModifyAccount( self, service_identifier ):
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
with ClientGUIDialogs.DialogTextEntry( self, 'Enter the access key for the account to be modified.' ) as dlg:
|
||||
|
||||
|
@ -1313,7 +1327,7 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
if service_identifier is not None:
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
account = service.GetInfo( 'account' )
|
||||
|
||||
|
@ -1395,7 +1409,7 @@ class FrameGUI( ClientGUICommon.FrameThatResizes ):
|
|||
|
||||
news = dlg.GetValue()
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
with wx.BusyCursor(): service.Request( HC.POST, 'news', { 'news' : news } )
|
||||
|
||||
|
@ -1592,7 +1606,9 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
|
||||
url_string = url
|
||||
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, url_string )
|
||||
job_key = HC.JobKey( pausable = False, cancellable = False )
|
||||
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, url_string, job_key )
|
||||
|
||||
HC.pubsub.pub( 'message', message )
|
||||
|
||||
|
@ -1620,7 +1636,7 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
|
||||
def _Stats( self, service_identifier ):
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
response = service.Request( HC.GET, 'stats' )
|
||||
|
||||
|
@ -2505,7 +2521,7 @@ class FrameReviewServices( ClientGUICommon.Frame ):
|
|||
|
||||
def _DisplayAccountInfo( self ):
|
||||
|
||||
self._service = HC.app.Read( 'service', self._service_identifier )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( self._service_identifier.GetServiceKey() )
|
||||
|
||||
service_type = self._service_identifier.GetType()
|
||||
|
||||
|
@ -2636,7 +2652,7 @@ class FrameReviewServices( ClientGUICommon.Frame ):
|
|||
|
||||
if service_type in HC.REPOSITORIES + HC.LOCAL_SERVICES:
|
||||
|
||||
service_info = HC.app.Read( 'service_info', self._service_identifier )
|
||||
service_info = HC.app.Read( 'service_info', self._service_identifier.GetServiceKey() )
|
||||
|
||||
if service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
|
||||
|
@ -2781,7 +2797,7 @@ class FrameReviewServices( ClientGUICommon.Frame ):
|
|||
|
||||
( name, text, timeout, ( num_hashes, hashes, share_key ) ) = shares[0]
|
||||
|
||||
self._service = HC.app.Read( 'service', HC.LOCAL_BOORU_SERVICE_IDENTIFIER )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( HC.LOCAL_BOORU_SERVICE_IDENTIFIER.GetServiceKey() )
|
||||
|
||||
info = self._service.GetInfo()
|
||||
|
||||
|
@ -2805,7 +2821,7 @@ class FrameReviewServices( ClientGUICommon.Frame ):
|
|||
|
||||
( name, text, timeout, ( num_hashes, hashes, share_key ) ) = shares[0]
|
||||
|
||||
self._service = HC.app.Read( 'service', HC.LOCAL_BOORU_SERVICE_IDENTIFIER )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( HC.LOCAL_BOORU_SERVICE_IDENTIFIER.GetServiceKey() )
|
||||
|
||||
info = self._service.GetInfo()
|
||||
|
||||
|
|
|
@ -433,6 +433,19 @@ class Canvas( object ):
|
|||
self.Bind( wx.EVT_PAINT, self.EventPaint )
|
||||
|
||||
|
||||
def _CopyHashToClipboard( self ):
|
||||
|
||||
if wx.TheClipboard.Open():
|
||||
|
||||
data = wx.TextDataObject( self._current_display_media.GetHash().encode( 'hex' ) )
|
||||
|
||||
wx.TheClipboard.SetData( data )
|
||||
|
||||
wx.TheClipboard.Close()
|
||||
|
||||
else: wx.MessageBox( 'I could not get permission to access the clipboard.' )
|
||||
|
||||
|
||||
def _DrawBackgroundBitmap( self ):
|
||||
|
||||
( client_width, client_height ) = self.GetClientSize()
|
||||
|
@ -539,7 +552,7 @@ class Canvas( object ):
|
|||
if service_identifier in self._service_identifiers_to_services: service = self._service_identifiers_to_services[ service_identifier ]
|
||||
else:
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
self._service_identifiers_to_services[ service_identifier ] = service
|
||||
|
||||
|
@ -757,6 +770,8 @@ class Canvas( object ):
|
|||
|
||||
if media != self._current_media:
|
||||
|
||||
HC.app.ResetIdleTimer()
|
||||
|
||||
with wx.FrozenWindow( self ):
|
||||
|
||||
self._current_media = media
|
||||
|
@ -1051,6 +1066,30 @@ class CanvasFullscreenMediaList( ClientGUIMixins.ListeningMediaList, Canvas, Cli
|
|||
|
||||
|
||||
|
||||
def _Remove( self ):
|
||||
|
||||
next_media = self._GetNext( self._current_media )
|
||||
|
||||
if next_media == self._current_media: next_media = None
|
||||
|
||||
hashes = { self._current_display_media.GetHash() }
|
||||
|
||||
HC.pubsub.pub( 'remove_media', self._page_key, hashes )
|
||||
|
||||
singleton_media = { self._current_display_media }
|
||||
|
||||
ClientGUIMixins.ListeningMediaList._RemoveMedia( self, singleton_media, {} )
|
||||
|
||||
if self.HasNoMedia(): self.EventClose( None )
|
||||
elif self.HasMedia( self._current_media ):
|
||||
|
||||
self._DrawBackgroundBitmap()
|
||||
|
||||
self._DrawCurrentMedia()
|
||||
|
||||
else: self.SetMedia( next_media )
|
||||
|
||||
|
||||
def _ShowFirst( self ): self.SetMedia( self._GetFirst() )
|
||||
|
||||
def _ShowLast( self ): self.SetMedia( self._GetLast() )
|
||||
|
@ -1459,6 +1498,7 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
|
|||
if command == 'archive': self._Archive()
|
||||
elif command == 'copy_files':
|
||||
with wx.BusyCursor(): HC.app.Write( 'copy_files', ( self._current_media.GetHash(), ) )
|
||||
elif command == 'copy_hash': self._CopyHashToClipboard()
|
||||
elif command == 'copy_local_url': self._CopyLocalUrlToClipboard()
|
||||
elif command == 'copy_path': self._CopyPathToClipboard()
|
||||
elif command == 'delete': self._Delete()
|
||||
|
@ -1481,6 +1521,7 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
|
|||
elif command == 'pan_left': self._DoManualPan( -distance, 0 )
|
||||
elif command == 'pan_right': self._DoManualPan( distance, 0 )
|
||||
|
||||
elif command == 'remove': self._Remove()
|
||||
elif command == 'slideshow': self._StartSlideshow( data )
|
||||
elif command == 'slideshow_pause_play': self._PausePlaySlideshow()
|
||||
elif command == 'zoom_in': self._ZoomIn()
|
||||
|
@ -1511,9 +1552,9 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
|
|||
|
||||
def EventShowMenu( self, event ):
|
||||
|
||||
services = HC.app.Read( 'services' )
|
||||
services = HC.app.GetManager( 'services' ).GetServices()
|
||||
|
||||
local_ratings_services = [ service for service in services if service.GetServiceIdentifier().GetType() in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ) ]
|
||||
local_ratings_services = [ service for service in services if service.GetType() in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ) ]
|
||||
|
||||
i_can_post_ratings = len( local_ratings_services ) > 0
|
||||
|
||||
|
@ -1550,25 +1591,33 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
|
|||
|
||||
menu.AppendSeparator()
|
||||
|
||||
menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'manage_tags' ), 'manage tags' )
|
||||
manage_menu = wx.Menu()
|
||||
|
||||
if i_can_post_ratings: menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'manage_ratings' ), 'manage ratings' )
|
||||
manage_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'manage_tags' ), 'tags' )
|
||||
|
||||
if i_can_post_ratings: manage_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'manage_ratings' ), 'ratings' )
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, 'manage', manage_menu )
|
||||
|
||||
menu.AppendSeparator()
|
||||
|
||||
if self._current_media.HasInbox(): menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'archive' ), '&archive' )
|
||||
if self._current_media.HasArchive(): menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'inbox' ), 'return to &inbox' )
|
||||
menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'remove', HC.LOCAL_FILE_SERVICE_IDENTIFIER ), '&remove' )
|
||||
menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'delete', HC.LOCAL_FILE_SERVICE_IDENTIFIER ), '&delete' )
|
||||
|
||||
menu.AppendSeparator()
|
||||
share_menu = wx.Menu()
|
||||
|
||||
copy_menu = wx.Menu()
|
||||
|
||||
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_files' ) , 'file' )
|
||||
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_hash' ) , 'hash' )
|
||||
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_path' ) , 'path' )
|
||||
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_local_url' ) , 'local url' )
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, 'copy', copy_menu )
|
||||
share_menu.AppendMenu( CC.ID_NULL, 'copy', copy_menu )
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, 'share', share_menu )
|
||||
|
||||
menu.AppendSeparator()
|
||||
|
||||
|
@ -1582,7 +1631,7 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
|
|||
slideshow.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'slideshow', 80 ), 'william gibson' )
|
||||
slideshow.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'slideshow' ), 'custom interval' )
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, 'Start Slideshow', slideshow )
|
||||
menu.AppendMenu( CC.ID_NULL, 'start slideshow', slideshow )
|
||||
if self._timer_slideshow.IsRunning(): menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'slideshow_pause_play' ), 'stop slideshow' )
|
||||
|
||||
self._menu_open = True
|
||||
|
@ -1838,6 +1887,7 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
if command == 'archive': self._Archive()
|
||||
elif command == 'copy_files':
|
||||
with wx.BusyCursor(): HC.app.Write( 'copy_files', ( self._current_media.GetHash(), ) )
|
||||
elif command == 'copy_hash': self._CopyHashToClipboard()
|
||||
elif command == 'copy_local_url': self._CopyLocalUrlToClipboard()
|
||||
elif command == 'copy_path': self._CopyPathToClipboard()
|
||||
elif command == 'delete': self._Delete()
|
||||
|
@ -1851,6 +1901,7 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
elif command == 'inbox': self._Inbox()
|
||||
elif command == 'manage_ratings': self._ManageRatings()
|
||||
elif command == 'manage_tags': self._ManageTags()
|
||||
elif command == 'remove': self._Remove()
|
||||
elif command == 'slideshow': self._StartSlideshow( data )
|
||||
elif command == 'slideshow_pause_play': self._PausePlaySlideshow()
|
||||
elif command == 'zoom_in': self._ZoomIn()
|
||||
|
@ -1914,19 +1965,35 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
menu.AppendSeparator()
|
||||
|
||||
manage_menu = wx.Menu()
|
||||
|
||||
manage_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'manage_tags' ), 'tags' )
|
||||
|
||||
if i_can_post_ratings: manage_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'manage_ratings' ), 'ratings' )
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, 'manage', manage_menu )
|
||||
|
||||
menu.AppendSeparator()
|
||||
|
||||
if self._current_media.HasInbox(): menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'archive' ), '&archive' )
|
||||
if self._current_media.HasArchive(): menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'inbox' ), 'return to &inbox' )
|
||||
menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'remove', HC.LOCAL_FILE_SERVICE_IDENTIFIER ), '&remove' )
|
||||
menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'delete', HC.LOCAL_FILE_SERVICE_IDENTIFIER ), '&delete' )
|
||||
|
||||
menu.AppendSeparator()
|
||||
|
||||
share_menu = wx.Menu()
|
||||
|
||||
copy_menu = wx.Menu()
|
||||
|
||||
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_files' ) , 'file' )
|
||||
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_hash' ) , 'hash' )
|
||||
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_path' ) , 'path' )
|
||||
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_local_url' ) , 'local url' )
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, 'copy', copy_menu )
|
||||
share_menu.AppendMenu( CC.ID_NULL, 'copy', copy_menu )
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, 'share', share_menu )
|
||||
|
||||
menu.AppendSeparator()
|
||||
|
||||
|
@ -2578,7 +2645,7 @@ class RatingsFilterFrameLike( CanvasFullscreenMediaListFilter ):
|
|||
CanvasFullscreenMediaListFilter.__init__( self, my_parent, page_key, HC.LOCAL_FILE_SERVICE_IDENTIFIER, [], media_results )
|
||||
|
||||
self._rating_service_identifier = service_identifier
|
||||
self._service = HC.app.Read( 'service', service_identifier )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
FullscreenPopoutFilterLike( self )
|
||||
|
||||
|
@ -2651,7 +2718,7 @@ class RatingsFilterFrameNumerical( ClientGUICommon.FrameThatResizes ):
|
|||
if service_identifier.GetType() == HC.LOCAL_RATING_LIKE: self._score_gap = 1.0
|
||||
else:
|
||||
|
||||
self._service = HC.app.Read( 'service', service_identifier )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
( self._lower, self._upper ) = self._service.GetLowerUpper()
|
||||
|
||||
|
|
|
@ -2607,6 +2607,8 @@ class PopupMessageGauge( PopupMessage ):
|
|||
|
||||
PopupMessage.__init__( self, parent, message )
|
||||
|
||||
self._job_key = self._message.GetJobKey()
|
||||
|
||||
self._done = False
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
@ -2620,11 +2622,16 @@ class PopupMessageGauge( PopupMessage ):
|
|||
self._gauge = Gauge( self, size = ( 380, -1 ) )
|
||||
self._gauge.Bind( wx.EVT_RIGHT_DOWN, self.EventDismiss )
|
||||
|
||||
self._pause_button = wx.Button( self, label = 'pause' )
|
||||
self._pause_button.Bind( wx.EVT_BUTTON, self.EventPauseButton )
|
||||
self._pause_button.Bind( wx.EVT_RIGHT_DOWN, self.EventDismiss )
|
||||
|
||||
self._cancel_button = wx.Button( self, label = 'cancel' )
|
||||
self._cancel_button.Bind( wx.EVT_BUTTON, self.EventCancelButton )
|
||||
self._cancel_button.Bind( wx.EVT_RIGHT_DOWN, self.EventDismiss )
|
||||
|
||||
hbox.AddF( self._gauge, FLAGS_EXPAND_BOTH_WAYS )
|
||||
hbox.AddF( self._pause_button, FLAGS_MIXED )
|
||||
hbox.AddF( self._cancel_button, FLAGS_MIXED )
|
||||
|
||||
self._show_file_button = wx.Button( self )
|
||||
|
@ -2637,6 +2644,8 @@ class PopupMessageGauge( PopupMessage ):
|
|||
|
||||
self.SetSizer( vbox )
|
||||
|
||||
self._created = HC.GetNow()
|
||||
|
||||
|
||||
def Dismiss( self ):
|
||||
|
||||
|
@ -2653,6 +2662,8 @@ class PopupMessageGauge( PopupMessage ):
|
|||
|
||||
|
||||
|
||||
if self._job_key.IsPaused(): self._job_key.Cancel()
|
||||
|
||||
PopupMessage.Dismiss( self )
|
||||
|
||||
|
||||
|
@ -2660,14 +2671,28 @@ class PopupMessageGauge( PopupMessage ):
|
|||
|
||||
if self._message.GetInfo( 'mode' ) == 'cancelable gauge':
|
||||
|
||||
job_key = self._message.GetInfo( 'job_key' )
|
||||
|
||||
job_key.Cancel()
|
||||
self._job_key.Cancel()
|
||||
|
||||
self._cancel_button.Disable()
|
||||
|
||||
|
||||
|
||||
def EventPauseButton( self, event ):
|
||||
|
||||
if self._job_key.IsPaused():
|
||||
|
||||
self._job_key.Resume()
|
||||
|
||||
self._pause_button.SetLabel( 'pause' )
|
||||
|
||||
else:
|
||||
|
||||
self._job_key.Pause()
|
||||
|
||||
self._pause_button.SetLabel( 'resume' )
|
||||
|
||||
|
||||
|
||||
def EventShowFileButton( self, event ):
|
||||
|
||||
hashes = self._message.GetInfo( 'hashes' )
|
||||
|
@ -2681,6 +2706,9 @@ class PopupMessageGauge( PopupMessage ):
|
|||
|
||||
mode = self._message.GetInfo( 'mode' )
|
||||
text = self._message.GetInfo( 'text' )
|
||||
|
||||
if self._job_key.IsPausable(): self._pause_button.Show()
|
||||
else: self._pause_button.Hide()
|
||||
|
||||
if mode == 'files':
|
||||
|
||||
|
@ -3667,7 +3695,7 @@ class AdvancedTagOptions( AdvancedOptions ):
|
|||
self._namespaces = namespaces
|
||||
self._initial_settings = initial_settings
|
||||
|
||||
self._service_identifiers_to_checkbox_info = {}
|
||||
self._service_keys_to_checkbox_info = {}
|
||||
|
||||
AdvancedOptions.__init__( self, parent, 'advanced tag options' )
|
||||
|
||||
|
@ -3678,21 +3706,23 @@ class AdvancedTagOptions( AdvancedOptions ):
|
|||
|
||||
self._vbox.Clear( True )
|
||||
|
||||
self._service_identifiers_to_checkbox_info = {}
|
||||
self._service_keys_to_checkbox_info = {}
|
||||
|
||||
service_identifiers = HC.app.Read( 'service_identifiers', ( HC.TAG_REPOSITORY, HC.LOCAL_TAG ) )
|
||||
services = HC.app.GetManager( 'services' ).GetServices( ( HC.TAG_REPOSITORY, HC.LOCAL_TAG ) )
|
||||
|
||||
if len( service_identifiers ) > 0:
|
||||
if len( services ) > 0:
|
||||
|
||||
outer_gridbox = wx.FlexGridSizer( 0, 2 )
|
||||
|
||||
outer_gridbox.AddGrowableCol( 1, 1 )
|
||||
|
||||
for service_identifier in service_identifiers:
|
||||
for service in services:
|
||||
|
||||
self._service_identifiers_to_checkbox_info[ service_identifier ] = []
|
||||
service_key = service.GetKey()
|
||||
|
||||
outer_gridbox.AddF( wx.StaticText( panel, label = service_identifier.GetName() ), FLAGS_MIXED )
|
||||
self._service_keys_to_checkbox_info[ service_key ] = []
|
||||
|
||||
outer_gridbox.AddF( wx.StaticText( panel, label = service.GetName() ), FLAGS_MIXED )
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
|
@ -3703,12 +3733,12 @@ class AdvancedTagOptions( AdvancedOptions ):
|
|||
|
||||
namespace_checkbox = wx.CheckBox( panel, label = label )
|
||||
|
||||
if service_identifier in self._initial_settings and namespace in self._initial_settings[ service_identifier ]: namespace_checkbox.SetValue( True )
|
||||
if service_key in self._initial_settings and namespace in self._initial_settings[ service_key ]: namespace_checkbox.SetValue( True )
|
||||
else: namespace_checkbox.SetValue( False )
|
||||
|
||||
namespace_checkbox.Bind( wx.EVT_CHECKBOX, self.EventChecked )
|
||||
|
||||
self._service_identifiers_to_checkbox_info[ service_identifier ].append( ( namespace, namespace_checkbox ) )
|
||||
self._service_keys_to_checkbox_info[ service_key ].append( ( namespace, namespace_checkbox ) )
|
||||
|
||||
vbox.AddF( namespace_checkbox, FLAGS_EXPAND_BOTH_WAYS )
|
||||
|
||||
|
@ -3746,11 +3776,11 @@ class AdvancedTagOptions( AdvancedOptions ):
|
|||
|
||||
result = {}
|
||||
|
||||
for ( service_identifier, checkbox_info ) in self._service_identifiers_to_checkbox_info.items():
|
||||
for ( service_key, checkbox_info ) in self._service_keys_to_checkbox_info.items():
|
||||
|
||||
namespaces = [ namespace for ( namespace, checkbox ) in checkbox_info if checkbox.GetValue() == True ]
|
||||
|
||||
result[ service_identifier ] = namespaces
|
||||
result[ service_key ] = namespaces
|
||||
|
||||
|
||||
return result
|
||||
|
@ -3767,13 +3797,13 @@ class AdvancedTagOptions( AdvancedOptions ):
|
|||
|
||||
def SetInfo( self, info ):
|
||||
|
||||
for ( service_identifier, checkbox_info ) in self._service_identifiers_to_checkbox_info.items():
|
||||
for ( service_key, checkbox_info ) in self._service_keys_to_checkbox_info.items():
|
||||
|
||||
if service_identifier in info:
|
||||
if service_key in info:
|
||||
|
||||
for ( namespace, checkbox ) in checkbox_info:
|
||||
|
||||
if namespace in info[ service_identifier ]: checkbox.SetValue( True )
|
||||
if namespace in info[ service_key ]: checkbox.SetValue( True )
|
||||
else: checkbox.SetValue( False )
|
||||
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ def SelectServiceIdentifier( permission = None, service_types = HC.ALL_SERVICES,
|
|||
|
||||
if service_identifiers is None:
|
||||
|
||||
services = HC.app.Read( 'services', service_types )
|
||||
services = HC.app.GetManager( 'services' ).GetServices( service_types )
|
||||
|
||||
if permission is not None: services = [ service for service in services if service.GetInfo( 'account' ).HasPermission( permission ) ]
|
||||
|
||||
|
@ -608,7 +608,7 @@ class DialogGenerateNewAccounts( Dialog ):
|
|||
|
||||
self._num.SetValue( 1 )
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
response = service.Request( HC.GET, 'account_types' )
|
||||
|
||||
|
@ -670,7 +670,7 @@ class DialogGenerateNewAccounts( Dialog ):
|
|||
|
||||
lifetime = self._lifetime.GetClientData( self._lifetime.GetSelection() )
|
||||
|
||||
service = HC.app.Read( 'service', self._service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( self._service_identifier.GetServiceKey() )
|
||||
|
||||
try:
|
||||
|
||||
|
@ -894,7 +894,7 @@ class DialogInputCustomFilterAction( Dialog ):
|
|||
|
||||
service_identifier = self._ratings_like_service_identifiers.GetClientData( selection )
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
self._current_ratings_like_service = service
|
||||
|
||||
|
@ -918,7 +918,7 @@ class DialogInputCustomFilterAction( Dialog ):
|
|||
|
||||
service_identifier = self._ratings_numerical_service_identifiers.GetClientData( selection )
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
self._current_ratings_numerical_service = service
|
||||
|
||||
|
@ -1535,8 +1535,8 @@ class DialogInputFileSystemPredicate( Dialog ):
|
|||
|
||||
def PopulateControls():
|
||||
|
||||
self._local_numericals = HC.app.Read( 'services', ( HC.LOCAL_RATING_NUMERICAL, ) )
|
||||
self._local_likes = HC.app.Read( 'services', ( HC.LOCAL_RATING_LIKE, ) )
|
||||
self._local_numericals = HC.app.GetManager( 'services' ).GetServices( ( HC.LOCAL_RATING_NUMERICAL, ) )
|
||||
self._local_likes = HC.app.GetManager( 'services' ).GetServices( ( HC.LOCAL_RATING_LIKE, ) )
|
||||
|
||||
for service in self._local_numericals: self._service_numerical.Append( service.GetServiceIdentifier().GetName(), service )
|
||||
|
||||
|
@ -2108,7 +2108,7 @@ class DialogInputLocalBooruShare( Dialog ):
|
|||
|
||||
def EventCopyExternalShareURL( self, event ):
|
||||
|
||||
self._service = HC.app.Read( 'service', HC.LOCAL_BOORU_SERVICE_IDENTIFIER )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( HC.LOCAL_BOORU_SERVICE_IDENTIFIER.GetServiceKey() )
|
||||
|
||||
info = self._service.GetInfo()
|
||||
|
||||
|
@ -2125,7 +2125,7 @@ class DialogInputLocalBooruShare( Dialog ):
|
|||
|
||||
def EventCopyInternalShareURL( self, event ):
|
||||
|
||||
self._service = HC.app.Read( 'service', HC.LOCAL_BOORU_SERVICE_IDENTIFIER )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( HC.LOCAL_BOORU_SERVICE_IDENTIFIER.GetServiceKey() )
|
||||
|
||||
info = self._service.GetInfo()
|
||||
|
||||
|
@ -3550,7 +3550,7 @@ class DialogModifyAccounts( Dialog ):
|
|||
|
||||
Dialog.__init__( self, parent, 'modify account' )
|
||||
|
||||
self._service = HC.app.Read( 'service', service_identifier )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
self._subject_identifiers = list( subject_identifiers )
|
||||
|
||||
InitialiseControls()
|
||||
|
@ -3766,9 +3766,9 @@ class DialogPageChooser( Dialog ):
|
|||
|
||||
ArrangeControls()
|
||||
|
||||
self._services = HC.app.Read( 'services' )
|
||||
self._services = HC.app.GetManager( 'services' ).GetServices()
|
||||
|
||||
self._petition_service_identifiers = [ service.GetServiceIdentifier() for service in self._services if service.GetServiceIdentifier().GetType() in HC.REPOSITORIES and service.GetInfo( 'account' ).HasPermission( HC.RESOLVE_PETITIONS ) ]
|
||||
self._petition_service_identifiers = [ service.GetServiceIdentifier() for service in self._services if service.GetType() in HC.REPOSITORIES and service.GetInfo( 'account' ).HasPermission( HC.RESOLVE_PETITIONS ) ]
|
||||
|
||||
self._InitButtons( 'home' )
|
||||
|
||||
|
@ -3975,7 +3975,7 @@ class DialogPathsToTagsRegex( Dialog ):
|
|||
|
||||
def PopulateControls():
|
||||
|
||||
services = HC.app.Read( 'services', ( HC.TAG_REPOSITORY, ) )
|
||||
services = HC.app.GetManager( 'services' ).GetServices( ( HC.TAG_REPOSITORY, ) )
|
||||
|
||||
for service in services:
|
||||
|
||||
|
@ -3999,7 +3999,9 @@ class DialogPathsToTagsRegex( Dialog ):
|
|||
|
||||
self._tag_repositories.AddPage( page, name )
|
||||
|
||||
default_tag_repository = HC.options[ 'default_tag_repository' ]
|
||||
default_tag_repository_key = HC.options[ 'default_tag_repository' ]
|
||||
|
||||
default_tag_repository = HC.app.GetManager( 'services' ).GetService( default_tag_repository_key )
|
||||
|
||||
self._tag_repositories.Select( default_tag_repository.GetName() )
|
||||
|
||||
|
@ -4890,6 +4892,8 @@ class DialogSelectYoutubeURL( Dialog ):
|
|||
|
||||
url_string = title + ' ' + resolution + ' ' + extension
|
||||
|
||||
job_key = HC.JobKey( pausable = False, cancellable = False )
|
||||
|
||||
message = HC.MessageGauge( HC.MESSAGE_TYPE_GAUGE, url_string )
|
||||
|
||||
HydrusThreading.CallToThread( HydrusDownloading.THREADDownloadURL, message, url, url_string )
|
||||
|
|
|
@ -209,7 +209,7 @@ class DialogManageAccountTypes( ClientGUIDialogs.Dialog ):
|
|||
|
||||
def PopulateControls():
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
response = service.Request( HC.GET, 'account_types' )
|
||||
|
||||
|
@ -383,7 +383,7 @@ class DialogManageAccountTypes( ClientGUIDialogs.Dialog ):
|
|||
|
||||
def EventOK( self, event ):
|
||||
|
||||
service = HC.app.Read( 'service', self._service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( self._service_identifier.GetServiceKey() )
|
||||
|
||||
service.Request( HC.POST, 'account_types', { 'edit_log' : self._edit_log } )
|
||||
|
||||
|
@ -2845,7 +2845,7 @@ class DialogManageOptions( ClientGUIDialogs.Dialog ):
|
|||
self._default_tag_sort.Append( 'incidence (desc)', CC.SORT_BY_INCIDENCE_DESC )
|
||||
self._default_tag_sort.Append( 'incidence (asc)', CC.SORT_BY_INCIDENCE_ASC )
|
||||
|
||||
self._default_tag_repository = wx.Choice( self._gui_page )
|
||||
self._default_tag_repository = ClientGUICommon.BetterChoice( self._gui_page )
|
||||
|
||||
self._fullscreen_borderless = wx.CheckBox( self._gui_page )
|
||||
|
||||
|
@ -3050,11 +3050,13 @@ class DialogManageOptions( ClientGUIDialogs.Dialog ):
|
|||
elif HC.options[ 'default_tag_sort' ] == CC.SORT_BY_INCIDENCE_DESC: self._default_tag_sort.Select( 2 )
|
||||
elif HC.options[ 'default_tag_sort' ] == CC.SORT_BY_INCIDENCE_ASC: self._default_tag_sort.Select( 3 )
|
||||
|
||||
service_identifiers = HC.app.Read( 'service_identifiers', ( HC.LOCAL_TAG, HC.TAG_REPOSITORY ) )
|
||||
services = HC.app.GetManager( 'services' ).GetServices( ( HC.LOCAL_TAG, HC.TAG_REPOSITORY ) )
|
||||
|
||||
for service_identifier in service_identifiers: self._default_tag_repository.Append( service_identifier.GetName(), service_identifier )
|
||||
for service in services: self._default_tag_repository.Append( service.GetName(), service.GetKey() )
|
||||
|
||||
self._default_tag_repository.SetStringSelection( HC.options[ 'default_tag_repository' ].GetName() )
|
||||
default_tag_repository_key = HC.options[ 'default_tag_repository' ]
|
||||
|
||||
self._default_tag_repository.SelectClientData( default_tag_repository_key )
|
||||
|
||||
self._fullscreen_borderless.SetValue( HC.options[ 'fullscreen_borderless' ] )
|
||||
|
||||
|
@ -3644,7 +3646,7 @@ class DialogManageOptions( ClientGUIDialogs.Dialog ):
|
|||
|
||||
HC.options[ 'shortcuts' ] = shortcuts
|
||||
|
||||
HC.options[ 'default_tag_repository' ] = self._default_tag_repository.GetClientData( self._default_tag_repository.GetSelection() )
|
||||
HC.options[ 'default_tag_repository' ] = self._default_tag_repository.GetChoice()
|
||||
HC.options[ 'default_tag_sort' ] = self._default_tag_sort.GetClientData( self._default_tag_sort.GetSelection() )
|
||||
|
||||
new_local_port = self._local_port.GetValue()
|
||||
|
@ -3948,7 +3950,7 @@ class DialogManageRatings( ClientGUIDialogs.Dialog ):
|
|||
wx.Panel.__init__( self, parent )
|
||||
|
||||
self._service_identifier = service_identifier
|
||||
self._service = HC.app.Read( 'service', service_identifier )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
self._media = media
|
||||
|
||||
|
@ -4290,7 +4292,7 @@ class DialogManageServer( ClientGUIDialogs.Dialog ):
|
|||
|
||||
self._service_identifier = service_identifier
|
||||
|
||||
self._service = HC.app.Read( 'service', self._service_identifier )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( self._service_identifier.GetServiceKey() )
|
||||
|
||||
InitialiseControls()
|
||||
|
||||
|
@ -4606,7 +4608,7 @@ class DialogManageServices( ClientGUIDialogs.Dialog ):
|
|||
parent_listbook.AddPage( listbook, name )
|
||||
|
||||
|
||||
services = HC.app.Read( 'services', manageable_service_types )
|
||||
services = HC.app.GetManager( 'services' ).GetServices( manageable_service_types )
|
||||
|
||||
for service in services:
|
||||
|
||||
|
@ -5960,9 +5962,11 @@ class DialogManageTagCensorship( ClientGUIDialogs.Dialog ):
|
|||
self._tag_services.AddPage( page, name )
|
||||
|
||||
|
||||
default_tag_repository = HC.options[ 'default_tag_repository' ]
|
||||
default_tag_repository_key = HC.options[ 'default_tag_repository' ]
|
||||
|
||||
self._tag_services.Select( default_tag_repository.GetName() )
|
||||
service = HC.app.GetManager( 'services' ).GetService( default_tag_repository_key )
|
||||
|
||||
self._tag_services.Select( service.GetName() )
|
||||
|
||||
|
||||
def ArrangeControls():
|
||||
|
@ -6130,7 +6134,7 @@ class DialogManageTagParents( ClientGUIDialogs.Dialog ):
|
|||
|
||||
def PopulateControls():
|
||||
|
||||
services = HC.app.Read( 'services', ( HC.TAG_REPOSITORY, ) )
|
||||
services = HC.app.GetManager( 'services' ).GetServices( ( HC.TAG_REPOSITORY, ) )
|
||||
|
||||
for service in services:
|
||||
|
||||
|
@ -6154,9 +6158,11 @@ class DialogManageTagParents( ClientGUIDialogs.Dialog ):
|
|||
|
||||
self._tag_repositories.AddPage( page, name )
|
||||
|
||||
default_tag_repository = HC.options[ 'default_tag_repository' ]
|
||||
default_tag_repository_key = HC.options[ 'default_tag_repository' ]
|
||||
|
||||
self._tag_repositories.Select( default_tag_repository.GetName() )
|
||||
service = HC.app.GetManager( 'services' ).GetService( default_tag_repository_key )
|
||||
|
||||
self._tag_repositories.Select( service.GetName() )
|
||||
|
||||
|
||||
def ArrangeControls():
|
||||
|
@ -6309,7 +6315,7 @@ class DialogManageTagParents( ClientGUIDialogs.Dialog ):
|
|||
|
||||
if self._service_identifier != HC.LOCAL_TAG_SERVICE_IDENTIFIER:
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
self._account = service.GetInfo( 'account' )
|
||||
|
||||
|
@ -6598,7 +6604,7 @@ class DialogManageTagSiblings( ClientGUIDialogs.Dialog ):
|
|||
|
||||
self._tag_repositories.AddPage( page, name )
|
||||
|
||||
services = HC.app.Read( 'services', ( HC.TAG_REPOSITORY, ) )
|
||||
services = HC.app.GetManager( 'services' ).GetServices( ( HC.TAG_REPOSITORY, ) )
|
||||
|
||||
for service in services:
|
||||
|
||||
|
@ -6616,9 +6622,11 @@ class DialogManageTagSiblings( ClientGUIDialogs.Dialog ):
|
|||
|
||||
|
||||
|
||||
default_tag_repository = HC.options[ 'default_tag_repository' ]
|
||||
default_tag_repository_key = HC.options[ 'default_tag_repository' ]
|
||||
|
||||
self._tag_repositories.Select( default_tag_repository.GetName() )
|
||||
service = HC.app.GetManager( 'services' ).GetService( default_tag_repository_key )
|
||||
|
||||
self._tag_repositories.Select( service.GetName() )
|
||||
|
||||
|
||||
def ArrangeControls():
|
||||
|
@ -6777,7 +6785,7 @@ class DialogManageTagSiblings( ClientGUIDialogs.Dialog ):
|
|||
|
||||
if self._service_identifier != HC.LOCAL_TAG_SERVICE_IDENTIFIER:
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
self._account = service.GetInfo( 'account' )
|
||||
|
||||
|
@ -7273,9 +7281,11 @@ class DialogManageTags( ClientGUIDialogs.Dialog ):
|
|||
self._tag_repositories.AddPage( page_info, name )
|
||||
|
||||
|
||||
default_tag_repository = HC.options[ 'default_tag_repository' ]
|
||||
default_tag_repository_key = HC.options[ 'default_tag_repository' ]
|
||||
|
||||
self._tag_repositories.Select( default_tag_repository.GetName() )
|
||||
service = HC.app.GetManager( 'services' ).GetService( default_tag_repository_key )
|
||||
|
||||
self._tag_repositories.Select( service.GetName() )
|
||||
|
||||
|
||||
def ArrangeControls():
|
||||
|
@ -7449,7 +7459,7 @@ class DialogManageTags( ClientGUIDialogs.Dialog ):
|
|||
|
||||
if not self._i_am_local_tag_service:
|
||||
|
||||
service = HC.app.Read( 'service', tag_service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( tag_service_identifier.GetServiceKey() )
|
||||
|
||||
self._account = service.GetInfo( 'account' )
|
||||
|
||||
|
|
|
@ -639,10 +639,15 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
advanced_tag_options = self._advanced_tag_options.GetInfo()
|
||||
|
||||
for ( service_identifier, namespaces ) in advanced_tag_options.items():
|
||||
for ( service_key, namespaces ) in advanced_tag_options.items():
|
||||
|
||||
tags_manager = media.GetTagsManager()
|
||||
|
||||
try: service = HC.app.GetManager( 'services' ).GetService( service_key )
|
||||
except: continue
|
||||
|
||||
service_identifier = service.GetKey()
|
||||
|
||||
current = tags_manager.GetCurrent( service_identifier )
|
||||
pending = tags_manager.GetPending( service_identifier )
|
||||
|
||||
|
@ -1820,7 +1825,7 @@ class ManagementPanelPetitions( ManagementPanel ):
|
|||
|
||||
ManagementPanel.__init__( self, parent, page, page_key, file_service_identifier, starting_from_session = starting_from_session )
|
||||
|
||||
self._service = HC.app.Read( 'service', self._petition_service_identifier )
|
||||
self._service = HC.app.GetManager( 'services' ).GetService( self._petition_service_identifier.GetServiceKey() )
|
||||
self._can_ban = self._service.GetInfo( 'account' ).HasPermission( HC.MANAGE_USERS )
|
||||
|
||||
self._num_petitions = None
|
||||
|
|
|
@ -91,6 +91,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
HC.pubsub.sub( self, 'Collect', 'collect_media' )
|
||||
HC.pubsub.sub( self, 'Sort', 'sort_media' )
|
||||
HC.pubsub.sub( self, 'FileDumped', 'file_dumped' )
|
||||
HC.pubsub.sub( self, 'RemoveMedia', 'remove_media' )
|
||||
|
||||
self._PublishSelectionChange()
|
||||
|
||||
|
@ -815,6 +816,16 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
|
||||
|
||||
def RemoveMedia( self, page_key, hashes ):
|
||||
|
||||
if page_key == self._page_key:
|
||||
|
||||
media = self._GetMedia( hashes )
|
||||
|
||||
self._RemoveMedia( media, {} )
|
||||
|
||||
|
||||
|
||||
def SetFocussedMedia( self, page_key, media ):
|
||||
|
||||
if page_key == self._page_key:
|
||||
|
@ -1678,13 +1689,13 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
multiple_selected = num_selected > 1
|
||||
|
||||
services = HC.app.Read( 'services' )
|
||||
services = HC.app.GetManager( 'services' ).GetServices()
|
||||
|
||||
tag_repositories = [ service for service in services if service.GetServiceIdentifier().GetType() == HC.TAG_REPOSITORY ]
|
||||
tag_repositories = [ service for service in services if service.GetType() == HC.TAG_REPOSITORY ]
|
||||
|
||||
file_repositories = [ service for service in services if service.GetServiceIdentifier().GetType() == HC.FILE_REPOSITORY ]
|
||||
file_repositories = [ service for service in services if service.GetType() == HC.FILE_REPOSITORY ]
|
||||
|
||||
local_ratings_services = [ service for service in services if service.GetServiceIdentifier().GetType() in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ) ]
|
||||
local_ratings_services = [ service for service in services if service.GetType() in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ) ]
|
||||
|
||||
i_can_post_ratings = len( local_ratings_services ) > 0
|
||||
|
||||
|
|
|
@ -626,7 +626,7 @@ class DestinationPanel( wx.Panel ):
|
|||
elif command == 'read': status = 'read'
|
||||
elif command == 'unread': status = 'sent'
|
||||
|
||||
my_message_depot = HC.app.Read( 'service', self._identity )
|
||||
my_message_depot = HC.app.GetManager( 'services' ).GetService( self._identity.GetServiceKey() )
|
||||
|
||||
connection = my_message_depot.GetConnection()
|
||||
|
||||
|
@ -1250,7 +1250,7 @@ class DraftPanel( wx.Panel ):
|
|||
|
||||
try:
|
||||
|
||||
my_message_depot = HC.app.Read( 'service', self._contact_from )
|
||||
my_message_depot = HC.app.GetManager( 'services' ).GetService( self._contact_from.GetServiceKey() )
|
||||
|
||||
connection = my_message_depot.GetConnection()
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ options = {}
|
|||
# Misc
|
||||
|
||||
NETWORK_VERSION = 13
|
||||
SOFTWARE_VERSION = 125
|
||||
SOFTWARE_VERSION = 126
|
||||
|
||||
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )
|
||||
|
||||
|
@ -1522,12 +1522,17 @@ class ClientServiceIdentifier( HydrusYAMLBase ):
|
|||
|
||||
def GetType( self ): return self._type
|
||||
|
||||
LOCAL_FILE_SERVICE_IDENTIFIER = ClientServiceIdentifier( 'local files', LOCAL_FILE, 'local files' )
|
||||
LOCAL_TAG_SERVICE_IDENTIFIER = ClientServiceIdentifier( 'local tags', LOCAL_TAG, 'local tags' )
|
||||
LOCAL_BOORU_SERVICE_IDENTIFIER = ClientServiceIdentifier( 'local booru', LOCAL_BOORU, 'local booru' )
|
||||
COMBINED_FILE_SERVICE_IDENTIFIER = ClientServiceIdentifier( 'all known files', COMBINED_FILE, 'all known files' )
|
||||
COMBINED_TAG_SERVICE_IDENTIFIER = ClientServiceIdentifier( 'all known tags', COMBINED_TAG, 'all known tags' )
|
||||
NULL_SERVICE_IDENTIFIER = ClientServiceIdentifier( '', NULL_SERVICE, 'no service' )
|
||||
LOCAL_FILE_SERVICE_KEY = 'local files'
|
||||
LOCAL_TAG_SERVICE_KEY = 'local tags'
|
||||
LOCAL_BOORU_SERVICE_KEY = 'local booru'
|
||||
COMBINED_FILE_SERVICE_KEY = 'all known files'
|
||||
COMBINED_TAG_SERVICE_KEY = 'all known tags'
|
||||
|
||||
LOCAL_FILE_SERVICE_IDENTIFIER = ClientServiceIdentifier( LOCAL_FILE_SERVICE_KEY, LOCAL_FILE, 'local files' )
|
||||
LOCAL_TAG_SERVICE_IDENTIFIER = ClientServiceIdentifier( LOCAL_TAG_SERVICE_KEY, LOCAL_TAG, 'local tags' )
|
||||
LOCAL_BOORU_SERVICE_IDENTIFIER = ClientServiceIdentifier( LOCAL_BOORU_SERVICE_KEY, LOCAL_BOORU, 'local booru' )
|
||||
COMBINED_FILE_SERVICE_IDENTIFIER = ClientServiceIdentifier( COMBINED_FILE_SERVICE_KEY, COMBINED_FILE, 'all known files' )
|
||||
COMBINED_TAG_SERVICE_IDENTIFIER = ClientServiceIdentifier( COMBINED_TAG_SERVICE_KEY, COMBINED_TAG, 'all known tags' )
|
||||
|
||||
class ClientToServerUpdate( HydrusYAMLBase ):
|
||||
|
||||
|
@ -1742,10 +1747,13 @@ class JobDatabase( object ):
|
|||
|
||||
class JobKey( object ):
|
||||
|
||||
def __init__( self ):
|
||||
def __init__( self, pausable = True, cancellable = True ):
|
||||
|
||||
self._key = os.urandom( 32 )
|
||||
|
||||
self._pausable = pausable
|
||||
self._cancellable = cancellable
|
||||
|
||||
self._begun = threading.Event()
|
||||
self._done = threading.Event()
|
||||
self._cancelled = threading.Event()
|
||||
|
@ -1770,6 +1778,11 @@ class JobKey( object ):
|
|||
self.Finish()
|
||||
|
||||
|
||||
def DeleteVariable( self, name ):
|
||||
|
||||
with self._variable_lock: del self._variables[ name ]
|
||||
|
||||
|
||||
def Finish( self ): self._done.set()
|
||||
|
||||
def GetKey( self ): return self._key
|
||||
|
@ -1786,10 +1799,14 @@ class JobKey( object ):
|
|||
|
||||
def IsBegun( self ): return self._begun.is_set()
|
||||
|
||||
def IsCancellable( self ): return self._cancellable
|
||||
|
||||
def IsCancelled( self ): return shutdown or self._cancelled.is_set()
|
||||
|
||||
def IsDone( self ): return shutdown or self._done.is_set()
|
||||
|
||||
def IsPausable( self ): return self._pausable
|
||||
|
||||
def IsPaused( self ): return self._paused.is_set()
|
||||
|
||||
def IsWorking( self ): return self.IsBegun() and not self.IsDone()
|
||||
|
@ -1804,6 +1821,10 @@ class JobKey( object ):
|
|||
|
||||
def Resume( self ): self._paused.clear()
|
||||
|
||||
def SetCancellable( self, value ): self._cancellable = value
|
||||
|
||||
def SetPausable( self, value ): self._pausable = value
|
||||
|
||||
def SetVariable( self, name, value ):
|
||||
|
||||
with self._variable_lock: self._variables[ name ] = value
|
||||
|
@ -1906,16 +1927,18 @@ class Message( object ):
|
|||
|
||||
class MessageGauge( Message ):
|
||||
|
||||
def __init__( self, message_type, text ):
|
||||
def __init__( self, message_type, text, job_key ):
|
||||
|
||||
info = {}
|
||||
Message.__init__( self, message_type, {} )
|
||||
|
||||
info[ 'mode' ] = 'text'
|
||||
info[ 'text' ] = text
|
||||
self._info[ 'mode' ] = 'text'
|
||||
self._info[ 'text' ] = text
|
||||
|
||||
Message.__init__( self, message_type, info )
|
||||
self._job_key = job_key
|
||||
|
||||
|
||||
def GetJobKey( self ): return self._job_key
|
||||
|
||||
class Predicate( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!Predicate'
|
||||
|
@ -2224,7 +2247,8 @@ class ServerServiceIdentifier( HydrusYAMLBase ):
|
|||
|
||||
def GetType( self ): return self._type
|
||||
|
||||
SERVER_ADMIN_IDENTIFIER = ServerServiceIdentifier( 'server admin', SERVER_ADMIN )
|
||||
SERVER_ADMIN_KEY = 'server admin'
|
||||
SERVER_ADMIN_IDENTIFIER = ServerServiceIdentifier( SERVER_ADMIN_KEY, SERVER_ADMIN )
|
||||
|
||||
class ServiceUpdate( object ):
|
||||
|
||||
|
|
|
@ -56,7 +56,10 @@ def ConvertTagsToServiceIdentifiersToTags( tags, advanced_tag_options ):
|
|||
siblings_manager = HC.app.GetManager( 'tag_siblings' )
|
||||
parents_manager = HC.app.GetManager( 'tag_parents' )
|
||||
|
||||
for ( service_identifier, namespaces ) in advanced_tag_options.items():
|
||||
for ( service_key, namespaces ) in advanced_tag_options.items():
|
||||
|
||||
try: service_identifier = HC.app.GetManager( 'services' ).GetService( service_key ).GetServiceIdentifier()
|
||||
except: continue
|
||||
|
||||
if len( namespaces ) > 0:
|
||||
|
||||
|
@ -1766,6 +1769,7 @@ def THREADDownloadURL( message, url, url_string ):
|
|||
message.SetInfo( 'range', None )
|
||||
message.SetInfo( 'value', None )
|
||||
message.SetInfo( 'mode', 'gauge' )
|
||||
|
||||
temp_path = HC.http.Request( HC.GET, url, response_to_path = True, report_hooks = [ hook ] )
|
||||
|
||||
message.SetInfo( 'range', None )
|
||||
|
|
|
@ -120,7 +120,7 @@ class HydrusSessionManagerClient( object ):
|
|||
|
||||
# session key expired or not found
|
||||
|
||||
service = HC.app.Read( 'service', service_identifier )
|
||||
service = HC.app.GetManager( 'services' ).GetService( service_identifier.GetServiceKey() )
|
||||
|
||||
( response, cookies ) = service.Request( HC.GET, 'session_key', return_cookies = True )
|
||||
|
||||
|
|
|
@ -2884,9 +2884,9 @@ def DAEMONUPnP():
|
|||
|
||||
service_identifiers = HC.app.ReadDaemon( 'service_identifiers' )
|
||||
|
||||
all_options = { service_identifier : HC.app.ReadDaemon( 'options', service_identifier ) for service_identifier in service_identifiers }
|
||||
all_infos = HC.app.ReadDaemon( 'services' )
|
||||
|
||||
for ( service_identifier, options ) in all_options.items():
|
||||
for ( service_identifier, options ) in all_infos:
|
||||
|
||||
internal_port = options[ 'port' ]
|
||||
upnp = options[ 'upnp' ]
|
||||
|
@ -2899,12 +2899,12 @@ def DAEMONUPnP():
|
|||
|
||||
|
||||
|
||||
for ( service_identifier, options ) in all_options.items():
|
||||
for ( service_identifier, options ) in all_infos:
|
||||
|
||||
internal_port = options[ 'port' ]
|
||||
upnp = options[ 'upnp' ]
|
||||
|
||||
if ( local_ip, internal_port ) not in our_mappings:
|
||||
if upnp is not None and ( local_ip, internal_port ) not in our_mappings:
|
||||
|
||||
external_port = upnp
|
||||
|
||||
|
|
|
@ -961,14 +961,6 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
#
|
||||
|
||||
result = self._read( 'service', HC.LOCAL_FILE_SERVICE_IDENTIFIER )
|
||||
|
||||
self.assertEqual( result.GetServiceIdentifier(), HC.LOCAL_FILE_SERVICE_IDENTIFIER )
|
||||
|
||||
result = self._read( 'service', HC.LOCAL_TAG_SERVICE_IDENTIFIER )
|
||||
|
||||
self.assertEqual( result.GetServiceIdentifier(), HC.LOCAL_TAG_SERVICE_IDENTIFIER )
|
||||
|
||||
result = self._read( 'services', ( HC.LOCAL_FILE, HC.LOCAL_TAG ) )
|
||||
|
||||
result_s_is = { service.GetServiceIdentifier() for service in result }
|
||||
|
@ -977,7 +969,7 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
#
|
||||
|
||||
result = self._read( 'service_info', HC.LOCAL_FILE_SERVICE_IDENTIFIER )
|
||||
result = self._read( 'service_info', HC.LOCAL_FILE_SERVICE_IDENTIFIER.GetServiceKey() )
|
||||
|
||||
self.assertEqual( type( result ), dict )
|
||||
|
||||
|
@ -1055,18 +1047,7 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
self._write( 'update_services', edit_log )
|
||||
|
||||
with self.assertRaises( HydrusExceptions.DBException ):
|
||||
|
||||
self._read( 'service', new_local_like )
|
||||
|
||||
|
||||
result = self._read( 'service', other_new_tag_repo )
|
||||
|
||||
host = other_new_tag_repo_info_updated[ 'host' ]
|
||||
port = other_new_tag_repo_info_updated[ 'port' ]
|
||||
access_key = other_new_tag_repo_info_updated[ 'access_key' ]
|
||||
|
||||
self.assertEqual( result.GetCredentials(), CC.Credentials( host, port, access_key ) )
|
||||
# update this ~sometime~ to test the new services manager object, which should update with these changes!
|
||||
|
||||
#
|
||||
|
||||
|
@ -1076,10 +1057,7 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
self._write( 'update_services', edit_log )
|
||||
|
||||
with self.assertRaises( HydrusExceptions.DBException ):
|
||||
|
||||
self._read( 'service', other_new_tag_repo )
|
||||
|
||||
# update this ~sometime~ to test the new services manager object, which should update with these changes!
|
||||
|
||||
#
|
||||
|
||||
|
|
|
@ -58,8 +58,8 @@ class TestHydrusDownloadingFunctions( unittest.TestCase ):
|
|||
|
||||
advanced_tag_options = {}
|
||||
|
||||
advanced_tag_options[ local ] = [ '', 'character' ]
|
||||
advanced_tag_options[ remote ] = [ '', 'character' ]
|
||||
advanced_tag_options[ local.GetServiceKey() ] = [ '', 'character' ]
|
||||
advanced_tag_options[ remote.GetServiceKey() ] = [ '', 'character' ]
|
||||
|
||||
tags = [ 'a', 'character:b', 'series:c' ]
|
||||
|
||||
|
|
7
test.py
|
@ -52,6 +52,11 @@ class App( wx.App ):
|
|||
self._reads[ 'messaging_sessions' ] = []
|
||||
self._reads[ 'tag_censorship' ] = []
|
||||
self._reads[ 'options' ] = CC.CLIENT_DEFAULT_OPTIONS
|
||||
|
||||
services = []
|
||||
services.append( CC.Service( HC.LOCAL_BOORU_SERVICE_KEY, HC.LOCAL_BOORU, 'local booru', {} ) )
|
||||
self._reads[ 'services' ] = services
|
||||
|
||||
self._reads[ 'sessions' ] = []
|
||||
self._reads[ 'tag_parents' ] = {}
|
||||
self._reads[ 'tag_service_precedence' ] = []
|
||||
|
@ -65,6 +70,8 @@ class App( wx.App ):
|
|||
|
||||
self._managers = {}
|
||||
|
||||
self._managers[ 'services' ] = CC.ServiceManager()
|
||||
|
||||
self._managers[ 'hydrus_sessions' ] = HydrusSessions.HydrusSessionManagerClient()
|
||||
self._managers[ 'tag_censorship' ] = HydrusTags.TagCensorshipManager()
|
||||
self._managers[ 'tag_siblings' ] = HydrusTags.TagSiblingsManager()
|
||||
|
|