Version 133

This commit is contained in:
Hydrus 2014-10-08 15:17:55 -05:00
parent 72a2605d5b
commit 8585942d95
11 changed files with 297 additions and 129 deletions

View File

@ -8,6 +8,20 @@
<div class="content">
<h3>changelog</h3>
<ul>
<li><h3>version 133</h3></li>
<ul>
<li>reworked the add file process to correct file repository file counts</li>
<li>made add file process to calculate inbox and local thumbnail count more efficiently</li>
<li>fixed a critical bug in server db creation that was stopping file repository service from working</li>
<li>added go/exit fullscreen options to fullscreen right click menu as alternative for default shortcut 'f'</li>
<li>improved fullscreen position, size, maximised, and borderless state memory</li>
<li>removed old 'fullscreen_borderless' option in local options</li>
<li>thread checker now supports 8chan urls</li>
<li>thread checker now has 'number of checks still to do' spin control so you have more options to fire and forget</li>
<li>improved how the thread checker constructs and passes url information around</li>
<li>improved some thread checker timing logic which _might_ have been causing problems</li>
<li>improved some thread checker error reporting</li>
</ul>
<li><h3>version 132</h3></li>
<ul>
<li>merged two complicated serverside account tables into two simpler tables</li>
@ -26,7 +40,7 @@
<li>added 'copy account key' button to review services, which will now be the thing for users to use if they need an admin to modify their account</li>
<li>fixed serverside credential verification for non-instantiated (still have a registration key) access keys</li>
<li>added a bit of explaining text to the 'waiting' autocomplete state</li>
<li>fixed a typo when deleting files from a file repo</li>
<li>fixed a typo that caused errors when deleting files from a file repo</li>
</ul>
<li><h3>version 131</h3></li>
<ul>

View File

@ -228,7 +228,6 @@ default_sort_by_choices.append( ( 'namespaces', [ 'creator', 'series', 'title',
CLIENT_DEFAULT_OPTIONS[ 'sort_by' ] = default_sort_by_choices
CLIENT_DEFAULT_OPTIONS[ 'show_all_tags_in_autocomplete' ] = True
CLIENT_DEFAULT_OPTIONS[ 'fullscreen_borderless' ] = True
CLIENT_DEFAULT_OPTIONS[ 'default_advanced_tag_options' ] = {}
@ -295,9 +294,11 @@ CLIENT_DEFAULT_OPTIONS[ 'pause_subs_sync' ] = False
client_size = {}
client_size[ 'gui_fullscreen' ] = False
client_size[ 'gui_maximised' ] = True
client_size[ 'gui_restored_size' ] = [ 640, 480 ]
client_size[ 'gui_restored_position' ] = [ 20, 20 ]
client_size[ 'fs_fullscreen' ] = True
client_size[ 'fs_maximised' ] = True
client_size[ 'fs_restored_size' ] = [ 640, 480 ]
client_size[ 'fs_restored_position' ] = [ 20, 20 ]

View File

@ -1270,42 +1270,43 @@ class TagDB( object ):
class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
def _AddFiles( self, c, files_info_rows ):
def _AddFile( self, c, service_id, hash_id, size, mime, timestamp, width, height, duration, num_frames, num_words ):
# service_id, hash_id, size, mime, timestamp, width, height, duration, num_frames, num_words
result = c.execute( 'SELECT 1 FROM files_info WHERE service_id = ? AND hash_id = ?;', ( service_id, hash_id ) ).fetchone()
c.executemany( 'INSERT OR IGNORE INTO files_info VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );', files_info_rows )
service_ids_to_rows = HC.BuildKeyToListDict( [ ( row[ 0 ], row[ 1: ] ) for row in files_info_rows ] )
for ( service_id, rows ) in service_ids_to_rows.items():
if result is None:
hash_ids = [ row[ 0 ] for row in rows ]
splayed_hash_ids = HC.SplayListForDB( hash_ids )
c.execute( 'DELETE FROM deleted_files WHERE service_id = ? AND hash_id IN ' + splayed_hash_ids + ';', ( service_id, ) )
num_deleted_files_rescinded = self._GetRowCount( c )
c.execute( 'DELETE FROM file_transfers WHERE service_id = ? AND hash_id IN ' + splayed_hash_ids + ';', ( service_id, ) )
total_size = sum( [ row[ 1 ] for row in rows ] )
num_files = len( rows )
num_thumbnails = len( [ 1 for row in rows if row[ 2 ] in HC.MIMES_WITH_THUMBNAILS ] )
c.execute( 'INSERT OR IGNORE INTO files_info VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );', ( service_id, hash_id, size, mime, timestamp, width, height, duration, num_frames, num_words ) )
service_info_updates = []
service_info_updates.append( ( total_size, service_id, HC.SERVICE_INFO_TOTAL_SIZE ) )
service_info_updates.append( ( num_files, service_id, HC.SERVICE_INFO_NUM_FILES ) )
service_info_updates.append( ( num_thumbnails, service_id, HC.SERVICE_INFO_NUM_THUMBNAILS ) )
service_info_updates.append( ( -num_deleted_files_rescinded, service_id, HC.SERVICE_INFO_NUM_DELETED_FILES ) )
result = c.execute( 'SELECT 1 FROM deleted_files WHERE service_id = ? AND hash_id = ?;', ( service_id, hash_id ) ).fetchone()
if result is not None:
c.execute( 'DELETE FROM deleted_files WHERE service_id = ? AND hash_id = ?;', ( service_id, hash_id ) )
service_info_updates.append( ( -1, service_id, HC.SERVICE_INFO_NUM_DELETED_FILES ) )
if service_id != self._local_file_service_id:
result = c.execute( 'SELECT 1 FROM file_inbox WHERE hash_id = ?;', ( hash_id, ) ).fetchone()
if result is not None: service_info_updates.append( ( 1, service_id, HC.SERVICE_INFO_NUM_INBOX ) )
service_info_updates.append( ( size, service_id, HC.SERVICE_INFO_TOTAL_SIZE ) )
service_info_updates.append( ( 1, service_id, HC.SERVICE_INFO_NUM_FILES ) )
if mime in HC.MIMES_WITH_THUMBNAILS: service_info_updates.append( ( 1, service_id, HC.SERVICE_INFO_NUM_THUMBNAILS ) )
c.executemany( 'UPDATE service_info SET info = info + ? WHERE service_id = ? AND info_type = ?;', service_info_updates )
c.execute( 'DELETE FROM service_info WHERE service_id = ? AND info_type IN ' + HC.SplayListForDB( ( HC.SERVICE_INFO_NUM_INBOX, HC.SERVICE_INFO_NUM_THUMBNAILS_LOCAL ) ) + ';', ( service_id, ) )
c.execute( 'DELETE FROM file_transfers WHERE service_id = ? AND hash_id = ? ;', ( service_id, hash_id ) )
self._UpdateAutocompleteTagCacheFromFiles( c, service_id, hash_ids, 1 )
if mime in HC.MIMES_WITH_THUMBNAILS: c.execute( 'DELETE FROM service_info WHERE service_id = ? AND info_type = ?;', ( service_id, HC.SERVICE_INFO_NUM_THUMBNAILS_LOCAL ) )
self._UpdateAutocompleteTagCacheFromFiles( c, service_id, ( hash_id, ), 1 )
@ -3081,9 +3082,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
self._AddThumbnails( c, [ ( hash, thumbnail ) ] )
files_info_rows = [ ( self._local_file_service_id, hash_id, size, mime, timestamp, width, height, duration, num_frames, num_words ) ]
self._AddFiles( c, files_info_rows )
self._AddFile( c, self._local_file_service_id, hash_id, size, mime, timestamp, width, height, duration, num_frames, num_words )
content_update = HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_ADD, ( hash, size, mime, timestamp, width, height, duration, num_frames, num_words ) )
@ -3182,9 +3181,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
hash_id = self._GetHashId( c, hash )
file_info_row = ( service_id, hash_id, size, mime, timestamp, width, height, duration, num_frames, num_words )
self._AddFiles( c, ( file_info_row, ) )
self._AddFile( c, service_id, hash_id, size, mime, timestamp, width, height, duration, num_frames, num_words )
notify_new_thumbnails = True
@ -5309,6 +5306,25 @@ class DB( ServiceDB ):
if version == 132:
c.execute( 'DELETE FROM service_info WHERE info_type = ?;', ( HC.SERVICE_INFO_NUM_FILES, ) )
#
( HC.options, ) = c.execute( 'SELECT options FROM options;' ).fetchone()
client_size = HC.options[ 'client_size' ]
client_size[ 'fs_fullscreen' ] = True
client_size[ 'gui_fullscreen' ] = False
del HC.options[ 'fullscreen_borderless' ]
c.execute( 'UPDATE options SET options = ?;', ( HC.options, ) )
c.execute( 'UPDATE version SET version = ?;', ( version + 1, ) )
HC.is_db_updated = True

View File

@ -879,11 +879,6 @@ class CanvasFullscreenMediaList( ClientGUIMixins.ListeningMediaList, Canvas, Cli
self.Show( True )
if self.IsMaximized() and HC.options[ 'fullscreen_borderless' ]:
self.ShowFullScreen( True, wx.FULLSCREEN_ALL )
HC.app.SetTopWindow( self )
self._timer_cursor_hide = wx.Timer( self, id = ID_TIMER_CURSOR_HIDE )
@ -1637,6 +1632,11 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
menu.AppendMenu( CC.ID_NULL, 'start slideshow', slideshow )
if self._timer_slideshow.IsRunning(): menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'slideshow_pause_play' ), 'stop slideshow' )
menu.AppendSeparator()
if self.IsFullScreen(): menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'fullscreen_switch' ), 'exit fullscreen' )
else: menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'fullscreen_switch' ), 'go fullscreen' )
self._menu_open = True
self.PopupMenu( menu )
@ -1991,10 +1991,10 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
copy_menu = wx.Menu()
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_files' ) , 'file' )
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_hash' ) , 'hash' )
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_path' ) , 'path' )
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_local_url' ) , 'local url' )
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_files' ), 'file' )
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_hash' ), 'hash' )
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_path' ), 'path' )
copy_menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'copy_local_url' ), 'local url' )
share_menu.AppendMenu( CC.ID_NULL, 'copy', copy_menu )
@ -2002,6 +2002,9 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
menu.AppendSeparator()
if self.IsFullScreen(): menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'fullscreen_switch' ), 'exit fullscreen' )
else: menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'fullscreen_switch' ), 'go fullscreen' )
self._menu_open = True
self.PopupMenu( menu )
@ -2758,11 +2761,6 @@ class RatingsFilterFrameNumerical( ClientGUICommon.FrameThatResizes ):
self.Show( True )
if self.IsMaximized() and HC.options[ 'fullscreen_borderless' ]:
self.ShowFullScreen( True, wx.FULLSCREEN_ALL )
HC.app.SetTopWindow( self )
self._left_window = self._Panel( self._splitter )

