Version 79
This commit is contained in:
parent
46cff89b35
commit
ee159f8675
|
@ -21,7 +21,7 @@ from include import ClientController
|
|||
initial_sys_stdout = sys.stdout
|
||||
initial_sys_stderr = sys.stderr
|
||||
|
||||
with open( HC.LOGS_DIR + os.path.sep + 'client.log', 'a' ) as f:
|
||||
with HC.o( HC.LOGS_DIR + os.path.sep + 'client.log', 'a' ) as f:
|
||||
|
||||
sys.stdout = f
|
||||
sys.stderr = f
|
||||
|
|
|
@ -8,6 +8,52 @@
|
|||
<div class="content">
|
||||
<h3>changelog</h3>
|
||||
<ul>
|
||||
<li><h3>version 79</h3></li>
|
||||
<ul>
|
||||
<li>popup messages will now report whenever a subscription or import folder successfully imports some files, with a button to show them in a new search</li>
|
||||
<li>popup messages now wrap</li>
|
||||
<li>slightly better error popup</li>
|
||||
<li>many more errors reported through error popup</li>
|
||||
<li>old logging system switched over to new messaging system</li>
|
||||
<li>popup message manager will only show ten messages at once, now</li>
|
||||
<li>selectfromlistofstrings now supports enter key to select</li>
|
||||
<li>completely reworked how dialog cancel works; absolutely all dialogs should now close with escape key</li>
|
||||
<li>reworked how a bunch of dialogs do ok</li>
|
||||
<li>a huge amount of dialog refactoring</li>
|
||||
<li>made ok button initial focus of all dialogs</li>
|
||||
<li>couple of bugs in service options dialog fixed</li>
|
||||
<li>rejiggered some button names and focus behaviour a bit more</li>
|
||||
<li>some classname refactoring</li>
|
||||
<li>muchly improved string->unicode handling</li>
|
||||
<li>improved timestamp generation</li>
|
||||
<li>fixed a clientserviceidentifier->text bug</li>
|
||||
<li>reworked how namespace cache in tagsmanager object is calculated</li>
|
||||
<li>improved instantiation of noneablespinctrls</li>
|
||||
<li>fixed a bug in the thumbnails download daemon</li>
|
||||
<li>changed the way daemons wait for the db, much to the better</li>
|
||||
<li>moved daemons out of the db object</li>
|
||||
<li>rejiggered writedaemon synchrony so exceptions work</li>
|
||||
<li>fiddled around with some help links</li>
|
||||
<li>default, non-maximised size of client is a little more comfortable</li>
|
||||
<li>custom filter now has a popup that'll let you change the custom actions mid-filter</li>
|
||||
<li>server now uses new synchronous logging system</li>
|
||||
<li>fixed an options save bug for server</li>
|
||||
<li>updated server diagram in help</li>
|
||||
<li>added test for dialog selectfromlistofstrings</li>
|
||||
<li>added test for dialogyesno</li>
|
||||
<li>made a framework for testing that requires network stuff</li>
|
||||
<li>made a newgrounds test</li>
|
||||
<li>fixed newgrounds swf parsing</li>
|
||||
<li>made a framework for testing that requires file reads and writes</li>
|
||||
<li>fixed a graceful-exception bug in mime parsing</li>
|
||||
<li>added test for synchronous import_folders</li>
|
||||
<li>added test for delete import_folders</li>
|
||||
<li>wrote a test for importfolders daemon</li>
|
||||
<li>import folders no longer delete or reattempt failed imports; they'll just ignore them</li>
|
||||
<li>import folders are deleted on update, since old objects are obselete</li>
|
||||
<li>import folders won't try to do zips any more; they'll just ignore them</li>
|
||||
<li>rejiggered how import folders does its path parsing to remove mime calc cpu usage</li>
|
||||
</ul>
|
||||
<li><h3>version 78</h3></li>
|
||||
<ul>
|
||||
<li>expanded parents testing with a namespace example</li>
|
||||
|
@ -15,7 +61,7 @@
|
|||
<li>refactored ManageDialogs to their own file</li>
|
||||
<li>refactored Exceptions to their own file</li>
|
||||
<li>improved my testing framework so it can do wx gui elements</li>
|
||||
<li>added test for dialogchoosenewservicemethod, fixed a tuypo</li>
|
||||
<li>added test for dialogchoosenewservicemethod, fixed a typo</li>
|
||||
<li>added test for dialogfinishfiltering</li>
|
||||
<li>added test for dialogfinishratingfiltering</li>
|
||||
<li>those two finish filter dialogs are a little simpler, now</li>
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 153 KiB |
|
@ -112,14 +112,6 @@ field_string_lookup[ FIELD_FILE ] = 'file'
|
|||
field_string_lookup[ FIELD_THREAD_ID ] = 'thread id'
|
||||
field_string_lookup[ FIELD_PASSWORD ] = 'password'
|
||||
|
||||
LOG_ERROR = 0
|
||||
LOG_MESSAGE = 1
|
||||
|
||||
log_string_lookup = {}
|
||||
|
||||
log_string_lookup[ LOG_ERROR ] = 'error'
|
||||
log_string_lookup[ LOG_MESSAGE ] = 'message'
|
||||
|
||||
RESTRICTION_MIN_RESOLUTION = 0
|
||||
RESTRICTION_MAX_RESOLUTION = 1
|
||||
RESTRICTION_MAX_FILE_SIZE = 2
|
||||
|
@ -245,7 +237,7 @@ def GenerateDumpMultipartFormDataCTAndBody( fields ):
|
|||
|
||||
for ( name, type, value ) in fields:
|
||||
|
||||
if type in ( FIELD_TEXT, FIELD_COMMENT, FIELD_PASSWORD, FIELD_VERIFICATION_RECAPTCHA, FIELD_THREAD_ID ): m.field( name, str( value ) )
|
||||
if type in ( FIELD_TEXT, FIELD_COMMENT, FIELD_PASSWORD, FIELD_VERIFICATION_RECAPTCHA, FIELD_THREAD_ID ): m.field( name, HC.u( value ) )
|
||||
elif type == FIELD_CHECKBOX:
|
||||
|
||||
if value:
|
||||
|
@ -269,7 +261,7 @@ def GenerateMultipartFormDataCTAndBodyFromDict( fields ):
|
|||
|
||||
m = multipart.Multipart()
|
||||
|
||||
for ( name, value ) in fields.items(): m.field( name, str( value ) )
|
||||
for ( name, value ) in fields.items(): m.field( name, HC.u( value ) )
|
||||
|
||||
return m.get()
|
||||
|
||||
|
@ -292,6 +284,79 @@ def GetAllFileHashes():
|
|||
|
||||
return file_hashes
|
||||
|
||||
def GetAllPaths( raw_paths, quiet = False ):
|
||||
|
||||
file_paths = []
|
||||
|
||||
title = 'Parsing files and subdirectories'
|
||||
|
||||
if not quiet: progress = wx.ProgressDialog( title, u'Preparing', 1000, HC.app.GetTopWindow(), style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE | wx.PD_CAN_ABORT | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME )
|
||||
|
||||
try:
|
||||
|
||||
paths_to_process = raw_paths
|
||||
|
||||
total_paths_to_process = len( paths_to_process )
|
||||
|
||||
num_processed = 0
|
||||
|
||||
while len( paths_to_process ) > 0:
|
||||
|
||||
next_paths_to_process = []
|
||||
|
||||
for path in paths_to_process:
|
||||
|
||||
if not quiet:
|
||||
|
||||
# would rather use progress.SetRange( total_paths_to_process ) here, but for some reason wx python doesn't support it!
|
||||
|
||||
permill = int( 1000 * ( float( num_processed ) / float( total_paths_to_process ) ) )
|
||||
|
||||
( should_continue, skip ) = progress.Update( permill, 'Done ' + HC.u( num_processed ) + '/' + HC.u( total_paths_to_process ) )
|
||||
|
||||
if not should_continue:
|
||||
|
||||
progress.Destroy()
|
||||
|
||||
return []
|
||||
|
||||
|
||||
|
||||
if os.path.isdir( path ):
|
||||
|
||||
subpaths = [ path + os.path.sep + filename for filename in dircache.listdir( path ) ]
|
||||
|
||||
total_paths_to_process += len( subpaths )
|
||||
|
||||
next_paths_to_process.extend( subpaths )
|
||||
|
||||
else: file_paths.append( path )
|
||||
|
||||
num_processed += 1
|
||||
|
||||
|
||||
paths_to_process = next_paths_to_process
|
||||
|
||||
|
||||
except:
|
||||
|
||||
message = 'While parsing files, encountered this error:' + os.linesep + traceback.format_exc()
|
||||
|
||||
if not quiet:
|
||||
|
||||
wx.MessageBox( message )
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, Exception( message ) ) )
|
||||
|
||||
|
||||
print( message )
|
||||
|
||||
|
||||
if not quiet: progress.Destroy()
|
||||
|
||||
gc.collect()
|
||||
|
||||
return file_paths
|
||||
|
||||
def GetAllThumbnailHashes():
|
||||
|
||||
thumbnail_hashes = set()
|
||||
|
@ -387,74 +452,9 @@ def IntersectTags( tags_managers, service_identifier = HC.COMBINED_TAG_SERVICE_I
|
|||
|
||||
return ( current, deleted, pending, petitioned )
|
||||
|
||||
def ParseImportablePaths( raw_paths, include_subdirs = True, quiet = False ):
|
||||
def ParseImportablePaths( raw_paths, quiet = False ):
|
||||
|
||||
file_paths = []
|
||||
|
||||
if include_subdirs: title = 'Parsing files and subdirectories'
|
||||
else: title = 'Parsing files'
|
||||
|
||||
if not quiet: progress = wx.ProgressDialog( title, u'Preparing', 1000, HC.app.GetTopWindow(), style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE | wx.PD_CAN_ABORT | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME )
|
||||
|
||||
try:
|
||||
|
||||
paths_to_process = raw_paths
|
||||
|
||||
total_paths_to_process = len( paths_to_process )
|
||||
|
||||
num_processed = 0
|
||||
|
||||
while len( paths_to_process ) > 0:
|
||||
|
||||
next_paths_to_process = []
|
||||
|
||||
for path in paths_to_process:
|
||||
|
||||
if not quiet:
|
||||
|
||||
# would rather use progress.SetRange( total_paths_to_process ) here, but for some reason wx python doesn't support it!
|
||||
|
||||
permill = int( 1000 * ( float( num_processed ) / float( total_paths_to_process ) ) )
|
||||
|
||||
( should_continue, skip ) = progress.Update( permill, 'Done ' + str( num_processed ) + '/' + str( total_paths_to_process ) )
|
||||
|
||||
if not should_continue:
|
||||
|
||||
progress.Destroy()
|
||||
|
||||
return []
|
||||
|
||||
|
||||
|
||||
if os.path.isdir( path ):
|
||||
|
||||
if include_subdirs:
|
||||
|
||||
subpaths = [ path + os.path.sep + filename for filename in dircache.listdir( path ) ]
|
||||
|
||||
total_paths_to_process += len( subpaths )
|
||||
|
||||
next_paths_to_process.extend( subpaths )
|
||||
|
||||
|
||||
else: file_paths.append( path )
|
||||
|
||||
num_processed += 1
|
||||
|
||||
|
||||
paths_to_process = next_paths_to_process
|
||||
|
||||
|
||||
except:
|
||||
|
||||
if not quiet: wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
print( traceback.format_exc() )
|
||||
|
||||
|
||||
if not quiet: progress.Destroy()
|
||||
|
||||
gc.collect()
|
||||
file_paths = GetAllPaths( raw_paths, quiet )
|
||||
|
||||
good_paths_info = []
|
||||
odd_paths = []
|
||||
|
@ -469,7 +469,7 @@ def ParseImportablePaths( raw_paths, include_subdirs = True, quiet = False ):
|
|||
|
||||
if not quiet:
|
||||
|
||||
( should_continue, skip ) = progress.Update( i, 'Done ' + str( i ) + '/' + str( num_file_paths ) )
|
||||
( should_continue, skip ) = progress.Update( i, 'Done ' + HC.u( i ) + '/' + HC.u( num_file_paths ) )
|
||||
|
||||
if not should_continue: break
|
||||
|
||||
|
@ -505,7 +505,7 @@ def ParseImportablePaths( raw_paths, include_subdirs = True, quiet = False ):
|
|||
|
||||
if os.path.exists( potential_key_path ):
|
||||
|
||||
with open( potential_key_path, 'rb' ) as f: key_text = f.read()
|
||||
with HC.o( potential_key_path, 'rb' ) as f: key_text = f.read()
|
||||
|
||||
( aes_key, iv ) = HydrusEncryption.AESTextToKey( key_text )
|
||||
|
||||
|
@ -514,7 +514,9 @@ def ParseImportablePaths( raw_paths, include_subdirs = True, quiet = False ):
|
|||
|
||||
message = 'Tried to read a key, but did not understand it.'
|
||||
|
||||
if not quiet: wx.MessageBox( message )
|
||||
if not quiet:
|
||||
wx.MessageBox( message )
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, Exception( message ) ) )
|
||||
|
||||
print( message )
|
||||
|
||||
|
@ -598,11 +600,17 @@ def ParseImportablePaths( raw_paths, include_subdirs = True, quiet = False ):
|
|||
else:
|
||||
|
||||
print( odd_path + ' could not be imported because of this error:' )
|
||||
print( unicode( e ) )
|
||||
print( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
if not quiet: wx.MessageBox( str( len( odd_paths ) ) + ' files could not be added. Their paths and exact errors have been written to the log.' )
|
||||
if not quiet:
|
||||
|
||||
message = HC.u( len( odd_paths ) ) + ' files could not be added. Their paths and exact errors have been written to the log.'
|
||||
|
||||
wx.MessageBox( message )
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, Exception( message ) ) )
|
||||
|
||||
|
||||
|
||||
return good_paths_info
|
||||
|
@ -936,7 +944,7 @@ class ConnectionToService():
|
|||
|
||||
( host, port ) = self._credentials.GetAddress()
|
||||
|
||||
self._connection = HC.AdvancedHTTPConnection( host = host, port = port, service_identifier = self._service_identifier, accept_cookies = True )
|
||||
self._connection = HC.get_connection( host = host, port = port, service_identifier = self._service_identifier, accept_cookies = True )
|
||||
|
||||
self._connection.connect()
|
||||
|
||||
|
@ -1023,7 +1031,7 @@ class ConnectionToService():
|
|||
request_args[ 'title' ] = request_args[ 'title' ].encode( 'hex' )
|
||||
|
||||
|
||||
if len( request_args ) > 0: request_string += '?' + '&'.join( [ key + '=' + str( value ) for ( key, value ) in request_args.items() ] )
|
||||
if len( request_args ) > 0: request_string += '?' + '&'.join( [ key + '=' + HC.u( value ) for ( key, value ) in request_args.items() ] )
|
||||
|
||||
body = None
|
||||
|
||||
|
@ -1044,7 +1052,7 @@ class ConnectionToService():
|
|||
try: response = self._connection.request( request_type_string, request_string, headers = headers, body = body )
|
||||
except HydrusExceptions.ForbiddenException as e:
|
||||
|
||||
if unicode( e ) == 'Session not found!':
|
||||
if HC.u( e ) == 'Session not found!':
|
||||
|
||||
HC.app.DeleteSessionKey( self._service_identifier )
|
||||
|
||||
|
@ -1095,7 +1103,7 @@ class ConnectionToService():
|
|||
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
|
||||
with open( dlg.GetPath(), 'wb' ) as f: f.write( body )
|
||||
with HC.o( dlg.GetPath(), 'wb' ) as f: f.write( body )
|
||||
|
||||
|
||||
|
||||
|
@ -1204,7 +1212,7 @@ class Credentials( HC.HydrusYAMLBase ):
|
|||
|
||||
def __ne__( self, other ): return self.__hash__() != other.__hash__()
|
||||
|
||||
def __repr__( self ): return 'Credentials: ' + str( ( self._host, self._port, self._access_key.encode( 'hex' ) ) )
|
||||
def __repr__( self ): return 'Credentials: ' + HC.u( ( self._host, self._port, self._access_key.encode( 'hex' ) ) )
|
||||
|
||||
def GetAccessKey( self ): return self._access_key
|
||||
|
||||
|
@ -1216,7 +1224,7 @@ class Credentials( HC.HydrusYAMLBase ):
|
|||
|
||||
if self._access_key is not None: connection_string += self._access_key.encode( 'hex' ) + '@'
|
||||
|
||||
connection_string += self._host + ':' + str( self._port )
|
||||
connection_string += self._host + ':' + HC.u( self._port )
|
||||
|
||||
return connection_string
|
||||
|
||||
|
@ -1544,7 +1552,7 @@ class FileSystemPredicates():
|
|||
|
||||
( operator, years, months, days, hours ) = info
|
||||
|
||||
timestamp = int( time.time() ) - ( ( ( ( ( ( ( years * 12 ) + months ) * 30 ) + days ) * 24 ) + hours ) * 3600 )
|
||||
timestamp = HC.GetNow() - ( ( ( ( ( ( ( years * 12 ) + months ) * 30 ) + days ) * 24 ) + hours ) * 3600 )
|
||||
|
||||
# this is backwards because we are talking about age, not timestamp
|
||||
|
||||
|
@ -1957,15 +1965,12 @@ class Log():
|
|||
|
||||
self._entries = []
|
||||
|
||||
HC.pubsub.sub( self, 'AddMessage', 'log_message' )
|
||||
HC.pubsub.sub( self, 'AddError', 'log_error' )
|
||||
HC.pubsub.sub( self, 'AddMessage', 'message' )
|
||||
|
||||
|
||||
def __iter__( self ): return self._entries.__iter__()
|
||||
|
||||
def AddError( self, source, message ): self._entries.append( ( LOG_ERROR, source, message, time.time() ) )
|
||||
|
||||
def AddMessage( self, source, message ): self._entries.append( ( LOG_MESSAGE, source, message, time.time() ) )
|
||||
def AddMessage( self, message ): self._entries.append( ( message, HC.GetNow() ) )
|
||||
|
||||
class MediaResult():
|
||||
|
||||
|
@ -2018,9 +2023,7 @@ class MediaResult():
|
|||
|
||||
service_type = service_identifier.GetType()
|
||||
|
||||
if service_type in ( HC.LOCAL_TAG, HC.TAG_REPOSITORY ):
|
||||
try: tags_manager.ProcessContentUpdate( service_identifier, content_update )
|
||||
except: print( traceback.format_exc() )
|
||||
if service_type in ( HC.LOCAL_TAG, HC.TAG_REPOSITORY ): tags_manager.ProcessContentUpdate( service_identifier, content_update )
|
||||
elif service_type in ( HC.FILE_REPOSITORY, HC.LOCAL_FILE ):
|
||||
|
||||
if service_type == HC.LOCAL_FILE:
|
||||
|
@ -2127,6 +2130,8 @@ class RenderedImageCache():
|
|||
|
||||
print( traceback.format_exc() )
|
||||
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, Exception( traceback.format_exc() ) ) )
|
||||
|
||||
raise
|
||||
|
||||
|
||||
|
@ -2215,7 +2220,7 @@ class ServiceRemote( Service ):
|
|||
|
||||
def GetRecentErrorPending( self ): return HC.ConvertTimestampToPrettyPending( self._last_error + 600 )
|
||||
|
||||
def HasRecentError( self ): return self._last_error + 600 > int( time.time() )
|
||||
def HasRecentError( self ): return self._last_error + 600 > HC.GetNow()
|
||||
|
||||
def SetCredentials( self, credentials ): self._credentials = credentials
|
||||
|
||||
|
@ -2229,7 +2234,7 @@ class ServiceRemote( Service ):
|
|||
|
||||
( action, row ) = service_update.ToTuple()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_ERROR: self._last_error = int( time.time() )
|
||||
if action == HC.SERVICE_UPDATE_ERROR: self._last_error = HC.GetNow()
|
||||
elif action == HC.SERVICE_UPDATE_RESET:
|
||||
|
||||
self._service_identifier = row
|
||||
|
@ -2266,8 +2271,8 @@ class ServiceRemoteRestricted( ServiceRemote ):
|
|||
|
||||
def HasRecentError( self ):
|
||||
|
||||
if self._account.HasPermission( HC.GENERAL_ADMIN ): return self._last_error + 600 > int( time.time() )
|
||||
else: return self._last_error + 3600 * 4 > int( time.time() )
|
||||
if self._account.HasPermission( HC.GENERAL_ADMIN ): return self._last_error + 600 > HC.GetNow()
|
||||
else: return self._last_error + 3600 * 4 > HC.GetNow()
|
||||
|
||||
|
||||
def IsInitialised( self ):
|
||||
|
@ -2340,7 +2345,7 @@ class ServiceRemoteRestrictedRepository( ServiceRemoteRestricted ):
|
|||
|
||||
|
||||
|
||||
def HasUpdateDue( self ): return self._next_begin + HC.UPDATE_DURATION + 1800 < int( time.time() )
|
||||
def HasUpdateDue( self ): return self._next_begin + HC.UPDATE_DURATION + 1800 < HC.GetNow()
|
||||
|
||||
def SetNextBegin( self, next_begin ):
|
||||
|
||||
|
@ -2444,7 +2449,7 @@ class ServiceRemoteRestrictedDepot( ServiceRemoteRestricted ):
|
|||
|
||||
|
||||
|
||||
def HasCheckDue( self ): return self._last_check + self._check_period + 5 < int( time.time() )
|
||||
def HasCheckDue( self ): return self._last_check + self._check_period + 5 < HC.GetNow()
|
||||
|
||||
def ProcessServiceUpdates( self, service_identifiers_to_service_updates ):
|
||||
|
||||
|
@ -2521,7 +2526,7 @@ class ThumbnailCache():
|
|||
|
||||
for name in names:
|
||||
|
||||
with open( HC.STATIC_DIR + os.path.sep + name + '.png', 'rb' ) as f: file = f.read()
|
||||
with HC.o( HC.STATIC_DIR + os.path.sep + name + '.png', 'rb' ) as f: file = f.read()
|
||||
|
||||
thumbnail = HydrusImageHandling.GenerateHydrusBitmapFromFile( HydrusImageHandling.GenerateThumbnailFileFromFile( file, self._options[ 'thumbnail_dimensions' ] ) )
|
||||
|
||||
|
@ -2816,7 +2821,7 @@ class WebSessionManagerClient():
|
|||
|
||||
def GetCookies( self, name ):
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
with self._lock:
|
||||
|
||||
|
@ -2832,7 +2837,7 @@ class WebSessionManagerClient():
|
|||
|
||||
if name == 'hentai foundry':
|
||||
|
||||
connection = HC.AdvancedHTTPConnection( url = 'http://www.hentai-foundry.com', accept_cookies = True )
|
||||
connection = HC.get_connection( url = 'http://www.hentai-foundry.com', accept_cookies = True )
|
||||
|
||||
# this establishes the php session cookie, the csrf cookie, and tells hf that we are 18 years of age
|
||||
connection.request( 'GET', '/?enterAgree=1' )
|
||||
|
@ -2850,7 +2855,7 @@ class WebSessionManagerClient():
|
|||
raise Exception( 'You need to set up your pixiv credentials in services->manage pixiv account.' )
|
||||
|
||||
|
||||
connection = HC.AdvancedHTTPConnection( url = 'http://www.pixiv.net', accept_cookies = True )
|
||||
connection = HC.get_connection( url = 'http://www.pixiv.net', accept_cookies = True )
|
||||
|
||||
form_fields = {}
|
||||
|
||||
|
|
|
@ -454,7 +454,7 @@ class MessageSystemPredicates():
|
|||
days = int( days )
|
||||
|
||||
|
||||
timestamp = int( time.time() ) - ( ( ( ( ( years * 12 ) + months ) * 30 ) + days ) * 86400 )
|
||||
timestamp = HC.GetNow() - ( ( ( ( ( years * 12 ) + months ) * 30 ) + days ) * 86400 )
|
||||
|
||||
# this is backwards because we are talking about age, not timestamp
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class Controller( wx.App ):
|
|||
else: return self._db.Read( action, HC.HIGH_PRIORITY, *args, **kwargs )
|
||||
|
||||
|
||||
def _Write( self, action, priority, *args, **kwargs ): self._db.Write( action, priority, *args, **kwargs )
|
||||
def _Write( self, action, priority, synchronous, *args, **kwargs ): return self._db.Write( action, priority, synchronous, *args, **kwargs )
|
||||
|
||||
def ClearCaches( self ):
|
||||
|
||||
|
@ -93,12 +93,12 @@ class Controller( wx.App ):
|
|||
|
||||
def EventMaintenanceTimer( self, event ):
|
||||
|
||||
if int( time.time() ) - self._last_idle_time > 60 * 60: # a long time, so we probably just woke up from a sleep
|
||||
if HC.GetNow() - self._last_idle_time > 60 * 60: # a long time, so we probably just woke up from a sleep
|
||||
|
||||
self._last_idle_time = int( time.time() )
|
||||
self._last_idle_time = HC.GetNow()
|
||||
|
||||
|
||||
if int( time.time() ) - self._last_idle_time > 20 * 60: # 20 mins since last user-initiated db request
|
||||
if HC.GetNow() - self._last_idle_time > 20 * 60: # 20 mins since last user-initiated db request
|
||||
|
||||
self.MaintainDB()
|
||||
|
||||
|
@ -115,8 +115,10 @@ class Controller( wx.App ):
|
|||
except TypeError: pass
|
||||
except Exception as e:
|
||||
|
||||
print( type( e ) )
|
||||
print( traceback.format_exc() )
|
||||
message = type( e ).__name__ + os.linesep + traceback.format_exc()
|
||||
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, Exception( message ) ) )
|
||||
print( message )
|
||||
|
||||
|
||||
pubsubs_queue.task_done()
|
||||
|
@ -147,7 +149,7 @@ class Controller( wx.App ):
|
|||
|
||||
gc.collect()
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
shutdown_timestamps = self.Read( 'shutdown_timestamps' )
|
||||
|
||||
|
@ -185,7 +187,7 @@ class Controller( wx.App ):
|
|||
|
||||
except HydrusExceptions.DBAccessException as e:
|
||||
|
||||
print( unicode( e ) )
|
||||
print( HC.u( e ) )
|
||||
|
||||
message = 'This instance of the client had a problem connecting to the database, which probably means an old instance is still closing.'
|
||||
message += os.linesep + os.linesep
|
||||
|
@ -247,10 +249,8 @@ class Controller( wx.App ):
|
|||
self._maintenance_event_timer.Start( 20 * 60000, wx.TIMER_CONTINUOUS )
|
||||
|
||||
except sqlite3.OperationalError as e:
|
||||
print( traceback.format_exc() )
|
||||
message = 'Database error!'
|
||||
message += os.linesep + os.linesep
|
||||
message += unicode( e )
|
||||
|
||||
message = 'Database error!' + os.linesep + os.linesep + traceback.format_exc()
|
||||
|
||||
print message
|
||||
|
||||
|
@ -284,12 +284,19 @@ class Controller( wx.App ):
|
|||
|
||||
def Read( self, action, *args, **kwargs ):
|
||||
|
||||
self._last_idle_time = int( time.time() )
|
||||
self._last_idle_time = HC.GetNow()
|
||||
|
||||
return self._Read( action, *args, **kwargs )
|
||||
|
||||
|
||||
def ReadDaemon( self, action, *args, **kwargs ): return self._Read( action, *args, **kwargs )
|
||||
def ReadDaemon( self, action, *args, **kwargs ):
|
||||
|
||||
result = self._Read( action, *args, **kwargs )
|
||||
|
||||
time.sleep( 0.1 )
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def SetSplashText( self, text ):
|
||||
|
||||
|
@ -311,14 +318,21 @@ class Controller( wx.App ):
|
|||
|
||||
def Write( self, action, *args, **kwargs ):
|
||||
|
||||
self._last_idle_time = int( time.time() )
|
||||
self._last_idle_time = HC.GetNow()
|
||||
|
||||
if False and action == 'content_updates': self._undo_manager.AddCommand( 'content_updates', *args, **kwargs )
|
||||
|
||||
self._Write( action, HC.HIGH_PRIORITY, *args, **kwargs )
|
||||
return self._Write( action, HC.HIGH_PRIORITY, False, *args, **kwargs )
|
||||
|
||||
|
||||
def WriteDaemon( self, action, *args, **kwargs ): self._Write( action, HC.LOW_PRIORITY, *args, **kwargs )
|
||||
def WriteDaemon( self, action, *args, **kwargs ):
|
||||
|
||||
result = self._Write( action, HC.LOW_PRIORITY, True, *args, **kwargs )
|
||||
|
||||
time.sleep( 0.1 )
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def WriteLowPriority( self, action, *args, **kwargs ): self._Write( action, HC.LOW_PRIORITY, *args, **kwargs )
|
||||
def WriteLowPriority( self, action, *args, **kwargs ): return self._Write( action, HC.LOW_PRIORITY, False, *args, **kwargs )
|
||||
|
2086
include/ClientDB.py
2086
include/ClientDB.py
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -574,7 +574,14 @@ class CanvasFullscreenMediaList( ClientGUIMixins.ListeningMediaList, Canvas, Cli
|
|||
|
||||
siblings_manager = HC.app.GetTagSiblingsManager()
|
||||
|
||||
( creators, series, titles, volumes, chapters, pages ) = self._current_media.GetDisplayMedia().GetTagsManager().GetCSTVCP()
|
||||
namespaces = self._current_media.GetDisplayMedia().GetTagsManager().GetCombinedNamespaces( ( 'creator', 'series', 'title', 'volume', 'chapter', 'page' ) )
|
||||
|
||||
creators = namespaces[ 'creator' ]
|
||||
series = namespaces[ 'series' ]
|
||||
titles = namespaces[ 'title' ]
|
||||
volumes = namespaces[ 'volume' ]
|
||||
chapters = namespaces[ 'chapter' ]
|
||||
pages = namespaces[ 'page' ]
|
||||
|
||||
if len( creators ) > 0:
|
||||
|
||||
|
@ -612,9 +619,9 @@ class CanvasFullscreenMediaList( ClientGUIMixins.ListeningMediaList, Canvas, Cli
|
|||
|
||||
( volume, ) = volumes
|
||||
|
||||
collections_string_append = 'volume ' + str( volume )
|
||||
collections_string_append = 'volume ' + HC.u( volume )
|
||||
|
||||
else: collections_string_append = 'volumes ' + str( min( volumes ) ) + '-' + str( max( volumes ) )
|
||||
else: collections_string_append = 'volumes ' + HC.u( min( volumes ) ) + '-' + HC.u( max( volumes ) )
|
||||
|
||||
if len( collections_string ) > 0: collections_string += ' - ' + collections_string_append
|
||||
else: collections_string = collections_string_append
|
||||
|
@ -626,9 +633,9 @@ class CanvasFullscreenMediaList( ClientGUIMixins.ListeningMediaList, Canvas, Cli
|
|||
|
||||
( chapter, ) = chapters
|
||||
|
||||
collections_string_append = 'chapter ' + str( chapter )
|
||||
collections_string_append = 'chapter ' + HC.u( chapter )
|
||||
|
||||
else: collections_string_append = 'chapters ' + str( min( chapters ) ) + '-' + str( max( chapters ) )
|
||||
else: collections_string_append = 'chapters ' + HC.u( min( chapters ) ) + '-' + HC.u( max( chapters ) )
|
||||
|
||||
if len( collections_string ) > 0: collections_string += ' - ' + collections_string_append
|
||||
else: collections_string = collections_string_append
|
||||
|
@ -640,9 +647,9 @@ class CanvasFullscreenMediaList( ClientGUIMixins.ListeningMediaList, Canvas, Cli
|
|||
|
||||
( page, ) = pages
|
||||
|
||||
collections_string_append = 'page ' + str( page )
|
||||
collections_string_append = 'page ' + HC.u( page )
|
||||
|
||||
else: collections_string_append = 'pages ' + str( min( pages ) ) + '-' + str( max( pages ) )
|
||||
else: collections_string_append = 'pages ' + HC.u( min( pages ) ) + '-' + HC.u( max( pages ) )
|
||||
|
||||
if len( collections_string ) > 0: collections_string += ' - ' + collections_string_append
|
||||
else: collections_string = collections_string_append
|
||||
|
@ -1141,8 +1148,9 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
print( unicode( e ) )
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
print( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
|
@ -1274,6 +1282,8 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
self.SetMedia( self._GetFirst() )
|
||||
|
||||
FullscreenPopoutFilterCustom( self )
|
||||
|
||||
HC.pubsub.sub( self, 'AddMediaResult', 'add_media_result' )
|
||||
|
||||
|
||||
|
@ -1317,6 +1327,14 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
def _Inbox( self ): HC.app.Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, ( self._current_media.GetHash(), ) ) ] } )
|
||||
|
||||
def EventActions( self, event ):
|
||||
|
||||
with ClientGUIDialogs.DialogSetupCustomFilterActions( self ) as dlg:
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK: self._actions = dlg.GetActions()
|
||||
|
||||
|
||||
|
||||
def EventKeyDown( self, event ):
|
||||
|
||||
if self._ShouldSkipInputDueToFlash(): event.Skip()
|
||||
|
@ -1471,8 +1489,9 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
print( unicode( e ) )
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
print( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
|
@ -1659,8 +1678,9 @@ class CanvasFullscreenMediaListFilter( CanvasFullscreenMediaList ):
|
|||
self._kept = set()
|
||||
self._deleted = set()
|
||||
|
||||
except:
|
||||
except Exception as e:
|
||||
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
print( traceback.format_exc() )
|
||||
|
||||
|
@ -1762,8 +1782,9 @@ class CanvasFullscreenMediaListFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
print( unicode( e ) )
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
print( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
|
@ -1941,6 +1962,30 @@ class FullscreenPopout( wx.Frame ):
|
|||
event.Skip()
|
||||
|
||||
|
||||
class FullscreenPopoutFilterCustom( FullscreenPopout ):
|
||||
|
||||
def _InitialisePopoutWindow( self, sizer ):
|
||||
|
||||
window = wx.Window( self )
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
parent = self.GetParent()
|
||||
|
||||
actions = wx.Button( window, label = 'actions' )
|
||||
actions.Bind( wx.EVT_BUTTON, parent.EventActions )
|
||||
|
||||
done = wx.Button( window, label = 'done' )
|
||||
done.Bind( wx.EVT_BUTTON, parent.EventClose )
|
||||
|
||||
vbox.AddF( actions, FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( done, FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
window.SetSizer( vbox )
|
||||
|
||||
return window
|
||||
|
||||
|
||||
class FullscreenPopoutFilterInbox( FullscreenPopout ):
|
||||
|
||||
def _InitialisePopoutWindow( self, sizer ):
|
||||
|
@ -2213,8 +2258,9 @@ class RatingsFilterFrameLike( CanvasFullscreenMediaListFilter ):
|
|||
self._kept = set()
|
||||
self._deleted = set()
|
||||
|
||||
except:
|
||||
except Exception as e:
|
||||
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
print( traceback.format_exc() )
|
||||
|
||||
|
@ -2399,7 +2445,7 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
else: against_string += ' - like'
|
||||
|
||||
|
||||
center_string = str( len( self._media_to_initial_scores_dict ) ) + ' files being rated. after ' + str( len( self._decision_log ) ) + ' decisions, ' + str( len( certain_ratings ) ) + ' are certain'
|
||||
center_string = HC.u( len( self._media_to_initial_scores_dict ) ) + ' files being rated. after ' + HC.u( len( self._decision_log ) ) + ' decisions, ' + HC.u( len( certain_ratings ) ) + ' are certain'
|
||||
|
||||
elif service_type == HC.LOCAL_RATING_NUMERICAL:
|
||||
|
||||
|
@ -2433,7 +2479,7 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
against_string += ' - ' + HC.ConvertNumericalRatingToPrettyString( self._lower, self._upper, rating )
|
||||
|
||||
|
||||
center_string = str( len( self._media_to_initial_scores_dict ) ) + ' files being rated. after ' + str( len( self._decision_log ) ) + ' decisions, ' + str( len( certain_ratings ) ) + ' are certain and ' + str( len( uncertain_ratings ) ) + ' are uncertain'
|
||||
center_string = HC.u( len( self._media_to_initial_scores_dict ) ) + ' files being rated. after ' + HC.u( len( self._decision_log ) ) + ' decisions, ' + HC.u( len( certain_ratings ) ) + ' are certain and ' + HC.u( len( uncertain_ratings ) ) + ' are uncertain'
|
||||
|
||||
|
||||
if self._unrated_is_on_the_left:
|
||||
|
@ -2810,8 +2856,9 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
|
||||
HC.app.Write( 'content_updates', { self._service_identifier : content_updates } )
|
||||
|
||||
except:
|
||||
except Exception as e:
|
||||
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
print( traceback.format_exc() )
|
||||
|
||||
|
@ -2852,8 +2899,9 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
print( unicode( e ) )
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
print( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
|
@ -3193,8 +3241,9 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
print( unicode( e ) )
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
print( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ class AnimatedStaticTextTimestamp( wx.StaticText ):
|
|||
self._timestamp = timestamp
|
||||
self._suffix = suffix
|
||||
|
||||
self._last_tick = int( time.time() )
|
||||
self._last_tick = HC.GetNow()
|
||||
|
||||
wx.StaticText.__init__( self, parent, label = self._prefix + self._rendering_function( self._timestamp ) + self._suffix )
|
||||
|
||||
|
@ -61,7 +61,7 @@ class AnimatedStaticTextTimestamp( wx.StaticText ):
|
|||
|
||||
update = False
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
difference = abs( now - self._timestamp )
|
||||
|
||||
|
@ -471,7 +471,7 @@ class AutoCompleteDropdownTags( AutoCompleteDropdown ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
|
||||
|
@ -1281,7 +1281,7 @@ class ListBook( wx.Panel ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
|
||||
|
@ -1658,7 +1658,7 @@ class ListBox( wx.ScrolledWindow ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
|
||||
|
@ -1853,7 +1853,7 @@ class ListBoxMessagesPredicates( ListBoxMessages ):
|
|||
|
||||
class NoneableSpinCtrl( wx.Panel ):
|
||||
|
||||
def __init__( self, parent, message, value, none_phrase = 'no limit', max = 1000000, multiplier = 1, num_dimensions = 1 ):
|
||||
def __init__( self, parent, message, none_phrase = 'no limit', max = 1000000, multiplier = 1, num_dimensions = 1 ):
|
||||
|
||||
wx.Panel.__init__( self, parent )
|
||||
|
||||
|
@ -1863,36 +1863,12 @@ class NoneableSpinCtrl( wx.Panel ):
|
|||
self._checkbox = wx.CheckBox( self, label = none_phrase )
|
||||
self._checkbox.Bind( wx.EVT_CHECKBOX, self.EventCheckBox )
|
||||
|
||||
if value is None:
|
||||
|
||||
self._one = wx.SpinCtrl( self, initial = 0, max = max, size = ( 80, -1 ) )
|
||||
self._one.Disable()
|
||||
|
||||
if num_dimensions == 2:
|
||||
|
||||
self._two = wx.SpinCtrl( self, initial = 0, max = max, size = ( 80, -1 ) )
|
||||
self._two.Disable()
|
||||
|
||||
|
||||
self._checkbox.SetValue( True )
|
||||
|
||||
else:
|
||||
|
||||
if num_dimensions == 2:
|
||||
|
||||
( value, value_2 ) = value
|
||||
|
||||
self._two = wx.SpinCtrl( self, max = max, size = ( 80, -1 ) )
|
||||
self._two.SetValue( value_2 / multiplier )
|
||||
|
||||
|
||||
self._one = wx.SpinCtrl( self, max = max, size = ( 80, -1 ) )
|
||||
self._one.SetValue( value / multiplier )
|
||||
|
||||
self._checkbox.SetValue( False )
|
||||
|
||||
self._one = wx.SpinCtrl( self, max = max, size = ( 80, -1 ) )
|
||||
|
||||
if num_dimensions == 2: self._two = wx.SpinCtrl( self, initial = 0, max = max, size = ( 80, -1 ) )
|
||||
|
||||
hbox = wx.BoxSizer( wx.HORIZONTAL )
|
||||
|
||||
hbox.AddF( wx.StaticText( self, label=message + ': ' ), FLAGS_MIXED )
|
||||
hbox.AddF( self._one, FLAGS_MIXED )
|
||||
|
||||
|
@ -1944,16 +1920,17 @@ class NoneableSpinCtrl( wx.Panel ):
|
|||
|
||||
self._checkbox.SetValue( False )
|
||||
|
||||
self._one.Enable()
|
||||
if self._num_dimensions == 2: self._two.Enable()
|
||||
|
||||
if self._num_dimensions == 2:
|
||||
|
||||
self._two.Enable()
|
||||
|
||||
( value, y ) = value
|
||||
|
||||
self._two.SetValue( y / self._multiplier )
|
||||
|
||||
|
||||
self._one.Enable()
|
||||
|
||||
self._one.SetValue( value / self._multiplier )
|
||||
|
||||
|
||||
|
@ -2026,16 +2003,17 @@ class PopupMessage( wx.Window ):
|
|||
|
||||
class PopupMessageError( PopupMessage ):
|
||||
|
||||
def __init__( self, parent, message_string ):
|
||||
def __init__( self, parent, exception ):
|
||||
|
||||
PopupMessage.__init__( self, parent )
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
error = wx.StaticText( self, label = 'error', style = wx.ALIGN_CENTER )
|
||||
error = wx.StaticText( self, label = type( exception ).__name__, style = wx.ALIGN_CENTER )
|
||||
error.Bind( wx.EVT_RIGHT_DOWN, self.EventDismiss )
|
||||
|
||||
text = wx.StaticText( self, label = message_string ) # make this multi-line. There's an easy way to do that, right? A func that takes a pixel width, I think
|
||||
text = wx.StaticText( self, label = HC.u( exception ) )
|
||||
text.Wrap( 380 )
|
||||
text.Bind( wx.EVT_RIGHT_DOWN, self.EventDismiss )
|
||||
|
||||
vbox.AddF( error, FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
@ -2054,7 +2032,8 @@ class PopupMessageFiles( PopupMessage ):
|
|||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
text = wx.StaticText( self, label = message_string ) # make this multi-line. There's an easy way to do that, right? A func that takes a pixel width, I think
|
||||
text = wx.StaticText( self, label = message_string )
|
||||
text.Wrap( 380 )
|
||||
text.Bind( wx.EVT_RIGHT_DOWN, self.EventDismiss )
|
||||
|
||||
button = wx.Button( self, label = 'show files in new page' )
|
||||
|
@ -2086,6 +2065,7 @@ class PopupMessageText( PopupMessage ):
|
|||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
text = wx.StaticText( self, label = message_string ) # make this multi-line. There's an easy way to do that, right? A func that takes a pixel width, I think
|
||||
text.Wrap( 380 )
|
||||
text.Bind( wx.EVT_RIGHT_DOWN, self.EventDismiss )
|
||||
|
||||
vbox.AddF( text, FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
@ -2101,10 +2081,13 @@ class PopupMessageManager( wx.Frame ):
|
|||
|
||||
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
|
||||
|
||||
self._max_messages_to_display = 10
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
self.SetSizer( vbox )
|
||||
|
||||
self._pending_messages = []
|
||||
self._message_windows = []
|
||||
|
||||
top_level_parent.Bind( wx.EVT_SIZE, self.EventMove )
|
||||
|
@ -2115,7 +2098,23 @@ class PopupMessageManager( wx.Frame ):
|
|||
HC.pubsub.sub( self, 'AddMessage', 'message' )
|
||||
# maybe make a ding noise when a new message arrives
|
||||
|
||||
# on right mouse click, dismiss relevant message and refit
|
||||
|
||||
def _CheckPending( self ):
|
||||
|
||||
if len( self._pending_messages ) > 0 and len( self._message_windows ) < self._max_messages_to_display:
|
||||
|
||||
message = self._pending_messages.pop( 0 )
|
||||
|
||||
window = self._CreateMessageWindow( message )
|
||||
|
||||
self._message_windows.append( window )
|
||||
|
||||
vbox = self.GetSizer()
|
||||
|
||||
vbox.AddF( window, FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
self._SizeAndPositionAndShow()
|
||||
|
||||
|
||||
|
||||
def _CreateMessageWindow( self, message ):
|
||||
|
@ -2135,11 +2134,11 @@ class PopupMessageManager( wx.Frame ):
|
|||
|
||||
exception = info
|
||||
|
||||
message_string = str( exception )
|
||||
message_string = HC.u( exception )
|
||||
|
||||
print( 'error: ' + message_string )
|
||||
|
||||
window = PopupMessageError( self, message_string )
|
||||
window = PopupMessageError( self, exception )
|
||||
|
||||
elif message_type == HC.MESSAGE_TYPE_FILES:
|
||||
|
||||
|
@ -2172,15 +2171,9 @@ class PopupMessageManager( wx.Frame ):
|
|||
|
||||
def AddMessage( self, message ):
|
||||
|
||||
window = self._CreateMessageWindow( message )
|
||||
self._pending_messages.append( message )
|
||||
|
||||
self._message_windows.append( window )
|
||||
|
||||
vbox = self.GetSizer()
|
||||
|
||||
vbox.AddF( window, FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
self._SizeAndPositionAndShow()
|
||||
self._CheckPending()
|
||||
|
||||
|
||||
def Dismiss( self, window ):
|
||||
|
@ -2195,6 +2188,8 @@ class PopupMessageManager( wx.Frame ):
|
|||
|
||||
self._SizeAndPositionAndShow()
|
||||
|
||||
self._CheckPending()
|
||||
|
||||
|
||||
def EventMove( self, event ):
|
||||
|
||||
|
@ -2766,9 +2761,11 @@ class AdvancedImportOptions( AdvancedOptions ):
|
|||
|
||||
self._exclude_deleted = wx.CheckBox( panel )
|
||||
|
||||
self._min_size = NoneableSpinCtrl( panel, 'minimum size (KB): ', 5120, multiplier = 1024 )
|
||||
self._min_size = NoneableSpinCtrl( panel, 'minimum size (KB): ', multiplier = 1024 )
|
||||
self._min_size.SetValue( 5120 )
|
||||
|
||||
self._min_resolution = NoneableSpinCtrl( panel, 'minimum resolution: ', ( 50, 50 ), num_dimensions = 2 )
|
||||
self._min_resolution = NoneableSpinCtrl( panel, 'minimum resolution: ', num_dimensions = 2 )
|
||||
self._min_resolution.SetValue( ( 50, 50 ) )
|
||||
|
||||
hbox1 = wx.BoxSizer( wx.HORIZONTAL )
|
||||
|
||||
|
@ -3073,7 +3070,7 @@ class TagsBox( ListBox ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -222,7 +222,7 @@ class CaptchaControl( wx.Panel ):
|
|||
|
||||
def EnableWithValues( self, challenge, bitmap, captcha_runs_out, entry, ready ):
|
||||
|
||||
if int( time.time() ) > captcha_runs_out: self.Enable()
|
||||
if HC.GetNow() > captcha_runs_out: self.Enable()
|
||||
else:
|
||||
|
||||
self._captcha_challenge = challenge
|
||||
|
@ -249,7 +249,7 @@ class CaptchaControl( wx.Panel ):
|
|||
|
||||
try:
|
||||
|
||||
connection = HC.AdvancedHTTPConnection( scheme = 'http', host = 'www.google.com', port = 80 )
|
||||
connection = HC.get_connection( scheme = 'http', host = 'www.google.com', port = 80 )
|
||||
|
||||
javascript_string = connection.request( 'GET', '/recaptcha/api/challenge?k=' + self._captcha_key )
|
||||
|
||||
|
@ -261,7 +261,7 @@ class CaptchaControl( wx.Panel ):
|
|||
|
||||
self._bitmap = HydrusImageHandling.GenerateHydrusBitmapFromFile( jpeg )
|
||||
|
||||
self._captcha_runs_out = int( time.time() ) + 5 * 60 - 15
|
||||
self._captcha_runs_out = HC.GetNow() + 5 * 60 - 15
|
||||
|
||||
self._DrawMain()
|
||||
self._DrawEntry( '' )
|
||||
|
@ -277,7 +277,7 @@ class CaptchaControl( wx.Panel ):
|
|||
|
||||
def EventTimer( self, event ):
|
||||
|
||||
if int( time.time() ) > self._captcha_runs_out: self.Enable()
|
||||
if HC.GetNow() > self._captcha_runs_out: self.Enable()
|
||||
else: self._DrawMain()
|
||||
|
||||
|
||||
|
@ -402,7 +402,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
( self._4chan_token, pin, timeout ) = HC.app.Read( '4chan_pass' )
|
||||
|
||||
self._have_4chan_pass = timeout > int( time.time() )
|
||||
self._have_4chan_pass = timeout > HC.GetNow()
|
||||
|
||||
self._imageboard = imageboard
|
||||
|
||||
|
@ -584,13 +584,13 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
try:
|
||||
|
||||
connection = HC.AdvancedHTTPConnection( scheme = self._post_scheme, host = self._post_host, port = self._post_port )
|
||||
connection = HC.get_connection( scheme = self._post_scheme, host = self._post_host, port = self._post_port )
|
||||
|
||||
data = connection.request( 'POST', self._post_request, headers = headers, body = body )
|
||||
|
||||
( status, phrase ) = ClientParsers.Parse4chanPostScreen( data )
|
||||
|
||||
except Exception as e: ( status, phrase ) = ( 'big error', unicode( e ) )
|
||||
except Exception as e: ( status, phrase ) = ( 'big error', HC.u( e ) )
|
||||
|
||||
wx.CallAfter( self.CALLBACKDoneDump, media_to_dump, post_field_info, status, phrase )
|
||||
|
||||
|
@ -622,11 +622,11 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
total_size = sum( [ m.GetSize() for m in self._media_list.GetSortedMedia() ] )
|
||||
|
||||
initial = 'Hydrus Network Client is starting a dump of ' + str( num_files ) + ' files, totalling ' + HC.ConvertIntToBytes( total_size ) + ':' + os.linesep + os.linesep
|
||||
initial = 'Hydrus Network Client is starting a dump of ' + HC.u( num_files ) + ' files, totalling ' + HC.ConvertIntToBytes( total_size ) + ':' + os.linesep + os.linesep
|
||||
|
||||
else: initial = ''
|
||||
|
||||
initial += str( index + 1 ) + '/' + str( num_files )
|
||||
initial += HC.u( index + 1 ) + '/' + HC.u( num_files )
|
||||
|
||||
advanced_tag_options = self._advanced_tag_options.GetInfo()
|
||||
|
||||
|
@ -674,7 +674,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
index = self._media_list.GetMediaIndex( self._current_media )
|
||||
|
||||
self._post_info.SetLabel( str( index + 1 ) + '/' + str( num_files ) + ': ' + dump_status_string )
|
||||
self._post_info.SetLabel( HC.u( index + 1 ) + '/' + HC.u( num_files ) + ': ' + dump_status_string )
|
||||
|
||||
for ( name, type, value ) in post_field_info:
|
||||
|
||||
|
@ -763,7 +763,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
if self._current_media == media_to_dump: HC.pubsub.pub( 'set_focus', self._page_key, None )
|
||||
|
||||
self._next_dump_time = int( time.time() ) + self._flood_time
|
||||
self._next_dump_time = HC.GetNow() + self._flood_time
|
||||
|
||||
self._num_dumped += 1
|
||||
|
||||
|
@ -776,7 +776,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
dump_status_enum = CC.DUMPER_RECOVERABLE_ERROR
|
||||
dump_status_string = 'captcha was incorrect'
|
||||
|
||||
self._next_dump_time = int( time.time() ) + 10
|
||||
self._next_dump_time = HC.GetNow() + 10
|
||||
|
||||
new_post_field_info = []
|
||||
|
||||
|
@ -802,7 +802,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
self._progress_info.SetLabel( 'Flood limit hit, retrying.' )
|
||||
|
||||
self._next_dump_time = int( time.time() ) + self._flood_time
|
||||
self._next_dump_time = HC.GetNow() + self._flood_time
|
||||
|
||||
elif status == 'big error':
|
||||
|
||||
|
@ -833,7 +833,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
if self._current_media == media_to_dump: HC.pubsub.pub( 'set_focus', self._page_key, None )
|
||||
|
||||
self._next_dump_time = int( time.time() ) + self._flood_time
|
||||
self._next_dump_time = HC.GetNow() + self._flood_time
|
||||
|
||||
self._next_dump_index += 1
|
||||
|
||||
|
@ -846,7 +846,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
if self._next_dump_index == len( self._media_list.GetSortedMedia() ):
|
||||
|
||||
self._progress_info.SetLabel( 'done - ' + str( self._num_dumped ) + ' dumped' )
|
||||
self._progress_info.SetLabel( 'done - ' + HC.u( self._num_dumped ) + ' dumped' )
|
||||
|
||||
self._start_button.Disable()
|
||||
|
||||
|
@ -882,7 +882,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
|
@ -910,7 +910,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
self._dumping = True
|
||||
self._start_button.SetLabel( 'pause' )
|
||||
|
||||
if self._next_dump_time == 0: self._next_dump_time = int( time.time() ) + 5
|
||||
if self._next_dump_time == 0: self._next_dump_time = HC.GetNow() + 5
|
||||
|
||||
# disable thread fields here
|
||||
|
||||
|
@ -931,7 +931,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
if self._dumping:
|
||||
|
||||
time_left = self._next_dump_time - int( time.time() )
|
||||
time_left = self._next_dump_time - HC.GetNow()
|
||||
|
||||
if time_left < 1:
|
||||
|
||||
|
@ -957,7 +957,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
( challenge, bitmap, captcha_runs_out, entry, ready ) = value
|
||||
|
||||
if int( time.time() ) > captcha_runs_out or not ready:
|
||||
if HC.GetNow() > captcha_runs_out or not ready:
|
||||
|
||||
wait = True
|
||||
|
||||
|
@ -1018,12 +1018,12 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
threading.Thread( target = self._THREADDoDump, args = ( media_to_dump, post_field_info, headers, body ) ).start()
|
||||
|
||||
|
||||
else: self._progress_info.SetLabel( 'dumping next file in ' + str( time_left ) + ' seconds' )
|
||||
else: self._progress_info.SetLabel( 'dumping next file in ' + HC.u( time_left ) + ' seconds' )
|
||||
|
||||
else:
|
||||
|
||||
if self._num_dumped == 0: self._progress_info.SetLabel( 'will dump to ' + self._imageboard.GetName() )
|
||||
else: self._progress_info.SetLabel( 'paused after ' + str( self._num_dumped ) + ' files dumped' )
|
||||
else: self._progress_info.SetLabel( 'paused after ' + HC.u( self._num_dumped ) + ' files dumped' )
|
||||
|
||||
|
||||
|
||||
|
@ -1135,7 +1135,7 @@ class ManagementPanelImport( ManagementPanel ):
|
|||
|
||||
def _GetPreimportStatus( self ):
|
||||
|
||||
status = 'importing ' + str( self._import_queue_position + 1 ) + '/' + str( len( self._import_queue ) )
|
||||
status = 'importing ' + HC.u( self._import_queue_position + 1 ) + '/' + HC.u( len( self._import_queue ) )
|
||||
|
||||
return status
|
||||
|
||||
|
@ -1146,10 +1146,10 @@ class ManagementPanelImport( ManagementPanel ):
|
|||
|
||||
strs = []
|
||||
|
||||
if self._successful > 0: strs.append( str( self._successful ) + ' successful' )
|
||||
if self._failed > 0: strs.append( str( self._failed ) + ' failed' )
|
||||
if self._deleted > 0: strs.append( str( self._deleted ) + ' already deleted' )
|
||||
if self._redundant > 0: strs.append( str( self._redundant ) + ' already in db' )
|
||||
if self._successful > 0: strs.append( HC.u( self._successful ) + ' successful' )
|
||||
if self._failed > 0: strs.append( HC.u( self._failed ) + ' failed' )
|
||||
if self._deleted > 0: strs.append( HC.u( self._deleted ) + ' already deleted' )
|
||||
if self._redundant > 0: strs.append( HC.u( self._redundant ) + ' already in db' )
|
||||
|
||||
return strs
|
||||
|
||||
|
@ -1189,7 +1189,7 @@ class ManagementPanelImport( ManagementPanel ):
|
|||
else:
|
||||
|
||||
self._currently_importing = False
|
||||
self._import_current_info.SetLabel( unicode( exception ) )
|
||||
self._import_current_info.SetLabel( HC.u( exception ) )
|
||||
self._import_gauge.SetValue( self._import_queue_position + 1 )
|
||||
self._import_queue_position += 1
|
||||
|
||||
|
@ -1292,9 +1292,13 @@ class ManagementPanelImport( ManagementPanel ):
|
|||
if exception is None: self._timer_process_import_queue.Start( 10, wx.TIMER_ONE_SHOT )
|
||||
else:
|
||||
|
||||
print( os.linesep + 'Had trouble importing ' + str( self._import_queue[ self._import_queue_position - 1 ] ) + ':' + os.linesep + unicode( exception ) )
|
||||
message = os.linesep + 'Had trouble importing ' + HC.u( self._import_queue[ self._import_queue_position - 1 ] ) + ':' + os.linesep + HC.u( exception )
|
||||
|
||||
self._import_current_info.SetLabel( unicode( exception ) )
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, Exception( message ) ) )
|
||||
|
||||
print( message )
|
||||
|
||||
self._import_current_info.SetLabel( HC.u( exception ) )
|
||||
|
||||
self._timer_process_import_queue.Start( 2000, wx.TIMER_ONE_SHOT )
|
||||
|
||||
|
@ -1357,7 +1361,7 @@ class ManagementPanelImportHDD( ManagementPanelImport ):
|
|||
|
||||
path = path_info
|
||||
|
||||
with open( path, 'rb' ) as f: file = f.read()
|
||||
with HC.o( path, 'rb' ) as f: file = f.read()
|
||||
|
||||
elif path_type == 'zip':
|
||||
|
||||
|
@ -1374,13 +1378,14 @@ class ManagementPanelImportHDD( ManagementPanelImport ):
|
|||
wx.CallAfter( self.CALLBACKImportArgs, file, self._advanced_import_options, service_identifiers_to_tags )
|
||||
|
||||
except Exception as e:
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
print( traceback.format_exc() )
|
||||
wx.CallAfter( self.CALLBACKImportArgs, '', {}, {}, exception = e )
|
||||
|
||||
|
||||
def _GetPreprocessStatus( self ):
|
||||
|
||||
status = 'reading ' + str( self._import_queue_position + 1 ) + '/' + str( len( self._import_queue ) )
|
||||
status = 'reading ' + HC.u( self._import_queue_position + 1 ) + '/' + HC.u( len( self._import_queue ) )
|
||||
|
||||
return status
|
||||
|
||||
|
@ -1448,7 +1453,7 @@ class ManagementPanelImportWithQueue( ManagementPanelImport ):
|
|||
|
||||
def _GetPreprocessStatus( self ):
|
||||
|
||||
status = 'checking url status ' + str( self._import_queue_position + 1 ) + '/' + str( len( self._import_queue ) )
|
||||
status = 'checking url status ' + HC.u( self._import_queue_position + 1 ) + '/' + HC.u( len( self._import_queue ) )
|
||||
|
||||
return status
|
||||
|
||||
|
@ -1709,7 +1714,7 @@ class ManagementPanelImportWithQueueAdvanced( ManagementPanelImportWithQueue ):
|
|||
|
||||
else:
|
||||
|
||||
HC.pubsub.pub( 'set_import_info', self._page_key, 'downloading ' + str( self._import_queue_position + 1 ) + '/' + str( len( self._import_queue ) ) )
|
||||
HC.pubsub.pub( 'set_import_info', self._page_key, 'downloading ' + HC.u( self._import_queue_position + 1 ) + '/' + HC.u( len( self._import_queue ) ) )
|
||||
|
||||
if do_tags: ( file, tags ) = downloader.GetFileAndTags( *url_args )
|
||||
else:
|
||||
|
@ -1727,6 +1732,7 @@ class ManagementPanelImportWithQueueAdvanced( ManagementPanelImportWithQueue ):
|
|||
|
||||
|
||||
except Exception as e:
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
print( traceback.format_exc() )
|
||||
wx.CallAfter( self.CALLBACKImportArgs, self._page_key, '', {}, {}, exception = e )
|
||||
|
||||
|
@ -1752,7 +1758,7 @@ class ManagementPanelImportWithQueueAdvanced( ManagementPanelImportWithQueue ):
|
|||
|
||||
for downloader in downloaders:
|
||||
|
||||
HC.pubsub.pub( 'set_outer_queue_info', self._page_key, 'found ' + str( total_urls_found ) + ' urls' )
|
||||
HC.pubsub.pub( 'set_outer_queue_info', self._page_key, 'found ' + HC.u( total_urls_found ) + ' urls' )
|
||||
|
||||
while self._pause_outer_queue: time.sleep( 1 )
|
||||
|
||||
|
@ -1779,8 +1785,9 @@ class ManagementPanelImportWithQueueAdvanced( ManagementPanelImportWithQueue ):
|
|||
|
||||
except HydrusExceptions.NotFoundException: pass
|
||||
except Exception as e:
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
print( traceback.format_exc() )
|
||||
HC.pubsub.pub( 'set_outer_queue_info', self._page_key, unicode( e ) )
|
||||
HC.pubsub.pub( 'set_outer_queue_info', self._page_key, HC.u( e ) )
|
||||
|
||||
HC.pubsub.pub( 'done_adding_to_import_queue', self._page_key )
|
||||
|
||||
|
@ -2036,13 +2043,13 @@ class ManagementPanelImportWithQueueURL( ManagementPanelImportWithQueue ):
|
|||
|
||||
else:
|
||||
|
||||
HC.pubsub.pub( 'set_import_info', self._page_key, 'downloading ' + str( self._import_queue_position + 1 ) + '/' + str( len( self._import_queue ) ) )
|
||||
HC.pubsub.pub( 'set_import_info', self._page_key, 'downloading ' + HC.u( self._import_queue_position + 1 ) + '/' + HC.u( len( self._import_queue ) ) )
|
||||
|
||||
parse_result = urlparse.urlparse( url )
|
||||
|
||||
( scheme, host, port ) = ( parse_result.scheme, parse_result.hostname, parse_result.port )
|
||||
|
||||
if ( scheme, host, port ) not in self._connections: self._connections[ ( scheme, host, port ) ] = HC.AdvancedHTTPConnection( scheme = scheme, host = host, port = port )
|
||||
if ( scheme, host, port ) not in self._connections: self._connections[ ( scheme, host, port ) ] = HC.get_connection( scheme = scheme, host = host, port = port )
|
||||
|
||||
connection = self._connections[ ( scheme, host, port ) ]
|
||||
|
||||
|
@ -2056,6 +2063,7 @@ class ManagementPanelImportWithQueueURL( ManagementPanelImportWithQueue ):
|
|||
|
||||
|
||||
except Exception as e:
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
print( traceback.format_exc() )
|
||||
wx.CallAfter( self.CALLBACKImportArgs, '', {}, {}, exception = e )
|
||||
|
||||
|
@ -2076,7 +2084,7 @@ class ManagementPanelImportWithQueueURL( ManagementPanelImportWithQueue ):
|
|||
|
||||
HC.pubsub.pub( 'set_outer_queue_info', self._page_key, 'Connecting to address' )
|
||||
|
||||
try: connection = HC.AdvancedHTTPConnection( scheme = scheme, host = host, port = port )
|
||||
try: connection = HC.get_connection( scheme = scheme, host = host, port = port )
|
||||
except: raise Exception( 'Could not connect to server' )
|
||||
|
||||
try: html = connection.geturl( url )
|
||||
|
@ -2089,7 +2097,7 @@ class ManagementPanelImportWithQueueURL( ManagementPanelImportWithQueue ):
|
|||
|
||||
wx.CallAfter( self.CALLBACKAddToImportQueue, urls )
|
||||
|
||||
except Exception as e: HC.pubsub.pub( 'set_outer_queue_info', self._page_key, unicode( e ) )
|
||||
except Exception as e: HC.pubsub.pub( 'set_outer_queue_info', self._page_key, HC.u( e ) )
|
||||
|
||||
HC.pubsub.pub( 'done_adding_to_import_queue', self._page_key )
|
||||
|
||||
|
@ -2174,7 +2182,7 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
|
|||
|
||||
try:
|
||||
|
||||
connection = HC.AdvancedHTTPConnection( url = url )
|
||||
connection = HC.get_connection( url = url )
|
||||
|
||||
raw_json = connection.geturl( url )
|
||||
|
||||
|
@ -2182,7 +2190,7 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
|
|||
|
||||
posts_list = json_dict[ 'posts' ]
|
||||
|
||||
image_infos = [ ( post[ 'md5' ].decode( 'base64' ), str( post[ 'tim' ] ), post[ 'ext' ], post[ 'filename' ] ) for post in posts_list if 'md5' in post ]
|
||||
image_infos = [ ( post[ 'md5' ].decode( 'base64' ), HC.u( post[ 'tim' ] ), post[ 'ext' ], post[ 'filename' ] ) for post in posts_list if 'md5' in post ]
|
||||
|
||||
image_infos_i_can_add = [ image_info for image_info in image_infos if image_info not in self._image_infos_already_added ]
|
||||
|
||||
|
@ -2200,14 +2208,14 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
HC.pubsub.pub( 'set_thread_info', self._page_key, unicode( e ) )
|
||||
HC.pubsub.pub( 'set_thread_info', self._page_key, HC.u( e ) )
|
||||
|
||||
wx.CallAfter( self._thread_pause_button.Disable )
|
||||
|
||||
return
|
||||
|
||||
|
||||
self._last_thread_check = int( time.time() )
|
||||
self._last_thread_check = HC.GetNow()
|
||||
|
||||
self._currently_checking_thread = False
|
||||
|
||||
|
@ -2248,13 +2256,13 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
|
|||
|
||||
else:
|
||||
|
||||
HC.pubsub.pub( 'set_import_info', self._page_key, 'downloading ' + str( self._import_queue_position + 1 ) + '/' + str( len( self._import_queue ) ) )
|
||||
HC.pubsub.pub( 'set_import_info', self._page_key, 'downloading ' + HC.u( self._import_queue_position + 1 ) + '/' + HC.u( len( self._import_queue ) ) )
|
||||
|
||||
parse_result = urlparse.urlparse( url )
|
||||
|
||||
( scheme, host, port ) = ( parse_result.scheme, parse_result.hostname, parse_result.port )
|
||||
|
||||
if ( scheme, host, port ) not in self._connections: self._connections[ ( scheme, host, port ) ] = HC.AdvancedHTTPConnection( scheme = scheme, host = host, port = port )
|
||||
if ( scheme, host, port ) not in self._connections: self._connections[ ( scheme, host, port ) ] = HC.get_connection( scheme = scheme, host = host, port = port )
|
||||
|
||||
connection = self._connections[ ( scheme, host, port ) ]
|
||||
|
||||
|
@ -2273,13 +2281,14 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
|
|||
|
||||
|
||||
except Exception as e:
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, e ) )
|
||||
print( traceback.format_exc() )
|
||||
wx.CallAfter( self.CALLBACKImportArgs, '', {}, {}, exception = e )
|
||||
|
||||
|
||||
def _GetPreprocessStatus( self ):
|
||||
|
||||
status = 'checking url/hash status ' + str( self._import_queue_position + 1 ) + '/' + str( len( self._import_queue ) )
|
||||
status = 'checking url/hash status ' + HC.u( self._import_queue_position + 1 ) + '/' + HC.u( len( self._import_queue ) )
|
||||
|
||||
return status
|
||||
|
||||
|
@ -2313,7 +2322,7 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
self._thread_info.SetLabel( unicode( e ) )
|
||||
self._thread_info.SetLabel( HC.u( e ) )
|
||||
|
||||
return
|
||||
|
||||
|
@ -2341,7 +2350,7 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
|
|||
|
||||
next_thread_check = self._last_thread_check + thread_time
|
||||
|
||||
if next_thread_check < int( time.time() ):
|
||||
if next_thread_check < HC.GetNow():
|
||||
|
||||
self._currently_checking_thread = True
|
||||
|
||||
|
@ -2572,7 +2581,7 @@ class ManagementPanelPetitions( ManagementPanel ):
|
|||
|
||||
if self._num_petitions > 0: self.EventGetPetition( event )
|
||||
|
||||
except Exception as e: self._num_petitions_text.SetLabel( unicode( e ) )
|
||||
except Exception as e: self._num_petitions_text.SetLabel( HC.u( e ) )
|
||||
|
||||
|
||||
def RefreshQuery( self, page_key ):
|
||||
|
|
|
@ -543,7 +543,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
if hashes is not None and len( hashes ) > 0:
|
||||
|
||||
try: HC.app.Write( 'content_updates', { file_service_identifier : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_RESCIND_PETITION, hashes ) ] } )
|
||||
except Exception as e: wx.MessageBox( unicode( e ) )
|
||||
except Exception as e: wx.MessageBox( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
|
@ -554,7 +554,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
if hashes is not None and len( hashes ) > 0:
|
||||
|
||||
try: HC.app.Write( 'content_updates', { file_service_identifier : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_RESCIND_PENDING, hashes ) ] } )
|
||||
except Exception as e: wx.MessageBox( unicode( e ) )
|
||||
except Exception as e: wx.MessageBox( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
|
@ -620,7 +620,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
if hashes is not None and len( hashes ) > 0:
|
||||
|
||||
try: HC.app.Write( 'content_updates', { file_service_identifier : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_PENDING, hashes ) ] } )
|
||||
except Exception as e: wx.MessageBox( unicode( e ) )
|
||||
except Exception as e: wx.MessageBox( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
|
@ -1192,7 +1192,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
|
||||
|
||||
|
||||
|
@ -1864,7 +1864,14 @@ class Thumbnail( Selectable ):
|
|||
|
||||
local = self.GetFileServiceIdentifiersCDPP().HasLocal()
|
||||
|
||||
( creators, series, titles, volumes, chapters, pages ) = self.GetTagsManager().GetCSTVCP()
|
||||
namespaces = self.GetTagsManager().GetCombinedNamespaces( ( 'creator', 'series', 'title', 'volume', 'chapter', 'page' ) )
|
||||
|
||||
creators = namespaces[ 'creator' ]
|
||||
series = namespaces[ 'series' ]
|
||||
titles = namespaces[ 'title' ]
|
||||
volumes = namespaces[ 'volume' ]
|
||||
chapters = namespaces[ 'chapter' ]
|
||||
pages = namespaces[ 'page' ]
|
||||
|
||||
if self._hydrus_bmp is None: self._LoadFromDB()
|
||||
|
||||
|
@ -1907,9 +1914,9 @@ class Thumbnail( Selectable ):
|
|||
|
||||
( volume, ) = volumes
|
||||
|
||||
collections_string = 'v' + str( volume )
|
||||
collections_string = 'v' + HC.u( volume )
|
||||
|
||||
else: collections_string = 'v' + str( min( volumes ) ) + '-' + str( max( volumes ) )
|
||||
else: collections_string = 'v' + HC.u( min( volumes ) ) + '-' + HC.u( max( volumes ) )
|
||||
|
||||
|
||||
if len( chapters ) > 0:
|
||||
|
@ -1918,9 +1925,9 @@ class Thumbnail( Selectable ):
|
|||
|
||||
( chapter, ) = chapters
|
||||
|
||||
collections_string_append = 'c' + str( chapter )
|
||||
collections_string_append = 'c' + HC.u( chapter )
|
||||
|
||||
else: collections_string_append = 'c' + str( min( chapters ) ) + '-' + str( max( chapters ) )
|
||||
else: collections_string_append = 'c' + HC.u( min( chapters ) ) + '-' + HC.u( max( chapters ) )
|
||||
|
||||
if len( collections_string ) > 0: collections_string += '-' + collections_string_append
|
||||
else: collections_string = collections_string_append
|
||||
|
@ -1932,9 +1939,9 @@ class Thumbnail( Selectable ):
|
|||
|
||||
( page, ) = pages
|
||||
|
||||
collections_string_append = 'p' + str( page )
|
||||
collections_string_append = 'p' + HC.u( page )
|
||||
|
||||
else: collections_string_append = 'p' + str( min( pages ) ) + '-' + str( max( pages ) )
|
||||
else: collections_string_append = 'p' + HC.u( min( pages ) ) + '-' + HC.u( max( pages ) )
|
||||
|
||||
if len( collections_string ) > 0: collections_string += '-' + collections_string_append
|
||||
else: collections_string = collections_string_append
|
||||
|
@ -2032,7 +2039,7 @@ class Thumbnail( Selectable ):
|
|||
|
||||
dc.DrawBitmap( CC.GlobalBMPs.collection_bmp, 1, height - 17 )
|
||||
|
||||
num_files_str = str( len( self._hashes ) )
|
||||
num_files_str = HC.u( len( self._hashes ) )
|
||||
|
||||
dc.SetFont( wx.SystemSettings.GetFont( wx.SYS_DEFAULT_GUI_FONT ) )
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ class ConversationsListCtrl( wx.ListCtrl, ListCtrlAutoWidthMixin, ColumnSorterMi
|
|||
def _GetPrettyStatus( self ):
|
||||
|
||||
if len( self._conversations ) == 1: return '1 conversation'
|
||||
else: return str( len( self._conversations ) ) + ' conversations'
|
||||
else: return HC.u( len( self._conversations ) ) + ' conversations'
|
||||
|
||||
|
||||
def _SetConversations( self, conversations ):
|
||||
|
@ -147,7 +147,7 @@ class ConversationsListCtrl( wx.ListCtrl, ListCtrlAutoWidthMixin, ColumnSorterMi
|
|||
updated_string = HC.ConvertTimestampToHumanPrettyTime( updated )
|
||||
|
||||
|
||||
self.Append( ( '', subject, name_from, ', '.join( [ contact.GetName() for contact in participants if contact.GetName() != name_from ] ), str( message_count ), str( unread_count ), created_string, updated_string ) )
|
||||
self.Append( ( '', subject, name_from, ', '.join( [ contact.GetName() for contact in participants if contact.GetName() != name_from ] ), HC.u( message_count ), HC.u( unread_count ), created_string, updated_string ) )
|
||||
|
||||
data_index = i
|
||||
|
||||
|
@ -186,8 +186,8 @@ class ConversationsListCtrl( wx.ListCtrl, ListCtrlAutoWidthMixin, ColumnSorterMi
|
|||
if inbox: self.SetItemImage( selection, 1 )
|
||||
else: self.SetItemImage( selection, 0 )
|
||||
|
||||
self.SetStringItem( selection, 4, str( message_count ) )
|
||||
self.SetStringItem( selection, 5, str( unread_count ) )
|
||||
self.SetStringItem( selection, 4, HC.u( message_count ) )
|
||||
self.SetStringItem( selection, 5, HC.u( unread_count ) )
|
||||
|
||||
if created is None:
|
||||
|
||||
|
@ -265,7 +265,7 @@ class ConversationsListCtrl( wx.ListCtrl, ListCtrlAutoWidthMixin, ColumnSorterMi
|
|||
|
||||
except Exception as e:
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
|
||||
|
@ -662,7 +662,7 @@ class DestinationPanel( wx.Panel ):
|
|||
|
||||
wx.MessageBox( 'Could not contact your message depot, so could not update status!' )
|
||||
|
||||
wx.MessageBox( unicode( e ) )
|
||||
wx.MessageBox( HC.u( e ) )
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
|
||||
|
@ -1300,7 +1300,10 @@ class DraftPanel( wx.Panel ):
|
|||
|
||||
except:
|
||||
|
||||
wx.MessageBox( 'The hydrus client could not connect to your message depot, so the message could not be sent!' )
|
||||
message = 'The hydrus client could not connect to your message depot, so the message could not be sent!'
|
||||
|
||||
wx.MessageBox( message )
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, Exception( message ) ) )
|
||||
print( traceback.format_exc() )
|
||||
|
||||
return
|
||||
|
|
|
@ -87,9 +87,9 @@ class PageLog( PageBase, wx.Panel ):
|
|||
|
||||
log = HC.app.GetLog()
|
||||
|
||||
self._log_list_ctrl = ClientGUICommon.SaneListCtrl( self, 480, [ ( 'type', 60 ), ( 'source', 180 ), ( 'message', -1 ), ( 'time', 120 ) ] )
|
||||
self._log_list_ctrl = ClientGUICommon.SaneListCtrl( self, 480, [ ( 'type', 60 ), ( 'message', -1 ), ( 'time', 120 ) ] )
|
||||
|
||||
for ( type, source, message, time ) in log: self._AddEntry( type, source, message, time )
|
||||
for ( message, timestamp ) in log: self.AddMessage( message, timestamp )
|
||||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
|
@ -97,24 +97,40 @@ class PageLog( PageBase, wx.Panel ):
|
|||
|
||||
self.SetSizer( vbox )
|
||||
|
||||
HC.pubsub.sub( self, 'AddError', 'log_error' )
|
||||
HC.pubsub.sub( self, 'AddMessage', 'log_message' )
|
||||
HC.pubsub.sub( self, 'AddMessage', 'message' )
|
||||
|
||||
|
||||
def _AddEntry( self, type, source, message, time ): self._log_list_ctrl.Append( ( CC.log_string_lookup[ type ], source, message, HC.ConvertTimestampToPrettyTime( time ) ), ( CC.log_string_lookup[ type ], source, message, time ) )
|
||||
def _AddEntry( self, message_type_string, message_string, timestamp ): self._log_list_ctrl.Append( ( message_type_string, message_string, HC.ConvertTimestampToPrettyTime( timestamp ) ), ( message_type_string, message_string, timestamp ) )
|
||||
|
||||
def AddError( self, source, message ):
|
||||
def AddMessage( self, message, timestamp = None ):
|
||||
|
||||
# assuming we want to show errors right now
|
||||
if timestamp is None: timestamp = HC.GetNow()
|
||||
|
||||
self._AddEntry( CC.LOG_ERROR, source, message, time.time() )
|
||||
message_type = message.GetType()
|
||||
info = message.GetInfo()
|
||||
|
||||
|
||||
def AddMessage( self, source, message ):
|
||||
if message_type == HC.MESSAGE_TYPE_TEXT:
|
||||
|
||||
message_type_string = 'message'
|
||||
|
||||
message_string = info
|
||||
|
||||
elif message_type == HC.MESSAGE_TYPE_ERROR:
|
||||
|
||||
message_type_string = 'error'
|
||||
|
||||
exception = info
|
||||
|
||||
message_string = HC.u( exception )
|
||||
|
||||
elif message_type == HC.MESSAGE_TYPE_FILES:
|
||||
|
||||
message_type_string = 'files'
|
||||
|
||||
( message_string, hashes ) = info
|
||||
|
||||
|
||||
# assuming we want to show messages right now
|
||||
|
||||
self._AddEntry( CC.LOG_MESSAGE, source, message, time.time() )
|
||||
self._AddEntry( message_type_string, message_string, timestamp )
|
||||
|
||||
|
||||
class PageMessages( PageBase, wx.SplitterWindow ):
|
||||
|
|
|
@ -14,7 +14,11 @@ def Parse4chanPostScreen( html ):
|
|||
|
||||
print( soup )
|
||||
|
||||
return ( 'big error', 'you are banned from this board! html written to log' )
|
||||
message = 'You are banned from this board! html written to log.'
|
||||
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, Exception( error ) ) )
|
||||
|
||||
return ( 'big error', message )
|
||||
|
||||
else:
|
||||
|
||||
|
@ -27,10 +31,14 @@ def Parse4chanPostScreen( html ):
|
|||
try: print( soup )
|
||||
except: pass
|
||||
|
||||
return ( 'error', 'unknown problem, writing 4chan html to log' )
|
||||
message = 'Unknown problem; writing 4chan html to log.'
|
||||
|
||||
HC.pubsub.pub( 'message', HC.Message( HC.MESSAGE_TYPE_ERROR, Exception( message ) ) )
|
||||
|
||||
return ( 'error', message )
|
||||
|
||||
|
||||
problem = str( problem_tag )
|
||||
problem = HC.u( problem_tag )
|
||||
|
||||
if 'CAPTCHA' in problem: return ( 'captcha', None )
|
||||
elif 'seconds' in problem: return ( 'too quick', None )
|
||||
|
|
|
@ -16,7 +16,7 @@ def GetFLACDuration( file ):
|
|||
|
||||
path = HC.TEMP_DIR + os.path.sep + 'flac_parse.flac'
|
||||
|
||||
with open( path, 'wb' ) as f: f.write( file )
|
||||
with HC.o( path, 'wb' ) as f: f.write( file )
|
||||
|
||||
try: flac_object = mutagen.flac.FLAC( path )
|
||||
except: raise Exception( 'Could not parse the ogg!' )
|
||||
|
@ -35,7 +35,7 @@ def GetMP3Duration( file ):
|
|||
|
||||
path = HC.TEMP_DIR + os.path.sep + 'mp3_parse.mp3'
|
||||
|
||||
with open( path, 'wb' ) as f: f.write( file )
|
||||
with HC.o( path, 'wb' ) as f: f.write( file )
|
||||
|
||||
try: mp3_object = mutagen.mp3.MP3( path )
|
||||
except: raise Exception( 'Could not parse the mp3!' )
|
||||
|
@ -54,7 +54,7 @@ def GetOGGVorbisDuration( file ):
|
|||
|
||||
path = HC.TEMP_DIR + os.path.sep + 'oggvorbis_parse.ogg'
|
||||
|
||||
with open( path, 'wb' ) as f: f.write( file )
|
||||
with HC.o( path, 'wb' ) as f: f.write( file )
|
||||
|
||||
try: ogg_object = mutagen.oggvorbis.OggVorbis( path )
|
||||
except: raise Exception( 'Could not parse the ogg!' )
|
||||
|
|
|
@ -17,6 +17,12 @@ import urlparse
|
|||
import wx
|
||||
import yaml
|
||||
|
||||
# open
|
||||
|
||||
o = open
|
||||
|
||||
# dirs
|
||||
|
||||
BASE_DIR = sys.path[0]
|
||||
|
||||
DB_DIR = BASE_DIR + os.path.sep + 'db'
|
||||
|
@ -33,7 +39,7 @@ TEMP_DIR = BASE_DIR + os.path.sep + 'temp'
|
|||
# Misc
|
||||
|
||||
NETWORK_VERSION = 10
|
||||
SOFTWARE_VERSION = 78
|
||||
SOFTWARE_VERSION = 79
|
||||
|
||||
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )
|
||||
|
||||
|
@ -548,7 +554,7 @@ def CleanTag( tag ):
|
|||
|
||||
tag = tag.lower()
|
||||
|
||||
tag = unicode( tag )
|
||||
tag = u( tag )
|
||||
|
||||
tag = re.sub( '[\s]+', ' ', tag, flags = re.UNICODE ) # turns multiple spaces into single spaces
|
||||
|
||||
|
@ -589,37 +595,28 @@ def ConvertIntToBytes( size ):
|
|||
|
||||
return '%.0f' % size + suffixes[ suffix_index ] + 'B'
|
||||
|
||||
def ConvertIntToPrettyString( num ):
|
||||
|
||||
processed_num = locale.format( "%d", num, grouping = True )
|
||||
|
||||
try: return unicode( processed_num )
|
||||
except:
|
||||
|
||||
try: return processed_num.decode( locale.getpreferredencoding() )
|
||||
except: return str( num )
|
||||
|
||||
|
||||
def ConvertIntToPrettyString( num ): return u( locale.format( "%d", num, grouping = True ) )
|
||||
|
||||
def ConvertMillisecondsToPrettyTime( ms ):
|
||||
|
||||
hours = ms / 3600000
|
||||
|
||||
if hours == 1: hours_result = '1 hour'
|
||||
else: hours_result = str( hours ) + ' hours'
|
||||
else: hours_result = u( hours ) + ' hours'
|
||||
|
||||
ms = ms % 3600000
|
||||
|
||||
minutes = ms / 60000
|
||||
|
||||
if minutes == 1: minutes_result = '1 minute'
|
||||
else: minutes_result = str( minutes ) + ' minutes'
|
||||
else: minutes_result = u( minutes ) + ' minutes'
|
||||
|
||||
ms = ms % 60000
|
||||
|
||||
seconds = ms / 1000
|
||||
|
||||
if seconds == 1: seconds_result = '1 second'
|
||||
else: seconds_result = str( seconds ) + ' seconds'
|
||||
else: seconds_result = u( seconds ) + ' seconds'
|
||||
|
||||
detailed_seconds = float( ms ) / 1000.0
|
||||
|
||||
|
@ -629,7 +626,7 @@ def ConvertMillisecondsToPrettyTime( ms ):
|
|||
ms = ms % 1000
|
||||
|
||||
if ms == 1: milliseconds_result = '1 millisecond'
|
||||
else: milliseconds_result = str( ms ) + ' milliseconds'
|
||||
else: milliseconds_result = u( ms ) + ' milliseconds'
|
||||
|
||||
if hours > 0: return hours_result + ' ' + minutes_result
|
||||
|
||||
|
@ -643,12 +640,12 @@ def ConvertNumericalRatingToPrettyString( lower, upper, rating, rounded_result =
|
|||
|
||||
rating_converted = ( rating * ( upper - lower ) ) + lower
|
||||
|
||||
if rounded_result: s = str( '%.2f' % round( rating_converted ) )
|
||||
else: s = str( '%.2f' % rating_converted )
|
||||
if rounded_result: s = u( '%.2f' % round( rating_converted ) )
|
||||
else: s = u( '%.2f' % rating_converted )
|
||||
|
||||
if out_of:
|
||||
|
||||
if lower in ( 0, 1 ): s += '/' + str( '%.2f' % upper )
|
||||
if lower in ( 0, 1 ): s += '/' + u( '%.2f' % upper )
|
||||
|
||||
|
||||
return s
|
||||
|
@ -688,35 +685,35 @@ def ConvertTimestampToPrettyAge( timestamp ):
|
|||
|
||||
if timestamp == 0 or timestamp is None: return 'unknown age'
|
||||
|
||||
age = int( time.time() ) - timestamp
|
||||
age = GetNow() - timestamp
|
||||
|
||||
seconds = age % 60
|
||||
if seconds == 1: s = '1 second'
|
||||
else: s = str( seconds ) + ' seconds'
|
||||
else: s = u( seconds ) + ' seconds'
|
||||
|
||||
age = age / 60
|
||||
minutes = age % 60
|
||||
if minutes == 1: m = '1 minute'
|
||||
else: m = str( minutes ) + ' minutes'
|
||||
else: m = u( minutes ) + ' minutes'
|
||||
|
||||
age = age / 60
|
||||
hours = age % 24
|
||||
if hours == 1: h = '1 hour'
|
||||
else: h = str( hours ) + ' hours'
|
||||
else: h = u( hours ) + ' hours'
|
||||
|
||||
age = age / 24
|
||||
days = age % 30
|
||||
if days == 1: d = '1 day'
|
||||
else: d = str( days ) + ' days'
|
||||
else: d = u( days ) + ' days'
|
||||
|
||||
age = age / 30
|
||||
months = age % 12
|
||||
if months == 1: mo = '1 month'
|
||||
else: mo = str( months ) + ' months'
|
||||
else: mo = u( months ) + ' months'
|
||||
|
||||
years = age / 12
|
||||
if years == 1: y = '1 year'
|
||||
else: y = str( years ) + ' years'
|
||||
else: y = u( years ) + ' years'
|
||||
|
||||
if years > 0: return ' '.join( ( y, mo ) ) + ' old'
|
||||
elif months > 0: return ' '.join( ( mo, d ) ) + ' old'
|
||||
|
@ -728,35 +725,35 @@ def ConvertTimestampToPrettyAgo( timestamp ):
|
|||
|
||||
if timestamp == 0: return 'unknown time'
|
||||
|
||||
age = int( time.time() ) - timestamp
|
||||
age = GetNow() - timestamp
|
||||
|
||||
seconds = age % 60
|
||||
if seconds == 1: s = '1 second'
|
||||
else: s = str( seconds ) + ' seconds'
|
||||
else: s = u( seconds ) + ' seconds'
|
||||
|
||||
age = age / 60
|
||||
minutes = age % 60
|
||||
if minutes == 1: m = '1 minute'
|
||||
else: m = str( minutes ) + ' minutes'
|
||||
else: m = u( minutes ) + ' minutes'
|
||||
|
||||
age = age / 60
|
||||
hours = age % 24
|
||||
if hours == 1: h = '1 hour'
|
||||
else: h = str( hours ) + ' hours'
|
||||
else: h = u( hours ) + ' hours'
|
||||
|
||||
age = age / 24
|
||||
days = age % 30
|
||||
if days == 1: d = '1 day'
|
||||
else: d = str( days ) + ' days'
|
||||
else: d = u( days ) + ' days'
|
||||
|
||||
age = age / 30
|
||||
months = age % 12
|
||||
if months == 1: mo = '1 month'
|
||||
else: mo = str( months ) + ' months'
|
||||
else: mo = u( months ) + ' months'
|
||||
|
||||
years = age / 12
|
||||
if years == 1: y = '1 year'
|
||||
else: y = str( years ) + ' years'
|
||||
else: y = u( years ) + ' years'
|
||||
|
||||
if years > 0: return ' '.join( ( y, mo ) ) + ' ago'
|
||||
elif months > 0: return ' '.join( ( mo, d ) ) + ' ago'
|
||||
|
@ -769,7 +766,7 @@ def ConvertTimestampToPrettyExpires( timestamp ):
|
|||
if timestamp is None: return 'does not expire'
|
||||
if timestamp == 0: return 'unknown expiry'
|
||||
|
||||
expires = int( time.time() ) - timestamp
|
||||
expires = GetNow() - timestamp
|
||||
|
||||
if expires >= 0: already_happend = True
|
||||
else:
|
||||
|
@ -781,31 +778,31 @@ def ConvertTimestampToPrettyExpires( timestamp ):
|
|||
|
||||
seconds = expires % 60
|
||||
if seconds == 1: s = '1 second'
|
||||
else: s = str( seconds ) + ' seconds'
|
||||
else: s = u( seconds ) + ' seconds'
|
||||
|
||||
expires = expires / 60
|
||||
minutes = expires % 60
|
||||
if minutes == 1: m = '1 minute'
|
||||
else: m = str( minutes ) + ' minutes'
|
||||
else: m = u( minutes ) + ' minutes'
|
||||
|
||||
expires = expires / 60
|
||||
hours = expires % 24
|
||||
if hours == 1: h = '1 hour'
|
||||
else: h = str( hours ) + ' hours'
|
||||
else: h = u( hours ) + ' hours'
|
||||
|
||||
expires = expires / 24
|
||||
days = expires % 30
|
||||
if days == 1: d = '1 day'
|
||||
else: d = str( days ) + ' days'
|
||||
else: d = u( days ) + ' days'
|
||||
|
||||
expires = expires / 30
|
||||
months = expires % 12
|
||||
if months == 1: mo = '1 month'
|
||||
else: mo = str( months ) + ' months'
|
||||
else: mo = u( months ) + ' months'
|
||||
|
||||
years = expires / 12
|
||||
if years == 1: y = '1 year'
|
||||
else: y = str( years ) + ' years'
|
||||
else: y = u( years ) + ' years'
|
||||
|
||||
if already_happend:
|
||||
|
||||
|
@ -829,38 +826,38 @@ def ConvertTimestampToPrettyPending( timestamp ):
|
|||
if timestamp is None: return ''
|
||||
if timestamp == 0: return 'imminent'
|
||||
|
||||
pending = int( time.time() ) - timestamp
|
||||
pending = GetNow() - timestamp
|
||||
|
||||
if pending >= 0: return 'imminent'
|
||||
else: pending *= -1
|
||||
|
||||
seconds = pending % 60
|
||||
if seconds == 1: s = '1 second'
|
||||
else: s = str( seconds ) + ' seconds'
|
||||
else: s = u( seconds ) + ' seconds'
|
||||
|
||||
pending = pending / 60
|
||||
minutes = pending % 60
|
||||
if minutes == 1: m = '1 minute'
|
||||
else: m = str( minutes ) + ' minutes'
|
||||
else: m = u( minutes ) + ' minutes'
|
||||
|
||||
pending = pending / 60
|
||||
hours = pending % 24
|
||||
if hours == 1: h = '1 hour'
|
||||
else: h = str( hours ) + ' hours'
|
||||
else: h = u( hours ) + ' hours'
|
||||
|
||||
pending = pending / 24
|
||||
days = pending % 30
|
||||
if days == 1: d = '1 day'
|
||||
else: d = str( days ) + ' days'
|
||||
else: d = u( days ) + ' days'
|
||||
|
||||
pending = pending / 30
|
||||
months = pending % 12
|
||||
if months == 1: mo = '1 month'
|
||||
else: mo = str( months ) + ' months'
|
||||
else: mo = u( months ) + ' months'
|
||||
|
||||
years = pending / 12
|
||||
if years == 1: y = '1 year'
|
||||
else: y = str( years ) + ' years'
|
||||
else: y = u( years ) + ' years'
|
||||
|
||||
if years > 0: return 'in ' + ' '.join( ( y, mo ) )
|
||||
elif months > 0: return 'in ' + ' '.join( ( mo, d ) )
|
||||
|
@ -872,35 +869,35 @@ def ConvertTimestampToPrettySync( timestamp ):
|
|||
|
||||
if timestamp == 0: return 'not updated'
|
||||
|
||||
age = int( time.time() ) - timestamp
|
||||
age = GetNow() - timestamp
|
||||
|
||||
seconds = age % 60
|
||||
if seconds == 1: s = '1 second'
|
||||
else: s = str( seconds ) + ' seconds'
|
||||
else: s = u( seconds ) + ' seconds'
|
||||
|
||||
age = age / 60
|
||||
minutes = age % 60
|
||||
if minutes == 1: m = '1 minute'
|
||||
else: m = str( minutes ) + ' minutes'
|
||||
else: m = u( minutes ) + ' minutes'
|
||||
|
||||
age = age / 60
|
||||
hours = age % 24
|
||||
if hours == 1: h = '1 hour'
|
||||
else: h = str( hours ) + ' hours'
|
||||
else: h = u( hours ) + ' hours'
|
||||
|
||||
age = age / 24
|
||||
days = age % 30
|
||||
if days == 1: d = '1 day'
|
||||
else: d = str( days ) + ' days'
|
||||
else: d = u( days ) + ' days'
|
||||
|
||||
age = age / 30
|
||||
months = age % 12
|
||||
if months == 1: mo = '1 month'
|
||||
else: mo = str( months ) + ' months'
|
||||
else: mo = u( months ) + ' months'
|
||||
|
||||
years = age / 12
|
||||
if years == 1: y = '1 year'
|
||||
else: y = str( years ) + ' years'
|
||||
else: y = u( years ) + ' years'
|
||||
|
||||
if years > 0: return 'updated to ' + ' '.join( ( y, mo ) ) + ' ago'
|
||||
elif months > 0: return 'updated to ' + ' '.join( ( mo, d ) ) + ' ago'
|
||||
|
@ -912,7 +909,7 @@ def ConvertTimestampToPrettyTime( timestamp ): return time.strftime( '%Y/%m/%d %
|
|||
|
||||
def ConvertTimestampToHumanPrettyTime( timestamp ):
|
||||
|
||||
now = int( time.time() )
|
||||
now = GetNow()
|
||||
|
||||
difference = now - timestamp
|
||||
|
||||
|
@ -952,6 +949,8 @@ def GetEmptyDataDict():
|
|||
|
||||
return data
|
||||
|
||||
def GetNow(): return int( time.time() )
|
||||
|
||||
def GetShortcutFromEvent( event ):
|
||||
|
||||
modifier = wx.ACCEL_NORMAL
|
||||
|
@ -1012,18 +1011,18 @@ def MergeKeyToListDicts( key_to_list_dicts ):
|
|||
|
||||
return result
|
||||
|
||||
class Message():
|
||||
def u( text_producing_object ):
|
||||
|
||||
def __init__( self, message_type, info ):
|
||||
if type( text_producing_object ) in ( str, unicode ): text = text_producing_object
|
||||
else: text = str( text_producing_object ) # dealing with exceptions, etc...
|
||||
|
||||
try: return unicode( text )
|
||||
except:
|
||||
|
||||
self._message_type = message_type
|
||||
self._info = info
|
||||
try: return text.decode( locale.getpreferredencoding() )
|
||||
except: return str( text )
|
||||
|
||||
|
||||
def GetInfo( self ): return self._info
|
||||
|
||||
def GetType( self ): return self._message_type
|
||||
|
||||
def SearchEntryMatchesPredicate( search_entry, predicate ):
|
||||
|
||||
( predicate_type, info ) = predicate.GetInfo()
|
||||
|
@ -1063,9 +1062,9 @@ def SearchEntryMatchesTag( search_entry, tag, search_siblings = True ):
|
|||
|
||||
return False
|
||||
|
||||
def SplayListForDB( xs ): return '(' + ','.join( [ '"' + str( x ) + '"' for x in xs ] ) + ')'
|
||||
def SplayListForDB( xs ): return '(' + ','.join( [ '"' + u( x ) + '"' for x in xs ] ) + ')'
|
||||
|
||||
def SplayTupleListForDB( first_column_name, second_column_name, xys ): return ' OR '.join( [ '( ' + first_column_name + '=' + str( x ) + ' AND ' + second_column_name + ' IN ' + SplayListForDB( ys ) + ' )' for ( x, ys ) in xys ] )
|
||||
def SplayTupleListForDB( first_column_name, second_column_name, xys ): return ' OR '.join( [ '( ' + first_column_name + '=' + u( x ) + ' AND ' + second_column_name + ' IN ' + SplayListForDB( ys ) + ' )' for ( x, ys ) in xys ] )
|
||||
|
||||
def ThumbnailResolution( original_resolution, target_resolution ):
|
||||
|
||||
|
@ -1133,7 +1132,7 @@ class AdvancedHTTPConnection():
|
|||
|
||||
def request( self, request_type, request, headers = {}, body = None, is_redirect = False, follow_redirects = True ):
|
||||
|
||||
if 'User-Agent' not in headers: headers[ 'User-Agent' ] = 'hydrus/' + str( NETWORK_VERSION )
|
||||
if 'User-Agent' not in headers: headers[ 'User-Agent' ] = 'hydrus/' + u( NETWORK_VERSION )
|
||||
|
||||
if len( self._cookies ) > 0: headers[ 'Cookie' ] = '; '.join( [ k + '=' + v for ( k, v ) in self._cookies.items() ] )
|
||||
|
||||
|
@ -1148,9 +1147,8 @@ class AdvancedHTTPConnection():
|
|||
except ( httplib.CannotSendRequest, httplib.BadStatusLine ):
|
||||
|
||||
# for some reason, we can't send a request on the current connection, so let's make a new one!
|
||||
|
||||
try:
|
||||
|
||||
|
||||
if self._scheme == 'http': self._connection = httplib.HTTPConnection( self._host, self._port )
|
||||
else: self._connection = httplib.HTTPSConnection( self._host, self._port )
|
||||
|
||||
|
@ -1220,7 +1218,7 @@ class AdvancedHTTPConnection():
|
|||
if mime_string in mime_enum_lookup and mime_enum_lookup[ mime_string ] == APPLICATION_YAML:
|
||||
|
||||
try: parsed_response = yaml.safe_load( raw_response )
|
||||
except Exception as e: raise HydrusExceptions.NetworkVersionException( 'Failed to parse a response object!' + os.linesep + unicode( e ) )
|
||||
except Exception as e: raise HydrusExceptions.NetworkVersionException( 'Failed to parse a response object!' + os.linesep + u( e ) )
|
||||
|
||||
else: parsed_response = raw_response
|
||||
|
||||
|
@ -1330,6 +1328,8 @@ class AdvancedHTTPConnection():
|
|||
|
||||
def SetCookie( self, key, value ): self._cookies[ key ] = value
|
||||
|
||||
get_connection = AdvancedHTTPConnection
|
||||
|
||||
class HydrusYAMLBase( yaml.YAMLObject ):
|
||||
|
||||
yaml_loader = yaml.SafeLoader
|
||||
|
@ -1350,7 +1350,7 @@ class Account( HydrusYAMLBase ):
|
|||
self._used_data = used_data
|
||||
self._banned_info = banned_info
|
||||
|
||||
self._object_instantiation_timestamp = int( time.time() )
|
||||
self._object_instantiation_timestamp = GetNow()
|
||||
|
||||
|
||||
def __repr__( self ): return self.ConvertToString()
|
||||
|
@ -1365,14 +1365,14 @@ class Account( HydrusYAMLBase ):
|
|||
( reason, created, expires ) = self._banned_info
|
||||
|
||||
if expires is None: return True
|
||||
else: return int( time.time() ) > expires
|
||||
else: return GetNow() > expires
|
||||
|
||||
|
||||
|
||||
def _IsExpired( self ):
|
||||
|
||||
if self._expires is None: return False
|
||||
else: return int( time.time() ) > self._expires
|
||||
else: return GetNow() > self._expires
|
||||
|
||||
|
||||
def CheckPermissions( self, permissions ):
|
||||
|
@ -1457,9 +1457,9 @@ class Account( HydrusYAMLBase ):
|
|||
|
||||
def IsBanned( self ): return self._IsBanned()
|
||||
|
||||
def IsStale( self ): return self._object_instantiation_timestamp + UPDATE_DURATION * 5 < int( time.time() )
|
||||
def IsStale( self ): return self._object_instantiation_timestamp + UPDATE_DURATION * 5 < GetNow()
|
||||
|
||||
def MakeFresh( self ): self._object_instantiation_timestamp = int( time.time() )
|
||||
def MakeFresh( self ): self._object_instantiation_timestamp = GetNow()
|
||||
|
||||
def MakeStale( self ): self._object_instantiation_timestamp = 0
|
||||
|
||||
|
@ -1493,7 +1493,7 @@ class AccountIdentifier( HydrusYAMLBase ):
|
|||
|
||||
def __ne__( self, other ): return self.__hash__() != other.__hash__()
|
||||
|
||||
def __repr__( self ): return 'Account Identifier: ' + str( ( self._access_key.encode( 'hex' ), self._hash.encode( 'hex' ), self._tag, self._account_id ) )
|
||||
def __repr__( self ): return 'Account Identifier: ' + u( ( self._access_key.encode( 'hex' ), self._hash.encode( 'hex' ), self._tag, self._account_id ) )
|
||||
|
||||
def GetAccessKey( self ): return self._access_key
|
||||
|
||||
|
@ -1580,7 +1580,7 @@ class ClientServiceIdentifier( HydrusYAMLBase ):
|
|||
|
||||
def __ne__( self, other ): return self.__hash__() != other.__hash__()
|
||||
|
||||
def __repr__( self ): return 'Client Service Identifier: ' + str( ( name, self._type, self._service_key ) )
|
||||
def __repr__( self ): return 'Client Service Identifier: ' + u( ( self._name, self._type, self._service_key ) )
|
||||
|
||||
def GetInfo( self ): return ( self._service_key, self._type, self._name )
|
||||
|
||||
|
@ -1715,7 +1715,7 @@ class ContentUpdate():
|
|||
|
||||
def __ne__( self, other ): return not self.__eq__( other )
|
||||
|
||||
def __repr__( self ): return 'Content Update: ' + str( ( self._data_type, self._action, self._row ) )
|
||||
def __repr__( self ): return 'Content Update: ' + u( ( self._data_type, self._action, self._row ) )
|
||||
|
||||
def GetHashes( self ):
|
||||
|
||||
|
@ -1755,6 +1755,7 @@ class DAEMON( threading.Thread ):
|
|||
|
||||
threading.Thread.__init__( self, name = name )
|
||||
|
||||
self._name = name
|
||||
self._callable = callable
|
||||
self._period = period
|
||||
|
||||
|
@ -1801,7 +1802,14 @@ class DAEMONQueue( DAEMON ):
|
|||
while self._queue.qsize() > 0: items.append( self._queue.get() )
|
||||
|
||||
try: self._callable( items )
|
||||
except: print( traceback.format_exc() )
|
||||
except Exception as e:
|
||||
|
||||
message = self._name + os.linesep + type( e ).__name__ + os.linesep + traceback.format_exc()
|
||||
|
||||
pubsub.pub( 'message', Message( MESSAGE_TYPE_ERROR, Exception( message ) ) )
|
||||
|
||||
print( message )
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1828,7 +1836,14 @@ class DAEMONWorker( DAEMON ):
|
|||
if shutdown: return
|
||||
|
||||
try: self._callable()
|
||||
except: print( traceback.format_exc() )
|
||||
except Exception as e:
|
||||
|
||||
message = self._name + os.linesep + type( e ).__name__ + os.linesep + traceback.format_exc()
|
||||
|
||||
pubsub.pub( 'message', Message( MESSAGE_TYPE_ERROR, Exception( message ) ) )
|
||||
|
||||
print( message )
|
||||
|
||||
|
||||
if shutdown: return
|
||||
|
||||
|
@ -1840,6 +1855,18 @@ class DAEMONWorker( DAEMON ):
|
|||
|
||||
def set( self, *args, **kwargs ): self._event.set()
|
||||
|
||||
class Message():
|
||||
|
||||
def __init__( self, message_type, info ):
|
||||
|
||||
self._message_type = message_type
|
||||
self._info = info
|
||||
|
||||
|
||||
def GetInfo( self ): return self._info
|
||||
|
||||
def GetType( self ): return self._message_type
|
||||
|
||||
class JobInternal():
|
||||
|
||||
yaml_tag = u'!JobInternal'
|
||||
|
@ -1930,7 +1957,7 @@ class Predicate():
|
|||
|
||||
def __ne__( self, other ): return self.__hash__() != other.__hash__()
|
||||
|
||||
def __repr__( self ): return 'Predicate: ' + str( ( self._predicate_type, self._value, self._count ) )
|
||||
def __repr__( self ): return 'Predicate: ' + u( ( self._predicate_type, self._value, self._count ) )
|
||||
|
||||
def AddToCount( self, count ): self._count += count
|
||||
|
||||
|
@ -1969,7 +1996,7 @@ class Predicate():
|
|||
|
||||
( operator, value ) = info
|
||||
|
||||
base += u' ' + operator + u' ' + unicode( value )
|
||||
base += u' ' + operator + u' ' + u( value )
|
||||
|
||||
|
||||
elif system_predicate_type == SYSTEM_PREDICATE_TYPE_SIZE:
|
||||
|
@ -1980,7 +2007,7 @@ class Predicate():
|
|||
|
||||
( operator, size, unit ) = info
|
||||
|
||||
base += u' ' + operator + u' ' + unicode( size ) + ConvertUnitToString( unit )
|
||||
base += u' ' + operator + u' ' + u( size ) + ConvertUnitToString( unit )
|
||||
|
||||
|
||||
elif system_predicate_type == SYSTEM_PREDICATE_TYPE_LIMIT:
|
||||
|
@ -1991,7 +2018,7 @@ class Predicate():
|
|||
|
||||
value = info
|
||||
|
||||
base += u' is ' + unicode( value )
|
||||
base += u' is ' + u( value )
|
||||
|
||||
|
||||
elif system_predicate_type == SYSTEM_PREDICATE_TYPE_AGE:
|
||||
|
@ -2002,7 +2029,7 @@ class Predicate():
|
|||
|
||||
( operator, years, months, days, hours ) = info
|
||||
|
||||
base += u' ' + operator + u' ' + unicode( years ) + u'y' + unicode( months ) + u'm' + unicode( days ) + u'd' + unicode( hours ) + u'h'
|
||||
base += u' ' + operator + u' ' + u( years ) + u'y' + u( months ) + u'm' + u( days ) + u'd' + u( hours ) + u'h'
|
||||
|
||||
|
||||
elif system_predicate_type == SYSTEM_PREDICATE_TYPE_HASH:
|
||||
|
@ -2035,7 +2062,7 @@ class Predicate():
|
|||
|
||||
( service_identifier, operator, value ) = info
|
||||
|
||||
base += u' for ' + service_identifier.GetName() + u' ' + operator + u' ' + unicode( value )
|
||||
base += u' for ' + service_identifier.GetName() + u' ' + operator + u' ' + u( value )
|
||||
|
||||
|
||||
elif system_predicate_type == SYSTEM_PREDICATE_TYPE_SIMILAR_TO:
|
||||
|
@ -2046,7 +2073,7 @@ class Predicate():
|
|||
|
||||
( hash, max_hamming ) = info
|
||||
|
||||
base += u' ' + hash.encode( 'hex' ) + u' using max hamming of ' + unicode( max_hamming )
|
||||
base += u' ' + hash.encode( 'hex' ) + u' using max hamming of ' + u( max_hamming )
|
||||
|
||||
|
||||
elif system_predicate_type == SYSTEM_PREDICATE_TYPE_FILE_SERVICE:
|
||||
|
@ -2182,7 +2209,7 @@ class ServerServiceIdentifier( HydrusYAMLBase ):
|
|||
|
||||
def __ne__( self, other ): return self.__hash__() != other.__hash__()
|
||||
|
||||
def __repr__( self ): return 'Server Service Identifier: ' + str( ( self._type, self._port ) )
|
||||
def __repr__( self ): return 'Server Service Identifier: ' + u( ( self._type, self._port ) )
|
||||
|
||||
def GetPort( self ): return self._port
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ class Downloader():
|
|||
|
||||
if ( scheme, host, port ) not in self._connections:
|
||||
|
||||
connection = HC.AdvancedHTTPConnection( scheme = scheme, host = host, port = port )
|
||||
connection = HC.get_connection( scheme = scheme, host = host, port = port )
|
||||
|
||||
self._EstablishSession( connection )
|
||||
|
||||
|
@ -178,7 +178,7 @@ class DownloaderBooru( Downloader ):
|
|||
else: index = self._num_pages_done * self._gallery_advance_num
|
||||
|
||||
|
||||
return self._search_url.replace( '%tags%', self._search_separator.join( self._tags ) ).replace( '%index%', str( index ) )
|
||||
return self._search_url.replace( '%tags%', self._search_separator.join( self._tags ) ).replace( '%index%', HC.u( index ) )
|
||||
|
||||
|
||||
def _ParseGalleryPage( self, html, url_base ):
|
||||
|
@ -324,7 +324,7 @@ class DownloaderDeviantArt( Downloader ):
|
|||
Downloader.__init__( self )
|
||||
|
||||
|
||||
def _GetNextGalleryPageURL( self ): return self._gallery_url + str( self._num_pages_done * 24 )
|
||||
def _GetNextGalleryPageURL( self ): return self._gallery_url + HC.u( self._num_pages_done * 24 )
|
||||
|
||||
def _ParseGalleryPage( self, html, url_base ):
|
||||
|
||||
|
@ -427,7 +427,7 @@ class DownloaderGiphy( Downloader ):
|
|||
Downloader.__init__( self )
|
||||
|
||||
|
||||
def _GetNextGalleryPageURL( self ): return self._gallery_url + str( self._num_pages_done + 1 )
|
||||
def _GetNextGalleryPageURL( self ): return self._gallery_url + HC.u( self._num_pages_done + 1 )
|
||||
|
||||
def _ParseGalleryPage( self, data, url_base ):
|
||||
|
||||
|
@ -444,7 +444,7 @@ class DownloaderGiphy( Downloader ):
|
|||
|
||||
def GetTags( self, url, id ):
|
||||
|
||||
url = 'http://giphy.com/api/gifs/' + str( id )
|
||||
url = 'http://giphy.com/api/gifs/' + HC.u( id )
|
||||
|
||||
connection = self._GetConnection( url )
|
||||
|
||||
|
@ -503,7 +503,7 @@ class DownloaderHentaiFoundry( Downloader ):
|
|||
|
||||
gallery_url = 'http://www.hentai-foundry.com/pictures/user/' + artist
|
||||
|
||||
return gallery_url + '/page/' + str( self._num_pages_done + 1 )
|
||||
return gallery_url + '/page/' + HC.u( self._num_pages_done + 1 )
|
||||
|
||||
elif self._query_type == 'artist scraps':
|
||||
|
||||
|
@ -511,13 +511,13 @@ class DownloaderHentaiFoundry( Downloader ):
|
|||
|
||||
gallery_url = 'http://www.hentai-foundry.com/pictures/user/' + artist + '/scraps'
|
||||
|
||||
return gallery_url + '/page/' + str( self._num_pages_done + 1 )
|
||||
return gallery_url + '/page/' + HC.u( self._num_pages_done + 1 )
|
||||
|
||||
elif self._query_type == 'tags':
|
||||
|
||||
tags = self._query
|
||||
|
||||
return 'http://www.hentai-foundry.com/search/pictures?query=' + '+'.join( tags ) + '&search_in=all&scraps=-1&page=' + str( self._num_pages_done + 1 )
|
||||
return 'http://www.hentai-foundry.com/search/pictures?query=' + '+'.join( tags ) + '&search_in=all&scraps=-1&page=' + HC.u( self._num_pages_done + 1 )
|
||||
# scraps = 0 hide
|
||||
# -1 means show both
|
||||
# 1 means scraps only. wetf
|
||||
|
@ -592,7 +592,7 @@ class DownloaderHentaiFoundry( Downloader ):
|
|||
|
||||
title = soup.find( 'title' )
|
||||
|
||||
( data, nothing ) = unicode( title.string ).split( ' - Hentai Foundry' )
|
||||
( data, nothing ) = HC.u( title.string ).split( ' - Hentai Foundry' )
|
||||
|
||||
data_reversed = data[::-1] # want to do it right-side first, because title might have ' by ' in it
|
||||
|
||||
|
@ -733,7 +733,7 @@ class DownloaderNewgrounds( Downloader ):
|
|||
|
||||
soup = bs4.BeautifulSoup( html )
|
||||
|
||||
tags = []
|
||||
tags = set()
|
||||
|
||||
author_links = soup.find( 'ul', class_ = 'authorlinks' )
|
||||
|
||||
|
@ -751,7 +751,7 @@ class DownloaderNewgrounds( Downloader ):
|
|||
|
||||
creator = href.replace( 'http://', '' ).replace( '.newgrounds.com', '' )
|
||||
|
||||
tags.append( 'creator:' + creator )
|
||||
tags.add( u'creator:' + creator )
|
||||
|
||||
except: pass
|
||||
|
||||
|
@ -761,7 +761,7 @@ class DownloaderNewgrounds( Downloader ):
|
|||
|
||||
title = soup.find( 'title' )
|
||||
|
||||
tags.append( 'title:' + title.string )
|
||||
tags.add( u'title:' + title.string )
|
||||
|
||||
except: pass
|
||||
|
||||
|
@ -773,7 +773,7 @@ class DownloaderNewgrounds( Downloader ):
|
|||
|
||||
href = link[ 'href' ]
|
||||
|
||||
if '/browse/tag/' in href: tags.append( link.string )
|
||||
if '/browse/tag/' in href: tags.add( link.string )
|
||||
|
||||
except: pass
|
||||
|
||||
|
@ -782,7 +782,7 @@ class DownloaderNewgrounds( Downloader ):
|
|||
|
||||
try:
|
||||
|
||||
components = html.split( '"src"' )
|
||||
components = html.split( '"http://uploads.ungrounded.net/' )
|
||||
|
||||
# there is sometimes another bit of api flash earlier on that we don't want
|
||||
# it is called http://uploads.ungrounded.net/apiassets/sandbox.swf
|
||||
|
@ -790,20 +790,13 @@ class DownloaderNewgrounds( Downloader ):
|
|||
if len( components ) == 2: flash_url = components[1]
|
||||
else: flash_url = components[2]
|
||||
|
||||
#"src": "http:\/\/flash.ngfiles.com\/video_player\/videoplayer.swf",
|
||||
#"width": "100%",
|
||||
flash_url = flash_url.split( '"', 1 )[0]
|
||||
|
||||
#"src": "http:\/\/uploads.ungrounded.net\/593000\/593806_Kitty.swf",
|
||||
#"width": "100%",
|
||||
flash_url = 'http://uploads.ungrounded.net/' + flash_url
|
||||
|
||||
flash_url = flash_url.split( '"width"', 1 )[0]
|
||||
|
||||
flash_url = flash_url.split( '"' )[1]
|
||||
flash_url = flash_url.replace( '\\/', '/' )
|
||||
|
||||
except: raise Exception( 'Could not find the swf file!' )
|
||||
|
||||
if flash_url == 'http://flash.ngfiles.com/video_player/videoplayer.swf': raise Exception( 'It was an mp4 movie, not a swf!' )
|
||||
except:
|
||||
print( traceback.format_exc())
|
||||
raise Exception( 'Could not find the swf file! It was probably an mp4!' )
|
||||
|
||||
return ( flash_url, tags )
|
||||
|
||||
|
@ -858,7 +851,7 @@ class DownloaderPixiv( Downloader ):
|
|||
|
||||
artist_id = self._query
|
||||
|
||||
gallery_url = 'http://www.pixiv.net/member_illust.php?id=' + str( artist_id )
|
||||
gallery_url = 'http://www.pixiv.net/member_illust.php?id=' + HC.u( artist_id )
|
||||
|
||||
elif self._query_type == 'tag':
|
||||
|
||||
|
@ -869,7 +862,7 @@ class DownloaderPixiv( Downloader ):
|
|||
gallery_url = 'http://www.pixiv.net/search.php?word=' + tag + '&s_mode=s_tag_full&order=date_d'
|
||||
|
||||
|
||||
return gallery_url + '&p=' + str( self._num_pages_done + 1 )
|
||||
return gallery_url + '&p=' + HC.u( self._num_pages_done + 1 )
|
||||
|
||||
|
||||
def _ParseGalleryPage( self, html, url_base ):
|
||||
|
@ -981,7 +974,7 @@ class DownloaderTumblr( Downloader ):
|
|||
Downloader.__init__( self )
|
||||
|
||||
|
||||
def _GetNextGalleryPageURL( self ): return self._gallery_url.replace( '%start%', str( self._num_pages_done * 50 ) )
|
||||
def _GetNextGalleryPageURL( self ): return self._gallery_url.replace( '%start%', HC.u( self._num_pages_done * 50 ) )
|
||||
|
||||
def _ParseGalleryPage( self, data, url_base ):
|
||||
|
||||
|
|
|
@ -42,9 +42,9 @@ def DecryptAESFile( aes_key, iv, path ):
|
|||
if '.encrypted' in path: path_to = path.replace( '.encrypted', '' )
|
||||
else: path_to = path + '.decrypted'
|
||||
|
||||
with open( path, 'rb' ) as encrypted_f:
|
||||
with HC.o( path, 'rb' ) as encrypted_f:
|
||||
|
||||
with open( path_to, 'wb' ) as decrypted_f:
|
||||
with HC.o( path_to, 'wb' ) as decrypted_f:
|
||||
|
||||
next_block = encrypted_f.read( 65536 )
|
||||
|
||||
|
@ -96,9 +96,9 @@ def EncryptAESFile( path, preface = '' ):
|
|||
|
||||
aes_cipher = Crypto.Cipher.AES.new( aes_key, Crypto.Cipher.AES.MODE_CFB, iv )
|
||||
|
||||
with open( path, 'rb' ) as decrypted_f:
|
||||
with HC.o( path, 'rb' ) as decrypted_f:
|
||||
|
||||
with open( path + '.encrypted', 'wb' ) as encrypted_f:
|
||||
with HC.o( path + '.encrypted', 'wb' ) as encrypted_f:
|
||||
|
||||
encrypted_f.write( preface )
|
||||
|
||||
|
@ -128,7 +128,7 @@ def EncryptAESFile( path, preface = '' ):
|
|||
|
||||
aes_key_text = AESKeyToText( aes_key, iv )
|
||||
|
||||
with open( path + '.key', 'wb' ) as f: f.write( aes_key_text )
|
||||
with HC.o( path + '.key', 'wb' ) as f: f.write( aes_key_text )
|
||||
|
||||
def EncryptPKCS( public_key, message ):
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ def GetFileInfo( file, hash ):
|
|||
|
||||
def GetMimeFromPath( filename ):
|
||||
|
||||
with open( filename, 'rb' ) as f: return GetMimeFromFilePointer( f )
|
||||
with HC.o( filename, 'rb' ) as f: return GetMimeFromFilePointer( f )
|
||||
|
||||
header_and_mime = [
|
||||
( 0, '\xff\xd8', HC.IMAGE_JPEG ),
|
||||
|
@ -109,7 +109,7 @@ def GetMimeFromFilePointer( f ):
|
|||
|
||||
path = HC.TEMP_DIR + os.path.sep + 'mime_parsing'
|
||||
|
||||
with open( path, 'wb' ) as temp_f:
|
||||
with HC.o( path, 'wb' ) as temp_f:
|
||||
|
||||
block = f.read( 65536 )
|
||||
|
||||
|
@ -121,29 +121,23 @@ def GetMimeFromFilePointer( f ):
|
|||
|
||||
|
||||
|
||||
try:
|
||||
mutagen_object = mutagen.File( path )
|
||||
|
||||
if type( mutagen_object ) == mutagen.oggvorbis.OggVorbis: return HC.AUDIO_OGG
|
||||
elif type( mutagen_object ) == mutagen.flac.FLAC: return HC.AUDIO_FLAC
|
||||
elif type( mutagen_object ) == mutagen.mp3.MP3: return HC.AUDIO_MP3
|
||||
elif type( mutagen_object ) == mutagen.mp4.MP4 or mutagen_object is None:
|
||||
|
||||
mutagen_object = mutagen.File( path )
|
||||
# mutagen sometimes does not auto-detect mp3s properly, so try it explicitly
|
||||
mutagen_object = mutagen.mp3.MP3( path )
|
||||
|
||||
if type( mutagen_object ) == mutagen.oggvorbis.OggVorbis: return HC.AUDIO_OGG
|
||||
elif type( mutagen_object ) == mutagen.flac.FLAC: return HC.AUDIO_FLAC
|
||||
elif type( mutagen_object ) == mutagen.mp3.MP3: return HC.AUDIO_MP3
|
||||
elif type( mutagen_object ) == mutagen.mp4.MP4 or mutagen_object is None:
|
||||
|
||||
# mutagen sometimes does not auto-detect mp3s properly, so try it explicitly
|
||||
mutagen_object = mutagen.mp3.MP3( path )
|
||||
|
||||
if type( mutagen_object ) == mutagen.mp3.MP3: return HC.AUDIO_MP3
|
||||
|
||||
if type( mutagen_object ) == mutagen.mp3.MP3: return HC.AUDIO_MP3
|
||||
|
||||
except: print( traceback.format_exc() )
|
||||
|
||||
return HC.mime_enum_lookup[ 'unknown mime' ]
|
||||
|
||||
|
||||
except:
|
||||
wx.MessageBox( traceback.format_exc() )
|
||||
raise Exception( 'I could not identify the mime of the file' )
|
||||
except: return HC.APPLICATION_UNKNOWN
|
||||
|
||||
def GetMimeFromString( file ):
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ class Message( HC.HydrusYAMLBase ):
|
|||
if type( self._body ) == unicode: body_text = self._body.encode( 'utf-8' )
|
||||
else: body_text = self._body
|
||||
|
||||
message += ''.join( [ yaml.safe_dump( public_key ) for public_key in contact_to_public_keys ] ) + subject_text + body_text + ''.join( self._files ) + str( self._conversation_key ) + str( self._timestamp )
|
||||
message += ''.join( [ yaml.safe_dump( public_key ) for public_key in contact_to_public_keys ] ) + subject_text + body_text + ''.join( self._files ) + HC.u( self._conversation_key ) + HC.u( self._timestamp )
|
||||
|
||||
hash_object = Crypto.Hash.SHA256.new( message )
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class HydrusPubSub():
|
|||
wx.PostEvent( HC.app, PubSubEvent() )
|
||||
|
||||
except wx.PyDeadObjectError: pass
|
||||
except: print( topic + ' for ' + str( object ) + ' bound to ' + method_name + os.linesep + traceback.format_exc() )
|
||||
except: print( topic + ' for ' + HC.u( object ) + ' bound to ' + method_name + os.linesep + traceback.format_exc() )
|
||||
|
||||
|
||||
|
||||
|
@ -77,7 +77,7 @@ class HydrusPubSub():
|
|||
|
||||
try: getattr( object, method_name )( *args, **kwargs )
|
||||
except wx.PyDeadObjectError: pass
|
||||
except: print( topic + ' for ' + str( object ) + ' bound to ' + method_name + os.linesep + traceback.format_exc() )
|
||||
except: print( topic + ' for ' + HC.u( object ) + ' bound to ' + method_name + os.linesep + traceback.format_exc() )
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ eris = '''<html><head><title>hydrus</title></head><body><pre>
|
|||
<font color="gray">MM</font>:::::<font color="gray">M</font>:::::::::::::::::::::<font color="gray">MMM</font>
|
||||
<font color="gray">MM</font>::::<font color="gray">M</font>::::::::::::::::::::<font color="gray">MMM</font>
|
||||
<font color="gray">MM</font>:::<font color="gray">M</font>::::::::::::::::::::<font color="gray">MMM</font>
|
||||
<font color="gray">MM</font>::<font color="gray">M</font>:::::::::::::::::::<font color="gray">MMM</font> THIS IS THE HYDRUS SERVER ADMIN SERVICE, VERSION ''' + str( HC.SOFTWARE_VERSION ) + '''
|
||||
<font color="gray">MM</font>::<font color="gray">M</font>:::::::::::::::::::<font color="gray">MMM</font> THIS IS THE HYDRUS SERVER ADMIN SERVICE, VERSION ''' + HC.u( HC.SOFTWARE_VERSION ) + '''
|
||||
<font color="gray">MM</font>:<font color="gray">M</font>:::::::::::::::::::<font color="gray">MMM</font>
|
||||
<font color="gray">MMM</font>::::::::::::::::::<font color="gray">MMM</font>
|
||||
<font color="gray">MM</font>::::::::::::::::::<font color="gray">MMM</font>
|
||||
|
@ -205,7 +205,7 @@ CLIENT_ROOT_MESSAGE = '''<html>
|
|||
<title>hydrus client</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>This hydrus client uses software version ''' + str( HC.SOFTWARE_VERSION ) + ''' and network version ''' + str( HC.NETWORK_VERSION ) + '''.</p>
|
||||
<p>This hydrus client uses software version ''' + HC.u( HC.SOFTWARE_VERSION ) + ''' and network version ''' + HC.u( HC.NETWORK_VERSION ) + '''.</p>
|
||||
<p>It only serves requests from 127.0.0.1.</p>
|
||||
</body>
|
||||
</html>'''
|
||||
|
@ -215,7 +215,7 @@ ROOT_MESSAGE_BEGIN = '''<html>
|
|||
<title>hydrus service</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>This hydrus service uses software version ''' + str( HC.SOFTWARE_VERSION ) + ''' and network version ''' + str( HC.NETWORK_VERSION ) + '''.</p>
|
||||
<p>This hydrus service uses software version ''' + HC.u( HC.SOFTWARE_VERSION ) + ''' and network version ''' + HC.u( HC.NETWORK_VERSION ) + '''.</p>
|
||||
<p>'''
|
||||
|
||||
ROOT_MESSAGE_END = '''</p>
|
||||
|
@ -246,7 +246,7 @@ def ParseFileArguments( file ):
|
|||
try: ( size, mime, width, height, duration, num_frames, num_words ) = HydrusFileHandling.GetFileInfo( file, hash )
|
||||
except HydrusExceptions.SizeException: raise HydrusExceptions.ForbiddenException( 'File is of zero length!' )
|
||||
except HydrusExceptions.MimeException: raise HydrusExceptions.ForbiddenException( 'Filetype is not permitted!' )
|
||||
except Exception as e: raise HydrusExceptions.ForbiddenException( unicode( e ) )
|
||||
except Exception as e: raise HydrusExceptions.ForbiddenException( HC.u( e ) )
|
||||
|
||||
args = {}
|
||||
|
||||
|
@ -370,10 +370,10 @@ class HydrusHTTPServer( SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer )
|
|||
|
||||
class HydrusHTTPRequestHandler( BaseHTTPServer.BaseHTTPRequestHandler ):
|
||||
|
||||
server_version = 'hydrus/' + str( HC.NETWORK_VERSION )
|
||||
server_version = 'hydrus/' + HC.u( HC.NETWORK_VERSION )
|
||||
protocol_version = 'HTTP/1.1'
|
||||
|
||||
with open( HC.STATIC_DIR + os.path.sep + 'hydrus.ico', 'rb' ) as f: _favicon = f.read()
|
||||
with HC.o( HC.STATIC_DIR + os.path.sep + 'hydrus.ico', 'rb' ) as f: _favicon = f.read()
|
||||
|
||||
def __init__( self, request, client_address, server ):
|
||||
|
||||
|
@ -390,7 +390,7 @@ class HydrusHTTPRequestHandler( BaseHTTPServer.BaseHTTPRequestHandler ):
|
|||
try:
|
||||
|
||||
default_mime = HC.TEXT_HTML
|
||||
default_encoding = lambda x: unicode( x )
|
||||
default_encoding = lambda x: HC.u( x )
|
||||
|
||||
user_agent_text = self.headers.getheader( 'User-Agent' )
|
||||
|
||||
|
@ -407,7 +407,7 @@ class HydrusHTTPRequestHandler( BaseHTTPServer.BaseHTTPRequestHandler ):
|
|||
if client == 'hydrus':
|
||||
|
||||
default_mime = HC.APPLICATION_YAML
|
||||
default_encoding = lambda x: yaml.safe_dump( unicode( x ) )
|
||||
default_encoding = lambda x: yaml.safe_dump( HC.u( x ) )
|
||||
|
||||
network_version = int( network_version )
|
||||
|
||||
|
@ -416,7 +416,7 @@ class HydrusHTTPRequestHandler( BaseHTTPServer.BaseHTTPRequestHandler ):
|
|||
if network_version < HC.NETWORK_VERSION: message = 'Please download the latest release.'
|
||||
else: message = 'Please ask this server\'s admin to update to the latest release.'
|
||||
|
||||
raise HydrusExceptions.NetworkVersionException( 'Network version mismatch! This server\'s network version is ' + str( HC.NETWORK_VERSION ) + ', whereas your client\'s is ' + str( network_version ) + '! ' + message )
|
||||
raise HydrusExceptions.NetworkVersionException( 'Network version mismatch! This server\'s network version is ' + HC.u( HC.NETWORK_VERSION ) + ', whereas your client\'s is ' + HC.u( network_version ) + '! ' + message )
|
||||
|
||||
|
||||
|
||||
|
@ -555,7 +555,7 @@ class HydrusHTTPRequestHandler( BaseHTTPServer.BaseHTTPRequestHandler ):
|
|||
|
||||
def log_message( self, format, *args ): print( "[%s] %s%s" % ( self.log_date_time_string(), format%args, os.linesep ) )
|
||||
|
||||
def log_request( self, *args ): pass # to start logging a little about every request, just delete this def. the default pushes to log_message
|
||||
def log_request( self, *args ): pass
|
||||
|
||||
def log_string( self, message ): print( message )
|
||||
|
||||
|
@ -564,7 +564,7 @@ class HydrusHTTPRequestHandler( BaseHTTPServer.BaseHTTPRequestHandler ):
|
|||
|
||||
service_type = self._service_identifier.GetType()
|
||||
|
||||
server_version = HC.service_string_lookup[ service_type ] + '/' + str( HC.NETWORK_VERSION )
|
||||
server_version = HC.service_string_lookup[ service_type ] + '/' + HC.u( HC.NETWORK_VERSION )
|
||||
|
||||
return server_version + ' ' + self.sys_version
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ class HydrusSessionManagerClient():
|
|||
|
||||
def GetSessionKey( self, service_identifier ):
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
with self._lock:
|
||||
|
||||
|
@ -91,7 +91,7 @@ class HydrusSessionManagerServer():
|
|||
|
||||
def GetAccountIdentifier( self, session_key, service_identifier ):
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
with self._lock:
|
||||
|
||||
|
|
|
@ -55,52 +55,43 @@ class TagsManagerSimple():
|
|||
|
||||
self._service_identifiers_to_statuses_to_tags = service_identifiers_to_statuses_to_tags
|
||||
|
||||
self._cstvcp_initialised = False
|
||||
self._combined_namespaces_cache = None
|
||||
|
||||
|
||||
def _RecalcCSTVCP( self ):
|
||||
def GetCombinedNamespaces( self, namespaces ):
|
||||
|
||||
self._creators = set()
|
||||
self._series = set()
|
||||
self._titles = set()
|
||||
self._volumes = set()
|
||||
self._chapters = set()
|
||||
self._pages = set()
|
||||
|
||||
combined_statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_IDENTIFIER ]
|
||||
|
||||
combined_current = combined_statuses_to_tags[ HC.CURRENT ]
|
||||
combined_pending = combined_statuses_to_tags[ HC.PENDING ]
|
||||
|
||||
for tag in combined_current.union( combined_pending ):
|
||||
if self._combined_namespaces_cache is None:
|
||||
|
||||
combined_statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_IDENTIFIER ]
|
||||
|
||||
if ':' in tag:
|
||||
combined_current = combined_statuses_to_tags[ HC.CURRENT ]
|
||||
combined_pending = combined_statuses_to_tags[ HC.PENDING ]
|
||||
|
||||
self._combined_namespaces_cache = HC.BuildKeyToSetDict( tag.split( ':', 1 ) for tag in combined_current.union( combined_pending ) if ':' in tag )
|
||||
|
||||
only_int_allowed = ( 'volume', 'chapter', 'page' )
|
||||
|
||||
for namespace in only_int_allowed:
|
||||
|
||||
( namespace, tag ) = tag.split( ':', 1 )
|
||||
tags = self._combined_namespaces_cache[ namespace ]
|
||||
|
||||
if namespace == 'creator': self._creators.add( tag )
|
||||
elif namespace == 'series': self._series.add( tag )
|
||||
elif namespace == 'title': self._titles.add( tag )
|
||||
elif namespace in ( 'volume', 'chapter', 'page' ):
|
||||
int_tags = set()
|
||||
|
||||
for tag in tags:
|
||||
|
||||
try: tag = int( tag )
|
||||
except: continue
|
||||
|
||||
if namespace == 'volume': self._volumes.add( tag )
|
||||
elif namespace == 'chapter': self._chapters.add( tag )
|
||||
elif namespace == 'page': self._pages.add( tag )
|
||||
int_tags.add( tag )
|
||||
|
||||
|
||||
self._combined_namespaces_cache[ namespace ] = int_tags
|
||||
|
||||
|
||||
|
||||
self._cstvcp_initialised = True
|
||||
result = { namespace : self._combined_namespaces_cache[ namespace ] for namespace in namespaces }
|
||||
|
||||
|
||||
def GetCSTVCP( self ):
|
||||
|
||||
if not self._cstvcp_initialised: self._RecalcCSTVCP()
|
||||
|
||||
return ( self._creators, self._series, self._titles, self._volumes, self._chapters, self._pages )
|
||||
return result
|
||||
|
||||
|
||||
def GetNamespaceSlice( self, namespaces, collapse = True ):
|
||||
|
@ -110,7 +101,7 @@ class TagsManagerSimple():
|
|||
combined_current = combined_statuses_to_tags[ HC.CURRENT ]
|
||||
combined_pending = combined_statuses_to_tags[ HC.PENDING ]
|
||||
|
||||
slice = { tag for tag in list( combined_current ) + list( combined_pending ) if True in ( tag.startswith( namespace + ':' ) for namespace in namespaces ) }
|
||||
slice = { tag for tag in combined_current.union( combined_pending ) if True in ( tag.startswith( namespace + ':' ) for namespace in namespaces ) }
|
||||
|
||||
if collapse:
|
||||
|
||||
|
@ -159,7 +150,7 @@ class TagsManager( TagsManagerSimple ):
|
|||
|
||||
self._service_identifiers_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_IDENTIFIER ] = combined_statuses_to_tags
|
||||
|
||||
if self._cstvcp_initialised: self._RecalcCSTVCP()
|
||||
self._combined_namespaces_cache = None
|
||||
|
||||
|
||||
def DeletePending( self, service_identifier ):
|
||||
|
|
|
@ -50,7 +50,7 @@ def GetMP4Duration( file ):
|
|||
|
||||
filename = HC.TEMP_DIR + os.path.sep + 'mp4_parse.mp4'
|
||||
|
||||
with open( filename, 'wb' ) as f: f.write( file )
|
||||
with HC.o( filename, 'wb' ) as f: f.write( file )
|
||||
|
||||
try: mp4_object = mutagen.mp4.MP4( filename )
|
||||
except: raise Exception( 'Could not parse the mp4!' )
|
||||
|
|
|
@ -14,7 +14,7 @@ class Controller( wx.App ):
|
|||
|
||||
def _AlreadyRunning( self, port ):
|
||||
|
||||
connection = httplib.HTTPConnection( 'localhost:' + str( port ) )
|
||||
connection = httplib.HTTPConnection( 'localhost:' + HC.u( port ) )
|
||||
|
||||
try:
|
||||
|
||||
|
@ -36,7 +36,7 @@ class Controller( wx.App ):
|
|||
server_daemon.setDaemon( True )
|
||||
server_daemon.start()
|
||||
|
||||
connection = httplib.HTTPConnection( 'localhost:' + str( port ) )
|
||||
connection = httplib.HTTPConnection( 'localhost:' + HC.u( port ) )
|
||||
|
||||
connection.connect()
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class FileDB():
|
|||
|
||||
hash_id = self._GetHashId( c, hash )
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
if c.execute( 'SELECT 1 FROM file_map WHERE service_id = ? AND hash_id = ?;', ( service_id, hash_id ) ).fetchone() is None or c.execute( 'SELECT 1 FROM file_petitions WHERE service_id = ? AND hash_id = ? AND status = ?;', ( service_id, hash_id, HC.DELETED ) ).fetchone() is None:
|
||||
|
||||
|
@ -100,7 +100,7 @@ class FileDB():
|
|||
|
||||
file = file_dict[ 'file' ]
|
||||
|
||||
with open( dest_path, 'wb' ) as f: f.write( file )
|
||||
with HC.o( dest_path, 'wb' ) as f: f.write( file )
|
||||
|
||||
|
||||
if 'thumbnail' in file_dict:
|
||||
|
@ -111,7 +111,7 @@ class FileDB():
|
|||
|
||||
thumbnail = file_dict[ 'thumbnail' ]
|
||||
|
||||
with open( thumbnail_dest_path, 'wb' ) as f: f.write( thumbnail )
|
||||
with HC.o( thumbnail_dest_path, 'wb' ) as f: f.write( thumbnail )
|
||||
|
||||
|
||||
|
||||
|
@ -142,7 +142,7 @@ class FileDB():
|
|||
# this clears out any old reasons, if the user wants to overwrite them
|
||||
c.execute( 'DELETE FROM file_petitions WHERE service_id = ? AND account_id = ? AND hash_id IN ' + HC.SplayListForDB( valid_hash_ids ) + ' AND status = ?;', ( service_id, account_id, HC.PETITIONED ) )
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.executemany( 'INSERT OR IGNORE INTO file_petitions ( service_id, account_id, hash_id, reason_id, timestamp, status ) VALUES ( ?, ?, ?, ?, ?, ? );', [ ( service_id, account_id, hash_id, reason_id, now, HC.PETITIONED ) for hash_id in valid_hash_ids ] )
|
||||
|
||||
|
@ -174,7 +174,7 @@ class FileDB():
|
|||
c.execute( 'DELETE FROM file_map WHERE service_id = ? AND hash_id IN ' + splayed_hash_ids + ';', ( service_id, ) )
|
||||
c.execute( 'DELETE FROM file_petitions WHERE service_id = ? AND hash_id IN ' + splayed_hash_ids + ' AND status = ?;', ( service_id, HC.PETITIONED ) )
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.executemany( 'INSERT OR IGNORE INTO file_petitions ( service_id, account_id, hash_id, reason_id, timestamp, status ) VALUES ( ?, ?, ?, ?, ?, ? );', ( ( service_id, account_id, hash_id, reason_id, now, HC.DELETED ) for hash_id in hash_ids ) )
|
||||
|
||||
|
@ -247,7 +247,7 @@ class FileDB():
|
|||
|
||||
path = GetPath( 'file', hash )
|
||||
|
||||
with open( path, 'rb' ) as f: file = f.read()
|
||||
with HC.o( path, 'rb' ) as f: file = f.read()
|
||||
|
||||
except: raise HydrusExceptions.NotFoundException( 'Could not find that file!' )
|
||||
|
||||
|
@ -355,7 +355,7 @@ class FileDB():
|
|||
|
||||
path = GetPath( 'thumbnail', hash )
|
||||
|
||||
with open( path, 'rb' ) as f: thumbnail = f.read()
|
||||
with HC.o( path, 'rb' ) as f: thumbnail = f.read()
|
||||
|
||||
return thumbnail
|
||||
|
||||
|
@ -378,11 +378,11 @@ class MessageDB():
|
|||
|
||||
message_key = os.urandom( 32 )
|
||||
|
||||
c.execute( 'INSERT OR IGNORE INTO messages ( message_key, service_id, account_id, timestamp ) VALUES ( ?, ?, ?, ? );', ( sqlite3.Binary( message_key ), service_id, account_id, int( time.time() ) ) )
|
||||
c.execute( 'INSERT OR IGNORE INTO messages ( message_key, service_id, account_id, timestamp ) VALUES ( ?, ?, ?, ? );', ( sqlite3.Binary( message_key ), service_id, account_id, HC.GetNow() ) )
|
||||
|
||||
dest_path = GetPath( 'message', message_key )
|
||||
|
||||
with open( dest_path, 'wb' ) as f: f.write( message )
|
||||
with HC.o( dest_path, 'wb' ) as f: f.write( message )
|
||||
|
||||
|
||||
def _AddStatuses( self, c, contact_key, statuses ):
|
||||
|
@ -390,7 +390,7 @@ class MessageDB():
|
|||
try: ( service_id, account_id ) = c.execute( 'SELECT service_id, account_id FROM contacts WHERE contact_key = ?;', ( sqlite3.Binary( contact_key ), ) ).fetchone()
|
||||
except: raise HydrusExceptions.ForbiddenException( 'Did not find that contact key for the message depot!' )
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.executemany( 'INSERT OR REPLACE INTO message_statuses ( status_key, service_id, account_id, status, timestamp ) VALUES ( ?, ?, ?, ?, ? );', [ ( sqlite3.Binary( status_key ), service_id, account_id, sqlite3.Binary( status ), now ) for ( status_key, status ) in statuses ] )
|
||||
|
||||
|
@ -422,7 +422,7 @@ class MessageDB():
|
|||
|
||||
path = GetPath( 'message', message_key )
|
||||
|
||||
with open( path, 'rb' ) as f: message = f.read()
|
||||
with HC.o( path, 'rb' ) as f: message = f.read()
|
||||
|
||||
except: raise HydrusExceptions.NotFoundException( 'Could not find that message!' )
|
||||
|
||||
|
@ -466,7 +466,7 @@ class TagDB():
|
|||
hash_ids = set( hash_ids ).difference( already_deleted )
|
||||
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.executemany( 'INSERT OR IGNORE INTO mappings ( service_id, tag_id, hash_id, account_id, timestamp ) VALUES ( ?, ?, ?, ?, ? );', [ ( service_id, tag_id, hash_id, account_id, now ) for hash_id in hash_ids ] )
|
||||
|
||||
|
@ -479,7 +479,7 @@ class TagDB():
|
|||
|
||||
c.execute( 'DELETE FROM mapping_petitions WHERE service_id = ? AND account_id = ? AND tag_id = ? AND hash_id IN ' + HC.SplayListForDB( valid_hash_ids ) + ' AND STATUS = ?;', ( service_id, account_id, tag_id, HC.PETITIONED ) )
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.executemany( 'INSERT OR IGNORE INTO mapping_petitions ( service_id, account_id, tag_id, hash_id, reason_id, timestamp, status ) VALUES ( ?, ?, ?, ?, ?, ?, ? );', [ ( service_id, account_id, tag_id, hash_id, reason_id, now, HC.PETITIONED ) for hash_id in valid_hash_ids ] )
|
||||
|
||||
|
@ -501,7 +501,7 @@ class TagDB():
|
|||
|
||||
c.execute( 'DELETE FROM tag_parents WHERE service_id = ? AND account_id = ? AND old_tag_id = ? AND new_tag_id = ? AND status = ?;', ( service_id, account_id, old_tag_id, new_tag_id, status ) )
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.execute( 'INSERT OR IGNORE INTO tag_parents ( service_id, account_id, old_tag_id, new_tag_id, reason_id, status, timestamp ) VALUES ( ?, ?, ?, ?, ?, ?, ? );', ( service_id, account_id, old_tag_id, new_tag_id, reason_id, status, now ) )
|
||||
|
||||
|
@ -523,7 +523,7 @@ class TagDB():
|
|||
|
||||
c.execute( 'DELETE FROM tag_siblings WHERE service_id = ? AND account_id = ? AND old_tag_id = ? AND new_tag_id = ? AND status = ?;', ( service_id, account_id, old_tag_id, new_tag_id, status ) )
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.execute( 'INSERT OR IGNORE INTO tag_siblings ( service_id, account_id, old_tag_id, new_tag_id, reason_id, status, timestamp ) VALUES ( ?, ?, ?, ?, ?, ?, ? );', ( service_id, account_id, old_tag_id, new_tag_id, reason_id, status, now ) )
|
||||
|
||||
|
@ -572,7 +572,7 @@ class TagDB():
|
|||
if status == HC.PENDING: new_status = HC.CURRENT
|
||||
elif status == HC.PETITIONED: new_status = HC.DELETED
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.execute( 'INSERT OR IGNORE INTO tag_parents ( service_id, account_id, old_tag_id, new_tag_id, reason_id, status, timestamp ) VALUES ( ?, ?, ?, ?, ?, ?, ? );', ( service_id, account_id, old_tag_id, new_tag_id, reason_id, new_status, now ) )
|
||||
|
||||
|
@ -605,7 +605,7 @@ class TagDB():
|
|||
if status == HC.PENDING: new_status = HC.CURRENT
|
||||
elif status == HC.PETITIONED: new_status = HC.DELETED
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.execute( 'INSERT OR IGNORE INTO tag_siblings ( service_id, account_id, old_tag_id, new_tag_id, reason_id, status, timestamp ) VALUES ( ?, ?, ?, ?, ?, ?, ? );', ( service_id, account_id, old_tag_id, new_tag_id, reason_id, new_status, now ) )
|
||||
|
||||
|
@ -621,7 +621,7 @@ class TagDB():
|
|||
c.execute( 'DELETE FROM mappings WHERE service_id = ? AND tag_id = ? AND hash_id IN ' + splayed_hash_ids + ';', ( service_id, tag_id ) )
|
||||
c.execute( 'DELETE FROM mapping_petitions WHERE service_id = ? AND tag_id = ? AND hash_id IN ' + splayed_hash_ids + ' AND status = ?;', ( service_id, tag_id, HC.PETITIONED ) )
|
||||
|
||||
c.executemany( 'INSERT OR IGNORE INTO mapping_petitions ( service_id, tag_id, hash_id, account_id, reason_id, timestamp, status ) VALUES ( ?, ?, ?, ?, ?, ?, ? );', ( ( service_id, tag_id, hash_id, account_id, reason_id, int( time.time() ), HC.DELETED ) for hash_id in hash_ids ) )
|
||||
c.executemany( 'INSERT OR IGNORE INTO mapping_petitions ( service_id, tag_id, hash_id, account_id, reason_id, timestamp, status ) VALUES ( ?, ?, ?, ?, ?, ?, ? );', ( ( service_id, tag_id, hash_id, account_id, reason_id, HC.GetNow(), HC.DELETED ) for hash_id in hash_ids ) )
|
||||
|
||||
self._RefreshUpdateCache( c, service_id, affected_timestamps )
|
||||
|
||||
|
@ -923,7 +923,7 @@ class RatingDB():
|
|||
|
||||
hash_ids_to_new_timestamps = { hash_id : new_timestamp for ( hash_id, new_timestamp ) in c.execute( 'SELECT hash_id, new_timestamp FROM aggregate_ratings WHERE service_id = ? AND hash_id IN ' + HC.SplayListForDB( hash_ids ) + ';', ( service_id, ) ) }
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
for ( hash_id, total_score, count ) in aggregates:
|
||||
|
||||
|
@ -947,7 +947,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
def _AccountTypeExists( self, c, service_id, title ): return c.execute( 'SELECT 1 FROM account_types, account_type_map USING ( account_type_id ) WHERE service_id = ? AND title = ?;', ( service_id, title ) ).fetchone() is not None
|
||||
|
||||
def _AddNews( self, c, service_id, news ): c.execute( 'INSERT INTO news ( service_id, news, timestamp ) VALUES ( ?, ?, ? );', ( service_id, news, int( time.time() ) ) )
|
||||
def _AddNews( self, c, service_id, news ): c.execute( 'INSERT INTO news ( service_id, news, timestamp ) VALUES ( ?, ?, ? );', ( service_id, news, HC.GetNow() ) )
|
||||
|
||||
def _AddSession( self, c, session_key, service_identifier, account_identifier, expiry ):
|
||||
|
||||
|
@ -964,7 +964,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
splayed_subject_account_ids = HC.SplayListForDB( subject_account_ids )
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
if expiration is not None: expires = expiration + now
|
||||
else: expires = None
|
||||
|
@ -1077,14 +1077,14 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
path = GetPath( 'update', update_key_bytes )
|
||||
|
||||
with open( path, 'wb' ) as f: f.write( yaml.safe_dump( clean_update ) )
|
||||
with HC.o( path, 'wb' ) as f: f.write( yaml.safe_dump( clean_update ) )
|
||||
|
||||
c.execute( 'UPDATE update_cache SET dirty = ? WHERE service_id = ? AND begin = ?;', ( False, service_id, begin ) )
|
||||
|
||||
|
||||
def _ClearBans( self, c ):
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.execute( 'DELETE FROM bans WHERE expires < ?;', ( now, ) )
|
||||
|
||||
|
@ -1102,7 +1102,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
path = GetPath( 'update', update_key_bytes )
|
||||
|
||||
with open( path, 'wb' ) as f: f.write( yaml.safe_dump( update ) )
|
||||
with HC.o( path, 'wb' ) as f: f.write( yaml.safe_dump( update ) )
|
||||
|
||||
c.execute( 'INSERT OR REPLACE INTO update_cache ( service_id, begin, end, update_key, dirty ) VALUES ( ?, ?, ?, ?, ? );', ( service_id, begin, end, update_key, False ) )
|
||||
|
||||
|
@ -1159,9 +1159,9 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
account_ids = self._GetAccountIds( c, access_keys )
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
if expiration is not None: expires = expiration + int( time.time() )
|
||||
if expiration is not None: expires = expiration + HC.GetNow()
|
||||
else: expires = None
|
||||
|
||||
c.executemany( 'INSERT INTO account_map ( service_id, account_id, account_type_id, created, expires, used_bytes, used_requests ) VALUES ( ?, ?, ?, ?, ?, ?, ? );', [ ( service_id, account_id, account_type_id, now, expires, 0, 0 ) for account_id in account_ids ] )
|
||||
|
@ -1171,9 +1171,9 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
def _GenerateRegistrationKeys( self, c, service_id, num, account_type_id, expiration ):
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
if expiration is not None: expiry = expiration + int( time.time() )
|
||||
if expiration is not None: expiry = expiration + HC.GetNow()
|
||||
else: expiry = None
|
||||
|
||||
keys = [ ( os.urandom( HC.HYDRUS_KEY_LENGTH ), os.urandom( HC.HYDRUS_KEY_LENGTH ) ) for i in range( num ) ]
|
||||
|
@ -1331,7 +1331,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
result = c.execute( 'SELECT account_type_id FROM account_types, account_type_map USING ( account_type_id ) WHERE service_id = ? AND title = ?;', ( service_id, title ) ).fetchone()
|
||||
|
||||
if result is None: raise HydrusExceptions.NotFoundException( 'Could not find account title ' + str( title ) + ' in db for this service.' )
|
||||
if result is None: raise HydrusExceptions.NotFoundException( 'Could not find account title ' + HC.u( title ) + ' in db for this service.' )
|
||||
|
||||
( account_type_id, ) = result
|
||||
|
||||
|
@ -1357,7 +1357,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
path = GetPath( 'update', update_key_bytes )
|
||||
|
||||
with open( path, 'rb' ) as f: update = f.read()
|
||||
with HC.o( path, 'rb' ) as f: update = f.read()
|
||||
|
||||
return update
|
||||
|
||||
|
@ -1451,7 +1451,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
def _GetSessions( self, c ):
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.execute( 'DELETE FROM sessions WHERE ? > expiry;', ( now, ) )
|
||||
|
||||
|
@ -1494,7 +1494,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
title = account_type.GetTitle()
|
||||
|
||||
if self._AccountTypeExists( c, service_id, title ): raise HydrusExceptions.ForbiddenException( 'Already found account type ' + str( title ) + ' in the db for this service, so could not add!' )
|
||||
if self._AccountTypeExists( c, service_id, title ): raise HydrusExceptions.ForbiddenException( 'Already found account type ' + HC.u( title ) + ' in the db for this service, so could not add!' )
|
||||
|
||||
c.execute( 'INSERT OR IGNORE INTO account_types ( title, account_type ) VALUES ( ?, ? );', ( title, account_type ) )
|
||||
|
||||
|
@ -1523,7 +1523,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
title = account_type.GetTitle()
|
||||
|
||||
if old_title != title and self._AccountTypeExists( c, service_id, title ): raise HydrusExceptions.ForbiddenException( 'Already found account type ' + str( title ) + ' in the database, so could not rename ' + str( old_title ) + '!' )
|
||||
if old_title != title and self._AccountTypeExists( c, service_id, title ): raise HydrusExceptions.ForbiddenException( 'Already found account type ' + HC.u( title ) + ' in the database, so could not rename ' + HC.u( old_title ) + '!' )
|
||||
|
||||
account_type_id = self._GetAccountTypeId( c, service_id, old_title )
|
||||
|
||||
|
@ -1534,7 +1534,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
def _ModifyServices( self, c, account_id, edit_log ):
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
for ( action, data ) in edit_log:
|
||||
|
||||
|
@ -1545,7 +1545,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
service_type = service_identifier.GetType()
|
||||
port = service_identifier.GetPort()
|
||||
|
||||
if c.execute( 'SELECT 1 FROM services WHERE port = ?;', ( port, ) ).fetchone() is not None: raise Exception( 'There is already a service hosted at port ' + str( port ) )
|
||||
if c.execute( 'SELECT 1 FROM services WHERE port = ?;', ( port, ) ).fetchone() is not None: raise Exception( 'There is already a service hosted at port ' + HC.u( port ) )
|
||||
|
||||
c.execute( 'INSERT INTO services ( type, port, options ) VALUES ( ?, ?, ? );', ( service_type, port, yaml.safe_dump( HC.DEFAULT_OPTIONS[ service_type ] ) ) )
|
||||
|
||||
|
@ -1564,7 +1564,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
if service_type in HC.REPOSITORIES:
|
||||
|
||||
begin = 0
|
||||
end = int( time.time() )
|
||||
end = HC.GetNow()
|
||||
|
||||
self._CreateUpdate( c, service_id, begin, end )
|
||||
|
||||
|
@ -1575,7 +1575,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
service_id = self._GetServiceId( c, service_identifier )
|
||||
|
||||
if c.execute( 'SELECT 1 FROM services WHERE port = ?;', ( new_port, ) ).fetchone() is not None: raise Exception( 'There is already a service hosted at port ' + str( port ) )
|
||||
if c.execute( 'SELECT 1 FROM services WHERE port = ?;', ( new_port, ) ).fetchone() is not None: raise Exception( 'There is already a service hosted at port ' + HC.u( port ) )
|
||||
|
||||
c.execute( 'UPDATE services SET port = ? WHERE service_id = ?;', ( new_port, service_id ) )
|
||||
|
||||
|
@ -1661,7 +1661,7 @@ class ServiceDB( FileDB, MessageDB, TagDB ):
|
|||
|
||||
account_id = c.lastrowid
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.execute( 'INSERT INTO account_map ( service_id, account_id, account_type_id, created, expires, used_bytes, used_requests ) VALUES ( ?, ?, ?, ?, ?, ?, ? );', ( service_id, account_id, account_type_id, now, expiry, 0, 0 ) )
|
||||
|
||||
|
@ -1719,7 +1719,7 @@ class DB( ServiceDB ):
|
|||
already_running = False
|
||||
|
||||
|
||||
if already_running: raise Exception( 'The server appears to be running already!' + os.linesep + 'Either that, or something else is using port ' + str( port ) + '.' )
|
||||
if already_running: raise Exception( 'The server appears to be running already!' + os.linesep + 'Either that, or something else is using port ' + HC.u( port ) + '.' )
|
||||
|
||||
|
||||
service_id = self._GetServiceId( c, service_identifier )
|
||||
|
@ -1785,7 +1785,7 @@ class DB( ServiceDB ):
|
|||
c.execute( 'PRAGMA auto_vacuum = 0;' ) # none
|
||||
c.execute( 'PRAGMA journal_mode=WAL;' )
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
c.execute( 'CREATE TABLE services ( service_id INTEGER PRIMARY KEY, type INTEGER, port INTEGER, options TEXT_YAML );' )
|
||||
|
||||
|
@ -2005,7 +2005,7 @@ class DB( ServiceDB ):
|
|||
|
||||
#
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
#
|
||||
|
||||
|
@ -2125,7 +2125,7 @@ class DB( ServiceDB ):
|
|||
|
||||
path_to = HC.SERVER_FILES_DIR + os.path.sep + hash.encode( 'hex' )
|
||||
|
||||
with open( path_to, 'wb' ) as f: f.write( file )
|
||||
with HC.o( path_to, 'wb' ) as f: f.write( file )
|
||||
|
||||
|
||||
c.execute( 'DELETE FROM files WHERE hash_id IN ' + HC.SplayListForDB( local_files_subset ) + ';' )
|
||||
|
@ -2170,7 +2170,7 @@ class DB( ServiceDB ):
|
|||
|
||||
path_to = HC.SERVER_THUMBNAILS_DIR + os.path.sep + hash.encode( 'hex' )
|
||||
|
||||
with open( path_to, 'wb' ) as f: f.write( thumbnail )
|
||||
with HC.o( path_to, 'wb' ) as f: f.write( thumbnail )
|
||||
|
||||
|
||||
|
||||
|
@ -2256,7 +2256,7 @@ class DB( ServiceDB ):
|
|||
|
||||
update_key = update_key_bytes.encode( 'hex' )
|
||||
|
||||
with open( HC.SERVER_UPDATES_DIR + os.path.sep + update_key, 'wb' ) as f: f.write( update )
|
||||
with HC.o( HC.SERVER_UPDATES_DIR + os.path.sep + update_key, 'wb' ) as f: f.write( update )
|
||||
|
||||
c.execute( 'INSERT INTO update_cache ( service_id, begin, end, update_key, dirty ) VALUES ( ?, ?, ?, ?, ? );', ( service_id, begin, end, update_key, dirty ) )
|
||||
|
||||
|
@ -2388,7 +2388,7 @@ class DB( ServiceDB ):
|
|||
|
||||
for ( service_id, biggest_end ) in update_ends:
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
next_begin = biggest_end + 1
|
||||
next_end = biggest_end + HC.UPDATE_DURATION
|
||||
|
@ -2399,7 +2399,7 @@ class DB( ServiceDB ):
|
|||
|
||||
biggest_end = next_end
|
||||
|
||||
now = int( time.time() )
|
||||
now = HC.GetNow()
|
||||
|
||||
next_begin = biggest_end + 1
|
||||
next_end = biggest_end + HC.UPDATE_DURATION
|
||||
|
@ -2500,11 +2500,11 @@ class DB( ServiceDB ):
|
|||
|
||||
max_age = 30 * 86400
|
||||
|
||||
expiry = int( time.time() ) + max_age
|
||||
expiry = HC.GetNow() + max_age
|
||||
|
||||
HC.app.AddSession( session_key, service_identifier, account_identifier, expiry )
|
||||
|
||||
cookies = [ 'session_key=' + session_key.encode( 'hex' ) + '; Max-Age=' + str( max_age ) + '; Path=/' ]
|
||||
cookies = [ 'session_key=' + session_key.encode( 'hex' ) + '; Max-Age=' + HC.u( max_age ) + '; Path=/' ]
|
||||
|
||||
response_context = HC.ResponseContext( 200, mime = HC.APPLICATION_YAML, body = '', cookies = cookies )
|
||||
|
||||
|
@ -2810,6 +2810,8 @@ class DB( ServiceDB ):
|
|||
|
||||
options = request_args[ 'options' ]
|
||||
|
||||
service_identifier = self._GetServiceIdentifier( c, service_id )
|
||||
|
||||
self._SetOptions( c, service_id, service_identifier, options )
|
||||
|
||||
elif request == 'services_modification':
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
import ClientDB
|
||||
import collections
|
||||
import HydrusConstants as HC
|
||||
import os
|
||||
import TestConstants
|
||||
import unittest
|
||||
|
||||
class TestDaemons( unittest.TestCase ):
|
||||
|
||||
def test_import_folders_daemon( self ):
|
||||
|
||||
test_dir = HC.TEMP_DIR + os.path.sep + 'test'
|
||||
|
||||
if not os.path.exists( test_dir ): os.mkdir( test_dir )
|
||||
|
||||
with HC.o( test_dir + os.path.sep + '1', 'wb' ) as f: f.write( TestConstants.tinest_gif )
|
||||
with HC.o( test_dir + os.path.sep + '2', 'wb' ) as f: f.write( TestConstants.tinest_gif )
|
||||
with HC.o( test_dir + os.path.sep + '3', 'wb' ) as f: f.write( TestConstants.tinest_gif )
|
||||
with HC.o( test_dir + os.path.sep + '4', 'wb' ) as f: f.write( 'blarg' ) # broken
|
||||
with HC.o( test_dir + os.path.sep + '5', 'wb' ) as f: f.write( TestConstants.tinest_gif ) # previously failed for whatever reason
|
||||
|
||||
#
|
||||
|
||||
path = test_dir
|
||||
|
||||
details = {}
|
||||
|
||||
details[ 'type' ] = HC.IMPORT_FOLDER_TYPE_SYNCHRONISE
|
||||
details[ 'cached_imported_paths' ] = { test_dir + os.path.sep + '2' }
|
||||
details[ 'failed_imported_paths' ] = { test_dir + os.path.sep + '5' }
|
||||
details[ 'local_tag' ] = 'local tag'
|
||||
details[ 'last_checked' ] = HC.GetNow() - 1500
|
||||
details[ 'check_period' ] = 1000
|
||||
|
||||
old_details = dict( details )
|
||||
|
||||
HC.app.SetRead( 'import_folders', [ ( path, details ) ] )
|
||||
|
||||
ClientDB.DAEMONCheckImportFolders()
|
||||
|
||||
expected_import_file = [(('GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;',), {'service_identifiers_to_tags': {HC.LOCAL_TAG_SERVICE_IDENTIFIER: set(['local tag'])}}), (('GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;',), {'service_identifiers_to_tags': {HC.LOCAL_TAG_SERVICE_IDENTIFIER: set(['local tag'])}}), (('blarg',), {'service_identifiers_to_tags': {HC.LOCAL_TAG_SERVICE_IDENTIFIER: set(['local tag'])}})]
|
||||
|
||||
import_file = HC.app.GetWrite( 'import_file' )
|
||||
|
||||
self.assertEqual( import_file, expected_import_file )
|
||||
|
||||
[ ( ( updated_path, updated_details ), kwargs ) ] = HC.app.GetWrite( 'import_folder' )
|
||||
|
||||
self.assertEqual( path, updated_path )
|
||||
|
||||
self.assertEqual( updated_details[ 'type' ], old_details[ 'type' ] )
|
||||
self.assertEqual( updated_details[ 'cached_imported_paths' ], { test_dir + os.path.sep + '1', test_dir + os.path.sep + '2', test_dir + os.path.sep + '3' } )
|
||||
self.assertEqual( updated_details[ 'failed_imported_paths' ], { test_dir + os.path.sep + '4', test_dir + os.path.sep + '5' } )
|
||||
self.assertEqual( updated_details[ 'local_tag' ], old_details[ 'local_tag' ] )
|
||||
self.assertGreater( updated_details[ 'last_checked' ], old_details[ 'last_checked' ] )
|
||||
self.assertEqual( updated_details[ 'check_period' ], old_details[ 'check_period' ] )
|
||||
|
||||
#
|
||||
|
||||
path = test_dir
|
||||
|
||||
details = {}
|
||||
|
||||
details[ 'type' ] = HC.IMPORT_FOLDER_TYPE_DELETE
|
||||
details[ 'cached_imported_paths' ] = set()
|
||||
details[ 'failed_imported_paths' ] = { test_dir + os.path.sep + '5' }
|
||||
details[ 'local_tag' ] = 'local tag'
|
||||
details[ 'last_checked' ] = HC.GetNow() - 1500
|
||||
details[ 'check_period' ] = 1000
|
||||
|
||||
old_details = dict( details )
|
||||
|
||||
HC.app.SetRead( 'import_folders', [ ( path, details ) ] )
|
||||
|
||||
ClientDB.DAEMONCheckImportFolders()
|
||||
|
||||
expected_import_file = [(('GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;',), {'service_identifiers_to_tags': {HC.LOCAL_TAG_SERVICE_IDENTIFIER: set(['local tag'])}}), (('GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;',), {'service_identifiers_to_tags': {HC.LOCAL_TAG_SERVICE_IDENTIFIER: set(['local tag'])}}), (('GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;',), {'service_identifiers_to_tags': {HC.LOCAL_TAG_SERVICE_IDENTIFIER: set(['local tag'])}}), (('blarg',), {'service_identifiers_to_tags': {HC.LOCAL_TAG_SERVICE_IDENTIFIER: set(['local tag'])}})]
|
||||
|
||||
import_file = HC.app.GetWrite( 'import_file' )
|
||||
|
||||
self.assertEqual( import_file, expected_import_file )
|
||||
|
||||
[ ( ( updated_path, updated_details ), kwargs ) ] = HC.app.GetWrite( 'import_folder' )
|
||||
|
||||
self.assertEqual( path, updated_path )
|
||||
|
||||
self.assertEqual( updated_details[ 'type' ], old_details[ 'type' ] )
|
||||
self.assertEqual( updated_details[ 'cached_imported_paths' ], set() )
|
||||
self.assertEqual( updated_details[ 'failed_imported_paths' ], { test_dir + os.path.sep + '4', test_dir + os.path.sep + '5' } )
|
||||
self.assertEqual( updated_details[ 'local_tag' ], old_details[ 'local_tag' ] )
|
||||
self.assertGreater( updated_details[ 'last_checked' ], old_details[ 'last_checked' ] )
|
||||
self.assertEqual( updated_details[ 'check_period' ], old_details[ 'check_period' ] )
|
||||
|
||||
self.assertTrue( not os.path.exists( test_dir + os.path.sep + '1' ) )
|
||||
self.assertTrue( not os.path.exists( test_dir + os.path.sep + '2' ) )
|
||||
self.assertTrue( not os.path.exists( test_dir + os.path.sep + '3' ) )
|
||||
self.assertTrue( os.path.exists( test_dir + os.path.sep + '4' ) )
|
||||
self.assertTrue( os.path.exists( test_dir + os.path.sep + '5' ) )
|
||||
|
||||
os.remove( test_dir + os.path.sep + '4' )
|
||||
os.remove( test_dir + os.path.sep + '5' )
|
||||
|
||||
os.rmdir( test_dir )
|
||||
|
||||
|
|
@ -3,7 +3,9 @@ import HydrusConstants as HC
|
|||
import HydrusTags
|
||||
import os
|
||||
import random
|
||||
import TestConstants
|
||||
import urlparse
|
||||
|
||||
tinest_gif = '\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x00\xFF\x00\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00\x3B'
|
||||
|
||||
def GenerateClientServiceIdentifier( service_type ):
|
||||
|
||||
|
@ -16,4 +18,100 @@ def GenerateClientServiceIdentifier( service_type ):
|
|||
|
||||
return HC.ClientServiceIdentifier( service_key, service_type, service_name )
|
||||
|
||||
|
||||
|
||||
class FakeFile():
|
||||
|
||||
def __init__( self, data ):
|
||||
|
||||
self._data = data
|
||||
|
||||
|
||||
def __enter__( self ): return self
|
||||
|
||||
def __exit__( self, exc_type, exc_value, traceback ): return True
|
||||
|
||||
def read( self ): return self._data
|
||||
|
||||
def write( self, data ): self._data = data
|
||||
|
||||
class FakeFileManager():
|
||||
|
||||
def __init__( self ):
|
||||
|
||||
self._fake_files = {}
|
||||
|
||||
|
||||
def GetFile( self, path, access_type ): return self._fake_files[ path ]
|
||||
|
||||
def SetFile( self, path, fake_file ): self._fake_files[ path ] = fake_file
|
||||
|
||||
fake_file_manager = FakeFileManager()
|
||||
|
||||
class FakeHTTPConnection():
|
||||
|
||||
def __init__( self, url = '', scheme = 'http', host = '', port = None, service_identifier = None, accept_cookies = False ):
|
||||
|
||||
self._url = url
|
||||
self._scheme = scheme
|
||||
self._host = host
|
||||
self._port = port
|
||||
self._service_identifier = service_identifier
|
||||
self._accept_cookies = accept_cookies
|
||||
|
||||
self._responses = {}
|
||||
self._cookies = {}
|
||||
|
||||
|
||||
def close( self ): pass
|
||||
|
||||
def connect( self ): pass
|
||||
|
||||
def GetCookies( self ): return self._cookies
|
||||
|
||||
def geturl( self, url, headers = {}, is_redirect = False, follow_redirects = True ):
|
||||
|
||||
parse_result = urlparse.urlparse( url )
|
||||
|
||||
request = parse_result.path
|
||||
|
||||
query = parse_result.query
|
||||
|
||||
if query != '': request += '?' + query
|
||||
|
||||
return self.request( 'GET', request, headers = headers, is_redirect = is_redirect, follow_redirects = follow_redirects )
|
||||
|
||||
|
||||
def request( self, request_type, request, headers = {}, body = None, is_redirect = False, follow_redirects = True ):
|
||||
|
||||
response = self._responses[ ( request_type, request ) ]
|
||||
|
||||
if issubclass( type( response ), Exception ): raise response
|
||||
else: return response
|
||||
|
||||
|
||||
def SetCookie( self, key, value ): self._cookies[ key ] = value
|
||||
|
||||
def SetResponse( self, request_type, request, response ): self._responses[ ( request_type, request ) ] = response
|
||||
|
||||
class FakeHTTPConnectionManager():
|
||||
|
||||
def __init__( self ):
|
||||
|
||||
self._fake_connections = {}
|
||||
|
||||
|
||||
def GetConnection( self, url = '', scheme = 'http', host = '', port = None, service_identifier = None, accept_cookies = False ):
|
||||
|
||||
args = ( url, scheme, host, port, service_identifier, accept_cookies )
|
||||
|
||||
return self._fake_connections[ args ]
|
||||
|
||||
|
||||
def SetConnection( self, connection, url = '', scheme = 'http', host = '', port = None, service_identifier = None, accept_cookies = False ):
|
||||
|
||||
args = ( url, scheme, host, port, service_identifier, accept_cookies )
|
||||
|
||||
self._fake_connections[ args ] = connection
|
||||
|
||||
|
||||
fake_http_connection_manager = FakeHTTPConnectionManager()
|
|
@ -1,13 +1,4 @@
|
|||
import TestConstants
|
||||
import unittest
|
||||
|
||||
class TestDB( unittest.TestCase ): pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
app = TestConstants.TestController()
|
||||
|
||||
unittest.main( verbosity = 2, exit = False )
|
||||
|
||||
raw_input()
|
||||
|
||||
class TestDB( unittest.TestCase ): pass
|
|
@ -1,4 +1,4 @@
|
|||
import ClientConstants
|
||||
import ClientConstants as CC
|
||||
import ClientGUIDialogs
|
||||
import collections
|
||||
import HydrusConstants as HC
|
||||
|
@ -9,7 +9,33 @@ import wx
|
|||
|
||||
def HitButton( button ): wx.PostEvent( button, wx.CommandEvent( wx.EVT_BUTTON.typeId, button.GetId() ) )
|
||||
|
||||
class TestNonValidatorDialogs( unittest.TestCase ):
|
||||
def PressKey( window, key ):
|
||||
|
||||
event = wx.KeyEvent( wx.EVT_KEY_DOWN.typeId )
|
||||
|
||||
event.m_keyCode = key
|
||||
event.SetEventObject( window )
|
||||
event.SetId( window.GetId() )
|
||||
|
||||
wx.PostEvent( window, event )
|
||||
|
||||
class TestDBDialogs( unittest.TestCase ):
|
||||
|
||||
def test_dialog_select_booru( self ):
|
||||
|
||||
HC.app.SetRead( 'boorus', CC.DEFAULT_BOORUS )
|
||||
|
||||
with ClientGUIDialogs.DialogSelectBooru( None ) as dlg:
|
||||
|
||||
HitButton( dlg._dialog_cancel_button )
|
||||
|
||||
result = dlg.ShowModal()
|
||||
|
||||
self.assertEqual( result, wx.ID_CANCEL )
|
||||
|
||||
|
||||
|
||||
class TestNonDBDialogs( unittest.TestCase ):
|
||||
|
||||
def test_dialog_choose_new_service_method( self ):
|
||||
|
||||
|
@ -41,7 +67,7 @@ class TestNonValidatorDialogs( unittest.TestCase ):
|
|||
|
||||
with ClientGUIDialogs.DialogChooseNewServiceMethod( None ) as dlg:
|
||||
|
||||
HitButton( dlg._cancel )
|
||||
HitButton( dlg._dialog_cancel_button )
|
||||
|
||||
result = dlg.ShowModal()
|
||||
|
||||
|
@ -113,7 +139,7 @@ class TestNonValidatorDialogs( unittest.TestCase ):
|
|||
|
||||
with ClientGUIDialogs.DialogFirstStart( None ) as dlg:
|
||||
|
||||
HitButton( dlg._cancel )
|
||||
HitButton( dlg._dialog_cancel_button )
|
||||
|
||||
result = dlg.ShowModal()
|
||||
|
||||
|
@ -141,4 +167,66 @@ class TestNonValidatorDialogs( unittest.TestCase ):
|
|||
self.assertEqual( result, wx.ID_CANCEL )
|
||||
|
||||
|
||||
|
||||
def test_select_from_list_of_strings( self ):
|
||||
|
||||
with ClientGUIDialogs.DialogSelectFromListOfStrings( None, 'select from a list of strings', [ 'a', 'b', 'c' ] ) as dlg:
|
||||
|
||||
wx.CallAfter( dlg._strings.Select, 0 )
|
||||
PressKey( dlg._strings, wx.WXK_SPACE )
|
||||
|
||||
result = dlg.ShowModal()
|
||||
|
||||
self.assertEqual( result, wx.ID_OK )
|
||||
|
||||
value = dlg.GetString()
|
||||
|
||||
self.assertEqual( value, 'a' )
|
||||
|
||||
|
||||
with ClientGUIDialogs.DialogSelectFromListOfStrings( None, 'select from a list of strings', [ 'a', 'b', 'c' ] ) as dlg:
|
||||
|
||||
HitButton( dlg._dialog_cancel_button )
|
||||
|
||||
result = dlg.ShowModal()
|
||||
|
||||
self.assertEqual( result, wx.ID_CANCEL )
|
||||
|
||||
|
||||
with ClientGUIDialogs.DialogSelectFromListOfStrings( None, 'select from a list of strings', [ 'a', 'b', 'c' ] ) as dlg:
|
||||
|
||||
wx.CallAfter( dlg._strings.Select, 1 )
|
||||
|
||||
HitButton( dlg._ok )
|
||||
|
||||
result = dlg.ShowModal()
|
||||
|
||||
self.assertEqual( result, wx.ID_OK )
|
||||
|
||||
value = dlg.GetString()
|
||||
|
||||
self.assertEqual( value, 'b' )
|
||||
|
||||
|
||||
|
||||
def test_dialog_yes_no( self ):
|
||||
|
||||
with ClientGUIDialogs.DialogYesNo( None, 'hello' ) as dlg:
|
||||
|
||||
HitButton( dlg._yes )
|
||||
|
||||
result = dlg.ShowModal()
|
||||
|
||||
self.assertEqual( result, wx.ID_YES )
|
||||
|
||||
|
||||
with ClientGUIDialogs.DialogYesNo( None, 'hello' ) as dlg:
|
||||
|
||||
HitButton( dlg._no )
|
||||
|
||||
result = dlg.ShowModal()
|
||||
|
||||
self.assertEqual( result, wx.ID_NO )
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import collections
|
||||
import HydrusConstants as HC
|
||||
import HydrusDownloading
|
||||
import os
|
||||
import TestConstants
|
||||
import unittest
|
||||
|
||||
class TestDownloaders( unittest.TestCase ):
|
||||
|
||||
def test_newgrounds( self ):
|
||||
|
||||
with HC.o( HC.STATIC_DIR + os.path.sep + 'testing' + os.path.sep + 'newgrounds_gallery_games.html' ) as f: newgrounds_gallery_games = f.read()
|
||||
with HC.o( HC.STATIC_DIR + os.path.sep + 'testing' + os.path.sep + 'newgrounds_gallery_movies.html' ) as f: newgrounds_gallery_movies = f.read()
|
||||
|
||||
fake_connection = TestConstants.FakeHTTPConnection( host = 'warlord-of-noodles.newgrounds.com' )
|
||||
|
||||
fake_connection.SetResponse( 'GET', '/games/', newgrounds_gallery_games )
|
||||
fake_connection.SetResponse( 'GET', '/movies/', newgrounds_gallery_movies )
|
||||
|
||||
TestConstants.fake_http_connection_manager.SetConnection( fake_connection, host = 'warlord-of-noodles.newgrounds.com' )
|
||||
|
||||
HC.get_connection = TestConstants.fake_http_connection_manager.GetConnection
|
||||
|
||||
#
|
||||
|
||||
downloader = HydrusDownloading.DownloaderNewgrounds( 'warlord-of-noodles' )
|
||||
|
||||
#
|
||||
|
||||
gallery_urls = downloader.GetAnotherPage()
|
||||
|
||||
expected_gallery_urls = [('http://www.newgrounds.com/portal/view/621259',), ('http://www.newgrounds.com/portal/view/617915',), ('http://www.newgrounds.com/portal/view/612665',), ('http://www.newgrounds.com/portal/view/610813',), ('http://www.newgrounds.com/portal/view/609683',), ('http://www.newgrounds.com/portal/view/593806',), ('http://www.newgrounds.com/portal/view/606387',), ('http://www.newgrounds.com/portal/view/606111',), ('http://www.newgrounds.com/portal/view/604603',), ('http://www.newgrounds.com/portal/view/604152',), ('http://www.newgrounds.com/portal/view/603027',), ('http://www.newgrounds.com/portal/view/601680',), ('http://www.newgrounds.com/portal/view/600626',), ('http://www.newgrounds.com/portal/view/591049',), ('http://www.newgrounds.com/portal/view/583715',), ('http://www.newgrounds.com/portal/view/584272',), ('http://www.newgrounds.com/portal/view/577497',), ('http://www.newgrounds.com/portal/view/563780',), ('http://www.newgrounds.com/portal/view/562785',), ('http://www.newgrounds.com/portal/view/553298',), ('http://www.newgrounds.com/portal/view/550882',), ('http://www.newgrounds.com/portal/view/488200',), ('http://www.newgrounds.com/portal/view/509249',), ('http://www.newgrounds.com/portal/view/509175',), ('http://www.newgrounds.com/portal/view/488180',)]
|
||||
|
||||
self.assertEqual( gallery_urls, expected_gallery_urls )
|
||||
|
||||
#
|
||||
|
||||
with HC.o( HC.STATIC_DIR + os.path.sep + 'testing' + os.path.sep + 'newgrounds_page.html' ) as f: newgrounds_page = f.read()
|
||||
|
||||
fake_connection = TestConstants.FakeHTTPConnection( host = 'www.newgrounds.com' )
|
||||
|
||||
fake_connection.SetResponse( 'GET', '/portal/view/583715', newgrounds_page )
|
||||
|
||||
TestConstants.fake_http_connection_manager.SetConnection( fake_connection, host = 'www.newgrounds.com' )
|
||||
|
||||
fake_connection = TestConstants.FakeHTTPConnection( host = 'uploads.ungrounded.net' )
|
||||
|
||||
fake_connection.SetResponse( 'GET', '/583000/583715_catdust.swf', 'swf file' )
|
||||
|
||||
TestConstants.fake_http_connection_manager.SetConnection( fake_connection, host = 'uploads.ungrounded.net' )
|
||||
|
||||
info = downloader.GetFileAndTags( 'http://www.newgrounds.com/portal/view/583715' )
|
||||
|
||||
expected_info = ('swf file', set([u'chores', u'laser', u'silent', u'title:Cat Dust', u'creator:warlord-of-noodles', u'pointer']))
|
||||
|
||||
self.assertEqual( info, expected_info )
|
||||
|
||||
# check the swf url and tags are correct
|
||||
|
||||
#
|
||||
|
||||
HC.get_connection = HC.AdvancedHTTPConnection
|
||||
|
||||
|
|
@ -68,7 +68,9 @@ class TestMergeTagsManagers( unittest.TestCase ):
|
|||
|
||||
#
|
||||
|
||||
self.assertEqual( tags_manager.GetCSTVCP(), ( { 'tsutomu nihei' }, { 'blame!' }, { 'double page spread' }, { 3 }, { 1, 2 }, { 4, 5 } ) )
|
||||
result = { 'creator' : { 'tsutomu nihei' }, 'series' : { 'blame!' }, 'title' : { 'double page spread' }, 'volume' : { 3 }, 'chapter' : { 1, 2 }, 'page' : { 4, 5 } }
|
||||
|
||||
self.assertEqual( tags_manager.GetCombinedNamespaces( ( 'creator', 'series', 'title', 'volume', 'chapter', 'page' ) ), result )
|
||||
|
||||
self.assertEqual( tags_manager.GetNamespaceSlice( ( 'character', ) ), frozenset( { 'character:cibo' } ) )
|
||||
|
||||
|
@ -130,8 +132,9 @@ class TestTagsManager( unittest.TestCase ):
|
|||
|
||||
def test_get_cstvcp( self ):
|
||||
|
||||
# volume, chapter and page can only return numbers, so broken_volume etc. are discarded
|
||||
self.assertEqual( self._tags_manager.GetCSTVCP(), ( { 'tsutomu nihei' }, { 'blame!' }, { 'test title' }, { 3 }, { 2 }, { 1 } ) )
|
||||
result = { 'creator' : { 'tsutomu nihei' }, 'series' : { 'blame!' }, 'title' : { 'test title' }, 'volume' : { 3 }, 'chapter' : { 2 }, 'page' : { 1 } }
|
||||
|
||||
self.assertEqual( self._tags_manager.GetCombinedNamespaces( ( 'creator', 'series', 'title', 'volume', 'chapter', 'page' ) ), result )
|
||||
|
||||
|
||||
def test_delete_pending( self ):
|
||||
|
|
|
@ -66,7 +66,7 @@ def __is_number_start(text):
|
|||
# End of Assume
|
||||
|
||||
def base10 (text,base):
|
||||
number = str(text).lower()
|
||||
number = HC.u(text).lower()
|
||||
result=0L
|
||||
for digit in number:
|
||||
result*=base
|
||||
|
|
37
server.pyw
37
server.pyw
|
@ -14,22 +14,33 @@ import locale
|
|||
locale.setlocale( locale.LC_ALL, '' )
|
||||
|
||||
import os
|
||||
import sys
|
||||
from include import HydrusConstants as HC
|
||||
from include import ServerController
|
||||
|
||||
try:
|
||||
|
||||
app = ServerController.Controller( True, HC.LOGS_DIR + os.path.sep + 'server.log' )
|
||||
|
||||
app.MainLoop()
|
||||
|
||||
except:
|
||||
|
||||
import traceback
|
||||
print( traceback.format_exc() )
|
||||
|
||||
initial_sys_stdout = sys.stdout
|
||||
initial_sys_stderr = sys.stderr
|
||||
|
||||
try: HC.shutdown = True
|
||||
except: pass
|
||||
with HC.o( HC.LOGS_DIR + os.path.sep + 'server.log', 'a' ) as f:
|
||||
|
||||
sys.stdout = f
|
||||
sys.stderr = f
|
||||
|
||||
try:
|
||||
|
||||
app = ServerController.Controller()
|
||||
|
||||
app.MainLoop()
|
||||
|
||||
except:
|
||||
|
||||
import traceback
|
||||
print( traceback.format_exc() )
|
||||
|
||||
|
||||
sys.stdout = initial_sys_stdout
|
||||
sys.stderr = initial_sys_stderr
|
||||
|
||||
HC.shutdown = True
|
||||
|
||||
HC.pubsub.pubimmediate( 'shutdown' )
|
||||
|
|
|
@ -0,0 +1,536 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Warlord-of-Noodles's Games</title>
|
||||
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge" /><![endif]-->
|
||||
|
||||
<link rel="stylesheet" href="http://css.ngfiles.com/ng_publish.css?1374679673" type="text/css" media="all" /> <link rel="stylesheet" href="http://css.ngfiles.com/iphone.css?1328564601" type="text/css" media="only screen and (max-device-width: 480px)" /> <link rel="stylesheet" href="http://css.ngfiles.com/print.css?1328564601" type="text/css" media="print" />
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
PHP.set('is_ie', true);
|
||||
// ]]>
|
||||
</script>
|
||||
<![endif]-->
|
||||
|
||||
<!--[if lte IE 9]>
|
||||
<link rel="stylesheet" href="http://css.ngfiles.com/ie9.css?1328656560" type="text/css" media="screen" />
|
||||
<![endif]-->
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<link rel="stylesheet" href="http://css.ngfiles.com/ie8.css?1337819134" type="text/css" media="screen" />
|
||||
<![endif]-->
|
||||
|
||||
<!--[if lte IE 7]>
|
||||
<link rel="stylesheet" href="http://css.ngfiles.com/ie7.css?1328564601" type="text/css" media="screen" />
|
||||
<![endif]-->
|
||||
|
||||
<!--[if lte IE 6]>
|
||||
<link rel="stylesheet" href="http://css.ngfiles.com/ie6.css?1328564286" type="text/css" media="screen" />
|
||||
<![endif]-->
|
||||
|
||||
<style type="text/css">
|
||||
/* this way the menus work with or without the javascript working */
|
||||
#header dl dd {
|
||||
display: none;
|
||||
}
|
||||
#header dl:hover dd {
|
||||
/*display: block; */
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
if (!window.jQuery) {
|
||||
document.write('<script src="http://js.ngfiles.com/jquery/jquery.js" type="text/javascript"><\/script>');
|
||||
}
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/javascript" src="http://js.ngfiles.com/ng_publish.js?1374772896"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="http://js.ngfiles.com/css_browser_selector.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
var $ng_adcode_ctime = 1375211106;
|
||||
var $ng_adcode_country = 2;
|
||||
var $ng_adcode_revsharing_id = null;
|
||||
var $ng_adcode_page = "userpages";
|
||||
var $ng_adcode_suitability = "T";
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
|
||||
<link rel="icon" type="image/png" href="http://www.newgrounds.com/img/icons/favicon.png" />
|
||||
<link rel="shortcut icon" href="http://www.newgrounds.com/favicon.ico" type="image/vnd.microsoft.icon" />
|
||||
<link rel="apple-touch-icon" href="http://img.ngfiles.com/misc/newgrounds_webclip.png" />
|
||||
<meta http-equiv="content-type" content="text/html; charset=windows-1252" />
|
||||
<meta name="viewport" content="width=976" />
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var $ng_adcode_user_is_supporter = 0;
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-850825-1']);
|
||||
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div id="blackout" style="display: none">
|
||||
<div id="blackout_bg"></div>
|
||||
<div class="pagecentered" id="blackout_center">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="#main" class="skipto">Skip to content.</a>
|
||||
<div id="outer" >
|
||||
|
||||
<div id="header" class="header">
|
||||
<div class="siteinfo">
|
||||
|
||||
<h1><a href="http://www.newgrounds.com">Newgrounds.com — Everything, By Everyone.</a></h1>
|
||||
|
||||
<div class="navigation">
|
||||
<div class="navbar" id="header_nav">
|
||||
<dl id="games">
|
||||
<dt><a href="http://www.newgrounds.com/games">Games</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/games/browse">Latest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/games/browse/sort/score/interval/month">Greatest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/games/browse/sort/views/interval/week">Popular</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/games/under_judgment">Under Judgment</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/portal">Classic Portal</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/projects/games"><em>Submit Yours!</em></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collab/browse/programmer"><em>Team Up!</em></a></dd>
|
||||
</dl>
|
||||
<dl id="movies">
|
||||
<dt><a href="http://www.newgrounds.com/movies">Movies</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/movies/browse">Latest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies/browse/sort/score/interval/month">Greatest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies/browse/sort/views/interval/week">Popular</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies/under_judgment">Under Judgment</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/portal">Classic Portal</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/projects/movies"><em>Submit Yours!</em></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collab/browse/artist"><em>Team Up!</em></a></dd>
|
||||
</dl>
|
||||
<dl id="audio">
|
||||
<dt><a href="http://www.newgrounds.com/audio">Audio</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/audio/browse/sort/date">Latest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/audio/browse/sort/score/interval/month">Greatest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/audio/browse/sort/views/interval/week">Popular</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/bbs/forum/13">Audio Forum</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/projects/audio"><em>Submit Yours!</em></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collab/browse/musician"><em>Team Up!</em></a></dd>
|
||||
</dl>
|
||||
<dl id="art">
|
||||
<dt><a href="http://www.newgrounds.com/art">Art</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/art/browse">Latest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/art/browse/sort/score/interval/month">Greatest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/art/browse/sort/views/interval/week">Popular</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/bbs/forum/14">Art Forum</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/art/submit/create"><em>Submit Yours!</em></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collab/browse/artist"><em>Team Up!</em></a></dd>
|
||||
</dl>
|
||||
<dl id="channels">
|
||||
<dt><a href="http://www.newgrounds.com/collection">Channels</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/collection/series">Series</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collection">Collections</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies/under_judgment">Judgment</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/playlists">Playlists</a></dd>
|
||||
</dl>
|
||||
<dl id="community">
|
||||
<dt><a href="http://www.newgrounds.com/bbs">Community</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/bbs">Forums</a></dd>
|
||||
<dd><a href="http://chat.newgrounds.com">Chat</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/calendar">Calendar</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/news/artists">Artist News</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/rankings">Rankings</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/downloads">Downloads</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki">Wiki</a></dd>
|
||||
</dl>
|
||||
<dl id="shop">
|
||||
<dt><a href="http://www.newgrounds.com/store">Shop</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/store/category/apparel">T-Shirts</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/store/category/collectible">Collectibles</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/store/category/print">Print</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/store/category/disc">Discs</a></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<h6>
|
||||
<a href="http://qikalain.newgrounds.com">Wall Artist</a> </h6>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sitelinks">
|
||||
|
||||
|
||||
<form id="loginboxform" action="https://www.newgrounds.com/login" method="post" class="loginbox">
|
||||
|
||||
<label id="header_label_username" for="username" style="display:none">Username</label>
|
||||
<input type="text" maxlength="20" id="username" name="username" value="" />
|
||||
|
||||
<label id="header_label_password" for="password" style="display:none">Password</label>
|
||||
<input type="password" maxlength="32" id="password" name="password" />
|
||||
|
||||
<input type="hidden" name="referrer" value="http://warlord-of-noodles.newgrounds.com/games" />
|
||||
<div class="checkboxes">
|
||||
<input type="checkbox" value="on" id="remember" name="remember" />
|
||||
<span><label for="remember">Save Info?</label></span>
|
||||
</div>
|
||||
<button type="submit">Log In</button>
|
||||
<ul class="loginlinks">
|
||||
<li><a href="http://www.newgrounds.com/join">Not a member? Sign Up!</a></li>
|
||||
<li><a href="http://www.newgrounds.com/join/forgot">Forgot login?</a></li>
|
||||
</ul>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
<form class="search" id="topsearch" action="http://www.newgrounds.com/search" method="get">
|
||||
<input type="text" name="topsearch_text" id="topsearch_text" />
|
||||
<div class="select">
|
||||
<div></div>
|
||||
<span>Movies</span>
|
||||
|
||||
<select class="formtext" name="topsearch_type" id="topsearch_type">
|
||||
<option value="16">Games</option>
|
||||
<option value="15" selected="selected">Movies</option>
|
||||
<option value="17">Audio</option>
|
||||
<option value="14">Art</option>
|
||||
<option value="4">Forums</option> </select>
|
||||
</div>
|
||||
<button type="submit">Search</button>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
PHP.set('search_urls', {"16":"http:\/\/www.newgrounds.com\/portal\/search\/games","15":"http:\/\/www.newgrounds.com\/portal\/search\/movies","17":"http:\/\/www.newgrounds.com\/audio\/search\/title","14":"http:\/\/www.newgrounds.com\/art\/search","4":"http:\/\/www.newgrounds.com\/bbs\/search\/topic","9":"http:\/\/www.newgrounds.com\/users\/search"});
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="headerads">
|
||||
<!-- include ads here -->
|
||||
<div style='display:none' class='adcode_container'>top-superbanner:728x90</div> <div style="display:none" class="storead_container">212:90:0</div> </div>
|
||||
|
||||
<div id="main">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="three3">
|
||||
<div class="podtop userheader">
|
||||
<h2 class="empty" id="page_username"><img src="http://uimg.ngfiles.com/icons/2785/2785798_small.jpg" alt="Warlord-of-Noodles" width="25" height="25" title="" />Warlord-of-Noodles</h2>
|
||||
<div>
|
||||
<a href="/"><span>Main</span></a>
|
||||
<a href="/news/"><span>News</span></a>
|
||||
<a href="/movies/"><span>Movies</span></a>
|
||||
<a ><span>Games</span></a>
|
||||
<a href="/art/"><span>Art</span></a>
|
||||
<a href="/favorites/"><span>Favorites</span></a>
|
||||
<a href="/reviews/"><span>Reviews</span></a>
|
||||
<a href="/stats/"><span>Stats</span></a>
|
||||
<a href="/fans/"><span>2,357 Fans</span></a>
|
||||
|
||||
<a title="Manage Favorites" href="http://<deleted>.newgrounds.com/favorites/following"
|
||||
id="manage_favorites" class="fave" style="display: none">
|
||||
<span></span>
|
||||
<span class="hovertext"><span>Manage Favorites</span></span>
|
||||
</a>
|
||||
|
||||
<script type="text/javascript" src="http://js.ngfiles.com/portal/favorites.js"></script>
|
||||
|
||||
<form method="post" action="/follow" id="follow_user" class="fave">
|
||||
<input type="hidden" name="userkey" id="userkey" value="e7ae1%O825db0362509%14b6O9b47c7ac6c%Pc225cr75%%d2c9a4%7%1%105%e25fs948c5c0dO9e52r7732rs%3fe6e7%%sc%6%1d9db5d70d3r7Pa18e%6frPfb2b1ecr06e06eab28e914d426938429b15f15665%s%4d7P%%O%rr5791-3443319" /> <input type="hidden" value="30" name="fav_type" />
|
||||
<input type="hidden" name="id" value="2785798" />
|
||||
<button type="submit" name="submit_favorite"><span></span></button>
|
||||
<span class="hovertext">
|
||||
<span>Follow Warlord-of-Noodles</span>
|
||||
</span>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
listen_follow('#follow_user', '#manage_favorites');
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="thincol">
|
||||
|
||||
<div style='display:none' class='adcode_container'>left-rectangle:300x250</div>
|
||||
<div class="one3">
|
||||
<div class="podtop">
|
||||
<h2 class="info">Contact Info / Websites</h2>
|
||||
<div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="podcontent">
|
||||
<ul class="blocklist">
|
||||
<li class="mail"><a href="http://www.newgrounds.com/pm/send/warlord-of-noodles">Send a Private Message (PM)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="podcontent">
|
||||
<ol class="website-links">
|
||||
<li><a href="http://www.betsydraws.com/" target="_blank" rel="nofollow"><img alt="www.betsydraws.com" src="http://s2.googleusercontent.com/s2/favicons?domain=www.betsydraws.com&feature=newgrounds" /> www.betsydraws.com</a></li>
|
||||
<li><a href="http://warlordofnoodles.comicgenesis.com/" target="_blank" rel="nofollow"><img alt="warlordofnoodles.comicgenesis.com" src="http://s2.googleusercontent.com/s2/favicons?domain=warlordofnoodles.comicgenesis.com&feature=newgrounds" /> Brother Swan</a></li>
|
||||
<li><a href="http://www.youtube.com/user/LadyCelest" target="_blank" rel="nofollow"><img alt="www.youtube.com" src="http://s2.googleusercontent.com/s2/favicons?domain=www.youtube.com&feature=newgrounds" /> My Youtube</a></li>
|
||||
<li><a href="http://warlord-of-noodles.deviantart.com/" target="_blank" rel="nofollow"><img alt="warlord-of-noodles.deviantart.com" src="http://s2.googleusercontent.com/s2/favicons?domain=warlord-of-noodles.deviantart.com&feature=newgrounds" /> My Deviant Art</a></li>
|
||||
<li><a href="https://twitter.com/#!/Warlordofnoodle" target="_blank" rel="nofollow"><img alt="twitter.com" src="http://s2.googleusercontent.com/s2/favicons?domain=twitter.com&feature=newgrounds" /> My Twitter</a></li>
|
||||
<li><a href="http://brotherswan.proboards.com/" target="_blank" rel="nofollow"><img alt="brotherswan.proboards.com" src="http://s2.googleusercontent.com/s2/favicons?domain=brotherswan.proboards.com&feature=newgrounds" /> My Stories' forum</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="podbot"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="fatcol">
|
||||
|
||||
|
||||
<div class="two3">
|
||||
<div class="podcontent">
|
||||
<p><span style="text-transform:capitalize">Warlord-of-Noodles</span> does not have any games.</p>
|
||||
</div>
|
||||
<div class="podbot"></div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<br style="clear: both" />
|
||||
</div>
|
||||
|
||||
<div id="footer" >
|
||||
|
||||
<div class="featuredcontent">
|
||||
<div class="featurebar">
|
||||
<dl>
|
||||
<dt>Featured Content</dt>
|
||||
<dd id="featgames" >
|
||||
<a href="/ajax/footer_feature.php?footer_feature=games" rel="nofollow">Games</a>
|
||||
</dd>
|
||||
<dd id="featmovies" >
|
||||
<a href="/ajax/footer_feature.php?footer_feature=movies" rel="nofollow">Movies</a>
|
||||
</dd>
|
||||
<dd id="feataudio" >
|
||||
<a href="/ajax/footer_feature.php?footer_feature=audio" rel="nofollow">Audio</a>
|
||||
</dd>
|
||||
<dd id="featart" >
|
||||
<a href="/ajax/footer_feature.php?footer_feature=art" rel="nofollow">Art</a>
|
||||
</dd>
|
||||
<dd id="featchannels" >
|
||||
<a href="/ajax/footer_feature.php?footer_feature=channels" rel="nofollow">Channels</a>
|
||||
</dd>
|
||||
<dd id="featusers" class="currentfeat">
|
||||
<a href="/ajax/footer_feature.php?footer_feature=users" rel="nofollow">Users</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="footerfeatures">
|
||||
|
||||
<a href="/ajax/footer_feature.php?footer_feature=channels" class="fprev" rel="nofollow">
|
||||
<span>Previous Section</span>
|
||||
</a>
|
||||
|
||||
<div id="content">
|
||||
<div class="user">
|
||||
<a href="http://freyaloi.newgrounds.com/news/post/858254">
|
||||
Freyaloi <strong>livestream: online</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="user">
|
||||
<a href="http://mirocka.newgrounds.com/news/post/858251">
|
||||
Mirocka <strong>Commissions</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="user">
|
||||
<a href="http://ramenrider.newgrounds.com/news/post/858249">
|
||||
RamenRider <strong>Update Entry (July 30th)</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="user">
|
||||
<a href="http://gujit.newgrounds.com/news/post/858246">
|
||||
Gujit <strong>Way to the Mountain</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="user">
|
||||
<a href="http://evil-dog.newgrounds.com/news/post/858244">
|
||||
Evil-Dog <strong>Road of the Dead 2: Live streaming all day!</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="user">
|
||||
<a href="http://sonik1.newgrounds.com/news/post/858239">
|
||||
sonik1 <strong>Suprise project comming up!</strong>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="/ajax/footer_feature.php?footer_feature=games" class="fnext" rel="nofollow">
|
||||
<span>Next Section</span>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
PHP.set('feature_url', '/ajax/footer_feature.php');
|
||||
|
||||
(function () {
|
||||
var featuredcontent = jQuery('#footer div.featuredcontent');
|
||||
featuredcontent.delegate('div.featurebar a, a.fprev, a.fnext', 'click', function (e) {
|
||||
featuredcontent.load(
|
||||
PHP.get('feature_url'),
|
||||
this.href.split('?')[1]
|
||||
);
|
||||
e.preventDefault();
|
||||
});
|
||||
})();
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</div>
|
||||
<div class="footerads">
|
||||
<div style="display:none" class="storead_container">212:90:0</div> <div style='display:none' class='adcode_container'>bottom-superbanner:728x90</div> </div>
|
||||
|
||||
<div class="siteinfo">
|
||||
<div class="copyright">
|
||||
<p><strong>© Copyright 1995-2013 Newgrounds, Inc. All rights reserved. <a href="http://www.newgrounds.com/wiki/help-information/privacy-policy">Privacy Policy</a> | <a href="http://www.newgrounds.com/wiki/help-information/terms-of-use">Terms of Use</a></strong></p>
|
||||
<p>newgrounds.com — Your #1 online entertainment & artist community! All your base are belong to us.</p>
|
||||
</div>
|
||||
|
||||
<div class="navigation">
|
||||
<dl>
|
||||
<dt>Main Sections</dt>
|
||||
<dd><a href="http://www.newgrounds.com/games"><span>Games</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies"><span>Movies</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/art"><span>Art</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/audio"><span>Audio</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/store"><span>Store</span></a></dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Extra, Extra!</dt>
|
||||
<dd><a href="http://www.newgrounds.com/collection/series"><span>Series</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collection"><span>Collections</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/games/under_judgment"><span>Game Judging</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies/under_judgment"><span>Movie Judging</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/portal"><span>Classic Portal</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/downloads"><span>Downloads</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/creator-resources"><span>Creator Resources</span></a></dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Community</dt>
|
||||
<dd><a href="http://www.newgrounds.com/bbs"><span>Forums</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/calendar"><span>Calendar</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/news/artists"><span>Artist News</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/rankings"><span>Rankings</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki"><span>NG Wiki</span></a></dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>NG Related</dt>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/about-newgrounds"><span>About NG</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/help-information"><span>Site Help</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/about-newgrounds/staff"><span>The Staff</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/about-newgrounds/history"><span>NG History</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/help-information/rss"><span>RSS</span></a></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="//www.newgrounds.com/ads/cache/ad_controller.js?rand=1363205747"></script>
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
(function ($) {
|
||||
if ($ng_adcode_user_is_supporter) {
|
||||
//$('#footer').css('height','575px');
|
||||
//$('#frontpagemessage').css('bottom','-556px');
|
||||
} else {
|
||||
$('.adcode_container').each(function() {
|
||||
$(this).show();
|
||||
var params = $(this).html().split(":");
|
||||
var adcode = $ng_adcode_config.getUnit(params[0],params[1]);
|
||||
$(this).html(''+adcode);
|
||||
});
|
||||
$('.storead_container').each(function() {
|
||||
$(this).show();
|
||||
var params = $(this).html().split(":");
|
||||
var adcode = $ng_adcode_config.getStoreAd(params[0],params[1],params[2]);
|
||||
$(this).html(''+adcode);
|
||||
});
|
||||
}
|
||||
})(jQuery);
|
||||
$ng_adcode_config = null; // free memory
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript"> (function(){ var sNew = document.createElement("script"); sNew.defer = true; sNew.src = "http://tag.crsspxl.com/s1.js?d=1370"; var s0 = document.getElementsByTagName('script')[0]; s0.parentNode.insertBefore(sNew, s0); })(); </script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1,989 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Warlord-of-Noodles's Movies</title>
|
||||
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge" /><![endif]-->
|
||||
|
||||
<link rel="stylesheet" href="http://css.ngfiles.com/ng_publish.css?1374679673" type="text/css" media="all" /> <link rel="stylesheet" href="http://css.ngfiles.com/iphone.css?1328564601" type="text/css" media="only screen and (max-device-width: 480px)" /> <link rel="stylesheet" href="http://css.ngfiles.com/print.css?1328564601" type="text/css" media="print" />
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
PHP.set('is_ie', true);
|
||||
// ]]>
|
||||
</script>
|
||||
<![endif]-->
|
||||
|
||||
<!--[if lte IE 9]>
|
||||
<link rel="stylesheet" href="http://css.ngfiles.com/ie9.css?1328656560" type="text/css" media="screen" />
|
||||
<![endif]-->
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<link rel="stylesheet" href="http://css.ngfiles.com/ie8.css?1337819134" type="text/css" media="screen" />
|
||||
<![endif]-->
|
||||
|
||||
<!--[if lte IE 7]>
|
||||
<link rel="stylesheet" href="http://css.ngfiles.com/ie7.css?1328564601" type="text/css" media="screen" />
|
||||
<![endif]-->
|
||||
|
||||
<!--[if lte IE 6]>
|
||||
<link rel="stylesheet" href="http://css.ngfiles.com/ie6.css?1328564286" type="text/css" media="screen" />
|
||||
<![endif]-->
|
||||
|
||||
<style type="text/css">
|
||||
/* this way the menus work with or without the javascript working */
|
||||
#header dl dd {
|
||||
display: none;
|
||||
}
|
||||
#header dl:hover dd {
|
||||
/*display: block; */
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
if (!window.jQuery) {
|
||||
document.write('<script src="http://js.ngfiles.com/jquery/jquery.js" type="text/javascript"><\/script>');
|
||||
}
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/javascript" src="http://js.ngfiles.com/ng_publish.js?1374772896"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="http://js.ngfiles.com/css_browser_selector.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
var $ng_adcode_ctime = 1375207749;
|
||||
var $ng_adcode_country = 2;
|
||||
var $ng_adcode_revsharing_id = null;
|
||||
var $ng_adcode_page = "userpages";
|
||||
var $ng_adcode_suitability = "T";
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
|
||||
<link rel="icon" type="image/png" href="http://www.newgrounds.com/img/icons/favicon.png" />
|
||||
<link rel="shortcut icon" href="http://www.newgrounds.com/favicon.ico" type="image/vnd.microsoft.icon" />
|
||||
<link rel="apple-touch-icon" href="http://img.ngfiles.com/misc/newgrounds_webclip.png" />
|
||||
<meta http-equiv="content-type" content="text/html; charset=windows-1252" />
|
||||
<meta name="viewport" content="width=976" />
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var $ng_adcode_user_is_supporter = 0;
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-850825-1']);
|
||||
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div id="blackout" style="display: none">
|
||||
<div id="blackout_bg"></div>
|
||||
<div class="pagecentered" id="blackout_center">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="#main" class="skipto">Skip to content.</a>
|
||||
<div id="outer" >
|
||||
|
||||
<div id="header" class="header">
|
||||
<div class="siteinfo">
|
||||
|
||||
<h1><a href="http://www.newgrounds.com">Newgrounds.com — Everything, By Everyone.</a></h1>
|
||||
|
||||
<div class="navigation">
|
||||
<div class="navbar" id="header_nav">
|
||||
<dl id="games">
|
||||
<dt><a href="http://www.newgrounds.com/games">Games</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/games/browse">Latest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/games/browse/sort/score/interval/month">Greatest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/games/browse/sort/views/interval/week">Popular</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/games/under_judgment">Under Judgment</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/portal">Classic Portal</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/projects/games"><em>Submit Yours!</em></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collab/browse/programmer"><em>Team Up!</em></a></dd>
|
||||
</dl>
|
||||
<dl id="movies">
|
||||
<dt><a href="http://www.newgrounds.com/movies">Movies</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/movies/browse">Latest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies/browse/sort/score/interval/month">Greatest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies/browse/sort/views/interval/week">Popular</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies/under_judgment">Under Judgment</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/portal">Classic Portal</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/projects/movies"><em>Submit Yours!</em></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collab/browse/artist"><em>Team Up!</em></a></dd>
|
||||
</dl>
|
||||
<dl id="audio">
|
||||
<dt><a href="http://www.newgrounds.com/audio">Audio</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/audio/browse/sort/date">Latest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/audio/browse/sort/score/interval/month">Greatest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/audio/browse/sort/views/interval/week">Popular</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/bbs/forum/13">Audio Forum</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/projects/audio"><em>Submit Yours!</em></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collab/browse/musician"><em>Team Up!</em></a></dd>
|
||||
</dl>
|
||||
<dl id="art">
|
||||
<dt><a href="http://www.newgrounds.com/art">Art</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/art/browse">Latest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/art/browse/sort/score/interval/month">Greatest</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/art/browse/sort/views/interval/week">Popular</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/bbs/forum/14">Art Forum</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/art/submit/create"><em>Submit Yours!</em></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collab/browse/artist"><em>Team Up!</em></a></dd>
|
||||
</dl>
|
||||
<dl id="channels">
|
||||
<dt><a href="http://www.newgrounds.com/collection">Channels</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/collection/series">Series</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collection">Collections</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies/under_judgment">Judgment</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/playlists">Playlists</a></dd>
|
||||
</dl>
|
||||
<dl id="community">
|
||||
<dt><a href="http://www.newgrounds.com/bbs">Community</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/bbs">Forums</a></dd>
|
||||
<dd><a href="http://chat.newgrounds.com">Chat</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/calendar">Calendar</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/news/artists">Artist News</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/rankings">Rankings</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/downloads">Downloads</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki">Wiki</a></dd>
|
||||
</dl>
|
||||
<dl id="shop">
|
||||
<dt><a href="http://www.newgrounds.com/store">Shop</a></dt>
|
||||
<dd><a href="http://www.newgrounds.com/store/category/apparel">T-Shirts</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/store/category/collectible">Collectibles</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/store/category/print">Print</a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/store/category/disc">Discs</a></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<h6>
|
||||
<a href="http://qikalain.newgrounds.com">Wall Artist</a> </h6>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sitelinks">
|
||||
|
||||
|
||||
<form id="loginboxform" action="https://www.newgrounds.com/login" method="post" class="loginbox">
|
||||
|
||||
<label id="header_label_username" for="username" style="display:none">Username</label>
|
||||
<input type="text" maxlength="20" id="username" name="username" value="" />
|
||||
|
||||
<label id="header_label_password" for="password" style="display:none">Password</label>
|
||||
<input type="password" maxlength="32" id="password" name="password" />
|
||||
|
||||
<input type="hidden" name="referrer" value="http://warlord-of-noodles.newgrounds.com/movies/" />
|
||||
<div class="checkboxes">
|
||||
<input type="checkbox" value="on" id="remember" name="remember" />
|
||||
<span><label for="remember">Save Info?</label></span>
|
||||
</div>
|
||||
<button type="submit">Log In</button>
|
||||
<ul class="loginlinks">
|
||||
<li><a href="http://www.newgrounds.com/join">Not a member? Sign Up!</a></li>
|
||||
<li><a href="http://www.newgrounds.com/join/forgot">Forgot login?</a></li>
|
||||
</ul>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
<form class="search" id="topsearch" action="http://www.newgrounds.com/search" method="get">
|
||||
<input type="text" name="topsearch_text" id="topsearch_text" />
|
||||
<div class="select">
|
||||
<div></div>
|
||||
<span>Movies</span>
|
||||
|
||||
<select class="formtext" name="topsearch_type" id="topsearch_type">
|
||||
<option value="16">Games</option>
|
||||
<option value="15" selected="selected">Movies</option>
|
||||
<option value="17">Audio</option>
|
||||
<option value="14">Art</option>
|
||||
<option value="4">Forums</option> </select>
|
||||
</div>
|
||||
<button type="submit">Search</button>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
PHP.set('search_urls', {"16":"http:\/\/www.newgrounds.com\/portal\/search\/games","15":"http:\/\/www.newgrounds.com\/portal\/search\/movies","17":"http:\/\/www.newgrounds.com\/audio\/search\/title","14":"http:\/\/www.newgrounds.com\/art\/search","4":"http:\/\/www.newgrounds.com\/bbs\/search\/topic","9":"http:\/\/www.newgrounds.com\/users\/search"});
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="headerads">
|
||||
<!-- include ads here -->
|
||||
<div style='display:none' class='adcode_container'>top-superbanner:728x90</div> <div style="display:none" class="storead_container">212:90:0</div> </div>
|
||||
|
||||
<div id="main">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="three3">
|
||||
<div class="podtop userheader">
|
||||
<h2 class="empty" id="page_username"><img src="http://uimg.ngfiles.com/icons/2785/2785798_small.jpg" alt="Warlord-of-Noodles" width="25" height="25" title="" />Warlord-of-Noodles</h2>
|
||||
<div>
|
||||
<a href="/"><span>Main</span></a>
|
||||
<a href="/news/"><span>News</span></a>
|
||||
<a ><span>Movies</span></a>
|
||||
<a href="/art/"><span>Art</span></a>
|
||||
<a href="/favorites/"><span>Favorites</span></a>
|
||||
<a href="/reviews/"><span>Reviews</span></a>
|
||||
<a href="/stats/"><span>Stats</span></a>
|
||||
<a href="/fans/"><span>2,357 Fans</span></a>
|
||||
|
||||
<a title="Manage Favorites" href="http://<deleted>.newgrounds.com/favorites/following"
|
||||
id="manage_favorites" class="fave" style="display: none">
|
||||
<span></span>
|
||||
<span class="hovertext"><span>Manage Favorites</span></span>
|
||||
</a>
|
||||
|
||||
<script type="text/javascript" src="http://js.ngfiles.com/portal/favorites.js"></script>
|
||||
|
||||
<form method="post" action="/follow" id="follow_user" class="fave">
|
||||
<input type="hidden" name="userkey" id="userkey" value="f0fe1%O425db43666fd%74b6O9b4cc7a1bc%Pc221br72%%d2c9a4%7%7%105%ea5fs448a5cf7O9e8br773frs%dde6e6%%s8%9%1c9db5d74dbr3Pa800%60rPfb290dcr06e06eab28e914d426938429b15f15665%s%4d7P%%O%rr2116-3425970" /> <input type="hidden" value="30" name="fav_type" />
|
||||
<input type="hidden" name="id" value="2785798" />
|
||||
<button type="submit" name="submit_favorite"><span></span></button>
|
||||
<span class="hovertext">
|
||||
<span>Follow Warlord-of-Noodles</span>
|
||||
</span>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
listen_follow('#follow_user', '#manage_favorites');
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="thincol">
|
||||
|
||||
<div style='display:none' class='adcode_container'>left-rectangle:300x250</div>
|
||||
<div class="one3">
|
||||
<div class="podtop">
|
||||
<h2 class="info">Contact Info / Websites</h2>
|
||||
<div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="podcontent">
|
||||
<ul class="blocklist">
|
||||
<li class="mail"><a href="http://www.newgrounds.com/pm/send/warlord-of-noodles">Send a Private Message (PM)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="podcontent">
|
||||
<ol class="website-links">
|
||||
<li><a href="http://www.betsydraws.com/" target="_blank" rel="nofollow"><img alt="www.betsydraws.com" src="http://s2.googleusercontent.com/s2/favicons?domain=www.betsydraws.com&feature=newgrounds" /> www.betsydraws.com</a></li>
|
||||
<li><a href="http://warlordofnoodles.comicgenesis.com/" target="_blank" rel="nofollow"><img alt="warlordofnoodles.comicgenesis.com" src="http://s2.googleusercontent.com/s2/favicons?domain=warlordofnoodles.comicgenesis.com&feature=newgrounds" /> Brother Swan</a></li>
|
||||
<li><a href="http://www.youtube.com/user/LadyCelest" target="_blank" rel="nofollow"><img alt="www.youtube.com" src="http://s2.googleusercontent.com/s2/favicons?domain=www.youtube.com&feature=newgrounds" /> My Youtube</a></li>
|
||||
<li><a href="http://warlord-of-noodles.deviantart.com/" target="_blank" rel="nofollow"><img alt="warlord-of-noodles.deviantart.com" src="http://s2.googleusercontent.com/s2/favicons?domain=warlord-of-noodles.deviantart.com&feature=newgrounds" /> My Deviant Art</a></li>
|
||||
<li><a href="https://twitter.com/#!/Warlordofnoodle" target="_blank" rel="nofollow"><img alt="twitter.com" src="http://s2.googleusercontent.com/s2/favicons?domain=twitter.com&feature=newgrounds" /> My Twitter</a></li>
|
||||
<li><a href="http://brotherswan.proboards.com/" target="_blank" rel="nofollow"><img alt="brotherswan.proboards.com" src="http://s2.googleusercontent.com/s2/favicons?domain=brotherswan.proboards.com&feature=newgrounds" /> My Stories' forum</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="podbot"></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="podtop">
|
||||
<h2 class="trophies">Movie Trophies</h2>
|
||||
<div><a href="/trophies">View All »</a></div>
|
||||
</div>
|
||||
|
||||
<div class="podcontent">
|
||||
<ul class="trophies">
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/621259" class="daily1">
|
||||
<strong>Little Bunny Foo Foo</strong>
|
||||
Daily Feature </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/621259" class="weekly2">
|
||||
<strong>Little Bunny Foo Foo</strong>
|
||||
Weekly 2nd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/617915" class="daily1">
|
||||
<strong>Swingers 006</strong>
|
||||
Daily Feature </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/612665" class="daily1">
|
||||
<strong>Tlaloc's Test</strong>
|
||||
Daily Feature </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/612665" class="weekly3">
|
||||
<strong>Tlaloc's Test</strong>
|
||||
Weekly 3rd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/610813" class="daily3">
|
||||
<strong>Dandy</strong>
|
||||
Daily 3rd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/609683" class="daily1">
|
||||
<strong>Swingers Episode 5</strong>
|
||||
Daily Feature </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/609683" class="weekly4">
|
||||
<strong>Swingers Episode 5</strong>
|
||||
Weekly 4th Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/606387" class="daily2">
|
||||
<strong>Out takes 01</strong>
|
||||
Daily 2nd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/606111" class="daily2">
|
||||
<strong>A Simple Melody</strong>
|
||||
Daily 2nd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/606111" class="weekly3">
|
||||
<strong>A Simple Melody</strong>
|
||||
Weekly 3rd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/604603" class="daily2">
|
||||
<strong>Coyote and Rattlesnake</strong>
|
||||
Daily 2nd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/603027" class="daily2">
|
||||
<strong>Swingers Episode 4</strong>
|
||||
Daily 2nd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/601680" class="daily1">
|
||||
<strong>And TheRaven Brought Fire</strong>
|
||||
Daily Feature </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/601680" class="weekly5">
|
||||
<strong>And TheRaven Brought Fire</strong>
|
||||
Weekly 5th Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/600626" class="daily3">
|
||||
<strong>The Fox and the Grapes</strong>
|
||||
Daily 3rd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/593806" class="daily4">
|
||||
<strong>Miss Kitty Sees You</strong>
|
||||
Daily 4th Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/591049" class="daily3">
|
||||
<strong>Swingers Episode 3</strong>
|
||||
Daily 3rd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/584272" class="daily4">
|
||||
<strong>Swingers Episode 2</strong>
|
||||
Daily 4th Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/583715" class="daily2">
|
||||
<strong>Cat Dust</strong>
|
||||
Daily 2nd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/583715" class="weekly4">
|
||||
<strong>Cat Dust</strong>
|
||||
Weekly 4th Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/577497" class="daily2">
|
||||
<strong>Swingers Episode 1</strong>
|
||||
Daily 2nd Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/563780" class="daily4">
|
||||
<strong>Do I Smell Chocolate?</strong>
|
||||
Daily 4th Place </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/562785" class="daily1">
|
||||
<strong>Step Sleeper</strong>
|
||||
Daily Feature </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.newgrounds.com/portal/view/488200" class="daily5">
|
||||
<strong>Mordred's Lullaby</strong>
|
||||
Daily 5th Place </a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="podbot"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="fatcol">
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<div class="podtop">
|
||||
<h2 class="movie">2013 Submissions</h2>
|
||||
<div>
|
||||
<a href="http://www.newgrounds.com/portal/view/621259"><strong>Best of 2013: </strong>Little Bunny Foo Foo </a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="podcontent iconarray movies">
|
||||
<a href="http://www.newgrounds.com/portal/view/621259" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/621000/flash_621259.jpg" alt="Little Bunny Foo Foo" width="140" height="90" title="" /> <span>
|
||||
<strong>Little Bunny Foo Foo</strong>
|
||||
<em><span style="width:89%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>someimes the field mice deserve it.</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/617915" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/617000/flash_617915.png" alt="Swingers 006" width="140" height="90" title="" /> <span>
|
||||
<strong>Swingers 006</strong>
|
||||
<em><span style="width:83%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Not even golden geese are easy money</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/612665" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/612000/flash_612665.jpg" alt="Tlaloc's Test" width="140" height="90" title="" /> <span>
|
||||
<strong>Tlaloc's Test</strong>
|
||||
<em><span style="width:90%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Do you trust the Water Pump?</span>
|
||||
<span>Other</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/610813" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/610000/flash_610813.png" alt="Dandy" width="140" height="90" title="" /> <span>
|
||||
<strong>Dandy</strong>
|
||||
<em><span style="width:87%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Be careful of whom you ask favors</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/609683" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/609000/flash_609683.jpg" alt="Swingers Episode 5" width="140" height="90" title="" /> <span>
|
||||
<strong>Swingers Episode 5</strong>
|
||||
<em><span style="width:84%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Curiosity Kills</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="podbot"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<div class="podtop">
|
||||
<h2 class="movie">2012 Submissions</h2>
|
||||
<div>
|
||||
<a href="http://www.newgrounds.com/portal/view/593806"><strong>Best of 2012: </strong>Miss Kitty Sees You </a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="podcontent iconarray movies">
|
||||
<a href="http://www.newgrounds.com/portal/view/606387" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/606000/flash_606387.jpg" alt="Out takes 01" width="140" height="90" title="" /> <span>
|
||||
<strong>Out takes 01</strong>
|
||||
<em><span style="width:80%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Out takes from swingers and no evil</span>
|
||||
<span>Other</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/606111" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/606000/flash_606111.jpg" alt="A Simple Melody" width="140" height="90" title="" /> <span>
|
||||
<strong>A Simple Melody</strong>
|
||||
<em><span style="width:89%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Sing a simple melody</span>
|
||||
<span>Other</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/604603" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/604000/flash_604603.jpg" alt="Coyote and Rattlesnake" width="140" height="90" title="" /> <span>
|
||||
<strong>Coyote and Rattlesnake</strong>
|
||||
<em><span style="width:86%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>A Sia Folktale</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/604152" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/604000/flash_604152.jpg" alt="Falling Angel" width="140" height="90" title="" /> <span>
|
||||
<strong>Falling Angel</strong>
|
||||
<em><span style="width:77%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>A message from above</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/603027" class="rated-t"><span></span>
|
||||
<img src="http://picon.ngfiles.com/603000/flash_603027.jpg" alt="Swingers Episode 4" width="140" height="90" title="" /> <span>
|
||||
<strong>Swingers Episode 4</strong>
|
||||
<em><span style="width:84%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>I do beleive in spooks</span>
|
||||
<span>Action</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/601680" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/601000/flash_601680.jpg" alt="And TheRaven Brought Fire" width="140" height="90" title="" /> <span>
|
||||
<strong>And TheRaven Brought Fire</strong>
|
||||
<em><span style="width:89%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>At one time there was nothing but darkness, and then the Raven brought fire</span>
|
||||
<span>Action</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/600626" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/600000/flash_600626.jpg" alt="The Fox and the Grapes" width="140" height="90" title="" /> <span>
|
||||
<strong>The Fox and the Grapes</strong>
|
||||
<em><span style="width:81%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>An Aesop Fabel</span>
|
||||
<span>Other</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/593806" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/593000/flash_593806.jpg" alt="Miss Kitty Sees You" width="140" height="90" title="" /> <span>
|
||||
<strong>Miss Kitty Sees You</strong>
|
||||
<em><span style="width:83%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Miss Kitty sings all ladylike</span>
|
||||
<span>Other</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/591049" class="rated-t"><span></span>
|
||||
<img src="http://picon.ngfiles.com/591000/flash_591049.jpg" alt="Swingers Episode 3" width="140" height="90" title="" /> <span>
|
||||
<strong>Swingers Episode 3</strong>
|
||||
<em><span style="width:82%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Blues is hazed</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="podbot"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<div class="podtop">
|
||||
<h2 class="movie">2011 Submissions</h2>
|
||||
<div>
|
||||
<a href="http://www.newgrounds.com/portal/view/583715"><strong>Best of 2011: </strong>Cat Dust </a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="podcontent iconarray movies">
|
||||
<a href="http://www.newgrounds.com/portal/view/584272" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/584000/flash_584272.jpg" alt="Swingers Episode 2" width="140" height="90" title="" /> <span>
|
||||
<strong>Swingers Episode 2</strong>
|
||||
<em><span style="width:82%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>An exstortionist comes to make an offer.</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/583715" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/583000/flash_583715.jpg" alt="Cat Dust" width="140" height="90" title="" /> <span>
|
||||
<strong>Cat Dust</strong>
|
||||
<em><span style="width:88%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>How far will lazyness go?</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/577497" class="rated-t"><span></span>
|
||||
<img src="http://picon.ngfiles.com/577000/flash_577497.jpg" alt="Swingers Episode 1" width="140" height="90" title="" /> <span>
|
||||
<strong>Swingers Episode 1</strong>
|
||||
<em><span style="width:82%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Tonight normal activity is broken by a thunderclap.... or several</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/563780" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/563000/flash_563780.jpg" alt="Do I Smell Chocolate?" width="140" height="90" title="" /> <span>
|
||||
<strong>Do I Smell Chocolate?</strong>
|
||||
<em><span style="width:75%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Papllion is a Special snowflake</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/562785" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/562000/flash_562785.jpg" alt="Step Sleeper" width="140" height="90" title="" /> <span>
|
||||
<strong>Step Sleeper</strong>
|
||||
<em><span style="width:82%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Happy cat is a stubborn cat</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="podbot"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<div class="podtop">
|
||||
<h2 class="movie">2010 Submissions</h2>
|
||||
<div>
|
||||
<a href="http://www.newgrounds.com/portal/view/553298"><strong>Best of 2010: </strong>She's in my Class </a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="podcontent iconarray movies">
|
||||
<a href="http://www.newgrounds.com/portal/view/553298" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/553000/flash_553298.jpg" alt="She's in my Class" width="140" height="90" title="" /> <span>
|
||||
<strong>She's in my Class</strong>
|
||||
<em><span style="width:74%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Sorrel is afraid of Spider</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/550882" class="rated-t"><span></span>
|
||||
<img src="http://picon.ngfiles.com/550000/flash_550882.jpeg" alt="The Tree Knows" width="140" height="90" title="" /> <span>
|
||||
<strong>The Tree Knows</strong>
|
||||
<em><span style="width:72%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>The tree sees you doing wrong</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="podbot"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<div class="podtop">
|
||||
<h2 class="movie">2009 Submissions</h2>
|
||||
<div>
|
||||
<a href="http://www.newgrounds.com/portal/view/488200"><strong>Best of 2009: </strong>Mordred's Lullaby </a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="podcontent iconarray movies">
|
||||
<a href="http://www.newgrounds.com/portal/view/509249" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/509000/flash_509249.png" alt="Doushite?" width="140" height="90" title="" /> <span>
|
||||
<strong>Doushite?</strong>
|
||||
<em><span style="width:73%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Spider has a nervous break down</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/509175" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/509000/flash_509175.png" alt="Oscar" width="140" height="90" title="" /> <span>
|
||||
<strong>Oscar</strong>
|
||||
<em><span style="width:78%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Havre Highschool is pleagued by the ghost of a janator</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/488200" class="rated-t"><span></span>
|
||||
<img src="http://picon.ngfiles.com/488000/flash_488200.png" alt="Mordred's Lullaby" width="140" height="90" title="" /> <span>
|
||||
<strong>Mordred's Lullaby</strong>
|
||||
<em><span style="width:86%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>Morgan Lafe Sings of her son's Destiny</span>
|
||||
<span>Music Video</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="http://www.newgrounds.com/portal/view/488180" class="rated-e"><span></span>
|
||||
<img src="http://picon.ngfiles.com/488000/flash_488180.png" alt="Stop Eating Mud" width="140" height="90" title="" /> <span>
|
||||
<strong>Stop Eating Mud</strong>
|
||||
<em><span style="width:82%">Rated Stars</span></em>
|
||||
</span>
|
||||
<span>
|
||||
<span>A little girl attempts to sell mud as candy.</span>
|
||||
<span>Comedy - Original</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="podbot"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<br style="clear: both" />
|
||||
</div>
|
||||
|
||||
<div id="footer" >
|
||||
|
||||
<div class="featuredcontent">
|
||||
<div class="featurebar">
|
||||
<dl>
|
||||
<dt>Featured Content</dt>
|
||||
<dd id="featgames" >
|
||||
<a href="/ajax/footer_feature.php?footer_feature=games" rel="nofollow">Games</a>
|
||||
</dd>
|
||||
<dd id="featmovies" >
|
||||
<a href="/ajax/footer_feature.php?footer_feature=movies" rel="nofollow">Movies</a>
|
||||
</dd>
|
||||
<dd id="feataudio" >
|
||||
<a href="/ajax/footer_feature.php?footer_feature=audio" rel="nofollow">Audio</a>
|
||||
</dd>
|
||||
<dd id="featart" >
|
||||
<a href="/ajax/footer_feature.php?footer_feature=art" rel="nofollow">Art</a>
|
||||
</dd>
|
||||
<dd id="featchannels" >
|
||||
<a href="/ajax/footer_feature.php?footer_feature=channels" rel="nofollow">Channels</a>
|
||||
</dd>
|
||||
<dd id="featusers" class="currentfeat">
|
||||
<a href="/ajax/footer_feature.php?footer_feature=users" rel="nofollow">Users</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="footerfeatures">
|
||||
|
||||
<a href="/ajax/footer_feature.php?footer_feature=channels" class="fprev" rel="nofollow">
|
||||
<span>Previous Section</span>
|
||||
</a>
|
||||
|
||||
<div id="content">
|
||||
<div class="user">
|
||||
<a href="http://mirocka.newgrounds.com/news/post/858251">
|
||||
Mirocka <strong>Commissions</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="user">
|
||||
<a href="http://ramenrider.newgrounds.com/news/post/858249">
|
||||
RamenRider <strong>Update Entry (July 30th)</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="user">
|
||||
<a href="http://gujit.newgrounds.com/news/post/858246">
|
||||
Gujit <strong>Way to the Mountain</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="user">
|
||||
<a href="http://evil-dog.newgrounds.com/news/post/858244">
|
||||
Evil-Dog <strong>Road of the Dead 2: Live streaming all day!</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="user">
|
||||
<a href="http://sonik1.newgrounds.com/news/post/858239">
|
||||
sonik1 <strong>Suprise project comming up!</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="user">
|
||||
<a href="http://justsomerandomdude.newgrounds.com/news/post/858238">
|
||||
justsomerandomdude <strong>Sneakpeek</strong>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="/ajax/footer_feature.php?footer_feature=games" class="fnext" rel="nofollow">
|
||||
<span>Next Section</span>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
PHP.set('feature_url', '/ajax/footer_feature.php');
|
||||
|
||||
(function () {
|
||||
var featuredcontent = jQuery('#footer div.featuredcontent');
|
||||
featuredcontent.delegate('div.featurebar a, a.fprev, a.fnext', 'click', function (e) {
|
||||
featuredcontent.load(
|
||||
PHP.get('feature_url'),
|
||||
this.href.split('?')[1]
|
||||
);
|
||||
e.preventDefault();
|
||||
});
|
||||
})();
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</div>
|
||||
<div class="footerads">
|
||||
<div style="display:none" class="storead_container">212:90:0</div> <div style='display:none' class='adcode_container'>bottom-superbanner:728x90</div> </div>
|
||||
|
||||
<div class="siteinfo">
|
||||
<div class="copyright">
|
||||
<p><strong>© Copyright 1995-2013 Newgrounds, Inc. All rights reserved. <a href="http://www.newgrounds.com/wiki/help-information/privacy-policy">Privacy Policy</a> | <a href="http://www.newgrounds.com/wiki/help-information/terms-of-use">Terms of Use</a></strong></p>
|
||||
<p>newgrounds.com — Your #1 online entertainment & artist community! All your base are belong to us.</p>
|
||||
</div>
|
||||
|
||||
<div class="navigation">
|
||||
<dl>
|
||||
<dt>Main Sections</dt>
|
||||
<dd><a href="http://www.newgrounds.com/games"><span>Games</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies"><span>Movies</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/art"><span>Art</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/audio"><span>Audio</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/store"><span>Store</span></a></dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Extra, Extra!</dt>
|
||||
<dd><a href="http://www.newgrounds.com/collection/series"><span>Series</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/collection"><span>Collections</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/games/under_judgment"><span>Game Judging</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/movies/under_judgment"><span>Movie Judging</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/portal"><span>Classic Portal</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/downloads"><span>Downloads</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/creator-resources"><span>Creator Resources</span></a></dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Community</dt>
|
||||
<dd><a href="http://www.newgrounds.com/bbs"><span>Forums</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/calendar"><span>Calendar</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/news/artists"><span>Artist News</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/rankings"><span>Rankings</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki"><span>NG Wiki</span></a></dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>NG Related</dt>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/about-newgrounds"><span>About NG</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/help-information"><span>Site Help</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/about-newgrounds/staff"><span>The Staff</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/about-newgrounds/history"><span>NG History</span></a></dd>
|
||||
<dd><a href="http://www.newgrounds.com/wiki/help-information/rss"><span>RSS</span></a></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="//www.newgrounds.com/ads/cache/ad_controller.js?rand=1363205747"></script>
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
(function ($) {
|
||||
if ($ng_adcode_user_is_supporter) {
|
||||
//$('#footer').css('height','575px');
|
||||
//$('#frontpagemessage').css('bottom','-556px');
|
||||
} else {
|
||||
$('.adcode_container').each(function() {
|
||||
$(this).show();
|
||||
var params = $(this).html().split(":");
|
||||
var adcode = $ng_adcode_config.getUnit(params[0],params[1]);
|
||||
$(this).html(''+adcode);
|
||||
});
|
||||
$('.storead_container').each(function() {
|
||||
$(this).show();
|
||||
var params = $(this).html().split(":");
|
||||
var adcode = $ng_adcode_config.getStoreAd(params[0],params[1],params[2]);
|
||||
$(this).html(''+adcode);
|
||||
});
|
||||
}
|
||||
})(jQuery);
|
||||
$ng_adcode_config = null; // free memory
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript"> (function(){ var sNew = document.createElement("script"); sNew.defer = true; sNew.src = "http://tag.crsspxl.com/s1.js?d=1370"; var s0 = document.getElementsByTagName('script')[0]; s0.parentNode.insertBefore(sNew, s0); })(); </script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
32
test.py
32
test.py
|
@ -1,10 +1,13 @@
|
|||
from include import HydrusConstants as HC
|
||||
from include import HydrusTags
|
||||
from include import TestClientDaemons
|
||||
from include import TestConstants
|
||||
from include import TestDialogs
|
||||
from include import TestDB
|
||||
from include import TestFunctions
|
||||
from include import TestHydrusDownloading
|
||||
from include import TestHydrusTags
|
||||
import collections
|
||||
import os
|
||||
import unittest
|
||||
import wx
|
||||
|
@ -22,14 +25,18 @@ class App( wx.App ):
|
|||
self._reads[ 'tag_service_precedence' ] = []
|
||||
self._reads[ 'tag_siblings' ] = {}
|
||||
|
||||
self._writes = collections.defaultdict( list )
|
||||
|
||||
self._tag_parents_manager = HydrusTags.TagParentsManager()
|
||||
self._tag_siblings_manager = HydrusTags.TagSiblingsManager()
|
||||
|
||||
suites = []
|
||||
|
||||
suites.append( unittest.TestLoader().loadTestsFromModule( TestClientDaemons ) )
|
||||
suites.append( unittest.TestLoader().loadTestsFromModule( TestDialogs ) )
|
||||
suites.append( unittest.TestLoader().loadTestsFromModule( TestDB ) )
|
||||
suites.append( unittest.TestLoader().loadTestsFromModule( TestFunctions ) )
|
||||
suites.append( unittest.TestLoader().loadTestsFromModule( TestHydrusDownloading ) )
|
||||
suites.append( unittest.TestLoader().loadTestsFromModule( TestHydrusTags ) )
|
||||
|
||||
suite = unittest.TestSuite( suites )
|
||||
|
@ -44,10 +51,35 @@ class App( wx.App ):
|
|||
def GetTagParentsManager( self ): return self._tag_parents_manager
|
||||
def GetTagSiblingsManager( self ): return self._tag_siblings_manager
|
||||
|
||||
def GetWrite( self, name ):
|
||||
|
||||
write = self._writes[ name ]
|
||||
|
||||
del self._writes[ name ]
|
||||
|
||||
return write
|
||||
|
||||
|
||||
def Read( self, name ): return self._reads[ name ]
|
||||
|
||||
def ReadDaemon( self, name ): return self.Read( name )
|
||||
|
||||
def SetRead( self, name, value ): self._reads[ name ] = value
|
||||
|
||||
def Write( self, name, *args, **kwargs ):
|
||||
|
||||
self._writes[ name ].append( ( args, kwargs ) )
|
||||
|
||||
|
||||
def WriteDaemon( self, name, *args, **kwargs ):
|
||||
|
||||
self._writes[ name ].append( ( args, kwargs ) )
|
||||
|
||||
if name == 'import_file':
|
||||
if args == ( 'blarg', ): raise Exception( 'File failed to import for some reason!' )
|
||||
else: return ( 'successful', 'hash' )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
app = App()
|
||||
|
|
Loading…
Reference in New Issue