fixing renderText script
This commit is contained in:
@@ -0,0 +1,512 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import urllib2
|
||||
import json
|
||||
from base64 import b64encode
|
||||
from getpass import getpass
|
||||
from urllib import urlencode
|
||||
from cookielib import CookieJar
|
||||
from os.path import expanduser, exists
|
||||
from pprint import pprint
|
||||
from collections import OrderedDict
|
||||
from argparse import ArgumentParser
|
||||
|
||||
USERNAME = "rbotara"
|
||||
PASSWORD = "cigareta"
|
||||
APIKEY_AUTH = "acfe292a432ded08e576f019fb4e34d104df16436"
|
||||
APIKEY_ANON = "641ff5860e0a7e26e97e48d8ee80d162"
|
||||
DEBUG = False
|
||||
|
||||
|
||||
class ImgurError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Imgur(object):
|
||||
"""
|
||||
This class can be used to upload images and manage an account on imgur.com
|
||||
"""
|
||||
|
||||
base = "api.imgur.com"
|
||||
connected = False
|
||||
urls = {
|
||||
# Anon
|
||||
"upload": "/2/upload",
|
||||
"image": "/2/image/%s",
|
||||
"delete": "/2/delete/%s",
|
||||
# Auth
|
||||
"signin": "/2/signin",
|
||||
"account": "/2/account",
|
||||
"account_images": "/2/account/images",
|
||||
"account_image": "/2/account/images/%s",
|
||||
"account_images_count": "/2/account/images_count",
|
||||
"albums": "/2/account/albums",
|
||||
"album": "/2/account/albums/%s",
|
||||
"albums_count": "/2/account/albums_count",
|
||||
"albums_order": "/2/account/albums_order",
|
||||
"album_order": "/2/account/albums_order/%s",
|
||||
# Other
|
||||
"stats": "/2/stats",
|
||||
"credits": "/2/credits",
|
||||
}
|
||||
|
||||
def __init__(self, apikey_auth=None, apikey_anon=None, print_results=True):
|
||||
self.apikey_auth = apikey_auth
|
||||
self.apikey_anon = apikey_anon
|
||||
self.print_results = print_results
|
||||
self.cj = CookieJar()
|
||||
|
||||
def _handle_response(fun):
|
||||
def new_f(self, *args, **kwargs):
|
||||
try:
|
||||
resp = fun(self, *args, **kwargs)
|
||||
except urllib2.HTTPError, err:
|
||||
raise ImgurError(err)
|
||||
else:
|
||||
if self.print_results:
|
||||
content = resp.read()
|
||||
try:
|
||||
#pprint(json.loads(content))
|
||||
json_print(json.loads(content))
|
||||
except:
|
||||
pprint(content)
|
||||
return resp
|
||||
return new_f
|
||||
|
||||
def connection_required(fun):
|
||||
""" A decorator that checks if the user is authenticated """
|
||||
def new_f(self, *args, **kwargs):
|
||||
if not self.connected:
|
||||
raise ImgurError("You must be connected to perform this"
|
||||
"operation")
|
||||
return fun(self, *args, **kwargs)
|
||||
return new_f
|
||||
|
||||
def connect(self, username=None, password=None):
|
||||
"""
|
||||
A cookie is created for the authentication
|
||||
"""
|
||||
response = self.request("POST", "signin",
|
||||
username=username, password=password)
|
||||
debug("Connected.")
|
||||
self.connected = True
|
||||
|
||||
def _json(self, data):
|
||||
try:
|
||||
return json.loads(data)
|
||||
except ValueError:
|
||||
raise ImgurError("Invalid data")
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _account(self):
|
||||
return self.request("GET", "account")
|
||||
|
||||
@_handle_response
|
||||
def _upload(self, filename, url, name, title, caption):
|
||||
if filename:
|
||||
with open(expanduser(filename), "rb") as f:
|
||||
img = b64encode(f.read())
|
||||
t = "base64"
|
||||
else:
|
||||
img = url
|
||||
t = "url"
|
||||
url = "account_images" if self.connected else "upload"
|
||||
return self.request("POST", url, image=img,
|
||||
type=t, name=name, title=title, caption=caption)
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _imgedit(self, hash, title="", caption=""):
|
||||
url = self.urls["account_image"] % hash
|
||||
return self.request("POST", url=url, title=title, caption=caption)
|
||||
|
||||
@_handle_response
|
||||
def _imginfos(self, hash):
|
||||
c = self.connected
|
||||
url = self.urls["account_image" if c else "image"] % hash
|
||||
return self.request("GET", url=url)
|
||||
|
||||
@_handle_response
|
||||
def _imgdelete(self, hash):
|
||||
c = self.connected
|
||||
url = self.urls["account_image" if c else "delete"] % hash
|
||||
return self.request("DELETE", url=url)
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _imgcount(self):
|
||||
return self.request("GET", "account_images_count")
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _list(self):
|
||||
return self.request("GET", "account_images")
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _albums(self, title="", description="", privacy="", layout="",
|
||||
count="", page="", create=True):
|
||||
if create:
|
||||
return self.request("POST", "albums", title=title,
|
||||
description=description, privacy=privacy, layout=layout)
|
||||
else:
|
||||
return self.request("GET", "albums", count=count, page=page)
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _albmlist(self, album_id):
|
||||
url = self.urls["album"] % album_id
|
||||
return self.request("GET", url=url)
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _albmdelete(self, album_id):
|
||||
url = self.urls["album"] % album_id
|
||||
return self.request("DELETE", url=url)
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _albmedit(self, album_id, title="", description="", cover="",
|
||||
privacy="", layout="", images="", add_images="", del_images=""):
|
||||
url = self.urls["album"] % album_id
|
||||
datas = {}
|
||||
for k in ("url", "title", "description", "cover", "privacy", "layout",
|
||||
"images", "add_images", "del_images"):
|
||||
datas[k] = locals()[k]
|
||||
return self.request("POST", **datas)
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _albmcount(self):
|
||||
return self.request("GET", "albums_count")
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _albmord(self, album_id, hashes):
|
||||
url = self.urls["album_order"] % album_id
|
||||
return self.request("POST", url=url, hashes=hashes)
|
||||
|
||||
@_handle_response
|
||||
@connection_required
|
||||
def _albmords(self, album_ids):
|
||||
return self.request("POST", "albums_order", album_ids=album_ids)
|
||||
|
||||
@_handle_response
|
||||
def _limits(self):
|
||||
return self.request("GET", "credits")
|
||||
|
||||
def _stats(self, view):
|
||||
return self.request("GET", "stats", view=view)
|
||||
|
||||
def request(self, method, key="", url="", headers=None, **params):
|
||||
# Send an http request.
|
||||
# if key is set, use the url from self.urls[key]
|
||||
# else use 'url'
|
||||
if not headers:
|
||||
headers = {}
|
||||
url = "http://" + self.base + (self.urls[key] if key else url) + ".json"
|
||||
params["key"] = self.apikey_auth if self.connected else self.apikey_anon
|
||||
data = None
|
||||
if method in ("POST", "DELETE"):
|
||||
for k in params.keys():
|
||||
if not params[k]:
|
||||
del params[k]
|
||||
data = urlencode(params)
|
||||
elif method in ("GET", "DELETE"):
|
||||
url = "%s?%s" % (url, urlencode(params))
|
||||
|
||||
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))
|
||||
urllib2.install_opener(opener)
|
||||
debug(url, params)
|
||||
req = urllib2.Request(url, data, headers)
|
||||
if not method in ("POST", "GET"):
|
||||
req.get_method = lambda: method
|
||||
return urllib2.urlopen(req)
|
||||
|
||||
def _get_json(self, fun_name, *args, **kwargs):
|
||||
return self._json(getattr(self, fun_name)(*args, **kwargs).read())
|
||||
|
||||
def _infos(self, img):
|
||||
""" Print the infos of an image """
|
||||
return dict_print(OrderedDict(img["image"].items() +
|
||||
img["links"].items()))
|
||||
|
||||
def _liststr(self, datas):
|
||||
""" Converts a list into "(foo,bar,baz)" """
|
||||
if isinstance(datas, (list, tuple)):
|
||||
datas = "(%s)" % (",".join(str(e) for e in datas))
|
||||
elif not datas.startswith("("):
|
||||
datas = "(%s)" % datas
|
||||
return datas
|
||||
|
||||
def upload_image(self, image="", name="", title="", caption="", hashes=False):
|
||||
"""
|
||||
Upload an image
|
||||
'image' can be a path or an url
|
||||
if hashes is True, return only the hashes
|
||||
"""
|
||||
url, file = "", ""
|
||||
if not exists(image):
|
||||
url = image
|
||||
else:
|
||||
file = image
|
||||
datas = self._get_json("_upload", file, url, name, title, caption)
|
||||
infos = datas["images" if self.connected else "upload"]
|
||||
if hashes:
|
||||
return "Hash: %s\nDelete: %s" % (infos["image"]["hash"],
|
||||
infos["image"]["deletehash"])
|
||||
else:
|
||||
return self._infos(infos)
|
||||
|
||||
def account(self):
|
||||
""" Get account infos """
|
||||
datas = self._get_json("_account")
|
||||
return dict_print(datas["account"])
|
||||
|
||||
def list_images(self):
|
||||
""" List all images in account """
|
||||
datas = self._get_json("_list")
|
||||
imgs = (self._infos(img) for img in datas["images"])
|
||||
return "\n *** \n".join(imgs)
|
||||
|
||||
def infos_image(self, hash):
|
||||
""" Retrieve informations from an image """
|
||||
datas = self._get_json("_imginfos", hash)
|
||||
return self._infos(datas["images" if self.connected else "image"])
|
||||
|
||||
def delete_image(self, hash):
|
||||
""" Delete an image """
|
||||
datas = self._get_json("_imgdelete", hash)
|
||||
return datas["images"]["message"] if self.connected else ""
|
||||
|
||||
def edit_image(self, hash, new_title="", new_caption=""):
|
||||
""" Edit an image """
|
||||
datas = self._get_json("_imgedit", hash, new_title, new_caption)
|
||||
return self._infos(datas["images"])
|
||||
|
||||
def count_images(self):
|
||||
""" Count all images in the account """
|
||||
return self._get_json("_imgcount")["images_count"]["count"]
|
||||
|
||||
def list_albums(self, count=30, page=1):
|
||||
"""
|
||||
List all albums in the account
|
||||
"""
|
||||
datas = self._get_json("_albums", count=count, page=page,
|
||||
create=False)
|
||||
return "\n *** \n".join(dict_print(alb) for alb in datas["albums"])
|
||||
|
||||
def create_album(self, title="", description="", privacy="", layout=""):
|
||||
"""
|
||||
All values are optional.
|
||||
privacy: public/hidden/secret
|
||||
layout: blog/horizontal/vertical/grid
|
||||
"""
|
||||
datas = self._get_json("_albums", title, description, privacy, layout)
|
||||
return dict_print(datas["albums"])
|
||||
|
||||
def list_album(self, album_id):
|
||||
""" List all images in an album """
|
||||
datas = self._get_json("_albmlist", album_id)
|
||||
imgs = (self._infos(img) for img in datas["albums"])
|
||||
return "\n *** \n".join(imgs)
|
||||
|
||||
def delete_album(self, album_id):
|
||||
""" Delete an album """
|
||||
datas = self._get_json("_albmdelete", album_id)
|
||||
return datas["albums"]["message"]
|
||||
|
||||
def edit_album(self, album_id, title="", description="", cover="",
|
||||
privacy="", layout="", images="", add_images="", del_images=""):
|
||||
"""
|
||||
Edit an album
|
||||
privacy: public/hidden/secret
|
||||
layout: blog/horizontal/vertical/grid
|
||||
cover: a hash of an image in the account
|
||||
'images' replaces all images in the album
|
||||
|
||||
images, add_images and del_images must be a list of hashes,
|
||||
or a string formatted like (hash1,hash2,...)
|
||||
"""
|
||||
for k in ("images", "add_images", "del_images"):
|
||||
locals()[k] = self._liststr(locals()[k])
|
||||
datas = self._get_json("_albmedit", album_id, title, description,
|
||||
cover, privacy, layout, images, add_images, del_images)
|
||||
imgs = (self._infos(img) for img in datas["albums"])
|
||||
return "\n *** \n".join(imgs)
|
||||
|
||||
def count_albums(self):
|
||||
""" Return the number of albums. """
|
||||
datas = self._get_json("_albmcount")
|
||||
return datas["albums_count"]["count"]
|
||||
|
||||
def order_album(self, album_id, hashes):
|
||||
hashes = self._liststr(hashes)
|
||||
datas = self._get_json("_albmord", album_id, hashes)
|
||||
return "\n *** \n".join(dict_print(alb) for alb in datas["albums_order"])
|
||||
|
||||
def order_albums(self, album_ids):
|
||||
album_ids = self._liststr(album_ids)
|
||||
datas = self._get_json("_albmords", album_ids)
|
||||
imgs = (self._infos(img) for img in datas["albums_order"])
|
||||
return "\n *** \n".join(imgs)
|
||||
|
||||
def stats(self, view="month"):
|
||||
"""
|
||||
View imgur's stats
|
||||
view: today|week|month
|
||||
"""
|
||||
return dict_print(self._get_json("_stats", view)["stats"])
|
||||
|
||||
|
||||
def debug(*datas):
|
||||
if DEBUG:
|
||||
print "DEBUG:", ", ".join(str(d) for d in datas)
|
||||
|
||||
def json_print(data, tab=0):
|
||||
if isinstance(data, (list, tuple)):
|
||||
print
|
||||
for elem in data:
|
||||
json_print(elem, tab)
|
||||
print
|
||||
elif isinstance(data, dict):
|
||||
print
|
||||
for e, d in data.items():
|
||||
print "\t"*tab, e,
|
||||
json_print(d, tab+1)
|
||||
else:
|
||||
print "\t"*tab, data
|
||||
|
||||
def dict_print(data):
|
||||
def align(l, r, w=80):
|
||||
return "%s: %s%s" % (l, (w-len(l))* " ", r)
|
||||
w = max(len(e) for e in data.keys())
|
||||
return "\n".join(align(k, v, w) for k, v in data.items())
|
||||
|
||||
def main():
|
||||
i = Imgur(APIKEY_AUTH, APIKEY_ANON, False)
|
||||
|
||||
# Parser definition
|
||||
parser = ArgumentParser(description="A command-line utility for imgur.com")
|
||||
parser.add_argument("--user")
|
||||
parser.add_argument("--password")
|
||||
parser.add_argument("--ask-pass", action="store_true",
|
||||
help="Prompt for a password, so that it will never be displayed.")
|
||||
parser.add_argument("--anon", action="store_true", default=False,
|
||||
help="Do not authenticate.")
|
||||
sparsers = parser.add_subparsers(metavar="ACTION", dest='sp_name',
|
||||
help="Use '%(prog)s action -h' for more help")
|
||||
|
||||
up_parser = sparsers.add_parser("upload", help="Upload a file or an url")
|
||||
up_parser.add_argument("image", help="A path or an url")
|
||||
up_parser.add_argument("-t", "--title")
|
||||
up_parser.add_argument("-n", "--name")
|
||||
up_parser.add_argument("-c", "--caption")
|
||||
up_parser.add_argument("-s", "--hashes", action="store_true",
|
||||
help="Only print the hashes instead of all the informations")
|
||||
|
||||
imgd_parser = sparsers.add_parser("delete", help="Delete an image")
|
||||
imgd_parser.add_argument("hash")
|
||||
|
||||
imgi_parser = sparsers.add_parser("infos", help="Get infos on the image")
|
||||
imgi_parser.add_argument("hash")
|
||||
|
||||
imge_parser = sparsers.add_parser("edit", help="Edit an image")
|
||||
imge_parser.add_argument("hash")
|
||||
imge_parser.add_argument("-t", "--title")
|
||||
imge_parser.add_argument("-c", "--caption")
|
||||
|
||||
list_parser = sparsers.add_parser("list", help="List all your images")
|
||||
|
||||
acc_parser = sparsers.add_parser("account", help="Account infos")
|
||||
|
||||
albc_parser = sparsers.add_parser("create-album", help="Create a new album")
|
||||
albc_parser.add_argument("-t", "--title")
|
||||
albc_parser.add_argument("-d", "--description")
|
||||
albc_parser.add_argument("-p", "--privacy", choices=["public", "hidden",
|
||||
"secret"])
|
||||
albc_parser.add_argument("-l", "--layout", choices=["blog", "horizontal",
|
||||
"vertical", "grid"])
|
||||
|
||||
albe_parser = sparsers.add_parser("edit-album", help="Edit an album")
|
||||
albe_parser.add_argument("album_id")
|
||||
albe_parser.add_argument("-t", "--title")
|
||||
albe_parser.add_argument("-d", "--description")
|
||||
albe_parser.add_argument("-p", "--privacy", choices=["public", "hidden",
|
||||
"secret"])
|
||||
albe_parser.add_argument("-l", "--layout", choices=["blog", "horizontal",
|
||||
"vertical", "grid"])
|
||||
albe_parser.add_argument("-c", "--cover", help="The hash of an image to use "
|
||||
"as cover for the album", metavar="hash")
|
||||
albe_parser.add_argument("-i", "--images", metavar="hash1,hash2,..,hashN",
|
||||
help="Replace all images in an album.")
|
||||
albe_parser.add_argument("-a", "--add", metavar="hash1,hash2,..,hashN",
|
||||
help="Add images to the album.")
|
||||
albe_parser.add_argument("-r", "--delete", metavar="hash1,hash2,..,hashN",
|
||||
help="Delete images from the album.")
|
||||
|
||||
albl_parser = sparsers.add_parser("list-albums",
|
||||
help="List all albums.")
|
||||
albl_parser.add_argument("-c", "--count", help="The number of albums to return")
|
||||
albl_parser.add_argument("-p", "--page", help="The pages of albums to return")
|
||||
|
||||
albs_parser = sparsers.add_parser("list-album",
|
||||
help="List all images in an album")
|
||||
albs_parser.add_argument("album_id")
|
||||
|
||||
albco_parser = sparsers.add_parser("count-albums",
|
||||
help="Get the number of albums")
|
||||
|
||||
albd_parser = sparsers.add_parser("delete-album", help="Delete an album")
|
||||
albd_parser.add_argument("album_id")
|
||||
|
||||
albos_parser = sparsers.add_parser("order-albums", help="Order all albums in the account")
|
||||
albos_parser.add_argument("album_ids", metavar="id1,id2,...,idn", help="The new list of album IDs")
|
||||
|
||||
albo_parser = sparsers.add_parser("order-album", help="Order all images in an album")
|
||||
albo_parser.add_argument("album_id")
|
||||
albo_parser.add_argument("hashes", metavar="hash1,hash2,...,hashn", help="The new list of hashes")
|
||||
|
||||
stats_parser = sparsers.add_parser("stats", help="Imgur statistics")
|
||||
stats_parser.add_argument("-v", "--view",
|
||||
choices=["today", "month", "week"])
|
||||
|
||||
# Authentification
|
||||
args = parser.parse_args()
|
||||
u, p, ap = args.user, args.password, args.ask_pass
|
||||
if u and not p:
|
||||
if ap:
|
||||
i.connect(u, getpass())
|
||||
else:
|
||||
i.connect(u, PASSWORD)
|
||||
elif p and not u:
|
||||
i.connect(USERNAME, p)
|
||||
elif u and p:
|
||||
i.connect(u, p)
|
||||
elif USERNAME and (not PASSWORD or ap) and not args.anon:
|
||||
i.connect(USERNAME, getpass())
|
||||
elif USERNAME and PASSWORD and not args.anon:
|
||||
i.connect(USERNAME, PASSWORD)
|
||||
|
||||
# Preparation
|
||||
opts = vars(args)
|
||||
spname = args.sp_name
|
||||
del opts["user"], opts["password"], opts["anon"], opts["ask_pass"]
|
||||
if spname in ("upload", "infos", "delete", "edit", "list", "count"):
|
||||
fun_name = spname + "_image" if hasattr(Imgur,
|
||||
spname + "_image") else spname + "_images"
|
||||
elif spname.rstrip("s").endswith("album"):
|
||||
fun_name = spname.replace("-", "_")
|
||||
else:
|
||||
fun_name = spname
|
||||
del opts["sp_name"]
|
||||
fun = getattr(Imgur, fun_name)
|
||||
|
||||
# And action.
|
||||
print fun(i, **opts)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user