1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
import os import requests import base64 import hmac import datetime from os.path import join, exists, relpath from mimetypes import MimeTypes from hashlib import sha1, md5 from pickle import dump, loads from cStringIO import StringIO, InputType, OutputType from lxml import html
KEY = '----------' SECRET = '----------' BUCKET = '----------' url = '----------' ABSOLUTE_PATH = '/Users/ficapy/CodeSpace/Blog/public'
s = requests.Session()
headers = { 'Date': datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT'), 'Content-Type': 'text/html', 'HOST': url, }
def signature(file_path): global headers path = join(ABSOLUTE_PATH, file_path) headers['Content-Type'] = MimeTypes().guess_type(path)[0] or 'text/html' sign = base64.b64encode(hmac.new(SECRET, 'PUT' + "\n" + '' + "\n" + headers['Content-Type'] + "\n" + headers['Date'] + "\n" + '/' + BUCKET + '/' + file_path, sha1).digest()).strip() headers.update({'Authorization': 'OSS ' + KEY + ':' + sign})
def read_in_chunks(file_object, blocksize=1024): file_object = file_object if isinstance(file_object, (InputType, OutputType)) else open( join(ABSOLUTE_PATH, file_object)) file_object.seek(0) while 1: data = file_object.read(blocksize) if not data: break yield data
def upload(file_path, file_object): signature(file_path) s.put('http://' + url + '/' + file_path, headers=headers, data=read_in_chunks(file_object)).raise_for_status() print('upload done: ' + file_path)
def local_md5(): file_md5_mp = {} for root, dirnames, files in os.walk(ABSOLUTE_PATH): for file in files: fullpath = join(root, file) rel = relpath(fullpath, ABSOLUTE_PATH) file_md5_mp[rel] = md5(open(fullpath).read()).hexdigest() return file_md5_mp
def remote_md5(): a = s.get('http://' + url + '/oss_fuck_md5') if a.status_code != 200: return {} else: return loads(a.content)
def path_process(file_path): file_path = join(ABSOLUTE_PATH, file_path) tree = html.parse(file_path).getroot() hrefs = tree.xpath('//*[@href]')
for i, href in enumerate(hrefs): rewrite = join(href.attrib['href'].split()[0], 'index.html') if exists(join(ABSOLUTE_PATH, rewrite[1:])): hrefs[i].attrib['href'] = rewrite f = StringIO() f.write(html.tostring(tree)) return f
def main(): remote = remote_md5() locals = local_md5() _locals = locals.copy() for local in _locals.keys(): if _locals[local] != remote.get(local, None): continue else: locals.pop(local)
for path in locals.keys(): if path.endswith('html'): upload(path, path_process(path)) else: upload(path, path)
f = StringIO() dump(_locals, f) upload('oss_fuck_md5', f)
if __name__ == '__main__': main()
|