Files
stacks-puppet-node/demos/python-filesharing/blockstack_files/main.py
2017-03-02 17:15:10 -05:00

223 lines
5.7 KiB
Python

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
This code is public domain.
Used as a demo for Blockstack.
"""
import sys
import os
import json
import argparse
import traceback
from .bsk import *
from .version import __version__
CONFIG_PATH = os.path.expanduser('~/.blockstack_files.conf')
DRIVERS = ['disk']
def load_datastore_info( config_path=CONFIG_PATH ):
"""
Get our config.
Returns {
'session': session,
'datastore_id': datastore ID
}
Or, returns None if there's no such file.
Raise on exception.
"""
if not os.path.exists(config_path):
return None
with open(config_path, 'r') as f:
dat = f.read().strip()
conf = json.loads(dat)
return conf
def store_datastore_info( session, datastore_id, config_path=CONFIG_PATH ):
"""
Store our config.
Return True on success
Raise on error
"""
conf = {
'session': session,
'datastore_id': datastore_id
}
with open(config_path, 'w') as f:
f.write( json.dumps(conf) )
return True
def login( api_password=None, drivers=DRIVERS, config_path=CONFIG_PATH ):
"""
Authenticate to Blockstack,
get a session, and create the
datastore if it doesn't exist already.
Store the session and datastore ID to disk.
Returns {'session': session, 'datastore_id': ...} on success
Returns None on error
"""
creds = load_datastore_info( config_path=config_path )
if creds is not None:
return creds
assert api_password, 'API password required'
# first-time signing in
session = bsk_get_session( api_password )
datastore_id = bsk_make_datastore( session, drivers=drivers )
store_datastore_info( session, datastore_id, config_path=config_path )
return {'session': session, 'datastore_id': datastore_id}
def logout( config_path=CONFIG_PATH ):
"""
Remove our cached credentials.
Return True on success
Raise on error
"""
if os.path.exists(config_path):
os.unlink(config_path)
return True
def run_cli( argv ):
"""
Run the CLI.
Return True on success
Return False on error
"""
argparser = argparse.ArgumentParser(description="blockstack-files version {}".format(__version__))
subparsers = argparser.add_subparsers(
dest='action', help='the action to be taken')
# ---------------------------
subparser = subparsers.add_parser(
'login', help='authenticate and log into your Blockstack node')
subparser.add_argument(
'api_password', action='store', help='Blockstack API password')
# ---------------------------
subparser = subparsers.add_parser(
'logout', help='log out of your Blockstack node')
# ---------------------------
subparser = subparsers.add_parser(
'ls', help='list a given directory')
subparser.add_argument(
'path', action='store', help='the path to the directory to list')
# ---------------------------
subparser = subparsers.add_parser(
'cat', help='cat a file to stdout')
subparser.add_argument(
'path', action='store', help='the path to the file to read')
# ---------------------------
subparser = subparsers.add_parser(
'mkdir', help='make a directory')
subparser.add_argument(
'path', action='store', help='the path to the directory to create')
# ---------------------------
subparser = subparsers.add_parser(
'put', help='store a file')
subparser.add_argument(
'local_path', action='store', help='the path to the local data on disk')
subparser.add_argument(
'path', action='store', help='the path in the data store to host this data')
# ---------------------------
subparser = subparsers.add_parser(
'rm', help='remove a file')
subparser.add_argument(
'path', action='store', help='the path to the file to delete')
# ---------------------------
subparser = subparsers.add_parser(
'rmdir', help='remove a directory')
subparser.add_argument(
'path', action='store', help='the path to the directory to remove.')
# act on it
args = argparser.parse_args()
try:
# authenticate, or get credentials
if args.action == 'login':
creds = login( args.api_password )
else:
try:
creds = login()
except:
print >> sys.stderr, 'Unable to log in. Try `{} login`'.format(argv[0])
return False
# bsk paths must be absolute
path = getattr(args, 'path', None)
if path:
if not path.startswith('/'):
print >> sys.stderr, "Error: {} is not absolute".format(path)
return False
session = creds['session']
datastore_id = creds['datastore_id']
if args.action == 'ls':
res = bsk_stat( session, datastore_id, path )
if res['type'] == 2:
bsk_listdir( session, datastore_id, path )
else:
print os.path.basename(path)
elif args.action == 'cat':
bsk_get_file( session, datastore_id, path )
elif args.action == 'mkdir':
bsk_mkdir( session, datastore_id, path )
elif args.action == 'put':
bsk_put_file( session, datastore_id, args.local_path, path )
elif args.action == 'rm':
bsk_delete_file( session, datastore_id, path )
elif args.action == 'rmdir':
bsk_rmdir( session, datastore_id, path )
elif args.action == 'logout':
logout()
else:
return False
return True
except Exception as e:
traceback.print_exc()
return False