gett-cli /

#!/usr/bin/env python

import sys, os, os.path
import argparse
import signal
import re

from itertools import chain
from time import sleep

from gett import *

url_re = re.compile(r'^(?:http://ge\.tt/|/)?(\w+)(?:/(?:v/(\d+)/?)?)?$')

def humanize(nbytes):
    for (exp, unit) in ((9, 'GB'), (6, 'MB'), (3, 'KB')):
       if nbytes >= 10**exp:
           return '%.2f %s' % (nbytes / 10**exp, unit)

    return '%.2f B' % nbytes

def print_status(upload, index, count):
        name =

        if len(name) > 15:
            name = name[:12] + '...'

        name = name.ljust(15)

        bar_size = int(50 * upload.percent_done / 100)
        bar = '[' + (bar_size * '#') + ((50 - bar_size) * '-') + ']'

        sys.stderr.write('\r%s (%d/%d) %s %d %%' % (name, index, count, bar, upload.percent_done))

def show_share(share):
    print('Share %s : %s (%d file(s))' % (, share.title or 'Untitled', len(share.files)))

    for file in share.files.values():
        size = ''
        if file.size is not None:
            size = '[%s]' % humanize(file.size)

        print('--- %-20s %s [%s]' % (, size, file.url))

def entry_point():
    except APIError as ex:
        print('API error : %s' % ex)

def pattern(string):
    import glob

    ret = []

    if os.path.isfile(string):
        ret.append(open(string, 'rb'))
        if os.path.isdir(string):
            pattern = string + '/*'
            pattern = string

        for item in glob.iglob(pattern):
            if os.path.isfile(item):
                ret.append(open(item, 'rb'))

    if not ret:
        print('warning: %s: no match' % string)
    return ret

def main():
    signal.signal(signal.SIGINT, signal.SIG_DFL)

    home = os.getenv('USERPROFILE') or os.getenv('HOME')

    parser = argparse.ArgumentParser(description="A command-line uploader and manager")
    parser.add_argument('-D', dest='debug', action='store_true', help='Debug API calls')

    upload_group = parser.add_argument_group('Upload options')
    upload_group.add_argument('file', nargs='*', type=pattern, help="Name of a file or a directory to upload. Patterns are allowed. This is not recursive.")
    upload_group.add_argument('-t', dest='title', help='Title of the share')
    upload_group.add_argument('-s', dest='share', help='Name or URL of the share to upload to (defaults to a newly created one)')
    upload_group.add_argument('-P', dest='parallel_upload', action='store_true', help='Upload files in parallel rather than sequentially, the progress bars are displayed in ascending file size order')

    other_group = parser.add_argument_group('Other actions')
    other_group.add_argument('--delete', nargs='+', dest='delete', metavar='SHARE_OR_FILE', help='Delete a share or a file (url or path)')
    other_group.add_argument('--list', nargs='*', dest='list', metavar='SHARE_NAME', help='List the files in the specified share. If no share is specified, list all your shares.')

    auth_group = parser.add_argument_group('Authentification')
    auth_group.add_argument('-L', dest='ignore_token', action='store_true', help='Log-in with a different account than the stored one (if any)')
    auth_group.add_argument('-e', dest='email', help='Email to login with')
    auth_group.add_argument('-p', dest='password', help='Password to login with')
    auth_group.add_argument('-k', dest='tokenfile', help=' token file path (~/.gett-token)', default=os.path.join(home, '.gett-token'))

    args = parser.parse_args()

    if args.debug:
        import gett
        gett.DEBUG = True

    user = User()
    logged = False

    # If not logging-in with a different account

    if not args.ignore_token and not
            # Try to log-in with the token

            token = open(args.tokenfile, 'r').read()

            logged = True
        except (APIError, IOError):

    if not logged:
        if not
   = input('Please enter your email: ')

        if not args.password:
            import getpass
            args.password = getpass.getpass('Please enter your password: ')

            user.login_auth(, args.password)
        except Exception as ex:
            print('Unable to login: %s' % ex.args[0])

        reply = input('Do you wish to store the session token? (y/n): ')

        if reply.lower() == 'y':
            # Save the refreshtoken to the user's home directory (by default)

            with open(args.tokenfile, 'w') as file:

    # --list command

    if args.list is not None:
        for name in args.list:
            share = Share(name)

        if not args.list:
            for share in user.list_shares():

    # --delete command

    if args.delete:
        for item in args.delete:
            match = url_re.match(item)

            if not match:
                parser.error('argument --delete: invalid format, please supply either file/share url or path')

            share = user.get_share(

                    id =
                    file = share.files[id]

                    print('Deleted file %s [%s]' % (, file.url))
                except KeyError:
                    print("No such file in the share")
                print('Deleted share %s' %

    # File uploads

    if args.file:
        if args.share:
            # Upload to existing share

            match = url_re.match(args.share)

            if match:
                share = user.get_share(
                parser.error('argument --list: invalid share name, please supply either URL or name')
            # Upload to a new share

            if args.title:
                share = user.create_share(args.title)
                share = user.create_share()

        uploads = []

        # Create the file URLs

        for fp in chain.from_iterable(args.file):
            name = os.path.basename(
            file = share.create_file(name)

            print('%s: %s' % (name, file.url))

            upload = FileUpload(file, fp)

            if args.parallel_upload:



        if args.parallel_upload:
            uploads.sort(key=lambda item: item.file_size)

        for i, upload in enumerate(uploads):
            if not args.parallel_upload:

            while True:
                print_status(upload, i + 1, len(uploads))

                if not upload.is_alive():
                    print_status(upload, i + 1, len(uploads))

                    if upload.ex:
                        sys.stderr.write(('\rError uploading %s: %s' % (, upload.ex)).ljust(80))



    print('Storage used : %s out of %s (%d %%)' % (
            int(100 * user.storage_used / user.storage_limit)))

if __name__ == '__main__':
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
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.