def do_list(args): """ list transactions of code smell family Args: args (array) arguments """ if args.type is not None and args.type not in ('code_smell', 'proposal', 'vote'): raise CodeSmellException("Incorrect Transaction Type") if args.type in ('code_smell', 'vote') and args.active is not None: raise CodeSmellException("Incorrect parms combination") url = _get_url(args) keyfile = _get_keyfile(args) client = CodeSmellClient(base_url=url, keyfile=keyfile, work_path=HOME) if args.active is not None: transactions = client.list(txn_type=args.type, active_flag=1) else: transactions = client.list(txn_type=args.type) if len(transactions) == 0: raise CodeSmellException("No transactions found") else: print (transactions)
def do_vote(args): """ cast vote to accept or reject a code measure proposal Args: args (array) arguments<proposalid, vote> """ if args.view is None: if args.id is None: raise CodeSmellException("Missing proposal ID") if args.vote is None: raise CodeSmellException("Missing VOTE") if args.vote == 'yes': vote = 1 else: vote = 0 url = _get_url(args) keyfile = _get_keyfile(args) client = CodeSmellClient(base_url=url, keyfile=keyfile, work_path=HOME) if args.vote: response = client.vote(proposal_id=args.id, vote=vote) else: response = client.check_votes(proposal_id=args.view) print("Response: {}".format(response))
def _update_suse_file(self, proposal): """ update code smell configuration metrics, after the proposal is accepted the configuration file needs to be updated. Args: toml_config (dict), current configuration proposal (str), proposal that contains new configuration """ #get proposal payload proposal_payload = yaml.safe_load(proposal[2].replace(";", ",")) #identify code_smell family configuration file conf_file = self._work_path + '/etc/.suse' print(self._work_path) #get current config suse_config = _get_suse_config(conf_file) """ start by traversing the proposal, get the code smell and the metric """ try: for proposal_key, proposal_metric in proposal_payload.items(): tmp_type = "" """ we don't know where on the toml file is the code smell, traverse the toml dictionary looking for the same code smell. """ for code_type in suse_config["code_smells"]: """ once you found the code smell, break the loop and return a pseudo location """ if proposal_key in suse_config["code_smells"][ code_type].keys(): tmp_type = code_type break #update code smell metric if proposal_key == "CommentsToCodeRatioLower" or proposal_key == "CommentsToCodeRatioUpper": suse_config["code_smells"][tmp_type][proposal_key][ 0] = float(proposal_metric) else: suse_config["code_smells"][tmp_type][proposal_key][ 0] = int(proposal_metric) #save new configuration try: with open(conf_file, 'w+') as config: toml.dump(suse_config, config) #self._send_git_request(toml_config) except IOError as error: raise CodeSmellException( "Unable to open configuration file {}".format(error)) #publish new configuration file to all peers self._publish_config(conf_file=conf_file) except: raise CodeSmellException("Incorrect proposal format")
def do_vote(args): """ cast vote to accept or reject a code measure proposal user can also check the amount of votes of a specific proposal Args: args (array) arguments<proposalid, vote> """ if args.view is None: if args.id is None: raise CodeSmellException("Missing proposal ID") if args.vote is None: raise CodeSmellException("Missing VOTE") if args.vote == 'yes': vote = 1 else: vote = 0 url = _get_url(args) keyfile = _get_keyfile(args) client = CodeSmellClient(base_url=url, keyfile=keyfile, work_path=HOME) if args.vote: response_dict = client.vote(proposal_id=args.id, vote=vote) print(response_dict) else: response_list = client.check_votes(proposal_id=args.view) print(response_list)
def update_config(self, proposal): """ update code smell configuration metrics, after the proposal is accepted the configuration file needs to be updated. Args: toml_config (dict), current configuration proposal (str), proposal that contains new configuration """ #get proposal payload proposal_payload = yaml.safe_load(proposal[2].replace(";", ",")) work_path = os.path.dirname( os.path.dirname( os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) #identify code_smell family configuration file conf_file = work_path + '/etc/.suse' if os.path.isfile(conf_file): try: with open(conf_file) as config: raw_config = config.read() except IOError as error: raise CodeSmellException( "Unable to load code smell family configuration file: {}". format(error)) #load toml config into a dict toml_config = toml.loads(raw_config) """ start by traversing the proposal, get the code smell and the metric """ for proposal_key, proposal_metric in proposal_payload.items(): tmp_type = "" """ we don't know where on the toml file is the code smell, traverse the toml dictionary looking for the same code smell. """ for code_type in toml_config["code_smells"]: """ once you found the code smell, break the loop and return a pseudo location """ if proposal_key in toml_config["code_smells"][code_type].keys( ): tmp_type = code_type break #update configuration toml_config["code_smells"][tmp_type][proposal_key][0] = int( proposal_metric) #save new configuration try: with open(conf_file, 'w+') as config: toml.dump(toml_config, config) #self._send_git_request(toml_config) except IOError as error: raise CodeSmellException( "Unable to open configuration file {}".format(error))
def default(self): """ load a defautl code smell configuration """ #identify code_smell family configuration file conf_file = self._work_path + '/etc/.suse' response = "" if os.path.isfile(conf_file): try: with open(conf_file) as config: raw_config = config.read() except IOError as error: raise CodeSmellException( "Unable to load code smell family configuration file: {}". format(error)) #load toml config into a dict parsed_toml_config = toml.loads(raw_config) #get default code smells code_smells_config = parsed_toml_config['code_smells'] #code_smells_config = parsed_toml_config """traverse dict and process each code smell nested for loop to procces level two dict.""" for code_smells in code_smells_config.values(): for name, metric in code_smells.items(): #send trasaction response = self._send_code_smell_txn( txn_type='code_smell', txn_id=name, data=str(metric[0]), ## TODO: add weigth value state='create') code_smells_config = parsed_toml_config['vote_setting'] """traverse dict and process each code smell nested for loop to procces level two dict.""" for name, metric in code_smells_config.items(): #send transaction response = self._send_code_smell_txn(txn_type='code_smell', txn_id=name, data=str(metric[0]), state='create') else: raise CodeSmellException( "Configuration File {} does not exists".format(conf_file)) return response
def _update_proposal(self, proposal, state): """ update proposal, update state. Args: proposal (dict), proposal data sate (str), new proposal's state """ localtime = time.localtime(time.time()) transac_time = str(localtime.tm_year) + str(localtime.tm_mon) + str( localtime.tm_mday) propose_date = str(transac_time) response = self._send_code_smell_txn(txn_id=proposal[1], txn_type='proposal', data=proposal[2], state=state, date=propose_date) work_path = os.path.dirname( os.path.dirname( os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) conf_file = work_path + '/etc/.suse' if os.path.isfile(conf_file): try: with open(conf_file) as config: raw_config = config.read() except IOError as error: raise CodeSmellException( "Unable to load code smell family configuration file: {}". format(error)) #load toml config into a dict toml_config = toml.loads(raw_config) self._send_git_request(toml_config)
def main(prog_name=os.path.basename(sys.argv[0]), args=None): """ Expose core functionality of the code_smell family. Args: prog_name, program name (str) args, arguments to process code smells (array) """ if args is None: args = sys.argv[1:] parser = create_parser(prog_name) args = parser.parse_args(args) if args.verbose is None: verbose_level = 0 else: verbose_level = args.verbose setup_loggers(verbose_level=verbose_level) #Define code smell family functions if args.command == 'default': do_default(args) elif args.command == 'list': do_list(args) elif args.command == 'proposal': do_proposal(args) elif args.command == 'show': do_show(args) elif args.command == 'vote': do_vote(args) else: raise CodeSmellException("Invalid command: {}".format(args.command))
def _send_request(self, suffix, data=None, content_type=None, auth_user=None, auth_password=None): """ send request to code smell processor the transaction will be validate by the processor of each family. """ if self._base_url.startswith("http://"): url = "{}/{}".format(self._base_url, suffix) else: url = "http://{}/{}".format(self._base_url, suffix) headers = {} if auth_user is not None: auth_string = "{}:{}".format(auth_user, auth_password) b64_string = b64encode(auth_string.encode()).decode() auth_header = 'Basic {}'.format(b64_string) headers['authorization'] = auth_header if content_type is not None: headers['Content-Type'] = content_type try: if data is not None: result = requests.post(url, headers=headers, data=data) else: result = requests.get(url, headers=headers) if result.status_code == 404: raise CodeSmellException("No such transaction") elif not result.ok: raise CodeSmellException("Error {}:{}".format( result.status_code, result.reason)) except requests.ConnectionError as err: raise CodeSmellException('Failed to connect to {}:{}'.format( url, str(err))) except BaseException as err: raise CodeSmellException(err) return result.text
def _get_status(self, batch_id, wait, auth_user=None, auth_password=None): try: result = self._send_request('batch_status?id={}&wait={}'.format( batch_id, wait), auth_user=auth_user, auth_password=auth_password) return yaml.safe_load(result)['data'][0]['status'] except BaseException as err: raise CodeSmellException(err)
def do_show(args): """ list transaction of code smell family Args: args (array) arguments """ if args.address is None: raise CodeSmellException ("Missing Transaction Address") url = _get_url(args) keyfile = _get_keyfile(args) client = CodeSmellClient(base_url=url, keyfile=keyfile, work_path=HOME) transaction = client.show(address=args.address) if len(transaction) == 0: raise CodeSmellException("No transaction found") else: pprint (transaction)
def do_list(args): """ list transactions of code smell family Args: args (array) arguments """ #verify that we shave the right type if args.type is not None and args.type not in ('code_smell', 'proposal', 'vote', 'config'): raise CodeSmellException("Incorrect Transaction Type") url = _get_url(args) keyfile = _get_keyfile(args) client = CodeSmellClient(base_url=url, keyfile=keyfile, work_path=HOME) transactions = client.list(txn_type=args.type, active=args.active) if len(transactions) == 0: raise CodeSmellException("No transactions found") else: print (transactions)
def _get_suse_config(conf_file=None): if os.path.isfile(conf_file): try: with open(conf_file) as config: raw_config = config.read() except IOError as error: raise CodeSmellException( "Unable to load code smell family configuration file: {}". format(error)) #load toml config into a dict print(raw_config) toml_config = toml.loads(raw_config) return toml_config
def __init__(self, base_url, work_path, keyfile=None): self._base_url = base_url self._work_path = work_path if keyfile is None: self._signer = None return try: with open(keyfile) as fileptr: private_key_str = fileptr.read().strip() except OSError as err: raise CodeSmellException( 'Failed to read private key {}: {}'.format(keyfile, str(err))) try: private_key = Secp256k1PrivateKey.from_hex(private_key_str) except ParseError as error: raise CodeSmellException('Unable to load private key: {}'.format( str(error))) self._signer = CryptoFactory( create_context('secp256k1')).new_signer(private_key)
def _get_config_file(self): work_path = os.path.dirname( os.path.dirname( os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) #identify code_smell family configuration file conf_file = work_path + '/etc/.suse' if os.path.isfile(conf_file): try: with open(conf_file) as config: raw_config = config.read() except IOError as error: raise CodeSmellException( "Unable to load code smell family configuration file: {}". format(error)) #load toml config into a dict toml_config = toml.loads(raw_config) return toml_config
def update_config_file(config): """ update .suse file after getting new code smell configuration """ work_path = os.path.dirname( os.path.dirname( os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) #get code_smell family configuration file conf_file = work_path + '/etc/.suse' suse_config = json.loads(config.replace(";", ",").replace("'", "\"")) #save new configuration try: with open(conf_file, 'w+') as suse_file: toml.dump(suse_config, suse_file) suse_file.close() except IOError as error: raise CodeSmellException( "Unable to open configuration file {}".format(error))
def do_proposal(args): """ propose new metric for the code smell family Args: args (array) arguments """ if args.propose is None: raise CodeSmellException("Missing code smells") url = _get_url(args) keyfile = _get_keyfile(args) client = CodeSmellClient(base_url=url, keyfile=keyfile, work_path=HOME) #parse input into a dict code_smells = {} str_input = args.propose code_smells = dict(code_smell.split("=") for code_smell in str_input.split(",")) response = client.propose(code_smells=code_smells) print("Response: {}".format(response))