Source

gett-cli / gett.py

import json
import pprint
import datetime
import threading
import os.path

from urllib.request import urlopen, Request
from urllib.parse import urlencode
from urllib.error import HTTPError
from urllib.parse import urlparse

from http.client import HTTPConnection

API_BASE = 'https://open.ge.tt/1/'
API_KEY = 't05kormjprb2o6rm8f8wmts2thjjor'
DEBUG = False

class APIError(Exception):
    pass

def _post_request(path, **kwargs):
    qskeys = {}
    url = API_BASE + path

    for key, value in list(kwargs.items()):
        if key.startswith('_'):
            qskeys[key[1:]] = value
            del kwargs[key]

    if qskeys:
        url += '?' + urlencode(qskeys)

    input_data = json.dumps(kwargs).encode('utf-8')
    request = Request(url, input_data)

    return _request(request)

def _get_request(path, **kwargs):
    url = API_BASE + path

    if kwargs:
        url += '?' + urlencode(kwargs)

    request = Request(url)
    return _request(request)

def _request(req):
    try:
        resp = urlopen(req).read()
    except HTTPError as ex:
        resp = ex.read()

    result = json.loads(resp.decode('utf-8'))

    if DEBUG:
        print('--------------------------------------------------------------------------------')
        print("%s request to %s -->" % (req.get_method(), req.full_url))

        if req.data:
            print('data: ' + req.data.decode('utf-8'))

        print('result:')

        pprint.pprint(result)
        print()

    if "error" in result:
        raise APIError(result["error"])

    return result

class User(object):
    def _load(self, result):
        self.atoken = result['accesstoken']
        self.rtoken = result['refreshtoken']
        self.userid = result['user']['userid']
        self.email = result['user']['email']
        self.full_name = result['user']['fullname']
        self.storage_used = result['user']['storage']['used']
        self.storage_limit = result['user']['storage']['limit']

    def refresh(self):
        self.login_token(self.rtoken)

    def login_auth(self, email, password):
        result = _post_request('users/login', apikey=API_KEY, email=email, password=password)
        self._load(result)

    def login_token(self, rtoken):
        result = _post_request('users/login', refreshtoken=rtoken)
        self._load(result)

    def list_shares(self, skip=None, limit=None):
        if skip is not None and limit is not None:
            results = _get_request('shares', accesstoken=self.atoken, skip=str(skip), limit=str(limit))
        else:
            results = _get_request('shares', accesstoken=self.atoken)

        for share_result in results:
             share = UserShare(self)
             share._load(share_result)
             yield share

    def get_share(self, name):
        result = _get_request('shares/' + name)

        share = UserShare(self)
        share._load(result)

        return share

    def create_share(self, title=None):
        if title is not None:
            result = _post_request('shares/create', _accesstoken=self.atoken, title=title)
        else:
            result = _post_request('shares/create', _accesstoken=self.atoken)

        share = UserShare(self)
        share._load(result)

        return share

class Share(object):
    def __init__(self, name):
        self.name = name
        self.refresh()

    def _load(self, result):
        self.name = result['sharename']
        self.title = result.get('title')
        self.created = datetime.datetime.fromtimestamp(result['created'])
        self.url = result.get('getturl')
        self.files = {}

        for file_result in result['files']:
            f = File(self)
            f._load(file_result)

            self.files[f.id] = f

    def refresh(self):
        result = _get_request('shares/' + self.name)
        self._load(result)

class UserShare(Share):
    def __init__(self, user):
        self.user = user

    def update(self, **fields):
        result = _post_request('shares/' + self.name + '/update', _accesstoken=self.user.atoken, **fields)
        self._load(result)

    def destroy(self):
        _post_request('shares/' + self.name + '/destroy', _accesstoken=self.user.atoken)

    def create_file(self, filename):
        result = _post_request('files/' + self.name + '/create', _accesstoken=self.user.atoken, filename=filename)
        file = File(self)
        file._load(result)
        return file

class File(object):
    def __init__(self, share):
        self.share = share

    def _load(self, result):
        self.name = result['filename']
        self.id = result['fileid']
        self.size = result.get('size')
        self.downloads = result['downloads']
        self.readystate = result['readystate']
        self.created = datetime.datetime.fromtimestamp(result['created'])
        self.url = result.get('getturl')

        if 'upload' in result:
            self.put_url = result['upload']['puturl']
        else:
            self.put_url = None

    def destroy(self):
        _post_request('files/' + self.share.name + '/' + str(self.id) + '/destroy', _accesstoken=self.share.user.atoken)

    def refresh(self):
        result = _get_request('files/' + self.share.name + '/' + str(self.id))
        self._load(result)

class FileUpload(threading.Thread):
    def __init__(self, file, fp):
        super().__init__()

        self.file = file
        self.fp = fp
        self.file_size = os.path.getsize(fp.name)
        self.percent_done = 0
        self.bytes_written = 0
        self.ex = None

    def run(self):
        try:
            parsed = urlparse(self.file.put_url)
            conn = HTTPConnection(parsed.netloc)
            conn.connect()
            conn.putrequest('PUT', parsed.path + (('?' + parsed.query) if parsed.query else ''))
            conn.putheader('Content-Length', str(self.file_size))
            conn.endheaders()

            while self.bytes_written != self.file_size:
                data = self.fp.read(4096)
                conn.sock.sendall(data)
                self.bytes_written += len(data)
                self.percent_done = self.bytes_written * 100 / self.file_size

            resp = conn.getresponse()
        except Exception as ex:
            self.ex = ex
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.