# -*- coding: utf-8 -*-  

import sqlite3
import base64
import json
import urllib2
import os
import sys
import hashlib
from datetime import datetime

if len(sys.argv) != 3:
    print "Args error, please check arg, program exit."
    print "arg1: id_and_key"
    print "arg2: bucket_id"
    os._exit(0)
    if len(sys.argv[1]) != 55 or len(sys.argv[2]) != 24:
        print "Args error, please check arg, program exit."
        os._exit(0)

id_and_key = sys.argv[1]
bucket_id = sys.argv[2]

run_begin = datetime.now()
file_name_prefix = ""  # The file name prefix of files the download authorization will allow
valid_duration = 86400  # The number of seconds the authorization is valid for
maxFileCount = 100  # The maximum number of files to return from this call, Passing in 0 means to use the default of 100
startFileName = ""  # The first file name to return
prefix = ""
basic_auth_string = 'Basic ' + base64.b64encode(id_and_key)
headers = {'Authorization': basic_auth_string}
account_authorization_token = ""
api_url = ""
download_url = ""
res = ""
remote_file_sha1 = ""
i = ""
save_dir = ""
count = 1


class MyException(Exception):
    pass


# b2_authorize_account
def authorize_account():
    print datetime.now().strftime('%c'), "authorize_account start"
    global account_authorization_token
    global api_url
    global download_url
    global run_begin
    run_begin = datetime.now()
    request = urllib2.Request(
        'https://api.backblazeb2.com/b2api/v1/b2_authorize_account',
        headers=headers
    )
    response = urllib2.urlopen(request)
    response_data = json.loads(response.read())
    response.close()

    account_authorization_token = response_data['authorizationToken']
    api_url = response_data['apiUrl']
    download_url = response_data['downloadUrl']
    print datetime.now().strftime('%c'), "authorize_account finish"


def download_authorization():
    print datetime.now().strftime('%c'), "download_authorization start"
    request = urllib2.Request(
        '%s/b2api/v1/b2_get_download_authorization' % api_url,
        json.dumps(
            {'bucketId': bucket_id, 'fileNamePrefix': file_name_prefix, 'validDurationInSeconds': valid_duration}),
        headers={'Authorization': account_authorization_token}
    )
    response = urllib2.urlopen(request)
    response_data = json.loads(response.read())
    response.close()
    print datetime.now().strftime('%c'), "download_authorization finish"


def connect_db():
    global remote_file_sha1
    global conn
    global cursor
    global startFileName
    conn = sqlite3.connect('backblazeb2.db')
    cursor = conn.cursor()
    print datetime.now().strftime('%c'), ": DB connected"


def download():
    print datetime.now().strftime('%c'), "download start"
    global remote_file_sha1
    global i
    global save_dir
    global valid_duration
    global count

    try:
        # fetch one file to download
        fetch_file_cmd = '''
		select id,contentSha1,fileId,dl_url from filelist where dl_status = 'no' order by id limit 1 
		'''
        result = conn.execute(fetch_file_cmd)
        for row in result:
            dl_id = row[0]
            remote_file_sha1 = row[1]
            fileId = row[2]
            dl_url = row[3]

            # check the dir is available or not
            save_dir = sys.path[0] + '/' + (dl_url.split('/')[0]) + '/' + (dl_url.split('/')[1]) + '/' + (
                dl_url.split('/')[2])
            if os.path.exists(save_dir):
                pass
            else:
                os.makedirs(save_dir)

            local_file_sha1 = ''
            t = 0

            # verify the token is valid or not
            run_now = datetime.now()
            if (run_now - run_begin).seconds >= valid_duration:
                print datetime.now().strftime('%c'), ": Token is valid, start renew..."
                authorize_account()
                download_authorization()
                print datetime.now().strftime('%c'), ": Renew authorization token finish."

            # change db file download status
            update_file_cmd = '''
			UPDATE filelist SET dl_status = 'downloading' where id = ?
			'''
            result = conn.execute(update_file_cmd, (dl_id,))
            result = conn.commit()

            # verify the sha1 of the file downloaded
            while (local_file_sha1 == '' or local_file_sha1 != remote_file_sha1):
                t += 1
                print datetime.now().strftime('%c'), ': Downloading file #', count, ',fileId :', fileId, ',try #', t
                re = urllib2.Request(download_url + '/b2api/v1/b2_download_file_by_id?fileId=' + fileId,
                                     headers={'Authorization': account_authorization_token})
                try:
                    f = urllib2.urlopen(re, timeout=30)
                    data = f.read()
                    hash_new = hashlib.sha1()
                    hash_new.update(data)
                    local_file_sha1 = hash_new.hexdigest()
                except urllib2.URLError, e:
                    raise MyException(datetime.now().strftime('%c'), ": Download error: %r" % e)

            print datetime.now().strftime('%c'), ': sha1 verify finish, download finish'
            with open(save_dir + '/' + dl_url.split('/')[-1], "w") as code:
                code.write(data)
            count += 1

            # change the db status to complete the download
            update_file_cmd = '''
			UPDATE filelist SET dl_status = 'yes' where id = ?
			'''
            result = conn.execute(update_file_cmd, (dl_id,))
            result = conn.commit()

    except:
        pass
        fileId = ''
        print datetime.now().strftime('%c'), "All download finish, program exit"
        conn.close()
        os._exit(0)


authorize_account()
download_authorization()
connect_db()
while 1 != 0:
    download()