View File

@ -1332,29 +1332,25 @@ class FrameThatResizes( Frame ):
Frame.__init__( self, *args, **kwargs )
self._InitialiseSizeAndPosition()
self.Bind( wx.EVT_SIZE, self.EventSpecialResize )
self.Bind( wx.EVT_MOVE, self.EventSpecialMove )
def _InitialiseSizeAndPosition( self ):
client_size = HC.options[ 'client_size' ]
self.SetInitialSize( client_size[ self._resize_option_prefix + 'restored_size' ] )
self.SetMinSize( ( 480, 360 ) )
self._TryToSetPosition()
if client_size[ self._resize_option_prefix + 'maximised' ]: self.Maximize()
self.Bind( wx.EVT_SIZE, self.EventSpecialResize )
self.Bind( wx.EVT_MOVE_END, self.EventSpecialMoveEnd )
def _TryToSetPosition( self ):
client_size = HC.options[ 'client_size' ]
position = client_size[ self._resize_option_prefix + 'restored_position' ]
display_index = wx.Display.GetFromPoint( position )
if display_index == wx.NOT_FOUND: client_size[ self._resize_option_prefix + 'restored_position' ] = [ 20, 20 ]
if display_index == wx.NOT_FOUND: client_size[ self._resize_option_prefix + 'restored_position' ] = ( 20, 20 )
else:
display = wx.Display( display_index )
@ -1366,46 +1362,48 @@ class FrameThatResizes( Frame ):
x_bad = p_x < geometry.x or p_x > geometry.x + geometry.width
y_bad = p_y < geometry.y or p_y > geometry.y + geometry.height
if x_bad or y_bad: client_size[ self._resize_option_prefix + 'restored_position' ] = [ 20, 20 ]
if x_bad or y_bad: client_size[ self._resize_option_prefix + 'restored_position' ] = ( 20, 20 )
self.SetPosition( client_size[ self._resize_option_prefix + 'restored_position' ] )
if client_size[ self._resize_option_prefix + 'maximised' ]: self.Maximize()
if client_size[ self._resize_option_prefix + 'fullscreen' ]: wx.CallAfter( self.ShowFullScreen, True, wx.FULLSCREEN_ALL )
def EventSpecialMoveEnd( self, event ):
def _RecordSizeAndPosition( self ):
client_size = HC.options[ 'client_size' ]
client_size[ self._resize_option_prefix + 'restored_position' ] = list( self.GetPosition() )
client_size[ self._resize_option_prefix + 'maximised' ] = self.IsMaximized()
client_size[ self._resize_option_prefix + 'fullscreen' ] = self.IsFullScreen()
if not ( self.IsMaximized() or self.IsFullScreen() ):
# when dragging window up to be maximised, reported position is sometimes a bit dodgy
display_index = wx.Display.GetFromPoint( self.GetPosition() )
if display_index != wx.NOT_FOUND:
client_size[ self._resize_option_prefix + 'restored_size' ] = tuple( self.GetSize() )
client_size[ self._resize_option_prefix + 'restored_position' ] = tuple( self.GetPosition() )
def EventSpecialMove( self, event ):
self._RecordSizeAndPosition()
event.Skip()
def EventSpecialResize( self, event ):
client_size = HC.options[ 'client_size' ]
if self.IsMaximized() or self.IsFullScreen():
client_size[ self._resize_option_prefix + 'maximised' ] = True
else:
if client_size[ self._resize_option_prefix + 'maximised' ]: # we have just restored, so set size
self.SetSize( client_size[ self._resize_option_prefix + 'restored_size' ] )
self._TryToSetPosition()
else: # we have resized manually, so set new size
client_size[ self._resize_option_prefix + 'restored_size' ] = list( self.GetSize() )
client_size[ self._resize_option_prefix + 'restored_position' ] = list( self.GetPosition() )
client_size[ self._resize_option_prefix + 'maximised' ] = False
self._RecordSizeAndPosition()
event.Skip()

View File

@ -2853,8 +2853,6 @@ class DialogManageOptions( ClientGUIDialogs.Dialog ):
self._default_tag_repository = ClientGUICommon.BetterChoice( self._gui_page )
self._fullscreen_borderless = wx.CheckBox( self._gui_page )
self._listbook.AddPage( self._gui_page, 'gui' )
# sound
@ -3083,8 +3081,6 @@ class DialogManageOptions( ClientGUIDialogs.Dialog ):
self._default_tag_repository.SelectClientData( default_tag_repository_key )
self._fullscreen_borderless.SetValue( HC.options[ 'fullscreen_borderless' ] )
#
self._play_dumper_noises.SetValue( HC.options[ 'play_dumper_noises' ] )
@ -3278,9 +3274,6 @@ class DialogManageOptions( ClientGUIDialogs.Dialog ):
gridbox.AddF( wx.StaticText( self._gui_page, label = 'By default, search non-local tags in write-autocomplete: ' ), FLAGS_MIXED )
gridbox.AddF( self._gui_show_all_tags_in_autocomplete, FLAGS_MIXED )
gridbox.AddF( wx.StaticText( self._gui_page, label = 'By default, show fullscreen without borders: ' ), FLAGS_MIXED )
gridbox.AddF( self._fullscreen_borderless, FLAGS_MIXED )
self._gui_page.SetSizer( gridbox )
#
@ -3721,7 +3714,6 @@ class DialogManageOptions( ClientGUIDialogs.Dialog ):
HC.options[ 'confirm_client_exit' ] = self._confirm_client_exit.GetValue()
HC.options[ 'gui_capitalisation' ] = self._gui_capitalisation.GetValue()
HC.options[ 'show_all_tags_in_autocomplete' ] = self._gui_show_all_tags_in_autocomplete.GetValue()
HC.options[ 'fullscreen_borderless' ] = self._fullscreen_borderless.GetValue()
HC.options[ 'export_path' ] = HC.ConvertAbsPathToPortablePath( self._export_location.GetPath() )
HC.options[ 'default_sort' ] = self._default_sort.GetSelection()

