Last active
June 9, 2020 15:50
-
-
Save noirscape/f9a6e3e0d297c914b5e466abf17b4e21 to your computer and use it in GitHub Desktop.
Upload folder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import shutil | |
import requests | |
import argparse | |
import base64 | |
from typing import List | |
def parse_arguments(debug_args=None): | |
parser = argparse.ArgumentParser(description="Upload a folder of images and videos to a szurubooru instance.") | |
szuru_api_group = parser.add_argument_group('szuru api settings') | |
post_group = parser.add_argument_group('post settings') | |
szuru_api_group.add_argument("-l", metavar="URL", dest="url", help="Szurubooru API URL, no trailing slash", required=True) | |
szuru_api_group.add_argument("-u", metavar="USERNAME", dest="username", help="Username that can upload", required=True) | |
szuru_api_group.add_argument("-p", metavar="PASSWORD", dest="password", help="Password belonging to username", required=True) | |
post_group.add_argument("-f", metavar="FOLDER", dest="folder", help="The folder to upload", default=".") | |
post_group.add_argument("-r", metavar="RATING", dest="rating", help="Rating of uploaded images", required=True, choices=["safe", "sketchy", "unsafe"]) | |
post_group.add_argument("-t", metavar="TAG", dest="tags", help="Tag(s) to add on the uploaded image", required=True, nargs="+") | |
post_group.add_argument("-s", dest="link_relationship", help="Link nearby posts with a relationship", action="store_true") | |
if debug_args is not None: | |
return parser.parse_args(debug_args) | |
else: | |
return parser.parse_args() | |
def store_file_temporary(filename: str) -> str: | |
"""Uploads a file to the temporary server storage to reduce repeated uploads. | |
Arguments: | |
filename (str): Full path of file to upload | |
Returns: | |
str: Token of uploaded file. | |
""" | |
headers = { | |
"Accept": "application/json" | |
} | |
r = requests.post(url=arguments.url + "/uploads", headers=headers, files={ | |
"content": open(filename, 'rb') | |
}, auth=(arguments.username, arguments.password)) | |
return r.json()["token"] | |
def reverse_image_search(token: str) -> dict: | |
"""Preforms a token-based image search on the server. | |
Arguments: | |
token: An image token produced by `store_file_temporary()` | |
Returns: | |
dict: Image search result. See [here](https://github.com/rr-/szurubooru/blob/master/API.md#image-search-result) for more. | |
""" | |
headers = { | |
"Accept": "application/json", | |
"Content-Type": "application/json" | |
} | |
json = { | |
"contentToken": token | |
} | |
r = requests.post(url=arguments.url + "/posts/reverse-search", json=json, auth=(arguments.username, arguments.password), headers=headers) | |
return r.json() | |
def create_post(token: str, relations: List[str]) -> dict: | |
"""Create a new post on the server. | |
Arguments: | |
token (str): An image token produced by `store_file_temporary()` | |
relations (List[str]): A list containing relationships to add to the post. | |
Returns: | |
dict: A post. See [here](https://github.com/rr-/szurubooru/blob/master/API.md#image-search-result) for details. | |
""" | |
headers = { | |
"Accept": "application/json", | |
"Content-Type": "application/json" | |
} | |
json = { | |
"contentToken": token, | |
"tags": arguments.tags, | |
"safety": arguments.rating | |
} | |
r = requests.post(url=arguments.url + "/posts/", json=json, auth=(arguments.username, arguments.password), headers=headers) | |
return r.json() | |
class IdenticalFileException(Exception): | |
pass | |
def make_new_post(filename: str): | |
"""Preforms a number of functions in sequence to make a new post. | |
Arguments: | |
filename (str): Full path of file to add. | |
Raises: | |
IdenticalFileException: Close match (if not overriden) or exact match found. | |
""" | |
token = store_file_temporary(filename) | |
reverse_result = reverse_image_search(token) | |
relations = [] | |
for post in reverse_result["similarPosts"]: | |
relations.append(post["id"]) | |
if reverse_result["exactPost"]: | |
raise IdenticalFileException("Exact match found at ID {}".format(str(reverse_result["exactPost"]["id"]))) | |
elif len(reverse_result["similarPosts"]) != 0 and not arguments.link_relationship: | |
raise IdenticalFileException("Close match(es) found at ID(s) {}".format(relations)) | |
else: | |
result = create_post(token, relations) | |
print(result) | |
arguments = parse_arguments() | |
for filename in os.listdir(arguments.folder): | |
_, extension = os.path.splitext(filename) | |
if extension in ['.png', '.jpg', '.gif', '.webm', '.mp4', '.swf']: | |
try: | |
make_new_post(os.path.join(arguments.folder, filename)) | |
except IdenticalFileException as e: | |
print(f'{filename}: {e}') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment