async def run(cmd, data): proc = await asyncio.create_subprocess_shell( cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) stdout, stderr = await proc.communicate() print(f'[{cmd!r} exited with {proc.returncode}]') if stdout: print(f'{stdout.decode()}') r = stdout.decode() if server: await server.send( json.dumps( build_result( data['id'], r if isinstance(r, str) else r.decode("utf-8"), 'DONE'))) if stderr: print(f'{stderr.decode()}') r = stderr.decode() if server: await server.send( json.dumps( build_result( data['id'], r if isinstance(r, str) else r.decode("utf-8"), 'DONE')))
def delete(gistid, facade): """ Just deletes a gist. :param gistid: identifier of the Gist to delete :param facade: instance of the object that actually performs the request """ # First check if the gist exists response = facade.request_gist(gistid) if response.ok: # Gist Found. Ask for confirmation value_raw_input = literals.DELETE_CONFIRMATION % gistid value = input(value_raw_input) accepted_values_for_yes = ["y", "yes", "ofcourse", "ye"] if value.lower() in accepted_values_for_yes: # Perform the deletion response = facade.delete_gist(gistid) if response.ok: result = build_result(True, literals.DELETE_OK, gistid) else: res_message = response.json()['message'] result = build_result(False, literals.DELETE_NOK, res_message) else: # Aborted mission result = build_result(False, literals.DELETE_ABORTED) else: # Gist not retrieved. res_message = response.json()['message'] result = build_result(False, literals.DELETE_NOK, res_message) return result
def delete(gistid, facade): """ Just deletes a gist. :param gistid: identifier of the Gist to delete :param facade: instance of the object that actually performs the request """ # First check if the gist exists response = facade.request_gist(gistid) if response.ok: # Gist Found. Ask for confirmation value_raw_input = (literals.DELETE_CONFIRMATION) % (gistid) value = raw_input(value_raw_input) accepted_values_for_yes = ["y", "yes", "ofcourse", "ye"] if value.lower() in accepted_values_for_yes: # Perform the deletion response = facade.delete_gist(gistid) if response.ok: result = build_result(True, literals.DELETE_OK, gistid) else: res_message = get_json(response)['message'] result = build_result(False, literals.DELETE_NOK, res_message) else: # Aborted mission result = build_result(False, literals.DELETE_ABORTED) else: # Gist not retrieved. res_message = get_json(response)['message'] result = build_result(False, literals.DELETE_NOK, res_message) return result
def get(gist_id, requested_file, destination_dir, facade): """ Download a gist file. Gists can have several files. This method searches for and downloads a single file from a gist. If the 'requested_file' is not informed, then it won't raise an error only if the gist have just a single file. :param gist_id: identifier of the gist to download :param requested_file: name of the Gist file to download :param destination_dir: destination directory after the download :param facade: instance of the object that actually perform the request """ # Get the gist information response = facade.request_gist(gist_id) if response.ok: # Gist file found. Parse it into a 'model.Gist' class. gist_obj = model.Gist(response.json()) list_names = [gistfile.filename for gistfile in gist_obj.files] if len(gist_obj.files) == 1 and not requested_file: # Download the only file in the gist gistfile = gist_obj.files[0] download(gistfile.raw_url, destination_dir, gistfile.filename, gistfile.size) result = build_result(True, literals.DOWNLOAD_OK, gistfile.filename) else: # Gist have more than one file and filename not specified. Error if not requested_file: list_names = ", ".join(list_names) result = build_result(False, literals.DOWNLOAD_MORE_FILES, list_names) else: # Search for the Gist file gistfile = gist_obj.getFile(requested_file) if gistfile: # Gist file found. Download it. download(gistfile.raw_url, destination_dir, gistfile.filename, gistfile.size) result = build_result(True, literals.DOWNLOAD_OK, gistfile.filename) else: # Requested file not found in Gist list_of_names = ", ".join(list_names) result = build_result(False, literals.FILE_NOT_FOUND, list_of_names) else: # Handle GitHub response error result = build_result(False, literals.DOWNLOAD_ERROR, response.json()['message']) return result
def get(gist_id, requested_file, destination_dir, facade): """ Download a gist file. Gists can have several files. This method searches for and downloads a single file from a gist. If the 'requested_file' is not informed, then it won't raise an error only if the gist have just a single file. :param gist_id: identifier of the gist to download :param requested_file: name of the Gist file to download :param destination_dir: destination directory after the download :param facade: instance of the object that actually perform the request """ # Get the gist information response = facade.request_gist(gist_id) if response.ok: # Gist file found. Parse it into a 'model.Gist' class. gist_obj = model.Gist(get_json(response)) list_names = [gistfile.filename for gistfile in gist_obj.files] if len(gist_obj.files) == 1 and not requested_file: # Download the only file in the gist gistfile = gist_obj.files[0] download(gistfile.raw_url, destination_dir, gistfile.filename, gistfile.size) result = build_result(True, literals.DOWNLOAD_OK, gistfile.filename) else: # Gist have more than one file and filename not specified. Error if not requested_file: list_names = ", ".join(list_names) result = build_result(False, literals.DOWNLOAD_MORE_FILES, list_names) else: # Search for the Gist file gistfile = gist_obj.getFile(requested_file) if gistfile: # Gist file found. Download it. download(gistfile.raw_url, destination_dir, gistfile.filename, gistfile.size) result = build_result(True, literals.DOWNLOAD_OK, gistfile.filename) else: # Requested file not found in Gist list_of_names = ", ".join(list_names) result = build_result(False, literals.FILE_NOT_FOUND, list_of_names) else: # Handle GitHub response error result = build_result(False, literals.DOWNLOAD_ERROR, get_json(response)['message']) return result
def unstar(gist_id, facade): """ Unstars a gist. :param gist_id: identifier of the Gist to unstar :param facade: instance of the object that actually performs the request """ response = facade.unstar_gist(gist_id) if response.ok: result = build_result(True, literals.UNSTAR_OK, gist_id) else: res_message = response.json()['message'] result = build_result(False, literals.UNSTAR_NOK, res_message) return result
def unstar(gist_id, facade): """ Unstars a gist. :param gistid: identifier of the Gist to unstar :param facade: instance of the object that actually performs the request """ response = facade.unstar_gist(gist_id) if response.ok: result = build_result(True, literals.UNSTAR_OK, gist_id) else: res_message = get_json(response)['message'] result = build_result(False, literals.UNSTAR_NOK, res_message) return result
def post(username, password, public, upload_file, source_file, description, facade=GithubFacade()): """ Create a new Gist. Currently only support create Gist with single files. (Then you can 'update' the gist and attach more files in it, but the creation only supports one file) You are able to specify if you want to create a public or private gist and set its description. :param username: GitHub user name :param password: GitHub user password :param public: whenever new Gist should be public or private :param upload_file: input file to upload :param description: brief description of the Gist :param facade: instance of the object that actually performs the request """ # Prepare the content reading the file gistFile = model.GistFile() gistFile.filename = upload_file with open(source_file, 'r') as f: file_content = f.read() gistFile.content = file_content # Prepare the Gist file object and set its description and 'public' value gist = model.Gist() if description: gist.description = description gist.public = public gist.addFile(gistFile) print "Uploading gist... ", response = facade.create_gist(gist, username, password) # Parse the response if response.ok: print colored.green("Done!") gist = model.Gist(response.json) result = build_result(True, model.Gist(response.json)) else: print colored.red("Fail!") if response.json: result = build_result(False, response.json['message']) else: result = build_result(False, literals.UNHANDLED_EXCEPTION) return result
def fork(gist_id, facade): """ Forks a gist. :param gistid: identifier of the Gist to fork :param facade: instance of the object that actually performs the request """ response = facade.fork_gist(gist_id) if response.ok: result = build_result(True, model.Gist(get_json(response))) else: if get_json(response): result = build_result(False, literals.FORK_ERROR, gist_id, get_json(response)['message']) else: result = build_result(False, literals.UNHANDLED_EXCEPTION) return result
def fork(gist_id, facade): """ Forks a gist. :param gist_id: identifier of the Gist to fork :param facade: instance of the object that actually performs the request """ response = facade.fork_gist(gist_id) if response.ok: result = build_result(True, model.Gist(response.json())) else: if response.json(): result = build_result(False, literals.FORK_ERROR, gist_id, response.json()['message']) else: result = build_result(False, literals.UNHANDLED_EXCEPTION) return result
def authorize(facade): """ Configure the user and password of the GitHub user. :param facade: The Github interface """ # check if there is already an authorization for the app response = facade.list_authorizations() if response.ok: for auth in response.json(): authorization = model.Authorization(auth) if authorization.note == literals.APP_NAME: # write the token to the configuration file configurer = GistsConfigurer() configurer.setConfigUser(facade.username) configurer.setConfigToken(authorization.token) return build_result(True, authorization) else: return build_result(False, literals.AUTHORIZE_NOK, response.json()['message']) # build the authorization request auth = model.Authorization() auth.note = literals.APP_NAME auth.note_url = literals.APP_URL auth.scopes = ["gist"] response = facade.authorize(auth) if response.ok: auth = model.Authorization(response.json()) result = build_result(True, auth) # write the token to the configuration file configurer = GistsConfigurer() configurer.setConfigUser(facade.username) configurer.setConfigToken(auth.token) else: result = build_result(False, literals.AUTHORIZE_NOK, response.json()['message']) return result
def show(gist_id, requested_file, facade): """ Retrieve a single gist. If the 'requested_file' is None, then it will show the 'metadata' of the Gist. This is: its description, urls, file names.. If the 'requested_file' is informed, then it will show the content of the gist file. :param gist_id: identifier of the Gist to print :param requested_file: Gist File to show :param facade: instance of the object that actually performs the request """ # get the gist information response = facade.request_gist(gist_id) if response.ok: # Gist found. Parse the json response into the 'model.Gist' class gist_obj = model.Gist(get_json(response)) if not requested_file: # Fill the response with the metadata of the gist result = build_result(True, gist_obj) else: # We want to return the content of the file. Search for the content list_names = [gistfile.filename for gistfile in gist_obj.files] file_gist = gist_obj.getFile(requested_file) if file_gist: # Fill the response with the metadata of the gist result = build_result(True, file_gist) else: # File not found in Gist list_of_names = ", ".join(list_names) result = build_result(False, literals.FILE_NOT_FOUND, list_of_names) else: # GitHub response not ok. Parse the response result = build_result(False, literals.SHOW_ERROR, get_json(response)['message']) return result
def post(public, upload_files, filepath, description, facade): """ Create a new Gist. Currently only support create Gist with single files. (Then you can 'update' the gist and attach more files in it, but the creation only supports one file) You are able to specify if you want to create a public or private gist and set its description. :param public: whenever new Gist should be public or private :param upload_files: list with input files to upload :param filepath: input parameter path :param description: brief description of the Gist :param facade: instance of the object that actually performs the request """ # Prepare the Gist file object and set its description and 'public' value gist = model.Gist() if description: gist.description = description gist.public = public for upfile in upload_files: # Prepare the content reading the file gist_file = model.GistFile() gist_file.filename = upfile with open(os.path.join(filepath, upfile), 'r') as f: file_content = f.read() gist_file.content = file_content gist.addFile(gist_file) response = facade.create_gist(gist) # Parse the response if response.ok: result = build_result(True, model.Gist(response.json())) else: if response.json(): result = build_result(False, response.json()['message']) else: result = build_result(False, literals.UNHANDLED_EXCEPTION) return result
def authorize(facade): """ Configure the user and password of the GitHub user. :param facade: The Github interface """ # check if there is already an authorization for the app response = facade.list_authorizations() if response.ok: for auth in get_json(response): authorization = model.Authorization(auth) if authorization.note == literals.APP_NAME: # write the token to the configuration file configurer = GistsConfigurer() configurer.setConfigUser(facade.username) configurer.setConfigToken(authorization.token) return build_result(True, authorization) else: return build_result(False, literals.AUTHORIZE_NOK, get_json(response)['message']) # build the authorization request auth = model.Authorization() auth.note = literals.APP_NAME auth.note_url = literals.APP_URL auth.scopes = ["gist"] response = facade.authorize(auth) if response.ok: auth = model.Authorization(get_json(response)) result = build_result(True, auth) # write the token to the configuration file configurer = GistsConfigurer() configurer.setConfigUser(facade.username) configurer.setConfigToken(auth.token) else: result = build_result(False, literals.AUTHORIZE_NOK, get_json(response)['message']) return result
def post(public, upload_files, filepath, description, facade): """ Create a new Gist. Currently only support create Gist with single files. (Then you can 'update' the gist and attach more files in it, but the creation only supports one file) You are able to specify if you want to create a public or private gist and set its description. :param public: whenever new Gist should be public or private :param upload_files: list with input files to upload :param filepath: input parameter path :param description: brief description of the Gist :param facade: instance of the object that actually performs the request """ # Prepare the Gist file object and set its description and 'public' value gist = model.Gist() if description: gist.description = description gist.public = public for upfile in upload_files: # Prepare the content reading the file gistFile = model.GistFile() gistFile.filename = upfile with open(os.path.join(filepath, upfile), 'r') as f: file_content = f.read() gistFile.content = file_content gist.addFile(gistFile) response = facade.create_gist(gist) # Parse the response if response.ok: result = build_result(True, model.Gist(get_json(response))) else: if get_json(response): result = build_result(False, get_json(response)['message']) else: result = build_result(False, literals.UNHANDLED_EXCEPTION) return result
def show(gist_id, requested_file, facade): """ Retrieve a single gist. If the 'requested_file' is None, then it will show the 'metadata' of the Gist. This is: its description, urls, file names.. If the 'requested_file' is informed, then it will show the content of the gist file. :param gist_id: identifier of the Gist to print :param requested_file: Gist File to show :param facade: instance of the object that actually performs the request """ # get the gist information response = facade.request_gist(gist_id) if response.ok: # Gist found. Parse the json response into the 'model.Gist' class gist_obj = model.Gist(response.json()) if not requested_file: # Fill the response with the metadata of the gist result = build_result(True, gist_obj) else: # We want to return the content of the file. Search for the content list_names = [gistfile.filename for gistfile in gist_obj.files] file_gist = gist_obj.getFile(requested_file) if file_gist: # Fill the response with the metadata of the gist result = build_result(True, file_gist) else: # File not found in Gist list_of_names = ", ".join(list_names) result = build_result(False, literals.FILE_NOT_FOUND, list_of_names) else: # GitHub response not ok. Parse the response result = build_result(False, literals.SHOW_ERROR, response.json()['message']) return result
def list_gists(username, facade): """ Retrieve the list of gists for a concrete user. :param token: GitHub authentication token :param facade: instance of the object that actually performs the request """ response = facade.request_list_of_gists(username) if response.ok: # List of gists for the requested user found. list_gists = [] for gist in response.json: list_gists.append(model.Gist(gist)) return build_result(True, list_gists) else: # GitHub response error. Parse the response return build_result(False, literals.LISTS_ERROR, response.json['message'])
def list_gists(username, facade, want_starred): """ Retrieve the list of gists for a concrete user. :param token: GitHub authentication token :param facade: instance of the object that actually performs the request :param want_starred: if we want the starred ones """ if not want_starred: response = facade.request_list_of_gists(username) else: response = facade.request_list_starred_gists(username) if response.ok: # List of gists for the requested user found. list_gists = [] for gist in get_json(response): list_gists.append(model.Gist(gist)) return build_result(True, list_gists) else: # GitHub response error. Parse the response return build_result(False, literals.LISTS_ERROR, get_json(response)['message'])
def list_gists(username, facade, want_starred): """ Retrieve the list of gists for a concrete user. :param username: GitHub authentication token :param facade: instance of the object that actually performs the request :param want_starred: if we want the starred ones """ if not want_starred: response = facade.request_list_of_gists(username) else: response = facade.request_list_starred_gists(username) if response.ok: # List of gists for the requested user found. _list_gists = [] for gist in response.json(): _list_gists.append(model.Gist(gist)) return build_result(True, _list_gists) else: # GitHub response error. Parse the response return build_result(False, literals.LISTS_ERROR, response.json()['message'])
async def connect_client(): global last_error, need_update, server, app, SETTINGS _settings = SETTINGS connection_string = 'ws://' + _settings['remote'] + ':' + str( _settings.get('server_port')) while True: try: logger.info("Connecting to remote: " + connection_string) async with websockets.connect(connection_string) as _server: server = _server logger.info("Connection established.") await server.send( json.dumps({ 'type': 'name', 'name': _settings['name'] })) while True: try: msg = await server.recv() data = json.loads(msg) if data['type'] == "settings": await update_settings(_settings, data) elif data['type'] == "command": cmd = data['command'] logger.info(data) args = re.sub("[^\w-]", " ", cmd).split() user = re.findall(r'"(.*?)"', cmd) if user: _tmp = cmd.split('"') args = [_tmp[0], user[0]] for i in range(2, len(_tmp)): args += _tmp[i].strip().split(' ') cmd = args.pop(0).strip() if cmd == 'reload-data': need_update = True elif cmd == 'status': await server.send( json.dumps( build_status( data['id'], { 'queue': queue2json(), 'history': history2json() }))) elif cmd == 'restart-thread': startLauncher() elif cmd == 'clean-queue': clean_queue() else: QUEUE.enterabs(0, 1, action_wrapper, (cmd, args, data)) await server.send( json.dumps( build_result(data['id'], '', 'QUEUED'))) except websockets.ConnectionClosed as cc: logger.info("Connection Closed.") break except Exception as ee: logger.exception(ee) break except Exception as e: if last_error != str(e): logger.exception(e) logger.info("Disconnected from remote: " + connection_string + ". Reconnecting in " + str(_settings.get('reconnect_time')) + "s.") last_error = str(e) time.sleep(_settings.get('reconnect_time'))
def update(gistid, description, filenames, filepath, new, remove, facade): """ Updates a gist. :param gistid: identifier of the Gist to update :param description: new description of the Gist. If 'None' it won't be updated :param filenames: list with names of the files to modify its contents :param filepath: input parameter path :param new: whenever the file is new or already exists :param remove: if the file should be deleted instead of modified :param facade: instance of the object that actually performs the request """ # First get the result response = facade.request_gist(gistid) if response.ok: # Gist found. gist = model.Gist(response.json()) else: result = build_result(False, literals.UPDATE_NOK, response.json()['message']) return result if description: # Update the description of a Gist if requested gist.description = description if filenames: for filename in filenames: # File to update file_obj = gist.getFile(filename) if not file_obj: if remove: return build_result(False, literals.UPDATE_RM_NF) if new: # Upload a new file to gist gist_file = model.GistFile() gist_file.filename = filename with open(os.path.join(filepath, filename), 'r') as f: file_content = f.read() gist_file.content = file_content gist.addFile(gist_file) else: # File not found and option --new it does not exist return build_result(False, literals.UPDATE_NF) else: if new: # File not found and option --new it does not exist return build_result(False, literals.UPDATE_NEW_DUP) if remove: # Remove a file gist.setFile(filename, "null") else: # Update the contents of the file with open(os.path.join(filepath, filename), 'r') as f: file_content = f.read() file_obj.content = file_content gist.setFile(filename, file_obj) # prepare the request response = facade.update_gist(gist) if response.ok: return build_result(True, gist) else: return build_result(False, literals.UPDATE_NOK, response.json()['message'])
def update(gistid, description, filenames, filepath, new, remove, facade): """ Updates a gist. :param gistid: identifier of the Gist to update :param description: new description of the Gist. If 'None' it won't be updated :param filenames: list with names of the files to modify its contents :param filepath: input parameter path :param new: whenever the file is new or already exists :param remove: if the file should be deleted instead of modified :param facade: instance of the object that actually performs the request """ # First get the result response = facade.request_gist(gistid) if response.ok: # Gist found. gist = model.Gist(get_json(response)) else: result = build_result(False, literals.UPDATE_NOK, get_json(response)['message']) return result if description: # Update the description of a Gist if requested gist.description = description if filenames: for filename in filenames: # File to update file_obj = gist.getFile(filename) if not file_obj: if remove: return build_result(False, literals.UPDATE_RM_NF) if new: # Upload a new file to gist gistFile = model.GistFile() gistFile.filename = filename with open(os.path.join(filepath, filename), 'r') as f: file_content = f.read() gistFile.content = file_content gist.addFile(gistFile) else: # File not found and option --new it does not exist return build_result(False, literals.UPDATE_NF) else: if new: # File not found and option --new it does not exist return build_result(False, literals.UPDATE_NEW_DUP) if remove: # Remove a file gist.setFile(filename, "null") else: # Update the contents of the file with open(os.path.join(filepath, filename), 'r') as f: file_content = f.read() file_obj.content = file_content gist.setFile(filename, file_obj) # prepare the request response = facade.update_gist(gist) if response.ok: return build_result(True, gist) else: return build_result(False, literals.UPDATE_NOK, get_json(response)['message']) return result