class UploadHandler(BaseHandler): """ Upload files to google drive. Really, that's it. You supply it a file or a list of files and this will upload it for you. Raises errors on non-existant files based on the --ignore-errors argument. """ def init_with_config(self, config: Configuration): super().init_with_config(config) self.backend = DriveStorage(config) def init_args(self, subparser: _SubParsersAction) -> None: parser = super().init_args(subparser) parser.add_argument("files", nargs="+", help="Files you want to upload.") def execute_command(self, filepath): return self.backend.write(filepath) def run(self, args: Namespace): if not args.ignore_errors: bad_items = filter(lambda x: not path.isfile(x), args.files) if len(list(bad_items)) != 0: logger.critical( "Operation aborted because some files did not exist." "To upload other files, pass the --ignore_errors option." "The following files were not found: {}".format(bad_items) ) return None for f in args.files: if not path.isfile(f): logger.warning("{} is not a valid file. Ignoring.".format(f)) self.backend.write(f)
class TagHandler(BaseHandler): """ This class is used to tag *uploaded* files. Tags currently are just strings that are added in the file's description field. These tags are of the form: "<tag>:<value>" This has two main drawbacks as of now, 1. No control over the tag types. User can upload any data as tag. 2. Updating tags is not implemented. NOTE: Mechanism to tag file while uploading has not yet been implemented. """ def init_with_config(self, config: Configuration): super().init_with_config(config) self.backend = DriveStorage(config) self.search = SearchHandler(config=config) def init_args(self, subparser: _SubParsersAction) -> None: parser = super().init_args(subparser) parser.add_argument( "--for_name", action="store", metavar="NAME", help="Search for items with NAME", ) parser.add_argument( "--add_tags", action="store", nargs="+", help="add the provided tags to the search results", ) def execute_command(self, fileId, tags): self.backend.tag(fileId, tags) def run(self, args: Namespace): relevant_files = self.search.execute_command(name=args.for_name, tags=None, do_and=False) filenames = [x[0] for x in relevant_files] logger.debug("The following files were found: {}".format(filenames)) logger.debug("The following tags are going to be added: {}".format( args.add_tags)) file_ids = [x[1] for x in relevant_files] for fid in file_ids: self.backend.tag(fid, args.add_tags)
class SearchHandler(BaseHandler): """ This class does the searching. You provide it with search parameters and it find all matching files and their corresponding ids. This takes two search parameters: name and tags. *Name* is the actual filename it was uploaded with. Only one is allowed. *Tag* is the metadata the file was tagged with as defined in the TagHandler docs. There can be multiple tags supplied. Searching requires atleast one of them. If there are multiple tags or if both of them are supplied, the *do_and* parameter comes into play. If it is false, the search terms will be combined with an OR operator, i.e. "name OR tag1 OR tag2 ..." If true though, the ORs are replaced with ANDs, "name AND tag1 AND tag2 ..." More fine-grained controls will be added later. """ def init_with_config(self, config: Configuration): super().init_with_config(config) self.backend = DriveStorage(config) def init_args(self, subparser: _SubParsersAction) -> None: parser = super().init_args(subparser) parser.add_argument("--name", action="store", help="Search for a name") parser.add_argument( "--tags", action="store", nargs="*", help="Tags you want to search for" ) parser.add_argument( "--do_and", action="store_true", help="Make sure all the tags are ANDed instead of ORed by default", ) def execute_command(self, name, tags, do_and): if not name and not tags: logger.critical( "Neither name or tags specified. Atleast one is required. Exiting" ) return else: response = self.backend.search(name_subs=name, tag_subs=tags, do_and=do_and) return [(name, fid) for name, fid in response] def run(self, args: Namespace): if not args.name and not args.tags: logger.critical( "Neither name or tags specified. Atleast one is required. Exiting" ) return else: response = self.execute_command(args.name, args.tags, args.do_and) # TODO: Format Nicely print("Files\tIDs") for name, id in response: print("{}\t{}".format(name, id))
def run(self, args: Namespace): logger.debug("Starting initial run.") self._create_config(args.config) logger.debug("Starting OAuth with Google.") DriveStorage(self.config) logger.debug("OAuth completed.") logger.debug("Starting Orchestration.") Server(self.config).run_server()
def init_with_config(self, config: Configuration): super().init_with_config(config) self.backend = DriveStorage(config)
def init_with_config(self, config: Configuration): super().init_with_config(config) self.backend = DriveStorage(config) self.db = DBStorage(config) self.search = SearchHandler(config=config)
class PermissionHandler(BaseHandler): """ This class handles adding permissions to uploaded files. This has two main drawbacks as of now, 1. No control over the tag types. User can upload any data as tag. 2. Updating tags is not implemented. NOTE: Mechanism to tag file while uploading has not yet been implemented. """ def init_with_config(self, config: Configuration): super().init_with_config(config) self.backend = DriveStorage(config) self.db = DBStorage(config) self.search = SearchHandler(config=config) def init_args(self, subparser: _SubParsersAction) -> None: parser = super().init_args(subparser) parser.add_argument( "action", help="Define what action to take.", choices=["list", "add"] ) parser.add_argument( "--for_tags", help="Define which tags to add permissions for ", nargs="+" ) parser.add_argument( "--share_with", help="email id of the person to share with." ) parser.add_argument( "--not_persistent", action="store_true", help="If provided, future uploads wont be shared.", ) def execute_command(self): pass def run(self, args: Namespace): if args.action == "add": if not args.for_tags: logger.critical("--for_tags is required. Try again.") elif not args.share_with: logger.critical("--share_with is required. Try again.") else: tags = args.for_tags email = args.share_with role = "reader" if not args.not_persistent: self.db.add_permissions(tags, email, role) response = self.search.execute_command( name=None, tags=tags, do_and=False ) for item in response: id = item[1] self.backend.add_permissions_user(fileid=id, email=email, role=role) if args.action == "list": if args.for_tags is None: print(self.db.get_permissions()) else: for tag in args.for_tags: print(self.db.get_permissions(tag))