Skip to content

Instantly share code, notes, and snippets.

@zrzka
Created February 1, 2018 09:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zrzka/b61c74975c777a77232035a3e171337d to your computer and use it in GitHub Desktop.
Save zrzka/b61c74975c777a77232035a3e171337d to your computer and use it in GitHub Desktop.
Imgur Upload
#!python3
import base64
import json
import appex
import clipboard
import objc_util
import photos
import requests
#
# https://api.imgur.com/oauth2/addclient
#
# Select Anonymous usage without user authorization
#
# Authorization callback URL is mandatory even if it's not used, you
# have to fill in anything, https://callback/ works :)
#
IMGUR_CLIENT_ID = ''
IMGUR_API = 'https://api.imgur.com/3'
class ImgurError(Exception):
pass
@objc_util.on_main_thread # workaround for https://github.com/omz/Pythonista-Issues/issues/518
def pick_assets():
screenshots = photos.get_screenshots_album()
return photos.pick_asset(assets=screenshots, multi=True)
class ImgurAsset:
"""
Args:
asset (`photos.Asset`, `bytes`): Asset you would like to upload
"""
def __init__(self, asset):
self.asset = asset if isinstance(asset, photos.Asset) else None
self.bytes = asset if isinstance(asset, bytes) else None
if not self.asset and not self.bytes:
raise ValueError('Invalid asset value, pass photos.Asset or bytes')
self.link = None
self.delete_hash = None
@classmethod
def headers(cls):
return dict(Authorization=f'Client-ID {IMGUR_CLIENT_ID}')
def upload(self):
data = self.asset.get_image_data().getvalue() if self.asset else self.bytes
headers = self.headers()
payload = dict(image=base64.b64encode(data).decode())
response = requests.post(f'{IMGUR_API}/image', headers=headers, data=payload)
if not response.ok:
raise ImgurError('Failed to upload image')
j = json.loads(response.text)
if not j['success'] or not j['status'] == 200:
raise ImgurError('Failed to upload image')
self.link = j['data']['link']
self.delete_hash = j['data']['deletehash']
def delete(self):
if not self.delete_hash:
return
headers = self.headers()
response = requests.delete(f'{IMGUR_API}/image/{self.delete_hash}', headers=headers)
if not response.ok:
raise ImgurError(f'Failed to delete image {self.delete_hash}')
j = json.loads(response.text)
if not j['success'] or not j['status'] == 200:
raise ImgurError(f'Failed to delete image {self.delete_hash}')
self.link = None
self.delete_hash = None
def main():
if appex.is_running_extension():
assets = appex.get_images_data()
else:
assets = pick_assets()
if not assets:
print('No assets selected')
return
print(f'{len(assets)} asset(s) selected for upload')
imgur_assets = [ImgurAsset(x) for x in assets]
try:
for i, x in enumerate(imgur_assets):
print(f'Uploading {i+1}. asset')
x.upload()
except ImgurError as e:
print(e)
print('Upload failed, deleting already uploaded assets')
for x in imgur_assets:
try:
x.delete()
except Exception:
pass
else:
result = '\n'.join([
f'![]({x.link})'
for x in imgur_assets
if x.link
])
print(f'Asset links:\n{result}')
clipboard.set(result)
print('Asset links copied to the clipboard')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment