def load_cli_plugins(cli): if os.environ.get("DEBUG_PLUGINS", "0").lower() in ("true", "1"): # importing localstack.config is still quite expensive... logging.basicConfig(level=logging.DEBUG) loader = PluginManager("localstack.plugins.cli", load_args=(cli, )) loader.load_all()
def __init__(self, config): super().__init__() self.config = config self.plugin_manager = PluginManager(self, os.path.join(self.config['home_path'], self.config['plugin_path'])) self.plugin_manager.load_plugins() self.builtin_commands = { 'quit': self._quit, 'join': self._join, 'part': self._part, 'loaded': self._plugin_loaded, 'unload': self._plugin_unload, 'load': self._plugin_load, 'reload': self._plugin_reload, 'ping': self._ping, 'help': self._command_help } self.events = { 'send_privmsg': self._send_privmsg_event, 'privmsg': self._privmsg_event, 'stop': self._stop_event, 'pong': self._pong_event, 'users': self._qnull_event, 'part': self._part_event, 'recv': self._qnull_event, 'send': self._qnull_event, 'server_ping': self._qnull_event, 'join': self._qnull_event } self.channels = {}
class NaviDaemon: """ Application class for daemon process of navi """ def __init__(self): self.plugin_manager = PluginManager() self.plugin_manager.loadBasePlugins() def run(self): print "Hello, World!"
def __init__(self): ''' Gets references to important widgets, establishes event handlers, configures the tree view, and initializes the tree with the contents of the desktop. ''' # mark the root of this window with its PID so we can easily identify it # as this app root_atk = atk.get_root() root_atk.set_description(str(os.getpid())) self.node = Node() self.window = AccerciserMainWindow(self.node) self.window.connect('destroy', self._onQuit) # Start hotkey manager self.hotkey_manager = HotkeyManager() self.bookmarks_store = BookmarkStore(self.node) # load plugins self.plugin_manager = \ PluginManager(self.node, self.hotkey_manager, self.window.pluginview1, self.window.pluginview2) # connect signal handlers and show the GUI in its initial state self.window.show_all() main_actions = gtk.ActionGroup('MainActions') ui_manager.uimanager.insert_action_group(main_actions, 0) main_actions.add_actions([ ('Quit', gtk.STOCK_QUIT, None, '<control>q', 'Quit Accerciser', self._onQuit), ('Preferences', gtk.STOCK_PREFERENCES, _('_Preferences...'), '<control>p', 'Show preferences', self._onShowPreferences), ('Contents', gtk.STOCK_HELP, _('_Contents'), 'F1', 'View contents of manual', self._onHelp), ('About', gtk.STOCK_ABOUT, None, None, 'About Accerciser', self._onAbout) ]) for action_name, menu_path in [('Quit', ui_manager.FILE_MENU_PATH), ('Preferences', ui_manager.EDIT_MENU_PATH), ('Contents', ui_manager.HELP_MENU_PATH), ('About', ui_manager.HELP_MENU_PATH)]: action = main_actions.get_action(action_name) ui_manager.uimanager.add_ui(ui_manager.uimanager.new_merge_id(), menu_path, action_name, action_name, gtk.UIManagerItemType.MENUITEM, False) self.last_focused = None self.window.show_all()
def load_plugins(self): PluginManager.load_plugins() self.non_plugins = [] self.plugins = {} self.plugin_helps = {'help': HELP_DOC} for plugin in list_plugins(): if plugin.__doc__ and plugin.COMMAND: self.plugin_helps[ plugin.COMMAND.lower()] = plugin.__doc__.strip('\n') if plugin.COMMAND: self.plugins[plugin.COMMAND.lower()] = plugin else: self.non_plugins.append(plugin)
def load(namespace, name): """ Attempts to load a plugin using a PluginManager. """ manager = PluginManager(namespace) with console.status(f"Loading {namespace}:{name}"): then = time.time() plugin = manager.load(name) took = time.time() - then rprint( f":tada: successfully loaded [bold][green]{namespace}[/green][/bold]:[bold][cyan]{name}[/cyan][/bold] ({type(plugin)}" ) rprint(f":stopwatch: loading took {took:.4f} s")
def cmd_list(namespace): """ List all available plugins using a PluginManager from available endpoints. """ manager = PluginManager(namespace) t = Table() t.add_column("Name") t.add_column("Factory") for spec in manager.list_plugin_specs(): ep = spec_to_entry_point(spec) t.add_row(spec.name, ep.value) rprint(t)
def __init__(self, core, configfile): self.core = core self.configfile = configfile self.config = ConfigParser() self.config.read(configfile) host = self.config.get('base', 'host') port = self.config.getint('base', 'port') try: ssl = self.config.getboolean('base', 'ssl') except: ssl = False Client.__init__(self, (host, port), ssl) self.hooks = HookManager(self) self.plugins = PluginManager(self) self.hooks.install_owner(self) self.nick = None self.channels = {} superuser = self.config.get('base', 'superuser') self.allow_rules = {'*': {'ANY': 1}, superuser: {'ANY': 1000}} self.deny_rules = {} self._name = '_bot' autoload = self.config.get('base', 'autoload').split() for name in autoload: self.plugins.load(name) self.connect()
def __init__(self, home=None): if Collector._instance is not None: raise Exception("Called more than once") Collector._instance = self super(Collector, self).__init__() # Configuration config = Config.get_instance() self.add_manager('config', config) if home is not None: config.set_home(home) if self.conf('build_user_dir'): config.build_data_directory() # Plug-ins sys_plugin_path = config.get_appdata_path() sys_plugin_path = os.path.join(sys_plugin_path, 'user_plugins') # System plug-ins from collector.plugins import get_sys_plugins plugins = get_sys_plugins() # >= python 2.7 sys_plugins = {plugin.get_id(): plugin for plugin in plugins} plugin_manager = PluginManager.get_instance( self.conf('plugins_enabled'), sys_plugins, paths=[sys_plugin_path]) self.add_manager('plugin', plugin_manager) self.add_manager('collection', Collection.get_instance(True))
def __init__(self, spec): self.spec = spec self.basename = spec['basename'] self.files = {} self.plugin_mgr = PluginManager() # apply defaults self.spec['dir'] = self.merge_dicts(self.spec['dir'], { 'create': False, 'relative': False, 'cleanup': False, 'mode': 448 # 0700 }) # set up environment directory self.dir = os.path.expanduser(self.spec['dir']['path']) if self.spec['dir']['create']: try: os.mkdir(self.dir, self.spec['dir']['mode']) except OSError as e: if e.errno != errno.EEXIST: raise # setup files self.init_files()
def run_plugin(self, message: SteelyMessage): parsed_message = self.parse_command_message(message.text) if parsed_message is None: return command, rest_of_message = parsed_message # Run plugins following SEP1 interface. full_message = '{} {}'.format(command, rest_of_message) matched_command, plugin, args = PluginManager.get_listener_for_command( full_message) if matched_command is not None: passed_message = copy.copy(message) passed_message.text = full_message[len(matched_command) + 1:] thread = threading.Thread(target=plugin, args=(self, passed_message), kwargs=args) thread.deamon = True thread.start() # Run normal traditional steely plugins. if not command in self.plugins: return plugin = self.plugins[command] thread = threading.Thread(target=plugin.main, args=(self, message.author_id, rest_of_message, message.thread_id, message.thread_type), kwargs={}) thread.deamon = True thread.start()
def __init__(self, name=None, **kwargs): if name: self.name = name else: self.name = type(self).name self.log = logging.getLogger(self.name) self.log.info('Initialize cli') self.unknown_args = None global_parser = self.global_parser() # pre-parse from global_parser as well as config file and use for commands self.pre_parser = argparse.ArgumentParser(add_help=False, parents=[global_parser]) # specifically parsing arguments from associated config file if any #self.options = argparse.Namespace() self.options, self.unknown = self.pre_parser.parse_known_args() self.setup_logger(self.options.logfile, self.options.verbose) # then set up the real parser, cloning the initial one self.parser = argparse.ArgumentParser( parents=[self.pre_parser], add_help=True, formatter_class=argparse.ArgumentDefaultsHelpFormatter) if self.unknown: if '-h' or '-?' in self.unknown: self.parser.print_help() sys.exit(1) self.log.warn('Not parsing unknown arguments: {!s}'.format( self.unknown)) # check for application configs and parse app_config = current_path.absolute().joinpath('{0}.conf'.format( self.name)) self.read_config(app_config) # check for user config parameter and parse if self.options.config: self.read_config(self.options.config) self.plugin_manager = PluginManager(self.options) self.setup_plugins() self.log.debug('Current Params: {!s}'.format(self.options)) self.log.info('Complete CLI initialization')
class Yabbit(irc.IRCClient): def __init__(self): self.plugin_manager = PluginManager() self.config = config @property def nickname(self): """ Returns bot's nickname """ return self.factory.nickname @property def channels(self): """ Returns list of channels """ return self.factory.channels def signedOn(self): """ Actions which will be executed after connecting to a server """ # Load plugins for module in self.config.INSTALLED_PLUGINS: self.plugin_manager.load_plugin(module) # Join channels for channel in self.factory.channels: self.join(channel) def privmsg(self, user, channel, msg): """ Runs plugins when command defined in plugin class has been sent (directly or on a channel) """ nickname, hostmask = user.split("!", 1) if msg.startswith(self.config.COMMAND_CHAR): msg = msg.replace(self.config.COMMAND_CHAR, "").split() if not msg: return plugin = self.plugin_manager.get_plugin_by_command(msg[0]) if plugin: plugin.execute(self, nickname, hostmask, channel, msg)
def __init__( self, plugin_manager: PluginManager[ServicePlugin] = None, provider_config: ServiceProviderConfig = None, ) -> None: super().__init__() self.plugin_errors = ServicePluginErrorCollector() self.plugin_manager = plugin_manager or PluginManager( PLUGIN_NAMESPACE, listener=self.plugin_errors) self._api_provider_specs = None self.provider_config = provider_config or config.SERVICE_PROVIDER_CONFIG
def __init__(self): ''' Gets references to important widgets, establishes event handlers, configures the tree view, and initializes the tree with the contents of the desktop. ''' # mark the root of this window with its PID so we can easily identify it # as this app #root_atk = atk.get_root() #root_atk.set_description(str(os.getpid())) self.node = Node() self.window = AccerciserMainWindow(self.node) self.window.connect('destroy', self._onQuit) # Start hotkey manager self.hotkey_manager = HotkeyManager() self.bookmarks_store = BookmarkStore(self.node) # load plugins self.plugin_manager = \ PluginManager(self.node, self.hotkey_manager, self.window.pluginview1, self.window.pluginview2) # connect signal handlers and show the GUI in its initial state self.window.show_all() main_actions = gtk.ActionGroup('MainActions') ui_manager.uimanager.insert_action_group(main_actions, 0) main_actions.add_actions([ ('Quit', gtk.STOCK_QUIT, None, '<control>q', 'Quit Accerciser', self._onQuit), ('Preferences', gtk.STOCK_PREFERENCES, _('_Preferences...'), '<control>p', 'Show preferences', self._onShowPreferences), ('Contents', gtk.STOCK_HELP, _('_Contents'), 'F1', 'View contents of manual', self._onHelp), ('About', gtk.STOCK_ABOUT, None, None, 'About Accerciser', self._onAbout)]) for action_name, menu_path in [('Quit', ui_manager.FILE_MENU_PATH), ('Preferences', ui_manager.EDIT_MENU_PATH), ('Contents', ui_manager.HELP_MENU_PATH), ('About', ui_manager.HELP_MENU_PATH)]: action = main_actions.get_action(action_name) ui_manager.uimanager.add_ui(ui_manager.uimanager.new_merge_id(), menu_path, action_name, action_name, gtk.UIManagerItemType.MENUITEM, False) self.last_focused = None self.window.show_all()
def __init__(self, config_file=None, underlay_default_conf=True): # The basics ShowBase.__init__(self) base.disableMouse() #builtins.plugin_manager = PluginManager() #plugin_manager.load_plugins() configs = [] if underlay_default_conf: framework_conf = os.path.dirname( os.path.abspath(__file__)) + "/core.cfg" configs.append(framework_conf) if config_file is not None: configs.append(config_file) self.plugin_manager = PluginManager(configs)
def run_non_plugins(self, message: SteelyMessage): for plugin in self.non_plugins: thread = threading.Thread(target=plugin.main, args=(self, message.author_id, message.text, message.thread_id, message.thread_type), kwargs={}) thread.deamon = True thread.start() for plugin in PluginManager.get_passive_listeners(): thread = threading.Thread(target=plugin, args=(self, message), kwargs={}) thread.deamon = True thread.start()
class Player(): def __init__(self, account_id, private_key, provider, dev=False): self.plugin = PluginManager() self.plugin.load(PLUGINS_PATH) self.plugin.set_default_solverclass('gcs_solver.py') self.dev = dev self.account_id = account_id self.web3 = Web3(provider) self.interest = '' self.trusted_users = [] self.web3.eth.defaultAccount = account_id # PoA であれば geth_poa_middleware を利用 try: self.web3.eth.getBlock("latest") except ExtraDataLengthError: self.web3.middleware_onion.inject(geth_poa_middleware, layer=0) if private_key: self.web3.middleware_onion.add( construct_sign_and_send_raw_middleware(private_key)) self.deploy_erc1820() self.__observer = None self.__state = None self.assets = None # Wallet の情報 self.wallet = Wallet(self.web3, self.account_id) # オペレータ(トークンの交換などを担当)のコントラクト self.operator_address = None self.load_config() self.operator_address = self._fix_config_address( self.config['operator']['address']) if self.config['operator']['solver_pluginfile']: self.plugin.set_solverclass( self.operator_address, self.config['operator']['solver_pluginfile']) self.contracts = Contracts(self.web3) self.deploy_metemcyberutil() self.fetch_trusted_users() self.event_listener = BasicEventListener('') self.event_listener.start() # inventory (トークン・カタログの管理)のインスタンス生成 catalog_address = self._fix_config_address( self.config['catalog']['address']) broker_address = self._fix_config_address( self.config['broker']['address']) self.inventory = Inventory(self.contracts, self.account_id, self.event_listener, catalog_address, broker_address) # Seeker (チャレンジの依頼者)のインスタンス self.seeker = Seeker(self.contracts) # Solver (チャレンジの受領者)としてのインスタンス if self.operator_address: solverclass = self.plugin.get_solverclass(self.operator_address) self.solver = solverclass(self.contracts, self.account_id, self.operator_address) else: self.solver = None # MISP設定のinsert self.load_misp_config(MISP_INI_FILEPATH) def deploy_erc1820(self): # ERC777を利用するにはERC1820が必要 # https://github.com/ConsenSys/ERC1400/blob/master/migrations/2_erc1820_registry.js deployer_address = '0xa990077c3205cbDf861e17Fa532eeB069cE9fF96' contract_address = Web3.toChecksumAddress( '0x1820a4b7618bde71dce8cdc73aab6c95905fad24') code = self.web3.eth.getCode(contract_address) LOGGER.debug('erc1820_address has %s', code) if not code: #指定のアドレスへ送金 tx_hash = self.web3.eth.sendTransaction({ 'from': self.account_id, 'to': deployer_address, 'value': self.web3.toWei('0.1', 'ether') }) tx_receipt = self.web3.eth.waitForTransactionReceipt(tx_hash) GASLOG.info('erc1820.sendTransaction: gasUsed=%d', tx_receipt['gasUsed']) LOGGER.debug(tx_receipt) #ERC1820のデプロイ with open(ERC1820_RAW_TX_FILEPATH, 'r') as fin: raw_tx = fin.read().strip() tx_hash = self.web3.eth.sendRawTransaction(raw_tx) tx_receipt = self.web3.eth.waitForTransactionReceipt(tx_hash) GASLOG.info('erc1820.sendRawTransaction: gasUsed=%d', tx_receipt['gasUsed']) LOGGER.debug(tx_receipt) def deploy_metemcyberutil(self): metemcyber_util = self.contracts.accept(MetemcyberUtil()) if not self.config['metemcyber_util']['address']: self.config['metemcyber_util']['address'] = \ metemcyber_util.new().contract_address placeholder = metemcyber_util.register_library( self.config['metemcyber_util']['address'], self.config['metemcyber_util']['placeholder']) if placeholder != self.config['metemcyber_util']['placeholder']: self.config['metemcyber_util']['placeholder'] = placeholder self.save_config() def _fix_config_address(self, target): if self.web3.isChecksumAddress(target): return target if self.web3.isAddress(target): return self.web3.toChecksumAddress(target) return None def load_config(self): # コントラクトのアドレスを設定ファイルから読み込む fname = CONFIG_INI_FILEPATH config = configparser.ConfigParser() config.add_section('catalog') config.set('catalog', 'address', '') config.add_section('broker') config.set('broker', 'address', '') config.add_section('operator') config.set('operator', 'address', '') config.set('operator', 'owner', '') config.set('operator', 'solver_pluginfile', '') config.add_section('metemcyber_util') config.set('metemcyber_util', 'address', '') config.set('metemcyber_util', 'placeholder', '') if not os.path.exists(fname): self.config = config return config.read(fname) self.config = config LOGGER.info('[load config]') LOGGER.info('catalog address: %s', config['catalog']['address']) def save_config(self): if hasattr(self, 'inventory') and self.inventory: catalog = 'catalog' if not self.config.has_section(catalog): self.config.add_section(catalog) self.config.set(catalog, 'address', self.inventory.catalog_address) broker = 'broker' if not self.config.has_section(broker): self.config.add_section(broker) self.config.set(broker, 'address', self.inventory.broker_address) operator = 'operator' if not self.config.has_section(operator): self.config.add_section(operator) self.config.set(operator, 'address', self.operator_address if self.operator_address else '') self.config.set(operator, 'owner', self.account_id if self.account_id else '') if self.plugin and self.operator_address: fname = self.plugin.get_plugin_filename(self.operator_address) self.config.set(operator, 'solver_pluginfile', fname if fname else '') with open(CONFIG_INI_FILEPATH, 'w') as fout: self.config.write(fout) LOGGER.info('update config.') def load_misp_config(self, fname): # MISPに関する設定を設定ファイルから読み取る self.default_price = -1 self.default_quantity = -1 self.default_num_consign = -1 if not os.path.exists(fname): return config = configparser.ConfigParser() config.read(fname) try: self.default_price = config["MISP"].getint("defaultprice") self.default_quantity = config["MISP"].getint("defaultquantity") self.default_num_consign = config["MISP"].getint( "default_num_consign") LOGGER.info('[load MISP config]') except KeyError as err: LOGGER.warning('MISP configファイルの読み込みに失敗しました') LOGGER.warning(err) @staticmethod def uuid_to_filepath(uuid): return os.path.abspath('{}/{}.json'.format(MISP_DATAFILE_PATH, uuid)) @staticmethod def tokenaddress_to_filepath(address): return os.path.abspath('{}/{}'.format(FILESERVER_ASSETS_PATH, address)) def add_observer(self, observer): self.__observer = observer def notify_observer(self): self.__observer.update(self) @property def state(self): return self.__state @state.setter def state(self, state): self.__state = state # Stateと同じ名前の関数があれば自動実行 if state in dir(self): getattr(self, state)() self.notify_observer() def setup_inventory(self, catalog_address='', broker_address='', is_private=False): if catalog_address == '': catalog_address = self.contracts.accept(CTICatalog()).\ new(is_private).contract_address LOGGER.info('deployed CTICatalog. address: %s', catalog_address) if broker_address == '': broker_address = self.contracts.accept(CTIBroker()).\ new().contract_address LOGGER.info('deployed CTIBroker. address: %s', broker_address) if self.inventory: self.inventory.switch_catalog(catalog_address) self.inventory.switch_broker(broker_address) else: # inventory インスタンスの作成 self.inventory = Inventory(self.contracts, self.account_id, catalog_address, broker_address) self.save_config() def create_token(self, initial_supply, default_operators=None): # CTIトークンとなるERC777トークンの発行 ctitoken = self.contracts.accept(CTIToken()).new( initial_supply, default_operators if default_operators else []) return ctitoken.contract_address def accept_as_solver(self, view=None): LOGGER.info('accept as solver') if not self.inventory or not self.solver: return own_tokens = self.inventory.list_own_tokens(self.account_id) if len(own_tokens) == 0: return self.solver.accept_challenges(own_tokens, view=view) self.solver.reemit_pending_tasks() def setup_operator(self, operator_address='', solver_pluginfile='', view=None): if operator_address == self.operator_address: return if solver_pluginfile and \ not self.plugin.is_pluginfile(solver_pluginfile): raise Exception('invalid plugin file: ' + solver_pluginfile) old_operator_address = self.operator_address if operator_address == '': # オペレータのデプロイ ctioperator = self.contracts.accept(CTIOperator()) operator_address = ctioperator.new().contract_address ctioperator.set_recipient() if solver_pluginfile: self.plugin.set_solverclass(operator_address, solver_pluginfile) if operator_address != old_operator_address: if self.solver: self.solver.destroy() if operator_address: solverclass = self.plugin.get_solverclass(operator_address) self.solver = solverclass(self.contracts, self.account_id, operator_address) else: self.solver = None self.operator_address = operator_address self.save_config() if self.solver: self.accept_as_solver(view) def buy(self, token_address): # トークンの購買処理の実装 self.inventory.buy(token_address, allow_cheaper=True) def disseminate_token_from_mispdata(self, default_pirce, default_quantity, default_num_consign, view): # mispオブジェクトファイルの一覧をtokenとして公開する # 登録済みのtokenを取得 registered_token = self.fetch_registered_token() registered_uuid = [token.get('uuid') for token in registered_token] for obj_path in Path(MISP_DATAFILE_PATH).glob("./*.json"): # UUID (ファイル名から拡張子を省いた部分) を取得 uuid = obj_path.stem if uuid in registered_uuid: continue metadata = {} with open(obj_path) as fin: misp = json.load(fin) try: view.vio.print('disseminating CTI: \n' ' UUID: ' + uuid + '\n' ' TITLE: ' + misp['Event']['info'] + '\n') metadata['uuid'] = uuid metadata['title'] = misp['Event']['info'] metadata['price'] = default_pirce metadata['operator'] = self.operator_address metadata['quantity'] = default_quantity self.disseminate_new_token(metadata, default_num_consign) except KeyError: LOGGER.warning('There is no Event info in %s', misp) def disseminate_new_token(self, cti_metadata, num_consign=0): # ERC20/777 トークンを、独自トークンとして発行する # CTIトークンを作成 token_address = self.create_token(cti_metadata['quantity']) # カタログに登録して詳細をアップデート self.disseminate_token(token_address, cti_metadata) if num_consign > 0: self.inventory.consign(token_address, num_consign) return token_address def disseminate_token(self, token_address, cti_metadata): # トークンをカタログに登録 cti_metadata['tokenAddress'] = token_address self.create_asset_content(cti_metadata) self.register_catalog(token_address, cti_metadata) self.save_registered_token(cti_metadata) def create_asset_content(self, cti_metadata): misp_filepath = self.uuid_to_filepath(cti_metadata['uuid']) dist_linkpath = self.tokenaddress_to_filepath( cti_metadata['tokenAddress']) ## create a simple placeholder if MISP file does not exist. if not os.path.isfile(misp_filepath): LOGGER.warning('MISP file does not exist: %s', misp_filepath) os.makedirs(os.path.dirname(misp_filepath), exist_ok=True) ## simple placeholder with title. is this redundant? j = json.loads('{"Event":{"info": ""}}') j['Event']['info'] = cti_metadata['title'] with open(misp_filepath, 'w') as fout: json.dump(j, fout, indent=2, ensure_ascii=False) LOGGER.warning('created a simple placeholder. ' 'please overwrite the file above.') dist_dir = os.path.dirname(dist_linkpath) if not os.path.isdir(dist_dir): os.makedirs(dist_dir) LOGGER.warning('created missing directory for disseminate: %s', dist_dir) try: os.symlink(misp_filepath, dist_linkpath) except FileExistsError: LOGGER.error('disseminate link already exists: %s', dist_linkpath) def register_catalog(self, token_address, cti_metadata): self.inventory.register_token(self.account_id, token_address, cti_metadata) def unregister_catalog(self, token_address): self.inventory.unregister_token(token_address) def update_catalog(self, token_address, cti_metadata): self.inventory.modify_token(token_address, cti_metadata) @staticmethod def save_registered_token(cti_metadata): # cticatalog コントラクトに登録したtokenのmetadataを保存する fieldnames = [ 'uuid', 'tokenAddress', 'title', 'price', 'operator', 'quantity' ] is_empty = not os.path.isfile(REGISTERED_TOKEN_TSV) with open(REGISTERED_TOKEN_TSV, 'a', newline='') as tsvfile: writer = csv.DictWriter(tsvfile, fieldnames=fieldnames, extrasaction='ignore', delimiter='\t') if is_empty: writer.writeheader() writer.writerow(cti_metadata) @staticmethod def fetch_registered_token(): # 登録済みトークンのfetch registered_tokens = [] try: with open(REGISTERED_TOKEN_TSV, newline='') as tsvfile: tsv = csv.DictReader(tsvfile, delimiter='\t') for row in tsv: registered_tokens.append(row) return registered_tokens except FileNotFoundError: pass except Exception as err: LOGGER.error(err) return registered_tokens def consign(self, token_address, amount): self.inventory.consign(token_address, amount) def takeback(self, token_address, amount): self.inventory.takeback(token_address, amount) def watch_token_start(self, token_address, callback): ctitoken = self.contracts.accept(CTIToken()).get(token_address) argument_filters = dict() argument_filters['from'] = self.operator_address argument_filters['to'] = self.account_id event_filter = ctitoken.event_filter('Sent', fromBlock='latest', argument_filters=argument_filters) self.event_listener.add_event_filter('Sent:' + token_address, event_filter, callback) def watch_token_stop(self, token_address): self.event_listener.remove_event_filter_in_callback('Sent:' + token_address) def request_challenge(self, token_address, data=''): # token_address のトークンに対してチャレンジを実行 if self.seeker.challenge(self.operator_address, token_address, data=data): # トークン送付したので情報更新する self.inventory.update_balanceof_myself(token_address) @staticmethod def receive_challenge_answer(data): try: # data is generated at Solver.webhook(). download_url = data['download_url'] token_address = data['token_address'] if len(download_url) == 0 or len(token_address) == 0: raise Exception('received empty data') except: msg = '受信データの解析不能: ' + str(data) return False, msg msg = '' msg += '受信 URL: ' + download_url + '\n' msg += 'トークン: ' + token_address + '\n' try: request = Request(download_url, method="GET") with urlopen(request) as response: rdata = response.read() except Exception as err: LOGGER.error(err) msg += \ 'チャレンジ結果を受信しましたが、受信URLからの' + \ 'ダウンロードに失敗しました: ' + str(err) + '\n' msg += '手動でダウンロードしてください\n' return True, msg try: jdata = json.loads(rdata) title = jdata['Event']['info'] except: title = '(解析できませんでした)' msg += '取得データタイトル: ' + title try: if not os.path.isdir(DOWNLOADED_CTI_PATH): os.makedirs(DOWNLOADED_CTI_PATH) filepath = '{}/{}.json'.format(DOWNLOADED_CTI_PATH, token_address) with open(filepath, 'wb') as fout: fout.write(rdata) msg += '\n取得データを保存しました: ' + filepath except Exception as err: msg += '\n取得データの保存に失敗しました: ' + str(err) msg += '\n手動で再取得してください' return True, msg def cancel_challenge(self, task_id): assert self.operator_address self.seeker.cancel_challenge(self.operator_address, task_id) def fetch_task_id(self, token_address): token_related_task = self.contracts.accept(CTIOperator()).\ get(self.operator_address).history(token_address, MAX_HISTORY_NUM) # 最新の一つのみを表示 task_id = token_related_task[0] return task_id def fetch_trusted_users(self): # 信頼済みユーザのfetch trusted_users = [] try: with open(TRUSTED_USERS_TSV, newline='') as tsvfile: tsv = csv.DictReader(tsvfile, delimiter='\t') for row in tsv: try: row['id'] = Web3.toChecksumAddress(row['id']) except: continue if row['id'] == self.account_id: continue trusted_users.append(row['id']) self.trusted_users = trusted_users except FileNotFoundError: pass except Exception as err: LOGGER.error(err) def interest_assets(self): if not self.interest: return self.inventory.catalog_tokens filtered_assets = filter(lambda x: self.interest in x[1]['title'], self.inventory.catalog_tokens.items()) return dict(filtered_assets) def accept_challenge(self, token_address, view=None): LOGGER.info('accept_challenge token: %s', token_address) self.solver.accept_challenges([token_address], view=view) def refuse_challenge(self, token_address): LOGGER.info('refuse_challenge token: %s', token_address) self.solver.refuse_challenges([token_address]) def like_cti(self, token_address): assert self.inventory self.inventory.like_cti(token_address) def get_like_users(self): try: return self.inventory.like_users except: return dict() def send_token(self, token_address, target_address, amount): assert token_address and target_address and amount > 0 try: self.contracts.accept(CTIToken()).get(token_address).\ send_token(target_address, amount) # ブローカー経由でないためイベントは飛ばない。手動で反映する。 self.inventory.update_balanceof_myself(token_address) return True except Exception as err: LOGGER.exception(err) return False def burn_token(self, token_address, amount, data=''): assert token_address and amount > 0 try: self.contracts.accept(CTIToken()).get(token_address).\ burn_token(amount, data) # Burned イベントが飛ぶがキャッチしていない。手動で反映する。 self.inventory.update_balanceof_myself(token_address) return True except Exception as err: LOGGER.exception(err) return False
class Main(Tools): ''' Class for the main accerciser window. ''' COL_ACC = 4 COL_FILLED = 2 def __init__(self): ''' Gets references to important widgets, establishes event handlers, configures the tree view, and initializes the tree with the contents of the desktop. ''' # mark the root of this window with its PID so we can easily identify it # as this app #root_atk = atk.get_root() #root_atk.set_description(str(os.getpid())) self.node = Node() self.window = AccerciserMainWindow(self.node) self.window.connect('destroy', self._onQuit) # Start hotkey manager self.hotkey_manager = HotkeyManager() self.bookmarks_store = BookmarkStore(self.node) # load plugins self.plugin_manager = \ PluginManager(self.node, self.hotkey_manager, self.window.pluginview1, self.window.pluginview2) # connect signal handlers and show the GUI in its initial state self.window.show_all() main_actions = gtk.ActionGroup('MainActions') ui_manager.uimanager.insert_action_group(main_actions, 0) main_actions.add_actions([ ('Quit', gtk.STOCK_QUIT, None, '<control>q', 'Quit Accerciser', self._onQuit), ('Preferences', gtk.STOCK_PREFERENCES, _('_Preferences...'), '<control>p', 'Show preferences', self._onShowPreferences), ('Contents', gtk.STOCK_HELP, _('_Contents'), 'F1', 'View contents of manual', self._onHelp), ('About', gtk.STOCK_ABOUT, None, None, 'About Accerciser', self._onAbout)]) for action_name, menu_path in [('Quit', ui_manager.FILE_MENU_PATH), ('Preferences', ui_manager.EDIT_MENU_PATH), ('Contents', ui_manager.HELP_MENU_PATH), ('About', ui_manager.HELP_MENU_PATH)]: action = main_actions.get_action(action_name) ui_manager.uimanager.add_ui(ui_manager.uimanager.new_merge_id(), menu_path, action_name, action_name, gtk.UIManagerItemType.MENUITEM, False) self.last_focused = None self.window.show_all() def run(self): ''' Runs the app. ''' # Tell user if desktop accessibility is disabled. self._showNoA11yDialog() GObject.timeout_add(200, self._pumpEvents) try: pyatspi.Registry.start(async=True, gil=False) except KeyboardInterrupt: self._shutDown() def _pumpEvents(self): pyatspi.Registry.pumpQueuedEvents() return True def _showNoA11yDialog(self): ''' Shows a dialog with a relevant message when desktop accessibility seems to be disabled. If desktop accessibility is disabled in gsettings, prompts the user to enable it. ''' if not a11yAppSettings.get_boolean('toolkit-accessibility'): message = _('Accerciser could not see the applications on your desktop. ' 'You must enable desktop accessibility to fix this problem. ' 'Do you want to enable it now?') dialog = gtk.MessageDialog(self.window,type=gtk.MessageType.ERROR, buttons=gtk.ButtonsType.YES_NO, message_format=message) dialog.connect('response', self._onNoA11yResponse) dialog.show_all() def _onNoA11yResponse(self, dialog, response_id): dialog.destroy() if response_id == gtk.ResponseType.YES: a11yAppSettings.set_boolean('toolkit-accessibility', True) dialog = gtk.MessageDialog( self.window, type=gtk.MessageType.INFO, buttons=gtk.ButtonsType.OK, message_format=_('Note: Changes only take effect after logout.')) dialog.connect('response', lambda dia, resp: dia.destroy()) dialog.show_all() def _shutDown(self): ''' Cleans up any object instances that need explicit shutdown. ''' self.window.saveState() self.plugin_manager.close() def _onQuit(self, obj, data=None): ''' Quits the app. @param obj: The object that emitted the signal that this callback caught. @type obj: L{gtk.Widget} ''' self._shutDown() pyatspi.Registry.stop() def _onAbout(self, action, data=None): ''' Shows the about dialog. @param widget: The widget that emitted the signal that this callback caught. @type widget: L{gtk.Widget} ''' about = AccerciserAboutDialog() about.run() def _onHelp(self, action, page=""): ''' Shows the help dialog. @param widget: The widget that emitted the signal that this callback caught. @type widget: L{gtk.Widget} ''' uri = "ghelp:accerciser" if page: uri += "?%s" % page gtk.show_uri(gdk.Screen.get_default(), uri, gtk.get_current_event_time()) return True def _onShowPreferences(self, action, data=None): ''' Shows the preferences dialog. @param widget: The widget that emitted the signal that this callback caught. @type widget: L{gtk.Widget} ''' plugins_view = self.plugin_manager.View() hotkeys_view = HotkeyTreeView(self.hotkey_manager) dialog = AccerciserPreferencesDialog(plugins_view, hotkeys_view) dialog.show_all()
def __init__(self): self.plugin_manager = PluginManager() self.plugin_manager.loadBasePlugins()
class Environment(object): """An environment in which to run a program""" def __init__(self, spec): self.spec = spec self.basename = spec['basename'] self.files = {} self.plugin_mgr = PluginManager() # apply defaults self.spec['dir'] = self.merge_dicts(self.spec['dir'], { 'create': False, 'relative': False, 'cleanup': False, 'mode': 448 # 0700 }) # set up environment directory self.dir = os.path.expanduser(self.spec['dir']['path']) if self.spec['dir']['create']: try: os.mkdir(self.dir, self.spec['dir']['mode']) except OSError as e: if e.errno != errno.EEXIST: raise # setup files self.init_files() def __enter__(self): return self def __exit__(self, type, value, traceback): self.clean_up() def __getitem__(self, key): return self.files[key] def init_files(self): """Initialise files""" # initialise files, loading any config files first to ensure that any basename etc changes have applied configs = list(filter(lambda i: 'type' in self.spec['files'][i] and self.spec['files'][i]['type'] == 'config', self.spec['files'])) others = list(filter(lambda i: i not in configs, self.spec['files'])) for name in (configs + others): fspec = self.spec['files'][name] # apply defaults d = { 'type': 'raw', # raw file 'read': False, # don't read 'create': False, # don't create 'cleanup': False, # don't clean up 'mode': 448, # 0700 'rel_to': 'dir' # relative to environment directory } fspec = self.merge_dicts(fspec, d) # if we didn't get a name, use the name of the dictionary if 'name' not in fspec: fspec['name'] = name # substitute basename if self.basename: fspec['name'] = fspec['name'].format(basename=self.basename) # if this file doesn't have a path specified, use the name if 'path' not in fspec: # otherwise we use the 'path' field provided fspec['path'] = fspec['name'] # if environment var exists in this fspec then use it to override the path if 'var' in fspec and fspec['var'] in os.environ: fspec['path'] = os.environ[fspec['var']] else: # otherwise update the path based on the 'rel_to' field if fspec['rel_to'] == 'pkg' and 'pkg' in fspec: # relative to a given package, and package is specified fspec['path'] = pkg_resources.resource_filename(fspec['pkg'], fspec['path']) elif fspec['rel_to'] == 'pwd' or fspec['rel_to'] == 'cwd': # relative to the current working directory fspec['path'] = os.path.join(os.getcwd(), fspec['path']) elif fspec['rel_to'] == 'abs': # absolute path has been provided, don't update it pass else: # relative to the environment directory (the default) fspec['path'] = os.path.join(self.dir, fspec['path']) # store updated spec self.spec['files'][name] = fspec # create file if 'create' in fspec and fspec['create']: if fspec['type'] == 'plugin_dir': # create the plugin directory if it doesn't exist if not os.path.exists(fspec['path']): os.mkdir(fspec['path']) elif not os.path.exists(fspec['path']): # otherwise if it's a normal file of some kind and doesn't exist, create it fd = os.open(fspec['path'], os.O_WRONLY | os.O_CREAT, fspec['mode']) f = os.fdopen(fd, 'w') f.close() # load file if 'read' in fspec and fspec['read']: if fspec['type'] == 'config': # load as a config file self.files[name] = self.load_config(fspec) # if there was a basename variable specified in the config, grab the contents of it if 'basename_variable' in self.files[name] and self.files[name]['basename_variable'] in os.environ: bn = os.environ[self.files[name]['basename_variable']].replace("/", '') if len(bn) > 0: if len(bn) > MAX_BASENAME: bn = bn[-MAX_BASENAME:] self.basename = bn elif fspec['type'] == 'json': # load as a json file self.files[name] = self.load_json(fspec) elif fspec['type'] == 'raw': # load as raw file self.files[name] = self.load_raw(fspec) elif fspec['type'] == 'plugin_dir': # this is a plugin directory, ignore it here as we'll load it below pass else: # no idea, just load it as raw self.files[name] = self.load_raw(fspec) else: self.files[name] = fspec['path'] # load plugins if fspec['type'] == 'plugin_dir': self.load_plugins(fspec) def load_config(self, spec): """Load a JSON configuration file""" # load default config config = {} if 'default' in spec: # find where the default configuration is if spec['default']['rel_to'] == 'pkg': path = pkg_resources.resource_filename(spec['default']['pkg'], spec['default']['path']) elif spec['default']['rel_to'] == 'pwd': path = os.path.join(os.getcwd(), spec['default']['path']) elif spec['default']['rel_to'] == 'abs': path = spec['default']['path'] # load it try: config = self.parse_json(open(path).read()) except ValueError as e: raise IOError("Error parsing default configuration" + e.message) # load local config try: local_config = self.parse_json(open(spec['path']).read()) config = self.merge_dicts(local_config, config) except ValueError as e: raise ValueError("Error parsing local configuration: " + e.message) except IOError: pass return config def load_json(self, spec): """Load a JSON file""" return self.parse_json(file(spec['path']).read()) def load_raw(self, spec): """Load a raw text file""" return file(spec['path']).read() def load_plugins(self, spec): """Load plugins""" self.plugin_mgr.load_plugins(spec['path']) def parse_json(self, config): """Parse a JSON file""" lines = filter(lambda x: len(x) != 0 and x.strip()[0] != '#', config.split('\n')) return json.loads('\n'.join(lines)) def read_file(self, name): """Read a file within the environment""" # get a file spec spec = self.file_spec(name) # read file return file(spec['path']).read() def write_file(self, name, data): """Read a file within the environment""" # open file spec = self.file_spec(name) f = open(spec['path'], 'w+') # truncate the file if we're not appending if not 'append' in spec or 'append' in spec and not spec['append']: f.truncate() # write file f.write(data) f.close() def path_to(self, filename): """Return the path to a file within the environment""" return os.path.join(self.dir, filename) def file_spec(self, name): """Return a file spec for the specified name""" if name in self.spec['files']: spec = self.spec['files'][name] else: spec = {'name': name, 'type': 'raw', 'path':self.path_to(name)} return spec def clean_up(self): """Clean up the environment""" # remove any files that need to be cleaned up for name in self.spec['files']: fspec = self.spec['files'][name] if 'cleanup' in fspec and fspec['cleanup']: os.unlink(self.path_to(name)) # remove the directory if necessary if self.spec['dir']['cleanup']: os.rmdir(self.dir) def merge_dicts(self, d1, d2): """Merge two dictionaries""" # recursive merge where items in d2 override those in d1 for k1,v1 in d1.items(): if isinstance(v1, dict) and k1 in d2.keys() and isinstance(d2[k1], dict): self.merge_dicts(v1, d2[k1]) else: d2[k1] = v1 return d2 @property def plugins(self): return self.plugin_mgr.plugins
def is_new_style_command(message): message = strip_command(message) return (PluginManager.get_listener_for_command(message, logger=LOGGER) is not None)
def __init__(self): self.repositories: PluginManager[InstallerRepository] = PluginManager( InstallerRepository.namespace)
def __init__(self): self.plugin_manager = PluginManager() self.config = config
class Main(Tools): ''' Class for the main accerciser window. ''' COL_ACC = 4 COL_FILLED = 2 def __init__(self): ''' Gets references to important widgets, establishes event handlers, configures the tree view, and initializes the tree with the contents of the desktop. ''' # mark the root of this window with its PID so we can easily identify it # as this app root_atk = atk.get_root() root_atk.set_description(str(os.getpid())) self.node = Node() self.window = AccerciserMainWindow(self.node) self.window.connect('destroy', self._onQuit) # Start hotkey manager self.hotkey_manager = HotkeyManager() self.bookmarks_store = BookmarkStore(self.node) # load plugins self.plugin_manager = \ PluginManager(self.node, self.hotkey_manager, self.window.pluginview1, self.window.pluginview2) # connect signal handlers and show the GUI in its initial state self.window.show_all() main_actions = gtk.ActionGroup('MainActions') ui_manager.uimanager.insert_action_group(main_actions, 0) main_actions.add_actions([ ('Quit', gtk.STOCK_QUIT, None, '<control>q', 'Quit Accerciser', self._onQuit), ('Preferences', gtk.STOCK_PREFERENCES, _('_Preferences...'), '<control>p', 'Show preferences', self._onShowPreferences), ('Contents', gtk.STOCK_HELP, _('_Contents'), 'F1', 'View contents of manual', self._onHelp), ('About', gtk.STOCK_ABOUT, None, None, 'About Accerciser', self._onAbout) ]) for action_name, menu_path in [('Quit', ui_manager.FILE_MENU_PATH), ('Preferences', ui_manager.EDIT_MENU_PATH), ('Contents', ui_manager.HELP_MENU_PATH), ('About', ui_manager.HELP_MENU_PATH)]: action = main_actions.get_action(action_name) ui_manager.uimanager.add_ui(ui_manager.uimanager.new_merge_id(), menu_path, action_name, action_name, gtk.UIManagerItemType.MENUITEM, False) self.last_focused = None self.window.show_all() def run(self): ''' Runs the app. ''' # Tell user if desktop accessibility is disabled. self._showNoA11yDialog() GObject.timeout_add(200, self._pumpEvents) try: pyatspi.Registry.start(async=True, gil=False) except KeyboardInterrupt: self._shutDown() def _pumpEvents(self): pyatspi.Registry.pumpQueuedEvents() return True def _showNoA11yDialog(self): ''' Shows a dialog with a relevant message when desktop accessibility seems to be disabled. If desktop accessibility is disabled in gsettings, prompts the user to enable it. ''' if not a11yAppSettings.get_boolean('toolkit-accessibility'): message = _( 'Accerciser could not see the applications on your desktop. ' 'You must enable desktop accessibility to fix this problem. ' 'Do you want to enable it now?') dialog = gtk.MessageDialog(self.window, type=gtk.MessageType.ERROR, buttons=gtk.ButtonsType.YES_NO, message_format=message) dialog.connect('response', self._onNoA11yResponse) dialog.show_all() def _onNoA11yResponse(self, dialog, response_id): dialog.destroy() if response_id == gtk.ResponseType.YES: a11yAppSettings.set_boolean('toolkit-accessibility', True) dialog = gtk.MessageDialog( self.window, type=gtk.MessageType.INFO, buttons=gtk.ButtonsType.OK, message_format=_( 'Note: Changes only take effect after logout.')) dialog.connect('response', lambda dia, resp: dia.destroy()) dialog.show_all() def _shutDown(self): ''' Cleans up any object instances that need explicit shutdown. ''' self.window.saveState() self.plugin_manager.close() def _onQuit(self, obj, data=None): ''' Quits the app. @param obj: The object that emitted the signal that this callback caught. @type obj: L{gtk.Widget} ''' self._shutDown() pyatspi.Registry.stop() def _onAbout(self, action, data=None): ''' Shows the about dialog. @param widget: The widget that emitted the signal that this callback caught. @type widget: L{gtk.Widget} ''' about = AccerciserAboutDialog() about.run() def _onHelp(self, action, page=""): ''' Shows the help dialog. @param widget: The widget that emitted the signal that this callback caught. @type widget: L{gtk.Widget} ''' uri = "ghelp:accerciser" if page: uri += "?%s" % page gtk.show_uri(gdk.Screen.get_default(), uri, gtk.get_current_event_time()) return True def _onShowPreferences(self, action, data=None): ''' Shows the preferences dialog. @param widget: The widget that emitted the signal that this callback caught. @type widget: L{gtk.Widget} ''' plugins_view = self.plugin_manager.View() hotkeys_view = HotkeyTreeView(self.hotkey_manager) dialog = AccerciserPreferencesDialog(plugins_view, hotkeys_view) dialog.show_all()
class Bot(Client): def __init__(self, core, configfile): self.core = core self.configfile = configfile self.config = ConfigParser() self.config.read(configfile) host = self.config.get('base', 'host') port = self.config.getint('base', 'port') try: ssl = self.config.getboolean('base', 'ssl') except: ssl = False Client.__init__(self, (host, port), ssl) self.hooks = HookManager(self) self.plugins = PluginManager(self) self.hooks.install_owner(self) self.nick = None self.channels = {} superuser = self.config.get('base', 'superuser') self.allow_rules = {'*': {'ANY': 1}, superuser: {'ANY': 1000}} self.deny_rules = {} self._name = '_bot' autoload = self.config.get('base', 'autoload').split() for name in autoload: self.plugins.load(name) self.connect() def set_timer(self, fn, timestamp, owner=None): hook = TimestampHook(timestamp) hook.bind(fn, owner) self.hooks.install(hook) return hook def set_interval(self, fn, seconds, owner=None): hook = TimestampHook(time() + seconds, {'repeat': seconds}) hook.bind(fn, owner) self.hooks.install(hook) return hook def set_timeout(self, fn, seconds, owner=None): hook = TimestampHook(time() + seconds) hook.bind(fn, owner) self.hooks.install(hook) return hook def do_tick(self, timestamp): self.hooks.call_timestamp(timestamp) def privmsg(self, target, text): wraplen = 510 wraplen -= 1 + len(self.nick) # ":<nick>" wraplen -= 1 + 10 # "!<user>" wraplen -= 1 + 63 # "@<host>" wraplen -= 9 # " PRIVMSG " wraplen -= len(target) # "<target>" wraplen -= 2 # " :" for line in wrap(text, wraplen): self.send('PRIVMSG %s :%s' % (target, line)) def notice(self, target, text): wraplen = 510 wraplen -= 1 + len(self.nick) # ":<nick>" wraplen -= 1 + 10 # "!<user>" wraplen -= 1 + 63 # "@<host>" wraplen -= 8 # " NOTICE " wraplen -= len(target) # "<target>" wraplen -= 2 # " :" for line in wrap(text, wraplen): self.send('NOTICE %s :%s' % (target, line)) def join(self, channels, keys=None): if isinstance(channels, str): channels = (channels,) if channels: channel_s = ','.join(channels) if keys: if isinstance(keys, str): keys = (keys,) key_s = ','.join(keys) self.send('JOIN %s %s' % (channel_s, key_s)) pairs = list(zip(channels, keys)) for item in pairs: self.channels[item[0]] = {'key': item[1], 'joined': False, 'nicks': set()} else: self.send('JOIN %s' % channel_s) for channel in channels: self.channels[channel] = {'joined': False, 'nicks': set()} def part(self, channels, message=None): if type(channels) == str: channels = (channels,) if channels: channels = ','.join(channels) if message: self.send('PART %s :%s' % (channels, message)) else: self.send('PART %s' % channels) @hook @priority(0) def disconnect_event(self): for _, props in list(self.channels.items()): props['joined'] = False props['nicks'].clear() @hook @priority(0) def shutdown_event(self, reason): self.send('QUIT :%s' % reason) for name in self.plugins.list(): self.plugins.unload(name, True) @hook def _001_command(self, msg): self.server = msg.source self.nick = msg.param[0] @hook def _353_command(self, msg): channel = msg.param[2] if channel in self.channels and self.channels[channel]['joined']: nicks = self.channels[channel]['nicks'] for nick in msg.param[-1].split(): if nick.startswith(('~', '&', '@', '%', '+')): nicks.add(nick[1:]) else: nicks.add(nick) @hook def join_command(self, msg): channel = msg.param[0] if msg.source == self.nick: if channel not in self.channels: self.channels[channel] = {} self.channels[channel]['joined'] = True elif channel in self.channels: self.channels[channel]['nicks'].add(msg.source) @hook def kick_command(self, msg): channel = msg.param[0] if msg.param[1] == self.nick: if channel in self.channels: self.channels[channel]['joined'] = False if 'nicks' in self.channels[channel]: self.channels[channel]['nicks'].clear() elif channel in self.channels: self.channels[channel]['nicks'].remove(msg.source) @hook def nick_command(self, msg): new_nick = msg.param[0] if msg.source == self.nick: self.nick = new_nick for _, props in list(self.channels.items()): if 'nicks' in props and msg.source in props['nicks']: props['nicks'].remove(msg.source) props['nicks'].add(new_nick) @hook @priority(0) def part_command(self, msg): channel = msg.param[0] if msg.source == self.nick: if channel in self.channels: self.channels[channel]['joined'] = False if 'nicks' in self.channels[channel]: self.channels[channel]['nicks'].clear() elif channel in self.channels: self.channels[channel]['nicks'].remove(msg.source) @hook def ping_command(self, msg): self.send('PONG :%s' % msg.param[-1]) @hook @priority(0) def quit_command(self, msg): for _, props in list(self.channels.items()): if 'nicks' in props and msg.source in props['nicks']: props['nicks'].remove(msg.source)
class CLI(object): '''CLI module. ''' name = 'bitrunner' commands = {} plugins = {} def __init__(self, name=None, **kwargs): if name: self.name = name else: self.name = type(self).name self.log = logging.getLogger(self.name) self.log.info('Initialize cli') self.unknown_args = None global_parser = self.global_parser() # pre-parse from global_parser as well as config file and use for commands self.pre_parser = argparse.ArgumentParser(add_help=False, parents=[global_parser]) # specifically parsing arguments from associated config file if any #self.options = argparse.Namespace() self.options, self.unknown = self.pre_parser.parse_known_args() self.setup_logger(self.options.logfile, self.options.verbose) # then set up the real parser, cloning the initial one self.parser = argparse.ArgumentParser( parents=[self.pre_parser], add_help=True, formatter_class=argparse.ArgumentDefaultsHelpFormatter) if self.unknown: if '-h' or '-?' in self.unknown: self.parser.print_help() sys.exit(1) self.log.warn('Not parsing unknown arguments: {!s}'.format( self.unknown)) # check for application configs and parse app_config = current_path.absolute().joinpath('{0}.conf'.format( self.name)) self.read_config(app_config) # check for user config parameter and parse if self.options.config: self.read_config(self.options.config) self.plugin_manager = PluginManager(self.options) self.setup_plugins() self.log.debug('Current Params: {!s}'.format(self.options)) self.log.info('Complete CLI initialization') def global_parser(self): default_logfile = '{0}.log'.format(self.name) parser = argparse.ArgumentParser( description=self.__doc__, add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--config', help='Parse a local configuration file.') parser.add_argument('--version', action='version', version='%(prog)s {!s}'.format(__version__)) parser.add_argument('--logfile', default=default_logfile, action='store', help='Log to file') parser.add_argument('-v', '--verbose', default=0, action='count', help='Raise the verbosity') parser.add_argument('--profile', action='store_true', help='Profile application') parser.add_argument('--debug', action='store_true', help='Debug') return parser def setup_logger(self, logFile=None, verbose=0): # reconfigure root logger based on user input unless above flag thrown log = logging.getLogger() #TODO: review this.... # continue to keep root logger at DEBUG and allow each handler to control its own settings. #log.setLevel(logging.DEBUG) level = logging.ERROR - (10 * verbose) # Critical 50 Error 40 Warning 30 Info 20 Debug 10 NotSet 0 if level >= logging.CRITICAL: level = logging.CRITICAL elif level <= logging.NOTSET: level = logging.DEBUG log.setLevel(level) stream_handler = StreamHandler(sys.stdout) stream_handler.setLevel(level) log.addHandler(stream_handler) #if logFile: # file_handler = logging.handlers.RotatingFileHandler(logFile, maxBytes=102400, backupCount=5) # message_format = '%(asctime)s [%(process)d] %(name)-10s %(levelname)-8s %(message)s' # date_format = '%Y-%m-%d %H:%M:%S' # formatter = logging.Formatter(fmt=message_format, datefmt=date_format) # file_handler.setFormatter(formatter) #Set logging level for file handler # file_handler.setLevel(logging.INFO) # log.addHandler(file_handler) def read_config(self, configName=None): try: if not configName: return _config = configparser.ConfigParser(strict=True) configPath = os.path.join(current_path.absolute(), configName) if os.path.isfile(configPath): _config.read(configPath) self.log.info( 'Added params from config file at {0}'.format(configPath)) bools = [ 'True', 'true', 'TRUE', 'False', 'false', 'FALSE', 'yes', 'no', 'YES', 'NO', 'Yes', 'No' ] if _config.has_section('LOGGING'): log_dict = ast.literal_eval( _config.get('LOGGING', 'conf', raw=True)) logging.config.dictConfig(log_dict) else: for sect in _config.sections(): for key, value in _config.items(sect): if value in bools: #config_dict[key] = _config.getboolean(sect, key) setattr(self.options, key, _config.getboolean(sect, key)) else: #config_dict[key] = value setattr(self.options, key, value) self.log.debug('Namespace {!s}'.format(self.options)) # If no such file except IOError: self.log.error('No config file found at {0}'.format(configPath)) except configparser.Error as err: self.log.error('Config {0!s} failed: {1!r}'.format( configName, err)) def setup_plugins(self): ''' Add in external plugins ''' self.subparsers = self.parser.add_subparsers( title='plugins', help='Following plugins are available:') plugin_dict = self.plugin_manager.get_plugin_registry() if not plugin_dict: self.log.warn('No plugins were available!') return else: self.log.info('Plugins: {0!s}'.format(plugin_dict)) for plugin_class, plugin_module in plugin_dict.items(): try: assert isinstance(plugin_module, object) plugin_class = getattr(plugin_module, plugin_class) plugin = plugin_class() plugin_config_file = plugin.get_config_file() self.log.debug('Added params from plugin file at {0}'.format( plugin_config_file)) #plugin_args = {} self.read_config(plugin_config_file) parser = self.subparsers.add_parser(plugin.name, help=plugin.__doc__) parser.set_defaults(execute=plugin.execute) #parser.set_defaults(**plugin_args) plugin.setup(parser) self.log.info('Plugin Intialized: {0}'.format(plugin.name)) except Exception as err: self.log.warn('Plugin Failed To Load: {0} - {1!r}'.format( plugin.name, err)) def pre_execute(self): ''' Perform any last-minute configuration. ''' self.log.debug('Params before parsing in pre_execute:{0}'.format( self.options)) try: self.parser.parse_args(namespace=self.options) self.log.debug('Params after parsing in pre_execute:{0}'.format( self.options)) if self.unknown_args: self.log.debug( 'Unknown Arguments after parsing in pre_execute:{0}'. format(self.unknown_args)) except SystemExit: sys.exit(0) except Exception as err: raise Abort(err) def post_execute(self, returned): ''' Clean up after the application. ''' self.log.debug('Calling post_execute') # Interpret the returned value in the same way sys.exit() does. if returned is None: returned = 0 elif isinstance(returned, Abort): returned = returned.status else: try: returned = int(returned) except: returned = 1 return returned def execute(self, args=None): ''' Execute the application, returning its return value. Executes pre_execute and post_execute as well. ''' try: if hasattr(self.options, 'execute'): execute_method = getattr(self.options, 'execute') self.log.debug('Execute attribute exists: {0}({1})'.format( execute_method, type(execute_method))) self.pre_execute() self.log.info('[*] Execute: {0}'.format(self.options)) try: returned = execute_method.im_self.execute(self.options) except Exception as err: self.log.exception( 'Execute method execution failure: {0}'.format(err)) returned = err else: raise Abort('Plugin execution failure') #else: #setup command line console using existing params. Do teardown afterward. #args = (self,) #self.log.debug('No execute method found: process {0}'.format(args)) #if is_method_of(self.main, self): # if self.unknown_args: # args = self.unknown_args #try: #returned = subprocess.Popen('ls -la', env=os.environ) # returned = self.main(*args) #except Exception as err: # self.log.exception('Execution failure: {0}'.format(err)) # returned = err return self.post_execute(returned) except KeyboardInterrupt: raise except SystemExit: raise except Exception as err: logger.exception('Exception occurred : {0!r}'.format(err))
class Bot(Daemon): def __init__(self, config): super().__init__() self.config = config self.plugin_manager = PluginManager(self, os.path.join(self.config['home_path'], self.config['plugin_path'])) self.plugin_manager.load_plugins() self.builtin_commands = { 'quit': self._quit, 'join': self._join, 'part': self._part, 'loaded': self._plugin_loaded, 'unload': self._plugin_unload, 'load': self._plugin_load, 'reload': self._plugin_reload, 'ping': self._ping, 'help': self._command_help } self.events = { 'send_privmsg': self._send_privmsg_event, 'privmsg': self._privmsg_event, 'stop': self._stop_event, 'pong': self._pong_event, 'users': self._qnull_event, 'part': self._part_event, 'recv': self._qnull_event, 'send': self._qnull_event, 'server_ping': self._qnull_event, 'join': self._qnull_event } self.channels = {} def init_loop(self): logger.info("Bot started.") def cleanup_loop(self): self.event_handler(("stop", ())) def do(self): #TODO: Event driven framework? time.sleep(0.01) def event_handler(self, event): event_type, data = event # TODO: Pool? try: for _, plugin in self.plugin_manager.plugins.items(): try: attr = getattr(plugin, "{}_hook".format(event_type)) except AttributeError: attr = None if attr is not None: attr_thread = threading.Thread(target=attr, args=event) attr_thread.start() except RuntimeError as e: logger.debug("Skipped plugin hooks. {}".format(e)) self.events.get(event_type, self._null_event)(event) # Built-in commands @staticmethod def _null_command(data): logger.debug("Unknown command: {}".format(data)) def _quit(self, data): message = data[0] sender = data[1] destination = data[2] if re.search(self.config['admin_pass'], message): self.send_event("stop", message) self.stop() else: self.send_event("send_response", "F**k You!", sender) def _ping(self, data): self.send_event("ping", data) def _join(self, data): self.send_event("join", data) def _part(self, data): self.send_event("part", data) def _plugin_loaded(self, data): if data[2][0] == '#': destination = data[2] else: destination = data[1] self.send_event("send_response", "Loaded plugins: {}".format([i for i in self.plugin_manager.plugins.keys()]), destination) def _plugin_reload(self, data): try: plugin_name = data[0].split(" ")[2] except IndexError: plugin_name = None if plugin_name in self.plugin_manager.plugins: self._plugin_unload(data) self._plugin_load(data) def _plugin_unload(self, data): try: plugin_name = data[0].split(" ")[2] except IndexError: return if data[2][0] == '#': destination = data[2] else: destination = data[1] if plugin_name == "all": self.plugin_manager.unload_plugins() self.send_event("send_response", "All plugins unloaded.", destination) elif plugin_name in self.plugin_manager.plugins: self.plugin_manager.unload_plugin(plugin_name) self.send_event("send_response", "Plugin {} unloaded.".format(plugin_name), destination) def _plugin_load(self, data): try: plugin_name = data[0].split(" ")[2] except IndexError: return if data[2][0] == '#': destination = data[2] else: destination = data[1] if plugin_name == "all": self.plugin_manager.load_plugins() self.send_event("send_response", "All plugins loaded: {}".format([i for i in self.plugin_manager.plugins.keys()]), destination) else: self.plugin_manager.load_plugin(plugin_name) self.send_event("send_response", "Plugin {} loaded.".format(plugin_name), destination) def _command_help(self, data): if data[2][0] == '#': destination = data[2] else: destination = data[1] cmds = [i for i in self.builtin_commands] self.send_event("send_response", cmds, destination) cmds = [i for i in self.plugin_manager.commands] self.send_event("send_response", cmds, destination) # Events def _privmsg_event(self, event): event_type, data = event message = data[0] sender = data[1] destination = data[2] tokens = message.split(" ") prefix, command, message = None, None, None if len(tokens) == 1: command = tokens[0] elif len(tokens) == 2: command, message = tokens elif len(tokens) >= 3: prefix = tokens[0] if not re.search("{}[:,]?".format(self.config['name']), prefix): command, *message = tokens else: command, *message = tokens[1:] if destination[0] == '#' and prefix is None: command, message = message, "" prefix = self.config['name'] # TODO: Proper authentication if command is not None: if sender in self.config['authorized_users']: if prefix is None and destination != self.config['name']: return if command in self.builtin_commands: logger.debug("CMD | {}: {}".format(command, message)) self.builtin_commands.get(command, self._null_command)(data) elif command in self.plugin_manager.commands: logger.debug("CMD | {}: {}".format(command, message)) # TODO: threading plugin_thread = threading.Thread(target=self.plugin_manager.commands.get(command, self._null_command), args=data) logger.log(level=5, msg=plugin_thread) plugin_thread.start() else: self._null_command(command) def _stop_event(self, event): self.stop() def _pong_event(self, event): event_type, data = event try: if data[2][0] == '#': destination = data[2] else: destination = data[1] except IndexError: destination = data[1] logger.info("Ping time: {}".format(data[0])) self.send_event("send_response", "Ping time: {}".format(data[0]), destination) def _part_event(self, event): event_type, data = event # self.channels.pop(data[0]) def _send_privmsg_event(self, event): pass
def __init__(self, account_id, private_key, provider, dev=False): self.plugin = PluginManager() self.plugin.load(PLUGINS_PATH) self.plugin.set_default_solverclass('gcs_solver.py') self.dev = dev self.account_id = account_id self.web3 = Web3(provider) self.interest = '' self.trusted_users = [] self.web3.eth.defaultAccount = account_id # PoA であれば geth_poa_middleware を利用 try: self.web3.eth.getBlock("latest") except ExtraDataLengthError: self.web3.middleware_onion.inject(geth_poa_middleware, layer=0) if private_key: self.web3.middleware_onion.add( construct_sign_and_send_raw_middleware(private_key)) self.deploy_erc1820() self.__observer = None self.__state = None self.assets = None # Wallet の情報 self.wallet = Wallet(self.web3, self.account_id) # オペレータ(トークンの交換などを担当)のコントラクト self.operator_address = None self.load_config() self.operator_address = self._fix_config_address( self.config['operator']['address']) if self.config['operator']['solver_pluginfile']: self.plugin.set_solverclass( self.operator_address, self.config['operator']['solver_pluginfile']) self.contracts = Contracts(self.web3) self.deploy_metemcyberutil() self.fetch_trusted_users() self.event_listener = BasicEventListener('') self.event_listener.start() # inventory (トークン・カタログの管理)のインスタンス生成 catalog_address = self._fix_config_address( self.config['catalog']['address']) broker_address = self._fix_config_address( self.config['broker']['address']) self.inventory = Inventory(self.contracts, self.account_id, self.event_listener, catalog_address, broker_address) # Seeker (チャレンジの依頼者)のインスタンス self.seeker = Seeker(self.contracts) # Solver (チャレンジの受領者)としてのインスタンス if self.operator_address: solverclass = self.plugin.get_solverclass(self.operator_address) self.solver = solverclass(self.contracts, self.account_id, self.operator_address) else: self.solver = None # MISP設定のinsert self.load_misp_config(MISP_INI_FILEPATH)