View File

@ -1665,9 +1665,13 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
self._thread_info = wx.StaticText( self._thread_panel, label = 'enter a 4chan thread url' )
self._thread_time = wx.SpinCtrl( self._thread_panel, min = 30, max = 1800 )
self._thread_times_to_check = wx.SpinCtrl( self._thread_panel, size = ( 60, -1 ), min = 0, max = 100 )
self._thread_times_to_check.SetValue( 5 )
self._thread_times_to_check.Bind( wx.EVT_SPINCTRL, self.EventThreadVariable )
self._thread_time = wx.SpinCtrl( self._thread_panel, size = ( 100, -1 ), min = 30, max = 86400 )
self._thread_time.SetValue( 180 )
self._thread_time.Bind( wx.EVT_SPINCTRL, self.EventThreadTime )
self._thread_time.Bind( wx.EVT_SPINCTRL, self.EventThreadVariable )
self._thread_input = wx.TextCtrl( self._thread_panel, style = wx.TE_PROCESS_ENTER )
self._thread_input.Bind( wx.EVT_KEY_DOWN, self.EventKeyDown )
@ -1677,7 +1681,9 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
hbox = wx.BoxSizer( wx.HORIZONTAL )
hbox.AddF( wx.StaticText( self._thread_panel, label = 'check every ' ), FLAGS_MIXED )
hbox.AddF( wx.StaticText( self._thread_panel, label = 'check ' ), FLAGS_MIXED )
hbox.AddF( self._thread_times_to_check, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self._thread_panel, label = ' more times, every ' ), FLAGS_MIXED )
hbox.AddF( self._thread_time, FLAGS_MIXED )
hbox.AddF( wx.StaticText( self._thread_panel, label = ' seconds' ), FLAGS_MIXED )
@ -1695,13 +1701,15 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
vbox.AddF( self._advanced_tag_options, FLAGS_EXPAND_PERPENDICULAR )
def _SetThreadTime( self ):
def _SetThreadVariables( self ):
import_queue_job_key = self._import_controller.GetJobKey( 'import_queue' )
thread_time = self._thread_time.GetValue()
thread_times_to_check = self._thread_times_to_check.GetValue()
import_queue_job_key.SetVariable( 'thread_time', thread_time )
import_queue_job_key.SetVariable( 'thread_times_to_check', thread_times_to_check )
def _UpdateGUI( self ):
@ -1736,11 +1744,23 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
else: self._thread_pause_button.Disable()
# times to check
try:
thread_times_to_check = import_queue_job_key.GetVariable( 'thread_times_to_check' )
self._thread_times_to_check.SetValue( thread_times_to_check )
except: self._SetThreadVariables()
def EventKeyDown( self, event ):
if event.KeyCode in ( wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER ):
self._SetThreadVariables()
url = self._thread_input.GetValue()
if url == '': return
@ -1759,31 +1779,59 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
except: raise Exception ( 'Could not understand that url!' )
if host is None or '4chan.org' not in host: raise Exception( 'This only works for 4chan right now!' )
is_4chan = '4chan.org' in host
is_8chan = '8chan.co' in host
if not ( is_4chan or is_8chan ): raise Exception( 'This only works for 4chan right now!' )
try:
# 4chan
# /asp/thread/382059/post-your-favourite-martial-arts-video-if-martin
# http://a.4cdn.org/asp/thread/382059.json
# http://i.4cdn.org/asp/ for images
( board, rest_of_request ) = request[1:].split( '/thread/', 1 )
# 8chan
# /v/res/406061.html
# http://8chan.co/v/res/406061.json
# http://8chan.co/v/src/ for images
if '/' in rest_of_request: ( thread_id, gumpf ) = rest_of_request.split( '/' )
else: thread_id = rest_of_request
if is_4chan:
( board, rest_of_request ) = request[1:].split( '/thread/', 1 )
if '/' in rest_of_request: ( thread_id, gumpf ) = rest_of_request.split( '/' )
else: thread_id = rest_of_request
json_url = 'http://a.4cdn.org/' + board + '/thread/' + thread_id + '.json'
image_base = 'http://i.4cdn.org/' + board + '/'
elif is_8chan:
( board, rest_of_request ) = request[1:].split( '/res/', 1 )
json_url = url[:-4] + 'json'
image_base = 'http://8chan.co/' + board + '/src/'
except: raise Exception( 'Could not understand the board or thread id!' )
except Exception as e:
self._thread_info.SetLabel( HC.u( e ) )
import_queue_job_key = self._import_controller.GetJobKey( 'import_queue' )
import_queue_job_key.SetVariable( 'status', HC.u( e ) )
HC.ShowException( e )
return
self._thread_input.Disable()
self._SetThreadTime()
self._SetThreadVariables()
self._import_controller.PendImportQueue( ( board, thread_id ) )
self._import_controller.PendImportQueue( ( json_url, image_base ) )
else: event.Skip()
@ -1797,7 +1845,7 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
self._UpdateGUI()
def EventThreadTime( self, event ): self._SetThreadTime()
def EventThreadVariable( self, event ): self._SetThreadVariables()
def GetAdvancedTagOptions( self ): return self._advanced_tag_options.GetInfo()

