Created
August 20, 2014 12:25
-
-
Save mosquito/33d373630ab126e0ac85 to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env python | |
import os | |
import sys | |
import urllib2 | |
import ConfigParser | |
import traceback | |
import base64 | |
import tempfile | |
import json | |
from optparse import OptionParser | |
class Progress(object): | |
def __init__(self, title=''): | |
self._seen = 0.0 | |
self._filename = title | |
def __call__(self, total, size, name, *args): | |
self._seen += size | |
sys.stdout.write('\r%s in progress: %3.2f%%' % (self._filename, (self._seen / total) * 100.0)) | |
sys.stdout.flush() | |
class File(file): | |
def __init__(self, path, mode, callback=lambda x, y, z: (x, y, z)): | |
file.__init__(self, path, mode) | |
self.__total = os.stat(path).st_size | |
self.__callback = callback | |
self.__args = args | |
def __len__(self): | |
return self.__total | |
def read(self, size=2**15): | |
data = file.read(self, size) | |
self.__callback(self.__total, len(data), *self.__args) | |
return data | |
# curl -i --user api:YOUR_API_KEY --data-binary @large.png https://api.tinypng.com/shrink | |
def main(args, options): | |
top_level_url = options.url | |
for f in args: | |
if not os.path.exists(f): | |
print 'File "{0}" doesn\'t exists'.format(f) | |
exit(64) | |
name, ext = os.path.splitext(f) | |
if not ext.endswith('png'): | |
print 'File "{0}" not png file'.format(f) | |
exit(65) | |
for f in args: | |
print 'Shinking:' | |
with File(f, 'rb', Progress(' => "{0}"'.format(os.path.basename(f)))) as fd: | |
try: | |
request = urllib2.Request(top_level_url, fd) | |
size = os.stat(f).st_size | |
base64string = base64.encodestring('{0}:{1}'.format(options.username, options.api_key)).replace('\n', '') | |
request.add_header("Authorization", "Basic %s" % base64string) | |
result = urllib2.urlopen(request) | |
tmp_name = tempfile.NamedTemporaryFile(suffix='.png').name | |
result = json.load(result) | |
with open(tmp_name, 'w+') as tmp: | |
print '\n => Downloading "{0}"...'.format(result['output']['url']) | |
request = urllib2.Request(result['output']['url']) | |
response = urllib2.urlopen(request) | |
tmp.write(response.read()) | |
new_size = os.stat(tmp_name).st_size | |
os.rename(f, "{0}.bak".format(f)) | |
os.rename(tmp_name, f) | |
print " => Done shrinked {0} ({1}%)\n".format( | |
(result['input']['size'] - result['output']['size']), (1-result['output']['ratio']) * 100 | |
) | |
if not options.backup: | |
os.remove("{0}.bak".format(f)) | |
except urllib2.HTTPError as e: | |
print "\n => HTTP Error {0}: '{1}'".format(e.code, e.read()) | |
return exit(1) | |
except Exception as e: | |
print traceback.format_exc() | |
raise e | |
if __name__ == '__main__': | |
parser = OptionParser(usage="usage: %prog [options] file1 [file2...[fileN]]") | |
parser.add_option("-K", "--key", dest="api_key", | |
help='API key for "http://tinypng.com"', metavar="KEY", default=None) | |
parser.add_option("-U", "--url", dest="url", help='URL address for "http://tinypng.com"', | |
metavar="URL", default="https://api.tinypng.com/shrink") | |
parser.add_option("-u", "--user", dest="username", help='Username for "http://tinypng.com"', | |
metavar="USERNAME", default="api") | |
parser.add_option("-B", "--backup", dest="backup", help='Backup original file', | |
action='store_true', default=False) | |
options, args = parser.parse_args() | |
config_file = os.path.join(os.path.expanduser('~'), '.pngshrinkrc') | |
config = ConfigParser.ConfigParser() | |
if os.path.exists(config_file): | |
config.read(config_file) | |
api_key = config.get('main', 'key') | |
options.api_key = api_key | |
else: | |
if options.api_key: | |
api_key = options.api_key | |
config.add_section('main') | |
config.set('main', 'key', api_key) | |
else: | |
print "You must set api key" | |
exit(128) | |
with open(config_file, 'w+') as f: | |
config.write(f) | |
main(args, options) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment