2020-06-24 21:25:24 +00:00
import itertools
2013-02-19 00:11:43 +00:00
import os
2013-03-15 02:38:12 +00:00
import time
2020-05-27 21:27:52 +00:00
import typing
2020-04-22 21:00:35 +00:00
2019-11-14 03:56:30 +00:00
from qtpy import QtWidgets as QW
2020-04-22 21:00:35 +00:00
2020-05-27 21:27:52 +00:00
from hydrus . core import HydrusConstants as HC
2020-04-22 21:00:35 +00:00
from hydrus . core import HydrusExceptions
from hydrus . core import HydrusPaths
from hydrus . core import HydrusData
from hydrus . core import HydrusGlobals as HG
2020-07-29 20:52:44 +00:00
2020-04-22 21:00:35 +00:00
from hydrus . client import ClientConstants as CC
2022-11-16 21:34:30 +00:00
from hydrus . client import ClientLocation
2020-04-22 21:00:35 +00:00
from hydrus . client import ClientPaths
from hydrus . client import ClientThreading
2023-12-06 22:13:50 +00:00
from hydrus . client . gui import ClientGUIDialogsMessage
2020-04-22 21:00:35 +00:00
from hydrus . client . gui import ClientGUIDialogsQuick
2022-11-16 21:34:30 +00:00
from hydrus . client . gui import ClientGUIScrolledPanelsEdit
from hydrus . client . gui import ClientGUITopLevelWindowsPanels
2020-07-29 20:52:44 +00:00
from hydrus . client . media import ClientMedia
2013-02-19 00:11:43 +00:00
2020-08-27 01:00:42 +00:00
def CopyHashesToClipboard ( win : QW . QWidget , hash_type : str , medias : typing . Sequence [ ClientMedia . Media ] ) :
2020-06-24 21:25:24 +00:00
2023-09-27 21:12:55 +00:00
hex_it = True
2020-06-24 21:25:24 +00:00
2023-09-27 21:12:55 +00:00
desired_hashes = [ ]
flat_media = ClientMedia . FlattenMedia ( medias )
sha256_hashes = [ media . GetHash ( ) for media in flat_media ]
if hash_type in ( ' pixel_hash ' , ' blurhash ' ) :
file_info_managers = [ media . GetFileInfoManager ( ) for media in flat_media ]
if hash_type == ' pixel_hash ' :
desired_hashes = [ fim . pixel_hash for fim in file_info_managers if fim . pixel_hash is not None ]
elif hash_type == ' blurhash ' :
desired_hashes = [ fim . blurhash for fim in file_info_managers if fim . blurhash is not None ]
hex_it = False
elif hash_type == ' sha256 ' :
2020-06-24 21:25:24 +00:00
desired_hashes = sha256_hashes
else :
num_hashes = len ( sha256_hashes )
2023-09-27 21:12:55 +00:00
num_remote_medias = len ( [ not media . GetLocationsManager ( ) . IsLocal ( ) for media in flat_media ] )
2020-06-24 21:25:24 +00:00
2022-11-30 22:06:58 +00:00
source_to_desired = HG . client_controller . Read ( ' file_hashes ' , sha256_hashes , ' sha256 ' , hash_type )
desired_hashes = [ source_to_desired [ source_hash ] for source_hash in sha256_hashes if source_hash in source_to_desired ]
2020-06-24 21:25:24 +00:00
num_missing = num_hashes - len ( desired_hashes )
if num_missing > 0 :
if num_missing == num_hashes :
message = ' Unfortunately, none of the {} hashes could be found. ' . format ( hash_type )
else :
message = ' Unfortunately, {} of the {} hashes could not be found. ' . format ( HydrusData . ToHumanInt ( num_missing ) , hash_type )
2023-09-27 21:12:55 +00:00
if num_remote_medias > 0 :
2020-06-24 21:25:24 +00:00
2023-09-27 21:12:55 +00:00
message + = ' {} of the files you wanted are not currently in this client. If they have never visited this client, the lookup is impossible. ' . format ( HydrusData . ToHumanInt ( num_remote_medias ) )
2020-06-24 21:25:24 +00:00
2023-09-27 21:12:55 +00:00
if num_remote_medias < num_hashes :
2020-06-24 21:25:24 +00:00
message + = ' It could be that some of the local files are currently missing this information in the hydrus database. A file maintenance job (under the database menu) can repopulate this data. '
2023-12-06 22:13:50 +00:00
ClientGUIDialogsMessage . ShowWarning ( win , message )
2020-06-24 21:25:24 +00:00
if len ( desired_hashes ) > 0 :
2023-09-27 21:12:55 +00:00
if hex_it :
text_lines = [ desired_hash . hex ( ) for desired_hash in desired_hashes ]
else :
text_lines = desired_hashes
2020-06-24 21:25:24 +00:00
2020-11-04 23:23:07 +00:00
if HG . client_controller . new_options . GetBoolean ( ' prefix_hash_when_copying ' ) :
text_lines = [ ' {} : {} ' . format ( hash_type , hex_hash ) for hex_hash in text_lines ]
hex_hashes_text = os . linesep . join ( text_lines )
HG . client_controller . pub ( ' clipboard ' , ' text ' , hex_hashes_text )
2020-06-24 21:25:24 +00:00
2023-11-15 22:40:54 +00:00
job_status = ClientThreading . JobStatus ( )
2020-06-24 21:25:24 +00:00
2023-11-15 22:40:54 +00:00
job_status . SetStatusText ( ' {} {} hashes copied ' . format ( HydrusData . ToHumanInt ( len ( desired_hashes ) ) , hash_type ) )
2020-06-24 21:25:24 +00:00
2023-11-15 22:40:54 +00:00
HG . client_controller . pub ( ' message ' , job_status )
2020-06-24 21:25:24 +00:00
2023-11-29 22:27:53 +00:00
job_status . FinishAndDismiss ( 2 )
2020-06-24 21:25:24 +00:00
2018-08-22 21:10:59 +00:00
def CopyMediaURLs ( medias ) :
2018-08-15 20:40:30 +00:00
2018-08-22 21:10:59 +00:00
urls = set ( )
2018-08-15 20:40:30 +00:00
2018-08-22 21:10:59 +00:00
for media in medias :
2018-08-15 20:40:30 +00:00
2018-08-22 21:10:59 +00:00
media_urls = media . GetLocationsManager ( ) . GetURLs ( )
2018-08-15 20:40:30 +00:00
2018-08-22 21:10:59 +00:00
urls . update ( media_urls )
2018-08-15 20:40:30 +00:00
2018-08-22 21:10:59 +00:00
2020-05-13 19:03:16 +00:00
urls = sorted ( urls )
2018-08-22 21:10:59 +00:00
urls_string = os . linesep . join ( urls )
HG . client_controller . pub ( ' clipboard ' , ' text ' , urls_string )
2019-05-08 21:06:42 +00:00
def CopyMediaURLClassURLs ( medias , url_class ) :
2018-08-22 21:10:59 +00:00
urls = set ( )
for media in medias :
media_urls = media . GetLocationsManager ( ) . GetURLs ( )
for url in media_urls :
2020-12-16 22:29:51 +00:00
# can't do 'url_class.matches', as it will match too many
if HG . client_controller . network_engine . domain_manager . GetURLClass ( url ) == url_class :
2018-08-22 21:10:59 +00:00
urls . add ( url )
2020-05-13 19:03:16 +00:00
urls = sorted ( urls )
2018-08-22 21:10:59 +00:00
urls_string = os . linesep . join ( urls )
HG . client_controller . pub ( ' clipboard ' , ' text ' , urls_string )
2020-07-08 22:00:33 +00:00
def DoClearFileViewingStats ( win : QW . QWidget , flat_medias : typing . Collection [ ClientMedia . MediaSingleton ] ) :
2020-05-27 21:27:52 +00:00
if len ( flat_medias ) == 0 :
return
if len ( flat_medias ) == 1 :
insert = ' this file '
else :
insert = ' these {} files ' . format ( HydrusData . ToHumanInt ( len ( flat_medias ) ) )
2022-01-26 21:57:04 +00:00
message = ' Clear the file viewing count/duration and \' last viewed time \' for {} ? ' . format ( insert )
2020-05-27 21:27:52 +00:00
result = ClientGUIDialogsQuick . GetYesNo ( win , message )
if result == QW . QDialog . Accepted :
hashes = { m . GetHash ( ) for m in flat_medias }
content_update = HydrusData . ContentUpdate ( HC . CONTENT_TYPE_FILE_VIEWING_STATS , HC . CONTENT_UPDATE_DELETE , hashes )
HG . client_controller . Write ( ' content_updates ' , { CC . COMBINED_LOCAL_FILE_SERVICE_KEY : [ content_update ] } )
2019-03-20 21:22:10 +00:00
def DoOpenKnownURLFromShortcut ( win , media ) :
urls = media . GetLocationsManager ( ) . GetURLs ( )
matched_labels_and_urls = [ ]
unmatched_urls = [ ]
if len ( urls ) > 0 :
for url in urls :
2020-04-01 21:51:42 +00:00
try :
url_class = HG . client_controller . network_engine . domain_manager . GetURLClass ( url )
except HydrusExceptions . URLClassException :
continue
2019-03-20 21:22:10 +00:00
2019-05-08 21:06:42 +00:00
if url_class is None :
2019-03-20 21:22:10 +00:00
unmatched_urls . append ( url )
else :
2019-05-08 21:06:42 +00:00
label = url_class . GetName ( ) + ' : ' + url
2019-03-20 21:22:10 +00:00
matched_labels_and_urls . append ( ( label , url ) )
matched_labels_and_urls . sort ( )
unmatched_urls . sort ( )
if len ( matched_labels_and_urls ) == 0 :
return
elif len ( matched_labels_and_urls ) == 1 :
url = matched_labels_and_urls [ 0 ] [ 1 ]
else :
matched_labels_and_urls . extend ( ( url , url ) for url in unmatched_urls )
try :
url = ClientGUIDialogsQuick . SelectFromList ( win , ' Select which URL ' , matched_labels_and_urls , sort_tuples = False )
except HydrusExceptions . CancelledException :
return
ClientPaths . LaunchURLInWebBrowser ( url )
2022-11-16 21:34:30 +00:00
2022-12-14 22:22:11 +00:00
def EditDuplicateContentMergeOptions ( win : QW . QWidget , duplicate_type : int ) :
2022-11-16 21:34:30 +00:00
new_options = HG . client_controller . new_options
2022-12-14 22:22:11 +00:00
duplicate_content_merge_options = new_options . GetDuplicateContentMergeOptions ( duplicate_type )
2022-11-16 21:34:30 +00:00
with ClientGUITopLevelWindowsPanels . DialogEdit ( win , ' edit duplicate merge options ' ) as dlg :
2022-12-14 22:22:11 +00:00
panel = ClientGUIScrolledPanelsEdit . EditDuplicateContentMergeOptionsPanel ( dlg , duplicate_type , duplicate_content_merge_options )
2022-11-16 21:34:30 +00:00
dlg . SetPanel ( panel )
if dlg . exec ( ) == QW . QDialog . Accepted :
2022-12-14 22:22:11 +00:00
duplicate_content_merge_options = panel . GetValue ( )
2022-11-16 21:34:30 +00:00
2022-12-14 22:22:11 +00:00
new_options . SetDuplicateContentMergeOptions ( duplicate_type , duplicate_content_merge_options )
2022-11-16 21:34:30 +00:00
2020-02-12 22:50:37 +00:00
def OpenExternally ( media ) :
hash = media . GetHash ( )
mime = media . GetMime ( )
client_files_manager = HG . client_controller . client_files_manager
path = client_files_manager . GetFilePath ( hash , mime )
new_options = HG . client_controller . new_options
launch_path = new_options . GetMimeLaunch ( mime )
HydrusPaths . LaunchFile ( path , launch_path )
2023-05-24 20:44:12 +00:00
def OpenFileLocation ( media ) :
hash = media . GetHash ( )
mime = media . GetMime ( )
path = HG . client_controller . client_files_manager . GetFilePath ( hash , mime )
HydrusPaths . OpenFileLocation ( path )
2019-03-06 23:06:22 +00:00
def OpenURLs ( urls ) :
2020-05-13 19:03:16 +00:00
urls = sorted ( urls )
2019-03-06 23:06:22 +00:00
if len ( urls ) > 1 :
message = ' Open the {} URLs in your web browser? ' . format ( len ( urls ) )
if len ( urls ) > 10 :
message + = ' This will take some time. '
2020-07-15 20:52:09 +00:00
tlw = HG . client_controller . GetMainTLW ( )
result = ClientGUIDialogsQuick . GetYesNo ( tlw , message )
2019-09-05 00:05:32 +00:00
2019-11-14 03:56:30 +00:00
if result != QW . QDialog . Accepted :
2019-03-06 23:06:22 +00:00
2019-09-05 00:05:32 +00:00
return
2019-03-06 23:06:22 +00:00
def do_it ( urls ) :
2023-11-15 22:40:54 +00:00
job_status = None
2019-03-06 23:06:22 +00:00
num_urls = len ( urls )
if num_urls > 5 :
2023-11-15 22:40:54 +00:00
job_status = ClientThreading . JobStatus ( pausable = True , cancellable = True )
2019-03-06 23:06:22 +00:00
2023-11-15 22:40:54 +00:00
job_status . SetStatusTitle ( ' Opening URLs ' )
2019-03-06 23:06:22 +00:00
2023-11-15 22:40:54 +00:00
HG . client_controller . pub ( ' message ' , job_status )
2019-03-06 23:06:22 +00:00
try :
for ( i , url ) in enumerate ( urls ) :
2023-11-15 22:40:54 +00:00
if job_status is not None :
2019-03-06 23:06:22 +00:00
2023-11-15 22:40:54 +00:00
( i_paused , should_quit ) = job_status . WaitIfNeeded ( )
2019-03-13 21:04:21 +00:00
if should_quit :
2019-03-06 23:06:22 +00:00
return
2023-11-15 22:40:54 +00:00
job_status . SetStatusText ( HydrusData . ConvertValueRangeToPrettyString ( i + 1 , num_urls ) )
job_status . SetVariable ( ' popup_gauge_1 ' , ( i + 1 , num_urls ) )
2019-03-06 23:06:22 +00:00
ClientPaths . LaunchURLInWebBrowser ( url )
time . sleep ( 1 )
finally :
2023-11-15 22:40:54 +00:00
if job_status is not None :
2019-03-06 23:06:22 +00:00
2023-11-29 22:27:53 +00:00
job_status . FinishAndDismiss ( 1 )
2019-03-06 23:06:22 +00:00
HG . client_controller . CallToThread ( do_it , urls )
def OpenMediaURLs ( medias ) :
urls = set ( )
for media in medias :
media_urls = media . GetLocationsManager ( ) . GetURLs ( )
urls . update ( media_urls )
OpenURLs ( urls )
2019-05-08 21:06:42 +00:00
def OpenMediaURLClassURLs ( medias , url_class ) :
2019-03-06 23:06:22 +00:00
urls = set ( )
for media in medias :
media_urls = media . GetLocationsManager ( ) . GetURLs ( )
for url in media_urls :
2020-12-16 22:29:51 +00:00
# can't do 'url_class.matches', as it will match too many
if HG . client_controller . network_engine . domain_manager . GetURLClass ( url ) == url_class :
2019-03-06 23:06:22 +00:00
urls . add ( url )
OpenURLs ( urls )
2022-11-16 21:34:30 +00:00
def ShowDuplicatesInNewPage ( location_context : ClientLocation . LocationContext , hash , duplicate_type ) :
2022-05-04 21:40:27 +00:00
2022-11-16 21:34:30 +00:00
# TODO: this can be replaced by a call to the MediaResult when it holds these hashes
2022-11-30 22:06:58 +00:00
# don't forget to return itself in position 0!
2022-11-16 21:34:30 +00:00
hashes = HG . client_controller . Read ( ' file_duplicate_hashes ' , location_context , hash , duplicate_type )
2022-05-04 21:40:27 +00:00
2022-11-30 22:06:58 +00:00
if hashes is not None and len ( hashes ) > 1 :
2022-05-04 21:40:27 +00:00
2022-11-16 21:34:30 +00:00
HG . client_controller . pub ( ' new_page_query ' , location_context , initial_hashes = hashes )
2022-05-04 21:40:27 +00:00
2023-05-31 20:54:09 +00:00
else :
location_context = ClientLocation . LocationContext . STATICCreateSimple ( CC . COMBINED_FILE_SERVICE_KEY )
hashes = HG . client_controller . Read ( ' file_duplicate_hashes ' , location_context , hash , duplicate_type )
if hashes is not None and len ( hashes ) > 1 :
HydrusData . ShowText ( ' Could not find the members of this group in this location, so searched all known files and found more. ' )
HG . client_controller . pub ( ' new_page_query ' , location_context , initial_hashes = hashes )
else :
HydrusData . ShowText ( ' Sorry, could not find the members of this group either at the given location or in all known files. There may be a problem here, so let hydev know. ' )
2022-05-11 21:16:33 +00:00