View File

@ -64,7 +64,7 @@ options = {}
# Misc
NETWORK_VERSION = 15
SOFTWARE_VERSION = 132
SOFTWARE_VERSION = 133
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )

View File

@ -1234,12 +1234,7 @@ class ImportArgsGeneratorThread( ImportArgsGenerator ):
self._job_key.SetVariable( 'status', 'downloading' )
( md5, board, image_name, ext, filename ) = self._item
# where do I get 4chan_board from? is it set to the controller_job_key?
# that'd prob be the best place, but think about it
url = 'http://images.4chan.org/' + board + '/src/' + image_name + ext
( md5, image_url, filename ) = self._item
def hook( range, value ):
@ -1247,20 +1242,20 @@ class ImportArgsGeneratorThread( ImportArgsGenerator ):
self._job_key.SetVariable( 'value', value )
temp_path = HC.http.Request( HC.GET, url, report_hooks = [ hook ], response_to_path = True )
temp_path = HC.http.Request( HC.GET, image_url, report_hooks = [ hook ], response_to_path = True )
tags = [ 'filename:' + filename + ext ]
tags = [ 'filename:' + filename ]
service_keys_to_tags = ConvertTagsToServiceKeysToTags( tags, self._advanced_tag_options )
return ( url, temp_path, service_keys_to_tags, url )
return ( image_url, temp_path, service_keys_to_tags, image_url )
def _CheckCurrentStatus( self ):
self._job_key.SetVariable( 'status', 'checking md5 status' )
( md5, board, image_name, ext, filename ) = self._item
( md5, image_url, filename ) = self._item
( status, hash ) = HC.app.Read( 'md5_status', md5 )
@ -1684,13 +1679,31 @@ class ImportQueueGeneratorThread( ImportQueueGenerator ):
try:
( board, thread_id ) = self._item
( json_url, image_base ) = self._item
last_thread_check = 0
image_infos_already_added = set()
while True:
first_run = True
while True:
if not first_run:
thread_times_to_check = self._job_key.GetVariable( 'thread_times_to_check' )
while thread_times_to_check == 0:
self._job_key.SetVariable( 'status', 'checking is finished' )
time.sleep( 1 )
if self._job_key.IsCancelled(): break
thread_times_to_check = self._job_key.GetVariable( 'thread_times_to_check' )
if self._job_key.IsPaused():
self._job_key.SetVariable( 'status', 'paused' )
@ -1710,17 +1723,26 @@ class ImportQueueGeneratorThread( ImportQueueGenerator ):
self._job_key.SetVariable( 'status', 'checking thread' )
url = 'http://a.4cdn.org/' + board + '/thread/' + thread_id + '.json'
try:
raw_json = HC.http.Request( HC.GET, url )
raw_json = HC.http.Request( HC.GET, json_url )
json_dict = json.loads( raw_json )
posts_list = json_dict[ 'posts' ]
image_infos = [ ( post[ 'md5' ].decode( 'base64' ), board, HC.u( post[ 'tim' ] ), post[ 'ext' ], post[ 'filename' ] ) for post in posts_list if 'md5' in post ]
image_infos = []
for post in posts_list:
if 'md5' not in post: continue
image_md5 = post[ 'md5' ].decode( 'base64' )
image_url = image_base + HC.u( post[ 'tim' ] ) + post[ 'ext' ]
image_original_filename = post[ 'filename' ] + post[ 'ext' ]
image_infos.append( ( image_md5, image_url, image_original_filename ) )
image_infos_i_can_add = [ image_info for image_info in image_infos if image_info not in image_infos_already_added ]
@ -1741,8 +1763,15 @@ class ImportQueueGeneratorThread( ImportQueueGenerator ):
last_thread_check = HC.GetNow()
if first_run: first_run = False
else:
if thread_times_to_check > 0: self._job_key.SetVariable( 'thread_times_to_check', thread_times_to_check - 1 )
else: self._job_key.SetVariable( 'status', 'rechecking thread ' + HC.ConvertTimestampToPrettyPending( next_thread_check ) )
time.sleep( 0.1 )
except Exception as e:

