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
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
sha256_hashes = list ( itertools . chain . from_iterable ( ( media . GetHashes ( ordered = True ) for media in medias ) ) )
if hash_type == ' sha256 ' :
desired_hashes = sha256_hashes
else :
num_hashes = len ( sha256_hashes )
num_remote_sha256_hashes = len ( [ itertools . chain . from_iterable ( ( media . GetHashes ( discriminant = CC . DISCRIMINANT_NOT_LOCAL , ordered = True ) for media in medias ) ) ] )
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 )
if num_remote_sha256_hashes > 0 :
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_sha256_hashes ) )
if num_remote_sha256_hashes < num_hashes :
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. '
QW . QMessageBox . warning ( win , ' Warning ' , message )
if len ( desired_hashes ) > 0 :
2020-11-04 23:23:07 +00:00
text_lines = [ desired_hash . hex ( ) for desired_hash in 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
job_key = ClientThreading . JobKey ( )
job_key . SetVariable ( ' popup_text_1 ' , ' {} {} hashes copied ' . format ( HydrusData . ToHumanInt ( len ( desired_hashes ) ) , hash_type ) )
HG . client_controller . pub ( ' message ' , job_key )
job_key . Delete ( 2 )
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
def EditDuplicateActionOptions ( win : QW . QWidget , duplicate_type : int ) :
new_options = HG . client_controller . new_options
duplicate_action_options = new_options . GetDuplicateActionOptions ( duplicate_type )
with ClientGUITopLevelWindowsPanels . DialogEdit ( win , ' edit duplicate merge options ' ) as dlg :
panel = ClientGUIScrolledPanelsEdit . EditDuplicateActionOptionsPanel ( dlg , duplicate_type , duplicate_action_options )
dlg . SetPanel ( panel )
if dlg . exec ( ) == QW . QDialog . Accepted :
duplicate_action_options = panel . GetValue ( )
new_options . SetDuplicateActionOptions ( duplicate_type , duplicate_action_options )
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 )
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 ) :
job_key = None
num_urls = len ( urls )
if num_urls > 5 :
2019-03-13 21:04:21 +00:00
job_key = ClientThreading . JobKey ( pausable = True , cancellable = True )
2019-03-06 23:06:22 +00:00
2021-06-09 20:28:09 +00:00
job_key . SetStatusTitle ( ' Opening URLs ' )
2019-03-06 23:06:22 +00:00
HG . client_controller . pub ( ' message ' , job_key )
try :
for ( i , url ) in enumerate ( urls ) :
if job_key is not None :
2019-03-13 21:04:21 +00:00
( i_paused , should_quit ) = job_key . WaitIfNeeded ( )
if should_quit :
2019-03-06 23:06:22 +00:00
return
job_key . SetVariable ( ' popup_text_1 ' , HydrusData . ConvertValueRangeToPrettyString ( i + 1 , num_urls ) )
job_key . SetVariable ( ' popup_gauge_1 ' , ( i + 1 , num_urls ) )
ClientPaths . LaunchURLInWebBrowser ( url )
time . sleep ( 1 )
finally :
if job_key is not None :
job_key . Finish ( )
job_key . Delete ( 1 )
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
2022-05-11 21:16:33 +00:00