· 5 years ago · Jan 01, 2021, 10:30 PM
1from itertools import izip_longest as zip_longest
2import argparse
3import requests
4import urllib
5import json
6
7import os.path
8from os import path
9
10default_domain = 'localhost'
11default_port = '45869'
12
13parser = argparse.ArgumentParser(description='FlipFlip Hydrus Adapter')
14parser.add_argument('tags', help='Tags to search for.\nUse comma (\',\') to separate tags')
15parser.add_argument('access_key', help='Hydrus client API access key.\nSee https://hydrusnetwork.github.io/hydrus/help/client_api.html to configure client API')
16parser.add_argument('-s', '--ssl', dest='ssl', type=bool, default=False, help='Whether Hydrus should be accessed over secure connection, default: False')
17parser.add_argument('-d', '--domain', dest='domain', default=default_domain, help='Hydrus domain name, default: {0}'.format(default_domain))
18parser.add_argument('-p', '--port', dest='port', default=default_port, help='Hydrus port, default: {0}'.format(default_port))
19parser.add_argument('-i', '--install_dir', dest='install_dir', help='Local Hydrus installation directory')
20
21args = parser.parse_args()
22
23if args.install_dir:
24 local_files_path = '{0}/db/client_files'.format(args.install_dir)
25 local_files_exists = path.exists(local_files_path)
26 if not local_files_exists:
27 print('Failed to find Hydrus client_files directory\nPath: {0}'.format(local_files_path))
28 exit()
29
30scheme = 'https' if args.ssl else 'http'
31base_url = '{0}://{1}:{2}'.format(scheme, args.domain, args.port)
32print('Connecting to Hydrus client at {0}'.format(base_url))
33
34session_url = base_url + '/session_key'
35session_response = requests.get(session_url, headers={'Hydrus-Client-API-Access-Key': args.access_key})
36if session_response.status_code != 200:
37 print('failed to get session key')
38 exit()
39
40session_key = session_response.json()['session_key']
41session_headers = {'Hydrus-Client-API-Session-Key': session_key}
42
43tags_array = args.tags.split(',')
44tags_json_array = json.dumps(tags_array)
45encoded_tags = urllib.quote(tags_json_array, safe='')
46
47print('Searching files that match {0}'.format(args.tags))
48search_url = base_url + '/get_files/search_files?tags=' + encoded_tags
49search_response = requests.get(search_url, headers=session_headers)
50if search_response.status_code != 200:
51 print('failed to get search results')
52 print(search_response.text)
53 exit()
54
55file_ids = search_response.json()['file_ids']
56print('found {0} files'.format(len(file_ids)))
57
58def grouper(n, iterable, padvalue=None):
59 return zip_longest(*[iter(iterable)]*n, fillvalue=padvalue)
60
61metadata_array = []
62chunked_file_ids = grouper(1000, file_ids)
63for file_ids_chunk in chunked_file_ids:
64 resized_file_ids_chunk = tuple(id for id in file_ids_chunk if id is not None)
65 encoded_file_ids = urllib.quote(json.dumps(resized_file_ids_chunk), safe='')
66
67 print('Fetching metadata for found files')
68 metadata_url = base_url + '/get_files/file_metadata?file_ids=' + encoded_file_ids
69 metadata_response = requests.get(metadata_url, headers=session_headers)
70 if metadata_response.status_code != 200:
71 print('failed to get metadata for files')
72 print(metadata_response.text)
73 print('continue with next chunk')
74
75 metadata_array.extend(metadata_response.json()['metadata'])
76
77def build_local_url(metadata):
78 hash = metadata['hash']
79 file_extension = metadata['ext']
80 return 'file://{0}/db/client_files/f{1}/{2}{3}'.format(args.install_dir, hash[0:2], hash, file_extension)
81
82def build_remote_url(metadata):
83 file_id = metadata['file_id']
84 file_extension = metadata['ext']
85 # in order for flipflip to recognize the url as an image or video the file_ext query param is added,
86 # because flipflip filters out non-playable content by file extension. Hydrus ignores this query param.
87 return '{0}/get_files/file?file_id={1}&Hydrus-Client-API-Access-Key={2}&file_ext={3}'.format(base_url, file_id, args.access_key, file_extension)
88
89file_urls = []
90url_builder = build_local_url if args.install_dir else build_remote_url
91for metadata in metadata_array:
92 file_urls.append(url_builder(metadata))
93
94print('writing {0} file urls to file'.format(len(file_urls)))
95if len(file_urls) > 0:
96 file_name = ''
97 for tag in tags_array:
98 file_name += tag.replace(' ', '-')
99 file_name += '_'
100
101 file_name = file_name[:len(file_name) - 1] + '.txt'
102 with open(file_name, 'w') as file:
103 for file_url in file_urls:
104 file.write('{0}\r\n'.format(file_url))
105else:
106 print('No files were found with tags: ' + args.tags)