View File

@ -2029,11 +2029,14 @@ class DB( ServiceDB ):
hex_chars = '0123456789abcdef'
for ( one, two ) in itertools.product( hex_chars, hex_chars ):
for dir in dirs:
new_dir = dir + os.path.sep + one + two
if not os.path.exists( new_dir ): os.mkdir( new_dir )
for ( one, two ) in itertools.product( hex_chars, hex_chars ):
new_dir = dir + os.path.sep + one + two
if not os.path.exists( new_dir ): os.mkdir( new_dir )
( db, c ) = self._GetDBCursor()
@ -2408,6 +2411,23 @@ class DB( ServiceDB ):
if version == 132:
dirs = ( HC.SERVER_FILES_DIR, HC.SERVER_THUMBNAILS_DIR, HC.SERVER_MESSAGES_DIR )
hex_chars = '0123456789abcdef'
for dir in dirs:
for ( one, two ) in itertools.product( hex_chars, hex_chars ):
new_dir = dir + os.path.sep + one + two
if not os.path.exists( new_dir ): os.mkdir( new_dir )
c.execute( 'UPDATE version SET version = ?;', ( version + 1, ) )

View File

@ -1152,4 +1152,56 @@ class TestServerDB( unittest.TestCase ):
HC.SERVER_FILES_DIR = self._old_server_files_dir
HC.SERVER_THUMBNAILS_DIR = self._old_server_thumbnails_dir
# add read and write funcs like with client db
def _test_account_creation( self ):
# create rkeys
# create akeys
# test successive rkey fetch gives new akeys
# get session with akey
# make sure rkey is now dead
pass
def _test_content_creation( self ):
# create some tag and hashes business, try uploading a file, and test that
# fetch content update, test it. I think that works
pass
def _test_init_server_admin( self ):
# do it, however it works
pass
def _test_service_creation( self ):
# add tag, add file repo
# fetch service info or whatever to test
# change the port
# fetch service info or whatever to test
pass
def test_server( self ):
self._test_init_server_admin()
self._test_service_creation()
self._test_account_creation()
self._test_content_creation()