import sys import os.path import logging as log from argparse import ArgumentParser from util import spawnDaemon, splitHost import config as conf import stats from hashtree import HashTree from client import Client, Connection as ClientConnection, FailedConnection from server import Miniserver def _checkFile(f): if not os.path.isfile(f): print("invalid file specified:",f,file=sys.stderr) sys.exit(1) def buildTree(args): _checkFile(args.datafile) if os.path.isfile(args.treefile): treeMod=os.stat(args.treefile).st_mtime dataMod=os.stat(args.datafile).st_mtime if dataMod<treeMod and not args.force: print("tree file is up to date") return tree=HashTree.fromFile(args.datafile) tree.save(args.treefile) def push(args): _checkFile(args.datafile) if args.tree: _checkFile(args.tree) if args.host: conf.hosts=[args.host] if args.port: conf.port=args.port c=Client(args.datafile,args.tree) for h in conf.hosts: host=splitHost(h,conf.port) stats.reset() try: with ClientConnection(*host) as con: c.setConnection(con) blocksToTransfer=c.negotiate() c.sendData(blocksToTransfer) print() print(stats.report()) print() except FailedConnection: continue def pull(args): _checkFile(args.datafile) if args.tree: _checkFile(args.tree) if args.host: conf.hosts=[args.host] if args.port: conf.port=args.port c=Client(args.datafile,args.tree) host=splitHost(conf.hosts[0],conf.port) try: with ClientConnection(*host) as con: c.setConnection(con) blocksToTransfer=c.negotiate() c.pullData(blocksToTransfer) print() print(stats.report()) except FailedConnection: pass def serve(args): _checkFile(args.datafile) if args.tree: _checkFile(args.tree) if args.host: conf.hosts.insert(0,args.host) if args.port: conf.port=args.port s=Miniserver(args.datafile,args.tree) try: spawnDaemon(s.serve) except Exception as e: log.exception("exception: %s",e) parser=ArgumentParser() subparsers=parser.add_subparsers() pBuild=subparsers.add_parser("build") pBuild.add_argument("-f","--force",action="store_true",help="force tree rebuild") pBuild.add_argument("treefile", help="stored hash tree location") pBuild.add_argument("datafile") pBuild.set_defaults(func=buildTree) pUpdate=subparsers.add_parser("push") pUpdate.add_argument("-p","--port",type=int) pUpdate.add_argument("--host") pUpdate.add_argument("-t","--tree",help="stored hash tree location") pUpdate.add_argument("datafile") pUpdate.set_defaults(func=push) pUpdate=subparsers.add_parser("pull") pUpdate.add_argument("-p","--port",type=int) pUpdate.add_argument("--host") pUpdate.add_argument("-t","--tree",help="stored hash tree location") pUpdate.add_argument("datafile") pUpdate.set_defaults(func=pull) pServe=subparsers.add_parser("serve") pServe.add_argument("-p","--port",type=int) pServe.add_argument("--host") pServe.add_argument("-t","--tree",help="stored hash tree location") pServe.add_argument("datafile") pServe.set_defaults(func=serve) args=parser.parse_args() args.func(args)