def makeHandlers(self): ### SETUP HANDLER INSTANCE ### self.handler = Handler(self) self.gameHandler = GameHandler(self) ### SETUP HANDLERS DICT ### self.HandlerDict = { SMSG_AUTH_RESPONSE: self.handler.handleAuth_Response, SMSG_DISCONNECT_ACK: self.handler.handleDisconnect_ACK }
def __init__(self): super().__init__(title='sqlmap-gtk') self.connect('key_press_event', self.on_window_key_press_event) self.set_icon_from_file("sqlmap_gtk.ico") self._handlers = Handler(self, m) # g.Box默认的orientation是HORIZONTAL _main_box = Box(orientation=VERTICAL) self._target_notebook = g.Notebook() self._build_target_notebook(self._target_notebook) _main_box.pack_start(self._target_notebook, False, True, 0) self.main_notebook = g.Notebook() self.main_notebook.add_events(d.EventMask.SCROLL_MASK | d.EventMask.SMOOTH_SCROLL_MASK) self.main_notebook.connect('scroll-event', self.scroll_page) page1 = self._build_page1() page2 = self._build_page2() page3 = self._build_page3() page4 = self._build_page4() page5 = self._build_page5() page6 = self._build_page6() self.main_notebook.append_page(page1, label.new_with_mnemonic('选项区(_1)')) self.main_notebook.append_page(page2, label.new_with_mnemonic('输出区(_2)')) self.main_notebook.append_page(page3, label.new_with_mnemonic('日志区(_3)')) self.main_notebook.append_page(page4, label.new_with_mnemonic('API区(_4)')) self.main_notebook.append_page(page5, label.new_with_mnemonic('帮助(_H)')) self.main_notebook.append_page(page6, label.new('关于')) _main_box.pack_start(self.main_notebook, True, True, 0) self.add(_main_box) # 初始化完后, 必须要有焦点, 不然按任何键都会报错, 直到操作一次UI: # gtk_widget_event: assertion 'WIDGET_REALIZED_FOR_EVENT (widget, event)' failed` # 获取焦点 # m._url_combobox.get_child().grab_focus() self.set_focus(m._url_combobox.get_child()) # 添加tooltips, placeholders等 INIT_MESG(m) # 读取 上次所有选项 self.session = Session(m) self.session.load_from_tmp()
def __init__(self, parent): super().__init__(parent, title = 'sqlmap-wx') self.SetIcon(wx.Icon('sqlmap_wx.ico')) self.m = Model() self._handlers = Handler(self, self.m) # 需要先设置handler, Bind需要它 self.initUI() self.make_accelerators() # 要先初始化完成后, 才能设全局键 # 添加tooltips, placeholders等 INIT_MESG(self.m) # 读取 上次所有选项 self.session = Session(self.m) self.session.load_from_tmp()
def __init__(self): super().__init__(title='sqlmap-gtk') self.connect('key_press_event', self.on_quit_by_key) self.set_icon_from_file("static/title.ico") self.clipboard = g.Clipboard.get(d.SELECTION_CLIPBOARD) self._handlers = Handler(self, m) _main_box = Box(orientation=VERTICAL) self._target_notebook = g.Notebook() self.build_target_notebook(self._target_notebook) _main_box.pack_start(self._target_notebook, False, True, 0) self.main_notebook = g.Notebook() self.main_notebook.add_events(d.EventMask.SCROLL_MASK | d.EventMask.SMOOTH_SCROLL_MASK) self.main_notebook.connect('scroll-event', self.scroll_page) page1 = self.build_page1() page2 = self.build_page2() page3 = self.build_page3() page4 = self.build_page4() page5 = self.build_page5() page6 = self.build_page6() _ = m._ self.main_notebook.append_page( page1, label.new_with_mnemonic(_('OPTIONS(_1)'))) self.main_notebook.append_page( page2, label.new_with_mnemonic(_('EXECUTION(_2)'))) self.main_notebook.append_page(page3, label.new_with_mnemonic(_('LOG(_3)'))) self.main_notebook.append_page( page4, label.new_with_mnemonic(_('SQLMAPAPI(_4)'))) self.main_notebook.append_page(page5, label.new_with_mnemonic(_('HELP(_H)'))) self.main_notebook.append_page(page6, label.new(_('ABOUT'))) _main_box.pack_start(self.main_notebook, True, True, 0) self.add(_main_box) # 初始化完后, 必须要有焦点, 不然按任何键都会报错, 直到操作一次UI: # gtk_widget_event: assertion 'WIDGET_REALIZED_FOR_EVENT (widget, event)' failed` # m._url_combobox.get_child().grab_focus() self.set_focus(m._url_combobox.get_child()) # add tooltips, placeholders INIT_MESG(m) self.session = Session(m) self.session.load_from_tmp()
def main(): import time from widgets import d from model import Model from handlers import Handler from session import load_settings start = time.process_time() # -------- win = g.Window(title = 'options-gtk') css_provider = g.CssProvider.new() css_provider.load_from_path('static/css.css') g.StyleContext.add_provider_for_screen( d.Screen.get_default(), css_provider, g.STYLE_PROVIDER_PRIORITY_APPLICATION ) m = Model(load_settings()[0]) _ = Notebook(m, Handler(win, m)) win.add(_) win.connect('destroy', g.main_quit) win.show_all() # -------- end = time.process_time() print('loading cost: %.3f Seconds' % (end - start)) g.main()
class OrderBot(metaclass=Singleton): token = settings.TOKEN def __init__(self): self.bot = TeleBot(self.token) logger.setLevel(logging.INFO) # Outputs debug messages to console. self.db = DBManager() self.handler = Handler(self.bot) def start(self): self.handler.run_handlers() def run_bot(self): self.start() self.bot.polling(none_stop=True)
def makeHandlers(self): ### SETUP HANDLER INSTANCE ### self.handler = Handler(self) self.gameHandler = GameHandler(self) ### SETUP HANDLERS DICT ### self.HandlerDict = { SMSG_AUTH_RESPONSE : self.handler.handleAuth_Response, SMSG_DISCONNECT_ACK : self.handler.handleDisconnect_ACK }
class Dispatcher: def __init__(self): self.bot_token, self.last_update_body = self.get_update_data( self.get_last_update()) self.redis_connection = redis.Redis(host=RedisConfig.host, port=RedisConfig.port, db=RedisConfig.db) self.handler = None def get_last_update(self): return self.redis_connection.brpop(RedisConfig.update_queue, 0) def get_update_data(self, value): update = json.loads(value) for token, received_data in update.items(): return token, received_data def run(self): self.handler = Handler(self.last_update_body['type'], self.last_update_body['chat_id'], self.last_update_body['data'], self.bot_token, self.last_update_body) self.handler.run()
def __init__(self): # Create new project object project = Project() # import Glade generated GUI builder = Gtk.Builder.new_from_file('2CANN.glade') # Setup treeviews and liststores variables_liststore = self.__init_var_manager_treeview(builder.get_object('vm_treeview')) pro_liststore = self.__init_pro_manager_treeview(builder.get_object('pro_treeview')) loop_liststore = self.__init_loop_manager_treeview(builder.get_object('loop_treeview')) loop_viewer_liststore = self.__init_loop_viewer_treeview(builder.get_object('loop_viewer_treeview')) log_run_liststore = self.__init_log_run_treeview(builder.get_object('log_run_treeview')) log_mod_liststore = self.__init_log_mod_treeview(builder.get_object('log_mod_treeview')) liststores = (variables_liststore, pro_liststore, loop_liststore, loop_viewer_liststore, log_run_liststore, log_mod_liststore) # build tag table for command editor Gtk.TextView for different # text styles tagtable = init_tagtable() # connect event handlers builder.connect_signals(Handler(project, builder, liststores, tagtable)) # build GUI self.window = builder.get_object('wrapper') self.window.show_all()
def __init__(self) -> None: """initialization and prepare data.""" self.config = Config() self.model = ModelData() self.view = ViewGraph(self.config, main=self) self.controller = Controller(self.config, self.model, self.view) self.handler = Handler(self.config, self.model, self.view, self.controller) self.view.resized.connect( self.handler.reshow_elements_after_resize_main_window) self.view.bandwidths_clicked_event.connect( self.handler.bandwidths_activated) self.view.maximums_region_changed_event.connect( self.handler.change_range_search_extremums) self.view.minimums_region_changed_event.connect( self.handler.change_range_search_extremums) self.view.edit_max_start_changed_event.connect( self.handler.change_text_line_extremums_edits) self.view.edit_max_end_changed_event.connect( self.handler.change_text_line_extremums_edits) self.view.edit_min_start_changed_event.connect( self.handler.change_text_line_extremums_edits) self.view.edit_min_end_changed_event.connect( self.handler.change_text_line_extremums_edits) self.view.menu_open_file_event.connect(self.handler.show_dialog_open) self.view.open_clicked_event.connect(self.handler.show_dialog_open) self.view.menu_save_file_event.connect( self.handler.save_button_pressed) self.view.save_clicked_event.connect(self.handler.save_button_pressed) self.view.menu_close_file_event.connect( self.handler.close_button_pressed) self.view.add_clicked_event.connect(self.handler.add_new_bandwidth) self.view.value_changed_event.connect(self.handler.change_value_slider) self.view.toggle_visible_regions_event.connect( self.handler.hide_show_regions)
def main(): import time from widgets import EXPAND, BOTTOM from model import Model from handlers import Handler start = time.process_time() app = wx.App() # -------- win = wx.Frame(None, title='options-wx', size=(800, 600)) m = Model(False) n = Notebook(win, m, Handler(win, m)) box = wx.BoxSizer() box.Add(n, proportion=1, flag=EXPAND | BOTTOM, border=5) win.SetSizerAndFit(box) win.Centre() win.Show() # -------- end = time.process_time() print('loading cost: %s Seconds' % (end - start)) app.MainLoop()
class Window(g.Window): # @profile def __init__(self): super().__init__(title='sqlmap-gtk') self.connect('key_press_event', self.on_window_key_press_event) self.set_icon_from_file("sqlmap_gtk.ico") self._handlers = Handler(self, m) # g.Box默认的orientation是HORIZONTAL _main_box = Box(orientation=VERTICAL) self._target_notebook = g.Notebook() self._build_target_notebook(self._target_notebook) _main_box.pack_start(self._target_notebook, False, True, 0) self.main_notebook = g.Notebook() self.main_notebook.add_events(d.EventMask.SCROLL_MASK | d.EventMask.SMOOTH_SCROLL_MASK) self.main_notebook.connect('scroll-event', self.scroll_page) page1 = self._build_page1() page2 = self._build_page2() page3 = self._build_page3() page4 = self._build_page4() page5 = self._build_page5() page6 = self._build_page6() self.main_notebook.append_page(page1, label.new_with_mnemonic('选项区(_1)')) self.main_notebook.append_page(page2, label.new_with_mnemonic('输出区(_2)')) self.main_notebook.append_page(page3, label.new_with_mnemonic('日志区(_3)')) self.main_notebook.append_page(page4, label.new_with_mnemonic('API区(_4)')) self.main_notebook.append_page(page5, label.new_with_mnemonic('帮助(_H)')) self.main_notebook.append_page(page6, label.new('关于')) _main_box.pack_start(self.main_notebook, True, True, 0) self.add(_main_box) # 初始化完后, 必须要有焦点, 不然按任何键都会报错, 直到操作一次UI: # gtk_widget_event: assertion 'WIDGET_REALIZED_FOR_EVENT (widget, event)' failed` # 获取焦点 # m._url_combobox.get_child().grab_focus() self.set_focus(m._url_combobox.get_child()) # 添加tooltips, placeholders等 INIT_MESG(m) # 读取 上次所有选项 self.session = Session(m) self.session.load_from_tmp() def on_window_destroy(self): try: # 保存 此次所有选项 self.session.save_to_tmp() except Exception as e: raise e finally: g.main_quit() def scroll_page(self, notebook, event): ''' https://stackoverflow.com/questions/11773132/gtk-notebook-change-page-with-scrolling-and-alt1-like-firefox-chrome-epipha ''' if event.get_scroll_deltas()[2] < 0: notebook.prev_page() else: notebook.next_page() # returns True, so it should stop the emission. # 返回True, 会停止向上(父容器)传递信号, # 不然page1的_notebook处理完信号后, 会传递给父容器的main_notebook return True def set_file_entry_text(self, button, data): ''' data: [file_entry, 'title of chooser'] ''' if len(data) > 1: # 选择目录 dialog = g.FileChooserDialog(data[1], self, g.FileChooserAction.SELECT_FOLDER, ('_Cancel', g.ResponseType.CANCEL, '_Select', g.ResponseType.OK)) else: # 点击左侧的 最近使用 可选择目录, 小问题, 不用管. dialog = g.FileChooserDialog( "选择文件", self, g.FileChooserAction.OPEN, ('_Cancel', g.ResponseType.CANCEL, '_OK', g.ResponseType.OK)) try: if dialog.run() == g.ResponseType.OK: data[0].set_text(dialog.get_filename()) data[0].grab_focus() finally: dialog.destroy() def _show_warn(self, button, mesg): if button.get_active(): _warn_dialog = g.MessageDialog(parent=self, flags=g.DialogFlags.MODAL, type=g.MessageType.WARNING, buttons=g.ButtonsType.OK_CANCEL, message_format=mesg) _response = _warn_dialog.run() if _response in (g.ResponseType.CANCEL, g.ResponseType.DELETE_EVENT): button.set_active(False) _warn_dialog.destroy() def clear_all_entry(self, button): for _i in dir(m): if _i.endswith('entry'): _tmp_entry = getattr(m, _i) if isinstance( _tmp_entry, g.Entry) and _tmp_entry is not m._sqlmap_path_entry: _tmp_entry.set_text('') def unselect_all_ckbtn(self, button): for _i in dir(m): if _i.endswith('ckbtn'): _tmp_ckbtn = getattr(m, _i) if isinstance(_tmp_ckbtn, g.CheckButton): _tmp_ckbtn.set_active(False) for _i in m._enum_area_opts_ckbtns: for _j in _i: _j.set_active(False) # 如果是实现do_key_press_event, 那事件就传不出去了, why? def on_window_key_press_event(self, widget, event: d.EventKey): keysym = event.keyval # see: gdk/gdkkeysyms.h # key_name = d.keyval_name(keysym) # print('(keysym %s, %s)' % (keysym, key_name)) state = event.state _ctrl = (state & d.ModifierType.CONTROL_MASK) if _ctrl and (keysym == d.KEY_q or keysym == d.KEY_w): self.on_window_destroy() return True def _build_target_notebook(self, target_nb): target_nb.add_events(d.EventMask.SCROLL_MASK | d.EventMask.SMOOTH_SCROLL_MASK) target_nb.connect('scroll-event', self.scroll_page) # 目标url name_store = g.ListStore(int, str) name_store.append([1, "http://www.site.com/vuln.php?id=1"]) _url_area = Box() m._url_combobox.set_model(name_store) m._url_combobox.set_entry_text_column(1) _url_area.pack_start(m._url_combobox, True, True, 0) _burp_area = Box() m._burp_logfile_chooser.connect('clicked', self._handlers.set_file_entry_text, [m._burp_logfile]) _burp_area.pack_start(m._burp_logfile, True, True, 0) _burp_area.pack_start(m._burp_logfile_chooser, False, True, 0) _request_area = Box() m._request_file_chooser.connect('clicked', self._handlers.set_file_entry_text, [m._request_file]) _request_area.pack_start(m._request_file, True, True, 0) _request_area.pack_start(m._request_file_chooser, False, True, 0) _bulkfile_area = Box() m._bulkfile_chooser.connect('clicked', self._handlers.set_file_entry_text, [m._bulkfile]) _bulkfile_area.pack_start(m._bulkfile, True, True, 0) _bulkfile_area.pack_start(m._bulkfile_chooser, False, True, 0) _configfile_area = Box() m._configfile_chooser.connect('clicked', self._handlers.set_file_entry_text, [m._configfile]) _configfile_area.pack_start(m._configfile, True, True, 0) _configfile_area.pack_start(m._configfile_chooser, False, True, 0) _sitemap_url_area = Box() _sitemap_url_area.pack_start(m._sitemap_url, True, True, 0) _google_dork_area = Box() _google_dork_area.pack_start(m._google_dork, True, True, 0) target_nb.append_page(_url_area, label.new('目标url')) target_nb.append_page(_burp_area, label.new('burp日志')) target_nb.append_page(_request_area, label.new('HTTP请求')) target_nb.append_page(_bulkfile_area, label.new('BULKFILE')) target_nb.append_page(_configfile_area, label.new('ini文件')) target_nb.append_page(_sitemap_url_area, label.new('xml_url')) target_nb.append_page(_google_dork_area, label.new('GOOGLEDORK')) def _build_page1(self): box = Box(orientation=VERTICAL, spacing=6) box.set_border_width(10) # sqlmap命令语句 _cmd_area = Frame.new('A.收集选项 的结果显示在这:') _cmd_area.add(m._cmd_entry) box.pack_start(_cmd_area, False, True, 0) # 主构造区 _notebook = Notebook(m, self._handlers) m._page1_misc_purge_ckbtn.connect('toggled', self._show_warn, '这将抹除所有本地记录!\n确定勾选?') m._page1_general_flush_session_ckbtn.connect('toggled', self._show_warn, '这将清除本地缓存!\n确定勾选?') _notebook.add_events(d.EventMask.SCROLL_MASK | d.EventMask.SMOOTH_SCROLL_MASK) _notebook.connect('scroll-event', self.scroll_page) box.pack_start(_notebook, True, True, 0) # 构造与执行 _exec_area = Box() _build_button = btn.new_with_mnemonic('A.收集选项(_A)') _build_button.connect('clicked', self._handlers.build_all) # 用于改善ui的使用体验 _unselect_all_btn = btn.new_with_mnemonic('反选所有复选框(_S)') _unselect_all_btn.connect('clicked', self.unselect_all_ckbtn) _clear_all_entry = btn.new_with_mnemonic('清空所有输入框(_D)') _clear_all_entry.connect('clicked', self.clear_all_entry) _run_button = btn.new_with_mnemonic('B.开始(_F)') _run_button.connect('clicked', self._handlers.run_cmdline) _exec_area.pack_start(_build_button, False, True, 0) _exec_area.pack_start(_unselect_all_btn, True, False, 0) _exec_area.pack_start(_clear_all_entry, True, False, 0) _exec_area.pack_end(_run_button, False, True, 0) box.pack_end(_exec_area, False, True, 0) return box def _build_page2(self): ''' 用subprocess不可实现与sqlap的交互! 不管是多线程, 同步还是异步, 都不行, 只能使用pty ''' box = Box(orientation=VERTICAL, spacing=6) box.set_border_width(10) _row1 = Box(spacing=6) # m._page2_cmdline_str_label.set_alignment(0, 0.5) # 怎么没有垂直居中? m._page2_respwan_btn.connect('clicked', self._handlers.respawn_terminal) # _row1.pack_start(m._page2_cmdline_str_label, True, True, 0) _row1.pack_start(m._page2_respwan_btn, False, True, 0) _row2 = Frame() # 等价于_pty = m._page2_terminal.pty_new_sync(Vte.PtyFlags.DEFAULT) _pty = Vte.Pty.new_sync(Vte.PtyFlags.DEFAULT) m._page2_terminal.set_pty(_pty) # https://stackoverflow.com/questions/55105447/virtual-python-shell-with-vte-pty-spawn-async # https://gtk-d.dpldocs.info/vte.Pty.Pty.spawnAsync.html # API手册上的该方法签名有问题, 与实际的对不上 # 最后一个参数为回调函数, 是必填项 _pty.spawn_async(str(Path.home()), [self._handlers.shell], None, GLib.SpawnFlags.DO_NOT_REAP_CHILD, None, None, -1, None, lambda pty, task: None) _scrolled = g.ScrolledWindow() _scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _scrolled.add(m._page2_terminal) _row2.add(_scrolled) box.pack_start(_row1, False, True, 5) box.pack_end(_row2, True, True, 0) return box def _build_page3(self): box = Box(orientation=VERTICAL, spacing=6) box.set_border_width(10) _row1 = Frame() _log_view_textbuffer = m._page3_log_view.get_buffer() self._handlers.clear_log_view_buffer(None) _end = _log_view_textbuffer.get_end_iter() _log_view_textbuffer.create_mark('end', _end, False) _scrolled = g.ScrolledWindow() _scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _scrolled.add(m._page3_log_view) _row1.add(_scrolled) _row2 = Box() m._page3_read_target_btn.connect('clicked', self._handlers.read_target_file) m._page3_clear_btn.connect('clicked', self._handlers.clear_log_view_buffer) m._page3_read_log_btn.connect('clicked', self._handlers.read_log_file) _row2.pack_start(m._page3_read_target_btn, True, False, 0) _row2.pack_start(m._page3_clear_btn, True, False, 0) _row2.pack_start(m._page3_read_log_btn, True, False, 0) box.pack_start(_row1, True, True, 5) box.pack_end(_row2, False, True, 0) return box def _build_page4(self): box = Box(orientation=VERTICAL) box.set_border_width(10) _row1 = Box(spacing=6) _row1.pack_start(m._page4_api_server_label, False, True, 0) _row1.pack_start(m._page4_api_server_entry, True, True, 0) _row1.pack_start(m._page4_admin_token_label, False, True, 0) _row1.pack_start(m._page4_admin_token_entry, True, True, 0) _row2 = Box(spacing=6) _arrow_down = g.Image.new_from_icon_name('pan-down-symbolic', 1) m._page4_admin_list_btn.set_image(_arrow_down) m._page4_admin_list_btn.set_image_position(g.PositionType.RIGHT) m._page4_admin_list_btn.set_always_show_image(True) m._page4_task_new_btn.connect('clicked', self._handlers.api.task_new) m._page4_admin_list_btn.connect('clicked', self._handlers.api.admin_list) m._page4_admin_flush_btn.connect('clicked', self._handlers.api.admin_flush) m._page4_clear_task_view_btn.connect( 'clicked', self._handlers.clear_task_view_buffer) _row2.pack_start(m._page4_task_new_btn, False, True, 0) _row2.pack_start(m._page4_admin_list_btn, False, True, 0) _row2.pack_start(m._page4_admin_flush_btn, False, True, 0) _row2.pack_start(m._page4_clear_task_view_btn, False, True, 0) _row2.pack_end(m._page4_password_entry, False, True, 0) _row2.pack_end(m._page4_password_label, False, True, 0) _row2.pack_end(m._page4_username_entry, False, True, 0) _row2.pack_end(m._page4_username_label, False, True, 0) _row3 = Frame() _paned = g.Paned() self._api_admin_list_rows = g.ListBox.new() self._api_admin_list_rows.set_selection_mode(g.SelectionMode.NONE) _lscrolled = g.ScrolledWindow() _lscrolled.set_size_request(400, -1) _lscrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _lscrolled.add(self._api_admin_list_rows) _rbox = Box(orientation=VERTICAL) _page4_option_set_view_tip = label( label='所有选项见sqlmap目录中的optiondict.py', halign=g.Align.START) _option_set_view_textbuffer = m._page4_option_set_view.get_buffer() _options_example = ("{\n" " 'url': 'http://www.site.com/vuln.php?id=1',\n" " 'level': 1, 'risk': 1,\n\n" "}\n") _option_set_view_textbuffer.set_text( _options_example, len(_options_example.encode('utf8'))) # 貌似scrollwindow要直接包含textview, # 不然一直回车后, 页面不会向上滚 _option_set_scrolled = g.ScrolledWindow() _option_set_scrolled.set_size_request(400, -1) _option_set_scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _option_set_scrolled.add(m._page4_option_set_view) _rbox.pack_start(m._page4_option_get_entry, False, True, 2) _rbox.pack_start(_page4_option_set_view_tip, False, True, 2) _rbox.pack_start(_option_set_scrolled, True, True, 2) # Warning: don't edit pack1(), pack2() again, or it would be strange. _paned.pack1(_lscrolled, False, False) _paned.pack2(_rbox, False, True) _row3.add(_paned) _row4 = Frame() _task_view_textbuffer = m._page4_task_view.get_buffer() _end = _task_view_textbuffer.get_end_iter() _task_view_textbuffer.create_mark('end', _end, False) self._handlers.api.task_view_append('此处显示反馈的结果:') _scrolled = g.ScrolledWindow() _scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _scrolled.add(m._page4_task_view) _row4.add(_scrolled) box.pack_start(_row1, False, True, 5) box.pack_start(_row2, False, True, 5) box.pack_start(_row3, True, True, 5) box.pack_start(_row4, True, True, 5) return box def _build_page5(self): box = Box(orientation=VERTICAL) box.set_border_width(10) _row1 = Box() self._get_sqlmap_path_btn = btn.new_with_label('获取帮助') self._get_sqlmap_path_btn.set_sensitive(False) self._get_sqlmap_path_btn.connect('clicked', self._make_help_thread) _row1.pack_start(self._get_sqlmap_path_btn, False, True, 5) _row2 = Frame() self._make_help_thread(None) _scrolled = g.ScrolledWindow() _scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _scrolled.add(m._page5_manual_view) _row2.add(_scrolled) box.pack_start(_row1, False, True, 5) box.pack_start(_row2, True, True, 5) return box def _make_help_thread(self, button): isClick = True if button else False # 使用线程 填充 帮助标签, 加快启动速度 t = Thread(target=self._set_manual_view, args=(m._page5_manual_view.get_buffer(), isClick)) t.daemon = True # 主线程退出了, 当然守护进程也要退出 t.start() def _set_manual_view(self, textbuffer, isClick): ''' 不用多线程能行嘛? 想要获得输出结果就一定会有阻塞的可能! https://www.jianshu.com/p/11090e197648 https://wiki.gnome.org/Projects/PyGObject/Threading needle注: 操作的共享对象有两个: _get_sqlmap_path_btn, textbuffer 原则一样, 所有对共用对象的操作都要用GLib.idle_add 这样写是不是很丑? 另外, 如果没运行完, 主线程就退出了, 会卡住哦, 属于正常 ''' if isClick: GLib.idle_add(self._get_sqlmap_path_btn.set_sensitive, False) GLib.idle_add(textbuffer.set_text, '') # WIN下不能用此行 # _manual_hh = ['/usr/bin/env', 'sqlmap', '-hh'] # _manual_hh = '/home/needle/bin/output_interval.sh' _manual_hh = [self._handlers.get_sqlmap_path(), '-hh'] try: _subprocess = Popen(_manual_hh, stdout=PIPE, stderr=STDOUT, bufsize=1) for _an_bytes_line_tmp in iter(_subprocess.stdout.readline, b''): GLib.idle_add(self.textbuffer_insert, textbuffer, _an_bytes_line_tmp.decode('utf8')) _subprocess.wait() _subprocess.stdout.close() except FileNotFoundError as e: GLib.idle_add(self.textbuffer_insert, textbuffer, str(e)) except Exception as e: print(e) finally: GLib.idle_add(self._get_sqlmap_path_btn.set_sensitive, True) if isClick: GLib.idle_add(self._get_sqlmap_path_btn.grab_focus) def textbuffer_insert(self, textbuffer, line): # get_end_iter也要加锁, py有没有变量锁? 锁btn和textbuffer就行了嘛 textbuffer.insert(textbuffer.get_end_iter(), line) def _build_page6(self): box = Box() _about_str = ''' 1. VERSION: 0.3.4.2 2019年10月10日 08:06:05 required: python3.5+, python3-gi, sqlmap 作者: needle wang ( [email protected] ) https://github.com/needle-wang/sqlmap-gtk\n 2. 使用PyGObject(Gtk+3: python3-gi)重写sqm.py\n 3. Gtk+3教程: https://python-gtk-3-tutorial.readthedocs.io/en/latest\n 4. Gtk+3 API: https://lazka.github.io/pgi-docs/Gtk-3.0/\n\n 5. 感谢sqm带来的灵感, 其作者: KINGX ( https://github.com/kxcode ), sqm UI 使用的是python2 + tkinter ''' box.pack_start(label.new(_about_str), True, False, 0) return box
def run(self): self.handler = Handler(self.last_update_body['type'], self.last_update_body['chat_id'], self.last_update_body['data'], self.bot_token, self.last_update_body) self.handler.run()
from aiohttp.web import Application, get, run_app from handlers import Handler from photo_data_worker import PhotoDataWorker import config PhotoDataWorker().start() app = Application() app.router.add_static('/static', config.STATIC_FOLDER) handler = Handler(app) app.add_routes([ get('/', handler.handle_index), get('/{global_filter}', handler.global_filter), get('/emotion/{emotion}', handler.handle_emotion) ]) if __name__ == '__main__': run_app(app)
def _create_handler(self, handler_name, handler_method): return Handler(self, handler_name, handler_method)
class Network(): def __init__(self, _base): # Game base self.game = _base # Login state self.LOGGED = False ### SETUP NETWORKING ### ## TCP Connection ## self.tcpConnection = None ## TCP NETWORKING ## # TCP Manager self.tcpManager = QueuedConnectionManager() # TCP Listener self.tcpListener = QueuedConnectionListener(self.tcpManager, 0) # TCP Reader self.tcpReader = QueuedConnectionReader(self.tcpManager, 0) # TCP Writer self.tcpWriter = ConnectionWriter(self.tcpManager, 0) ## UDP NETWORKING ## # UDP Manager self.udpManager = QueuedConnectionManager() # UDP Reader self.udpReader = QueuedConnectionReader(self.udpManager, 0) # UDP Writer self.udpWriter = ConnectionWriter(self.udpManager, 0) ### SETUP NETWORKING TASKS ### # TCP ReaderTask taskMgr.add(self.tcpReaderTask, "ClientTCPReaderTask", -40) # UDP ReaderTask taskMgr.add(self.udpReaderTask, "ClientUDPReaderTask", -39) #----------------------------------------------------------------------# # NETWORK TASKS TCP MAIN #----------------------------------------------------------------------# def tcpReaderTask(self, task): """ Handle data from server. """ while 1: (datagram, data, opcode) = self.tcpNonBlockingRead(self.tcpReader) if opcode is MSG_NONE: # Do nothing break else: self.tcpHandleDatagram(data, opcode) return Task.cont def tcpNonBlockingRead(self, qcr): """ Return a datagram collection and type if data is available on the queued tcp connection reader. @param qcr: self.tcpReader """ if self.tcpReader.dataAvailable(): datagram = NetDatagram() if self.tcpReader.getData(datagram): data = PyDatagramIterator(datagram) opcode = data.getUint16() else: data = None opcode = MSG_NONE else: datagram = None data = None opcode = MSG_NONE return (datagram, data, opcode) def tcpHandleDatagram(self, data, opcode): """ Check for the handle assigned to the opcode. """ if opcode in self.HandlerDict.keys(): self.HandlerDict[opcode](opcode, data) else: logging.info("Unknown opcode received: %d", opcode) print "Unknown opcode: %d" % opcode print data return #----------------------------------------------------------------------# # NETWORK TASKS TCP END #----------------------------------------------------------------------# #----------------------------------------------------------------------# # NETWORK TASKS UDP MAIN #----------------------------------------------------------------------# def udpReaderTask(self, task): """ Handle any data from server on udp port. """ while 1: (datagram, data, opcode) = self.udpNonBlockingRead(self.udpReader) if opcode is MSG_NONE: # Do nothing break else: # Got some data handle it self.udpHandleDatagram(data, opcode) return Task.cont def udpNonBlockingRead(self, qcr): """ Return a datagram collection and type if data is available on the queued connection udpReader """ if self.udpReader.dataAvailable(): datagram = NetDatagram() if self.udpReader.getData(datagram): data = PyDatagramIterator(datagram) opcode = data.getUint16() else: data = None opcode = MSG_NONE else: datagram = None data = None opcode = MSG_NONE # Return the datagram to keep a handle on the data return (datagram, data, opcode) def udpHandleDatagram(self, data, opcode): """ Check for the handler assigned to the opcode. """ if opcode in self.HandlerDict.keys(): self.HandlerDict[opcode](opcode, data) else: logging.info("Unknown opcode received: %d", opcode) print "Unknown opcode received: %d" % opcode print data return #----------------------------------------------------------------------# # NETWORK TASKS UDP END #----------------------------------------------------------------------# def makeHandlers(self): ### SETUP HANDLER INSTANCE ### self.handler = Handler(self) self.gameHandler = GameHandler(self) ### SETUP HANDLERS DICT ### self.HandlerDict = { SMSG_AUTH_RESPONSE : self.handler.handleAuth_Response, SMSG_DISCONNECT_ACK : self.handler.handleDisconnect_ACK } def makeConnection(self, user, passw): """ Handle the login state for the client when the player enters the user/pass info """ if self.LOGGED == True: pass else: try: print "Connecting..." self.tcpConnection = self.tcpManager.openTCPClientConnection(IP, tcpPORT, TIMEOUT) self.tcpReader.addConnection(self.tcpConnection) # Start the Handlers self.makeHandlers() self.handler.auth_REQ(user, passw) self.LOGGED = True except: print "Connection to server failed, Server offline..." self.game.gui.login_gui.popError3() self.LOGGED = False
class Window(wx.Frame): def __init__(self, parent): super().__init__(parent, title = 'sqlmap-wx') self.SetIcon(wx.Icon('sqlmap_wx.ico')) self.m = Model() self._handlers = Handler(self, self.m) # 需要先设置handler, Bind需要它 self.initUI() self.make_accelerators() # 要先初始化完成后, 才能设全局键 # 添加tooltips, placeholders等 INIT_MESG(self.m) # 读取 上次所有选项 self.session = Session(self.m) self.session.load_from_tmp() # @profile def initUI(self): p = Panel(self) self._target_notebook = nb(p) self.build_target_notebook(self._target_notebook) self.main_notebook = nb(p) page1 = self.build_page1(self.main_notebook) page2 = self.build_page2(self.main_notebook) page3 = self.build_page3(self.main_notebook) page4 = self.build_page4(self.main_notebook) page5 = self.build_page5(self.main_notebook) page6 = self.build_page6(self.main_notebook) self.main_notebook.AddPage(page1, '选项区(1)') self.main_notebook.AddPage(page2, '输出区(2)') self.main_notebook.AddPage(page3, '日志区(3)') self.main_notebook.AddPage(page4, 'API区(4)') self.main_notebook.AddPage(page5, '帮助(H)') self.main_notebook.AddPage(page6, '关于') vbox = BoxSizer(VERTICAL) vbox.Add(self._target_notebook, flag = EXPAND) vbox.Add(self.main_notebook, proportion = 1, flag = EXPAND) p.SetSizer(vbox) _frame_sz = BoxSizer() _frame_sz.Add(p, proportion = 1, flag = EXPAND) # 使用SetSizerAndFit方法使frame拥有最小size self.SetSizerAndFit(_frame_sz) def make_accelerators(self): ''' https://www.blog.pythonlibrary.org/2017/09/28/wxpython-all-about-accelerators/ 只有最后一次的SetAcceleratorTable会生效 ''' self.Bind(wx.EVT_CLOSE, self.onExit) self.Bind(wx.EVT_MENU, self.onCloseByAccel, id = wx.ID_EXIT) self.accel_entries = [(wx.ACCEL_CTRL, ord('Q'), wx.ID_EXIT), (wx.ACCEL_CTRL, ord('W'), wx.ID_EXIT)] main_note_ks = ['1', '2', '3', '4', 'H'] for i in range(len(main_note_ks)): pageid = self.main_notebook.GetPage(i).GetId() self.accel_entries.append((wx.ACCEL_ALT, ord(main_note_ks[i]), pageid)) self.Bind( wx.EVT_MENU, lambda evt, page = i: self.main_notebook.SetSelection(page), id = pageid) _note_keys = ['Q', 'W', 'E', 'R', 'T'] for i in range(len(_note_keys)): pageid = self._notebook.GetPage(i).GetId() self.accel_entries.append((wx.ACCEL_ALT, ord(_note_keys[i]), pageid)) self.Bind( wx.EVT_MENU, lambda evt, page = i: self._notebook.SetSelection(page) if self.main_notebook.GetSelection() == 0 else evt.Skip(), id = pageid) # win下, 若焦点没按钮上, 则不响应mnemonic, 只能在这里实现了 _btn_keys = ['A', 'S', 'D', 'F'] btns = self.btn_grid.GetChildren() for i in range(len(btns)): btn = btns[i].GetWindow() btnid = btn.GetId() self.accel_entries.append((wx.ACCEL_ALT, ord(_btn_keys[i]), btnid)) self.Bind( wx.EVT_MENU, lambda evt, _btn = btn: # 防止闭包: btn这个变量名跟lambda绑定成一体 self.make_btn_accel(_btn) if self.main_notebook.GetSelection() == 0 else evt.Skip(), id = btnid) accel_tbl = wx.AcceleratorTable(self.accel_entries) self.SetAcceleratorTable(accel_tbl) def make_btn_accel(self, btn): ''' https://stackoverflow.com/questions/12786471/invoking-a-wxpython-evt-button-event-programmatically ''' evt = wx.PyCommandEvent(wx.EVT_BUTTON.typeId, btn.GetId()) # print(evt) wx.PostEvent(btn, evt) def clear_all_entry(self, event): m = self.m for _i in dir(m): if _i.endswith('entry'): _tmp_entry = getattr(m, _i) if isinstance(_tmp_entry, tc) and _tmp_entry is not m.sqlmap_path_entry: _tmp_entry.SetValue('') self._notebook.SetFocus() def unselect_all_ckbtn(self, event): m = self.m for _i in dir(m): if _i.endswith('ckbtn'): _tmp_ckbtn = getattr(m, _i) if isinstance(_tmp_ckbtn, cb) and _tmp_ckbtn.IsChecked(): _tmp_ckbtn.SetValue(False) for _i in m._enum_area_opts_ckbtns: for _j in _i: if _j.IsChecked(): _j.SetValue(False) self._notebook.SetFocus() def onCloseByAccel(self, event): ''' https://stackoverflow.com/questions/49454737/how-can-i-exit-out-of-a-wxpython-application-cleanly ''' # print('by accelerator.') wx.CallAfter(self.Close) def onExit(self, event): ''' https://www.daniweb.com/programming/software-development/code/216760/verify-exit-dialog-wxpython ''' # print('by ALT-<F4> or click close button.') try: # 保存 此次所有选项 self.session.save_to_tmp() except Exception as e: raise e finally: event.Skip() def build_target_notebook(self, parent): m = self.m m._url_combobox.Create(parent, choices = ['http://www.site.com/vuln.php?id=1']) # style = wx.CB_DROPDOWN p2 = Panel(parent) hbox2 = BoxSizer() m._burp_logfile.Create(p2) m._burp_logfile_chooser.Create(p2, label = '打开') m._burp_logfile_chooser.Bind( EVT_BUTTON, lambda evt, data = [m._burp_logfile]: self._handlers.set_file_entry_text(evt, data)) hbox2.Add(m._burp_logfile, proportion = 1, flag = EXPAND) hbox2.Add(m._burp_logfile_chooser, flag = EXPAND) p2.SetSizer(hbox2) p3 = Panel(parent) hbox3 = BoxSizer() m._request_file.Create(p3) m._request_file_chooser.Create(p3, label = '打开') m._request_file_chooser.Bind( EVT_BUTTON, lambda evt, data = [m._request_file]: self._handlers.set_file_entry_text(evt, data)) hbox3.Add(m._request_file, proportion = 1, flag = EXPAND) hbox3.Add(m._request_file_chooser, flag = EXPAND) p3.SetSizer(hbox3) p4 = Panel(parent) hbox4 = BoxSizer() m._bulkfile.Create(p4) m._bulkfile_chooser.Create(p4, label = '打开') m._bulkfile_chooser.Bind( EVT_BUTTON, lambda evt, data = [m._bulkfile]: self._handlers.set_file_entry_text(evt, data)) hbox4.Add(m._bulkfile, proportion = 1, flag = EXPAND) hbox4.Add(m._bulkfile_chooser, flag = EXPAND) p4.SetSizer(hbox4) p5 = Panel(parent) hbox5 = BoxSizer() m._configfile.Create(p5) m._configfile_chooser.Create(p5, label = '打开') m._configfile_chooser.Bind( EVT_BUTTON, lambda evt, data = [m._configfile]: self._handlers.set_file_entry_text(evt, data)) hbox5.Add(m._configfile, proportion = 1, flag = EXPAND) hbox5.Add(m._configfile_chooser, flag = EXPAND) p5.SetSizer(hbox5) m._sitemap_url.Create(parent) m._google_dork.Create(parent) parent.AddPage(m._url_combobox, '目标url') parent.AddPage(p2, 'burp日志') parent.AddPage(p3, 'HTTP请求') parent.AddPage(p4, 'BULKFILE') parent.AddPage(p5, 'ini文件') parent.AddPage(m._sitemap_url, 'xml_url') parent.AddPage(m._google_dork, 'GOOGLEDORK') def build_page1(self, parent): p = Panel(parent) m = self.m # sqlmap命令语句 cmd_area = StaticBoxSizer(VERTICAL, p, 'A.收集选项 的结果显示在这:') _cmd_area = cmd_area.GetStaticBox() m._cmd_entry.Create(_cmd_area) cmd_area.Add(m._cmd_entry, flag = EXPAND) # 主构造区 self._notebook = Notebook(p, m, self._handlers) # 构造与执行 和 改善ui的使用体验 self.btn_grid = GridSizer(1, 4, 0, 0) _build_button = btn(p, label = 'A.收集选项(A)') _unselect_all_btn = btn(p, label = '反选所有复选框(S)') _clear_all_entry = btn(p, label = '清空所有输入框(D)') _build_button.Bind(EVT_BUTTON, self._handlers.build_all) _unselect_all_btn.Bind(EVT_BUTTON, self.unselect_all_ckbtn) _clear_all_entry.Bind(EVT_BUTTON, self.clear_all_entry) _run_button = btn(p, label = 'B.开始(F)') _run_button.Bind(EVT_BUTTON, self._handlers.run_cmdline) self.btn_grid.Add(_build_button, flag = ALIGN_CENTER) self.btn_grid.Add(_unselect_all_btn, flag = ALIGN_CENTER) self.btn_grid.Add(_clear_all_entry, flag = ALIGN_CENTER) self.btn_grid.Add(_run_button, flag = ALIGN_CENTER) vbox = BoxSizer(VERTICAL) vbox.Add(cmd_area, flag = EXPAND) vbox.Add(self._notebook, proportion = 1, flag = EXPAND) vbox.Add(self.btn_grid, flag = EXPAND) p.SetSizerAndFit(vbox) return p def build_page2(self, parent): p = Panel(parent) st(p, label = 'TODO') return p def build_page3(self, parent): p = Panel(parent) m = self.m # 多行文本框的默认size太小了 # 默认高度太低, 不指定个高度, 会报 滚动条相关的size 警告 m._page3_log_view.Create(p, size = (-1, 300), style = wx.TE_MULTILINE | wx.TE_READONLY) # self._handlers.clear_log_view_buffer(None) grid = GridSizer(1, 3, 0, 0) m._page3_read_target_btn.Create(p, label = '查看target文件') m._page3_clear_btn.Create(p, label = '清空(&C)') m._page3_read_log_btn.Create(p, label = '查看log文件') m._page3_read_target_btn.Bind(EVT_BUTTON, self._handlers.read_target_file) m._page3_clear_btn.Bind(EVT_BUTTON, self._handlers.clear_log_view_buffer) m._page3_read_log_btn.Bind(EVT_BUTTON, self._handlers.read_log_file) grid.Add(m._page3_read_target_btn, flag = ALIGN_CENTER) grid.Add(m._page3_clear_btn, flag = ALIGN_CENTER) grid.Add(m._page3_read_log_btn, flag = ALIGN_CENTER) vbox = BoxSizer(VERTICAL) vbox.Add(m._page3_log_view, proportion = 1, flag = EXPAND | ALL, border = 10) vbox.Add(grid, flag = EXPAND) p.SetSizerAndFit(vbox) return p def build_page4(self, parent): p = Panel(parent) m = self.m border = SizerFlags().Border(LEFT | RIGHT, 5).Align(ALIGN_CENTER) proportion_border = SizerFlags(1).Border(LEFT | RIGHT, 5).Align(ALIGN_CENTER) row1, row2 = (BoxSizer() for _ in range(2)) m._page4_api_server_label.Create(p, label = 'REST-JSON API server:') m._page4_api_server_entry.Create(p, value = '127.0.0.1:8775') m._page4_admin_token_label.Create(p, label = 'Admin (secret) token:') m._page4_admin_token_entry.Create(p) m._page4_admin_token_entry.SetMaxLength(32) row1.Add(m._page4_api_server_label, border) row1.Add(m._page4_api_server_entry, proportion_border) row1.Add(m._page4_admin_token_label, border) row1.Add(m._page4_admin_token_entry, proportion_border) m._page4_task_new_btn.Create(p, label = '创建任务') m._page4_admin_list_btn.Create(p, label = '显示任务') m._page4_admin_flush_btn.Create(p, label = '删除所有任务') m._page4_clear_task_view_btn.Create(p, label = '清空反馈的结果') m._page4_username_label.Create(p, label = '用户名:') m._page4_username_entry.Create(p) m._page4_password_label.Create(p, label = '密码:') m._page4_password_entry.Create(p) _arrow_down = wx.ArtProvider.GetBitmap(wx.ART_GO_DOWN, wx.ART_BUTTON) m._page4_admin_list_btn.SetBitmap(_arrow_down, dir = RIGHT) m._page4_task_new_btn.Bind(EVT_BUTTON, self._handlers.api.task_new) m._page4_admin_list_btn.Bind(EVT_BUTTON, self._handlers.api.admin_list) m._page4_admin_flush_btn.Bind(EVT_BUTTON, self._handlers.api.admin_flush) m._page4_clear_task_view_btn.Bind(EVT_BUTTON, self._handlers.clear_task_view_buffer) row2.Add(m._page4_task_new_btn, border) row2.Add(m._page4_admin_list_btn, border) row2.Add(m._page4_admin_flush_btn, border) row2.Add(m._page4_clear_task_view_btn, border) row2.Add(m._page4_username_label, flag = ALIGN_CENTER | LEFT, border = 200) row2.Add(m._page4_username_entry, proportion_border) row2.Add(m._page4_password_label, border) row2.Add(m._page4_password_entry, proportion_border) row3 = SplitterWindow(p, style = wx.SP_LIVE_UPDATE | wx.BORDER_SUNKEN) # 不能放在SplitVertically后面, 不然gravity会无效 # row3.SetSashGravity(0.5) row3.SetMinimumPaneSize(400) lpane = Scroll(row3) self._api_admin_list_rows = lpane lpane.SetSizer(BoxSizer(VERTICAL)) rpane = Panel(row3) _rbox = BoxSizer(VERTICAL) m._page4_option_get_entry.Create(rpane, value = 'url risk level') _page4_option_set_view_tip = st(rpane, label = '所有选项见sqlmap目录中的optiondict.py') _options_example = ("{\n" " 'url': 'http://www.site.com/vuln.php?id=1',\n" " 'level': 1, 'risk': 1,\n\n" "}\n") m._page4_option_set_view.Create(rpane, value = _options_example, style = wx.TE_MULTILINE) _rbox.Add(m._page4_option_get_entry, flag = EXPAND | ALL, border = 2) _rbox.Add(_page4_option_set_view_tip, flag = ALL, border = 2) _rbox.Add(m._page4_option_set_view, proportion = 1, flag = EXPAND | ALL, border = 2) rpane.SetSizer(_rbox) row3.SplitVertically(lpane, rpane) # win下, lpane是灰色的, 将row3设下颜色, 又是兼容代码... row3.SetBackgroundColour(m._page4_option_set_view.GetBackgroundColour()) row3.SetSashPosition(lpane.GetMinWidth()) m._page4_task_view.Create(p, value = '此处显示反馈的结果:\n', style = wx.TE_MULTILINE | wx.TE_READONLY) vbox = BoxSizer(VERTICAL) vbox.Add(row1, flag = EXPAND | ALL, border = 5) vbox.Add(row2, flag = EXPAND | ALL, border = 5) vbox.Add(row3, proportion = 1, flag = EXPAND | LEFT | RIGHT, border = 10) vbox.Add(m._page4_task_view, proportion = 1, flag = EXPAND | ALL, border = 10) p.SetSizerAndFit(vbox) return p def build_page5(self, parent): p = Panel(parent) m = self.m self._get_sqlmap_path_btn = btn(p, label = '获取帮助') self._get_sqlmap_path_btn.Disable() # 多行文本框的默认size太小了 # 默认高度太低, 不指定个高度, gtk会报 滚动条相关的size 警告 m._page5_manual_view.Create(p, size = (-1, 300), style = wx.TE_MULTILINE | wx.TE_READONLY) self._get_sqlmap_path_btn.Bind( EVT_BUTTON, lambda evt, view = m._page5_manual_view: self._make_help_thread(evt, view)) self._make_help_thread(None, m._page5_manual_view) vbox = BoxSizer(VERTICAL) vbox.Add(self._get_sqlmap_path_btn, flag = TOP | LEFT | BOTTOM, border = 10) vbox.Add(m._page5_manual_view, proportion = 1, flag = EXPAND | LEFT | RIGHT, border = 10) p.SetSizerAndFit(vbox) return p def _make_help_thread(self, event, view): isClick = True if event else False # 使用线程 填充 帮助标签, 加快启动速度 t = Thread(target = self._set_manual_view, args = (view, isClick)) t.daemon = True # 主线程退出了, 当然守护进程也要退出 t.start() def _set_manual_view(self, view, isClick): ''' 不用多线程能行嘛? 想要获得输出结果就一定会有阻塞的可能! https://www.jianshu.com/p/11090e197648 https://wiki.gnome.org/Projects/PyGObject/Threading needle注: 操作的共享对象有两个: _get_sqlmap_path_btn, view 原则一样, 所有对共用对象的操作都要用CallAfter 这样写是不是很丑? ''' if isClick: wx.CallAfter(self._get_sqlmap_path_btn.Disable) wx.CallAfter(view.SetValue, '') byte_coding = 'utf8' if IS_POSIX else 'gbk' # _manual_hh = '/home/needle/bin/output_interval.sh' # win下的sqlmap -hh有Enter阻塞 _manual_hh = 'echo y|%s -hh' % self._handlers.get_sqlmap_path() try: _subprocess = Popen(_manual_hh, stdout=PIPE, stderr=STDOUT, bufsize=1, shell = True) for _an_bytes_line_tmp in iter(_subprocess.stdout.readline, b''): wx.CallAfter(view.write, _an_bytes_line_tmp.decode(byte_coding)) _subprocess.wait() _subprocess.stdout.close() except FileNotFoundError as e: wx.CallAfter(view.write, str(e)) except Exception as e: print(e) # 如果主线程结束太快, 会: AssertionError: No wx.App created yet finally: wx.CallAfter(self._get_sqlmap_path_btn.Enable) if isClick: # 用gtk时, 如果view不在屏幕上可见, ShowPosition会报错 wx.CallAfter(view.ShowPosition, 0) wx.CallAfter(self._get_sqlmap_path_btn.SetFocus) def build_page6(self, parent): p = Panel(parent) _about_str = ''' 1. VERSION: 0.3.3 2019年 10月 16日 星期三 06:54:46 CST required: python3.5+, wxPython4.0+, sqlmap 作者: needle wang ( [email protected] ) https://github.com/needle-wang/sqlmap-wx\n 2. 使用wxPython重写sqlmap-ui(using PyGObject)\n 3. wxpython教程: https://wiki.wxpython.org/ http://zetcode.com/wxpython/ 4. wxpython API: https://wxpython.org/Phoenix/docs/html/index.html\n\n 5. 感谢sqm带来的灵感, 其作者: KINGX ( https://github.com/kxcode ), sqm UI 使用的是python2 + tkinter ''' hbox = BoxSizer() _page6_about = st(p, label = _about_str) # 完全居中! hbox.Add(_page6_about, flag = ALIGN_CENTER) vbox = BoxSizer(VERTICAL) vbox.Add(hbox, proportion = 1, flag = ALIGN_CENTER) p.SetSizerAndFit(vbox) return p
def __init__(self): self.bot = TeleBot(self.token) logger.setLevel(logging.INFO) # Outputs debug messages to console. self.db = DBManager() self.handler = Handler(self.bot)
class Window(g.Window): # @profile def __init__(self): super().__init__(title='sqlmap-gtk') self.connect('key_press_event', self.on_quit_by_key) self.set_icon_from_file("static/title.ico") self.clipboard = g.Clipboard.get(d.SELECTION_CLIPBOARD) self._handlers = Handler(self, m) _main_box = Box(orientation=VERTICAL) self._target_notebook = g.Notebook() self.build_target_notebook(self._target_notebook) _main_box.pack_start(self._target_notebook, False, True, 0) self.main_notebook = g.Notebook() self.main_notebook.add_events(d.EventMask.SCROLL_MASK | d.EventMask.SMOOTH_SCROLL_MASK) self.main_notebook.connect('scroll-event', self.scroll_page) page1 = self.build_page1() page2 = self.build_page2() page3 = self.build_page3() page4 = self.build_page4() page5 = self.build_page5() page6 = self.build_page6() _ = m._ self.main_notebook.append_page( page1, label.new_with_mnemonic(_('OPTIONS(_1)'))) self.main_notebook.append_page( page2, label.new_with_mnemonic(_('EXECUTION(_2)'))) self.main_notebook.append_page(page3, label.new_with_mnemonic(_('LOG(_3)'))) self.main_notebook.append_page( page4, label.new_with_mnemonic(_('SQLMAPAPI(_4)'))) self.main_notebook.append_page(page5, label.new_with_mnemonic(_('HELP(_H)'))) self.main_notebook.append_page(page6, label.new(_('ABOUT'))) _main_box.pack_start(self.main_notebook, True, True, 0) self.add(_main_box) # 初始化完后, 必须要有焦点, 不然按任何键都会报错, 直到操作一次UI: # gtk_widget_event: assertion 'WIDGET_REALIZED_FOR_EVENT (widget, event)' failed` # m._url_combobox.get_child().grab_focus() self.set_focus(m._url_combobox.get_child()) # add tooltips, placeholders INIT_MESG(m) self.session = Session(m) self.session.load_from_tmp() def on_quit(self): try: self.session.save_to_tmp() except Exception as e: raise e finally: g.main_quit() # 如果是实现do_key_press_event, 那事件就传不出去了, why? def on_quit_by_key(self, widget, event: d.EventKey): keysym = event.keyval # see: gdk/gdkkeysyms.h # key_name = d.keyval_name(keysym) # print('(keysym %s, %s)' % (keysym, key_name)) state = event.state _ctrl = (state & d.ModifierType.CONTROL_MASK) if _ctrl and (keysym == d.KEY_q or keysym == d.KEY_w): self.on_quit() return True def scroll_page(self, notebook, event): ''' https://stackoverflow.com/questions/11773132/gtk-notebook-change-page-with-scrolling-and-alt1-like-firefox-chrome-epipha ''' if event.get_scroll_deltas()[2] < 0: notebook.prev_page() else: notebook.next_page() # returns True, so it would stop the emission. # 返回True, 会停止向上(父容器)传递信号, # 不然page1的_notebook处理完信号后, 会传递给父容器的main_notebook return True # def set_file_entry_text(self, button, data): # ''' # data: [file_entry, 'title of chooser'] # ''' # if len(data) > 1: # choose folder # dialog = g.FileChooserDialog(data[1], self, # g.FileChooserAction.SELECT_FOLDER, # ('_Cancel', g.ResponseType.CANCEL, # '_Select', g.ResponseType.OK)) # else: # # 点击左侧的 最近使用 可选择目录, 小问题, 不用管. # dialog = g.FileChooserDialog("choose file", self, # g.FileChooserAction.OPEN, # ('_Cancel', g.ResponseType.CANCEL, # '_OK', g.ResponseType.OK)) # try: # if dialog.run() == g.ResponseType.OK: # data[0].set_text(dialog.get_filename()) # data[0].grab_focus() # finally: # dialog.destroy() def clear_all_entry(self, button): for _i in dir(m): if _i.endswith('entry'): _tmp_entry = getattr(m, _i) if isinstance( _tmp_entry, g.Entry) and _tmp_entry is not m._sqlmap_path_entry: _tmp_entry.set_text('') def unselect_all_ckbtn(self, button): for _i in dir(m): if _i.endswith('ckbtn'): _tmp_ckbtn = getattr(m, _i) if isinstance(_tmp_ckbtn, g.CheckButton): _tmp_ckbtn.set_active(False) for _i in m._enum_area_opts_ckbtns: for _j in _i: _j.set_active(False) for _i in m.tampers: _i.set_active(False) def _show_warn(self, button, mesg): if button.get_active(): # Dialog windows should be set transient for the main application window! _ = g.MessageDialog(transient_for=self, flags=0, message_type=g.MessageType.WARNING, buttons=g.ButtonsType.OK_CANCEL, text=mesg) _response = _.run() if _response in (g.ResponseType.CANCEL, g.ResponseType.DELETE_EVENT): button.set_active(False) _.destroy() def build_target_notebook(self, target_nb): target_nb.add_events(d.EventMask.SCROLL_MASK | d.EventMask.SMOOTH_SCROLL_MASK) target_nb.connect('scroll-event', self.scroll_page) # --url name_store = g.ListStore(int, str) name_store.append([1, "http://www.site.com/vuln.php?id=1"]) _url_area = Box() m._url_combobox.set_model(name_store) m._url_combobox.set_entry_text_column(1) _url_area.pack_start(m._url_combobox, True, True, 0) _burp_area = Box() m._burp_logfile_chooser.connect('clicked', self._handlers.set_file_entry_text, [m._burp_logfile]) _burp_area.pack_start(m._burp_logfile, True, True, 0) _burp_area.pack_start(m._burp_logfile_chooser, False, True, 0) _request_area = Box() m._request_file_chooser.connect('clicked', self._handlers.set_file_entry_text, [m._request_file]) _request_area.pack_start(m._request_file, True, True, 0) _request_area.pack_start(m._request_file_chooser, False, True, 0) _bulkfile_area = Box() m._bulkfile_chooser.connect('clicked', self._handlers.set_file_entry_text, [m._bulkfile]) _bulkfile_area.pack_start(m._bulkfile, True, True, 0) _bulkfile_area.pack_start(m._bulkfile_chooser, False, True, 0) _configfile_area = Box() m._configfile_chooser.connect('clicked', self._handlers.set_file_entry_text, [m._configfile]) _configfile_area.pack_start(m._configfile, True, True, 0) _configfile_area.pack_start(m._configfile_chooser, False, True, 0) _google_dork_area = Box() _google_dork_area.pack_start(m._google_dork, True, True, 0) _direct_connect_area = Box() m._direct_connect.set_text( 'mysql://*****:*****@DBMS_IP:DBMS_PORT/DATABASE_NAME or ' 'access://DATABASE_FILEPATH') _direct_connect_area.pack_start(m._direct_connect, True, True, 0) _ = m._ target_nb.append_page(_url_area, label.new(_('-u URL'))) target_nb.append_page(_burp_area, label.new(_('-l LOGFILE'))) target_nb.append_page(_request_area, label.new(_('-r REQUESTFILE'))) target_nb.append_page(_bulkfile_area, label.new(_('-m BULKFILE'))) target_nb.append_page(_configfile_area, label.new(_('-c CONFIGFILE'))) target_nb.append_page(_google_dork_area, label.new(_('-g GOOGLEDORK'))) target_nb.append_page(_direct_connect_area, label.new(_('-d DIRECT'))) def build_page1(self): box = Box(orientation=VERTICAL, spacing=6) box.set_border_width(10) _ = m._ # sqlmap命令语句 _cmd_area = Frame.new(_('A.Options are collected here:')) _cmd_area.add(m._cmd_entry) # 主构造区 _notebook = Notebook(m, self._handlers) m._general_area_flush_session_ckbtn.connect( 'toggled', self._show_warn, 'check --flush-session:\n\n' 'Flush session files for current target?') m._misc_area_purge_ckbtn.connect( 'toggled', self._show_warn, 'check --purge:\n\n' 'Safely remove all content from sqlmap data directory?') _notebook.add_events(d.EventMask.SCROLL_MASK | d.EventMask.SMOOTH_SCROLL_MASK) _notebook.connect('scroll-event', self.scroll_page) # 构造与执行 _exec_area = Box() _build_button = btn.new_with_mnemonic(_('A.collect(_A)')) _build_button.connect('clicked', self._handlers.build_all) _unselect_all_btn = btn.new_with_mnemonic(_('unselect(_S)')) _unselect_all_btn.connect('clicked', self.unselect_all_ckbtn) _clear_all_entry = btn.new_with_mnemonic(_('clear all inputs(_D)')) _clear_all_entry.connect('clicked', self.clear_all_entry) _run_button = btn.new_with_mnemonic(_('B.run(_F)')) _run_button.connect('clicked', self._handlers.run_cmdline) _exec_area.pack_start(_build_button, False, True, 0) _exec_area.pack_start(_unselect_all_btn, True, False, 0) _exec_area.pack_start(_clear_all_entry, True, False, 0) _exec_area.pack_end(_run_button, False, True, 0) box.pack_start(_cmd_area, False, True, 0) box.pack_start(_notebook, True, True, 0) box.pack_end(_exec_area, False, True, 0) return box def build_page2(self): ''' 用subprocess不可实现与sqlmap的交互! 不管是多线程, 同步还是异步, 都不行, 只能使用pty ''' box = Box(orientation=VERTICAL, spacing=6) box.set_border_width(10) _row1 = Box(spacing=6) m._page2_respwan_btn.connect('clicked', self._handlers.respawn_terminal) m._page2_right_btn.connect("button-press-event", self.on_right_click) # can not disable # m._page2_right_btn.set_sensitive(False) self._build_page2_context() _row1.pack_start(m._page2_respwan_btn, False, True, 0) _row1.pack_start(m._page2_right_btn, False, True, 0) _row2 = Frame() # equals: _pty = m._page2_terminal.pty_new_sync(Vte.PtyFlags.DEFAULT) _pty = Vte.Pty.new_sync(Vte.PtyFlags.DEFAULT) m._page2_terminal.set_pty(_pty) m._page2_terminal.connect('key_press_event', self.on_clipboard_by_key) m._page2_terminal.connect("button-press-event", self.on_right_click, m._page2_right_btn) # https://stackoverflow.com/questions/55105447/virtual-python-shell-with-vte-pty-spawn-async # https://gtk-d.dpldocs.info/vte.Pty.Pty.spawnAsync.html # API手册上的该方法签名有问题, 与实际的对不上 # 最后一个参数为回调函数, 是必填项 _pty.spawn_async(str(Path.home()), [self._handlers.shell], None, GLib.SpawnFlags.DO_NOT_REAP_CHILD, None, None, -1, None, lambda pty, task: None) _scrolled = g.ScrolledWindow() _scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _scrolled.add(m._page2_terminal) _row2.add(_scrolled) box.pack_start(_row1, False, True, 5) box.pack_end(_row2, True, True, 0) return box def _build_page2_context(self): self.popover = g.Popover() self.popover.connect('key_press_event', self.on_right_click_by_accel) _vbox = g.Box(orientation=VERTICAL, spacing=6) copy = btn.new_with_label(m._('Copy(C)')) paste = btn.new_with_label(m._('Paste(V)')) copy.connect("clicked", self.on_right_click_copy) paste.connect("clicked", self.on_right_click_paste) _vbox.pack_start(copy, False, True, 5) _vbox.pack_start(paste, False, True, 5) self.popover.add(_vbox) self.popover.set_position(g.PositionType.BOTTOM) def on_right_click(self, button, event, widget=None): if widget: button = widget # right button if event.button == d.BUTTON_SECONDARY: self.popover.set_relative_to(button) self.popover.show_all() # self.popover.popup() def on_right_click_copy(self, widget): self._copy() self.popover.hide() def on_right_click_paste(self, widget): self._paste() self.popover.hide() def on_right_click_by_accel(self, widget, event): keysym = event.keyval if keysym == d.KEY_c: self.on_right_click_copy(widget) if keysym == d.KEY_v: self.on_right_click_paste(widget) if keysym == d.KEY_Escape: self.popover.hide() return True def on_clipboard_by_key(self, widget, event): _ctrl = event.state & d.ModifierType.CONTROL_MASK keysym = event.keyval if _ctrl and keysym == d.KEY_C: return self._copy() if _ctrl and keysym == d.KEY_V: return self._paste() def _copy(self): if m._page2_terminal.get_has_selection(): m._page2_terminal.copy_clipboard_format(Vte.Format(1)) return True def _paste(self): _text = self.clipboard.wait_for_text() if _text is not None and '\n' in _text: _ = g.MessageDialog(transient_for=self, flags=0, message_type=g.MessageType.WARNING, buttons=g.ButtonsType.OK_CANCEL, text=f'Warning: insecure paste:\n\n{_text}') _response = _.run() _.destroy() if _response != g.ResponseType.OK: return True m._page2_terminal.paste_clipboard() return True def build_page3(self): box = Box(orientation=VERTICAL, spacing=6) box.set_border_width(10) _row1 = Frame() _log_view_textbuffer = m._page3_log_view.get_buffer() self._handlers.clear_log_view_buffer(None) _end = _log_view_textbuffer.get_end_iter() _log_view_textbuffer.create_mark('end', _end, False) _scrolled = g.ScrolledWindow() _scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _scrolled.add(m._page3_log_view) _row1.add(_scrolled) _row2 = Box() m._page3_read_target_btn.connect('clicked', self._handlers.read_target_file) m._page3_clear_btn.connect('clicked', self._handlers.clear_log_view_buffer) m._page3_read_log_btn.connect('clicked', self._handlers.read_log_file) _row2.pack_start(m._page3_read_target_btn, True, False, 0) _row2.pack_start(m._page3_clear_btn, True, False, 0) _row2.pack_start(m._page3_read_log_btn, True, False, 0) box.pack_start(_row1, True, True, 5) box.pack_end(_row2, False, True, 0) return box def build_page4(self): box = Box(orientation=VERTICAL) box.set_border_width(10) _row1 = Box(spacing=6) _row1.pack_start(m._page4_api_server_label, False, True, 0) _row1.pack_start(m._page4_api_server_entry, True, True, 0) _row1.pack_start(m._page4_admin_token_label, False, True, 0) _row1.pack_start(m._page4_admin_token_entry, True, True, 0) _row2 = Box(spacing=6) _arrow_down = g.Image.new_from_icon_name('pan-down-symbolic', 1) m._page4_admin_list_btn.set_image(_arrow_down) m._page4_admin_list_btn.set_image_position(g.PositionType.RIGHT) m._page4_admin_list_btn.set_always_show_image(True) m._page4_task_new_btn.connect('clicked', self._handlers.api.task_new) m._page4_admin_list_btn.connect('clicked', self._handlers.api.admin_list) m._page4_admin_flush_btn.connect('clicked', self._handlers.api.admin_flush) m._page4_clear_task_view_btn.connect( 'clicked', self._handlers.clear_task_view_buffer) _row2.pack_start(m._page4_task_new_btn, False, True, 0) _row2.pack_start(m._page4_admin_list_btn, False, True, 0) _row2.pack_start(m._page4_admin_flush_btn, False, True, 0) _row2.pack_start(m._page4_clear_task_view_btn, False, True, 0) _row2.pack_end(m._page4_password_entry, False, True, 0) _row2.pack_end(m._page4_password_label, False, True, 0) _row2.pack_end(m._page4_username_entry, False, True, 0) _row2.pack_end(m._page4_username_label, False, True, 0) _row3 = Frame() _paned = g.Paned() self._api_admin_list_rows = g.ListBox.new() self._api_admin_list_rows.set_selection_mode(g.SelectionMode.NONE) _lscrolled = g.ScrolledWindow() _lscrolled.set_size_request(400, -1) _lscrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _lscrolled.add(self._api_admin_list_rows) _rbox = Box(orientation=VERTICAL) _page4_option_set_view_tip = label( label='check optiondict.py of sqlmap about options.', halign=g.Align.START) _option_set_view_textbuffer = m._page4_option_set_view.get_buffer() _options_example = ("{\n" " 'url': 'http://www.site.com/vuln.php?id=1',\n" " 'level': 1, 'risk': 1,\n\n" "}\n") _option_set_view_textbuffer.set_text( _options_example, len(_options_example.encode('utf8'))) # 貌似scrollwindow要直接包含textview, # 不然一直回车后, 页面不会向上滚 _option_set_scrolled = g.ScrolledWindow() _option_set_scrolled.set_size_request(400, -1) _option_set_scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _option_set_scrolled.add(m._page4_option_set_view) _rbox.pack_start(m._page4_option_get_entry, False, True, 2) _rbox.pack_start(_page4_option_set_view_tip, False, True, 2) _rbox.pack_start(_option_set_scrolled, True, True, 2) # Warning: don't edit pack1(), pack2() again, otherwise it becomes strange. _paned.pack1(_lscrolled, False, False) _paned.pack2(_rbox, False, True) _row3.add(_paned) _row4 = Frame() _task_view_textbuffer = m._page4_task_view.get_buffer() _end = _task_view_textbuffer.get_end_iter() _task_view_textbuffer.create_mark('end', _end, False) self._handlers.api.task_view_append('response result:') _scrolled = g.ScrolledWindow() _scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _scrolled.add(m._page4_task_view) _row4.add(_scrolled) box.pack_start(_row1, False, True, 5) box.pack_start(_row2, False, True, 5) box.pack_start(_row3, True, True, 5) box.pack_start(_row4, True, True, 5) return box def build_page5(self): box = Box(orientation=VERTICAL) box.set_border_width(10) _row1 = Box() self._get_sqlmap_path_btn = btn.new_with_label('sqlmap -hh') self._get_sqlmap_path_btn.set_sensitive(False) self._get_sqlmap_path_btn.connect('clicked', self._make_help_thread) _row1.pack_start(self._get_sqlmap_path_btn, False, True, 5) _row2 = Frame() self._make_help_thread(None) _scrolled = g.ScrolledWindow() _scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS) _scrolled.add(m._page5_manual_view) _row2.add(_scrolled) box.pack_start(_row1, False, True, 5) box.pack_start(_row2, True, True, 5) return box def _make_help_thread(self, button): isClick = True if button else False # 使用线程 填充 帮助标签, 加快启动速度 t = Thread(target=self._set_manual_view, args=(m._page5_manual_view.get_buffer(), isClick)) t.daemon = True # 主线程退出了, 当然守护进程也要退出 t.start() def _set_manual_view(self, textbuffer, isClick): ''' 不用多线程能行嘛? 想要获得输出结果就一定会有阻塞的可能! https://www.jianshu.com/p/11090e197648 https://wiki.gnome.org/Projects/PyGObject/Threading needle注: 操作的共享对象有两个: _get_sqlmap_path_btn, textbuffer 原则一样, 所有对共用对象的操作都要用GLib.idle_add 这样写是不是很丑? 另外, 如果没运行完, 主线程就退出了, 会卡住哦, 属于正常 ''' if isClick: GLib.idle_add(self._get_sqlmap_path_btn.set_sensitive, False) GLib.idle_add(textbuffer.set_text, '') # _manual_hh = '/home/needle/bin/output_interval.sh' _manual_hh = [self._handlers.get_sqlmap_path(), '-hh'] try: _subp = Popen(_manual_hh, stdout=PIPE, stderr=STDOUT) for _an_bytes_line_tmp in iter(_subp.stdout.readline, b''): GLib.idle_add(self.textbuffer_insert, textbuffer, _an_bytes_line_tmp.decode('utf8')) _subp.wait() except FileNotFoundError as e: GLib.idle_add(self.textbuffer_insert, textbuffer, str(e)) except Exception as e: print(e) finally: GLib.idle_add(self._get_sqlmap_path_btn.set_sensitive, True) if isClick: GLib.idle_add(self._get_sqlmap_path_btn.grab_focus) def textbuffer_insert(self, textbuffer, line): # get_end_iter也要加锁, py有没有变量锁? 锁btn和textbuffer就行了嘛 textbuffer.insert(textbuffer.get_end_iter(), line) def build_page6(self): box = Box(orientation=VERTICAL, spacing=6) box.set_border_width(10) _boxes = [Box() for _ in range(3)] _lang = label.new('language:') _tooltip = label.new('tooltips:') _boxes[0].pack_start(_lang, False, True, 10) _boxes[0].pack_start(m._page6_lang_en_radio, False, True, 10) _boxes[0].pack_start(m._page6_lang_zh_radio, False, True, 10) _boxes[0].pack_start( label.new(m._('Take effects after restarting GUI.')), False, True, 10) _boxes[1].pack_start(_tooltip, False, True, 10) _boxes[1].pack_start(m._page6_tooltips_en_radio, False, True, 10) _boxes[1].pack_start(m._page6_tooltips_zh_radio, False, True, 10) _version = '0.3.5.2' _timestamp = '2021-01-29 04:04:35' _url_self = 'https://github.com/needle-wang/sqlmap-gtk' _url_tutorial = 'https://python-gtk-3-tutorial.readthedocs.io/en/latest' _url_api = 'https://lazka.github.io/pgi-docs/Gtk-3.0/' _url_idea = 'https://github.com/kxcode' _about_str = f''' 1. <a href="{_url_self}" title = "{_url_self}">Website</a> VERSION: {_version} {_timestamp} required: python3.6+, gtk+3.20 above, python3-gi, requests, sqlmap\n 2. use PyGObject(python3-gi + Gtk+3) to recode sqm.py 3. thanks to the idea from sqm, author: <a href="{_url_idea}" title="{_url_idea}">KINGX</a>. sqm UI with python2 + tkinter\n 4. Python GTK+3 Tutorial: <a href="{_url_tutorial}">{_url_tutorial}</a> 5. PyGObject-GTK 3.0 API: <a href="{_url_api}">{_url_api}</a> ''' _ = label.new(_about_str) _.set_use_markup(True) # _.set_selectable(True) _boxes[2].pack_start(_, False, True, 0) box.pack_start(_boxes[0], False, True, 0) box.pack_start(_boxes[1], False, True, 0) box.pack_start(_boxes[2], False, True, 80) return box
if __name__ == "__main__": # as the method says... config, users = load_configuration() from loop import Loop looper = Loop(config) # importing the handler from handlers import Handler # initializing the handler # includes all callbacks handler = Handler(looper.com, users) # importing the server implmentation from server import HTTPServer # Starting the webserver, passing in all # route definitions http_server = HTTPServer(config, handler.routes) try: # start the processes looper.start() loop, tasks = http_server.run()
class Network(): def __init__(self, _base): # Game base self.game = _base # Login state self.LOGGED = False ### SETUP NETWORKING ### ## TCP Connection ## self.tcpConnection = None ## TCP NETWORKING ## # TCP Manager self.tcpManager = QueuedConnectionManager() # TCP Listener self.tcpListener = QueuedConnectionListener(self.tcpManager, 0) # TCP Reader self.tcpReader = QueuedConnectionReader(self.tcpManager, 0) # TCP Writer self.tcpWriter = ConnectionWriter(self.tcpManager, 0) ## UDP NETWORKING ## # UDP Manager self.udpManager = QueuedConnectionManager() # UDP Reader self.udpReader = QueuedConnectionReader(self.udpManager, 0) # UDP Writer self.udpWriter = ConnectionWriter(self.udpManager, 0) ### SETUP NETWORKING TASKS ### # TCP ReaderTask taskMgr.add(self.tcpReaderTask, "ClientTCPReaderTask", -40) # UDP ReaderTask taskMgr.add(self.udpReaderTask, "ClientUDPReaderTask", -39) #----------------------------------------------------------------------# # NETWORK TASKS TCP MAIN #----------------------------------------------------------------------# def tcpReaderTask(self, task): """ Handle data from server. """ while 1: (datagram, data, opcode) = self.tcpNonBlockingRead(self.tcpReader) if opcode is MSG_NONE: # Do nothing break else: self.tcpHandleDatagram(data, opcode) return Task.cont def tcpNonBlockingRead(self, qcr): """ Return a datagram collection and type if data is available on the queued tcp connection reader. @param qcr: self.tcpReader """ if self.tcpReader.dataAvailable(): datagram = NetDatagram() if self.tcpReader.getData(datagram): data = PyDatagramIterator(datagram) opcode = data.getUint16() else: data = None opcode = MSG_NONE else: datagram = None data = None opcode = MSG_NONE return (datagram, data, opcode) def tcpHandleDatagram(self, data, opcode): """ Check for the handle assigned to the opcode. """ if opcode in self.HandlerDict.keys(): self.HandlerDict[opcode](opcode, data) else: logging.info("Unknown opcode received: %d", opcode) print "Unknown opcode: %d" % opcode print data return #----------------------------------------------------------------------# # NETWORK TASKS TCP END #----------------------------------------------------------------------# #----------------------------------------------------------------------# # NETWORK TASKS UDP MAIN #----------------------------------------------------------------------# def udpReaderTask(self, task): """ Handle any data from server on udp port. """ while 1: (datagram, data, opcode) = self.udpNonBlockingRead(self.udpReader) if opcode is MSG_NONE: # Do nothing break else: # Got some data handle it self.udpHandleDatagram(data, opcode) return Task.cont def udpNonBlockingRead(self, qcr): """ Return a datagram collection and type if data is available on the queued connection udpReader """ if self.udpReader.dataAvailable(): datagram = NetDatagram() if self.udpReader.getData(datagram): data = PyDatagramIterator(datagram) opcode = data.getUint16() else: data = None opcode = MSG_NONE else: datagram = None data = None opcode = MSG_NONE # Return the datagram to keep a handle on the data return (datagram, data, opcode) def udpHandleDatagram(self, data, opcode): """ Check for the handler assigned to the opcode. """ if opcode in self.HandlerDict.keys(): self.HandlerDict[opcode](opcode, data) else: logging.info("Unknown opcode received: %d", opcode) print "Unknown opcode received: %d" % opcode print data return #----------------------------------------------------------------------# # NETWORK TASKS UDP END #----------------------------------------------------------------------# def makeHandlers(self): ### SETUP HANDLER INSTANCE ### self.handler = Handler(self) self.gameHandler = GameHandler(self) ### SETUP HANDLERS DICT ### self.HandlerDict = { SMSG_AUTH_RESPONSE: self.handler.handleAuth_Response, SMSG_DISCONNECT_ACK: self.handler.handleDisconnect_ACK } def makeConnection(self, user, passw): """ Handle the login state for the client when the player enters the user/pass info """ if self.LOGGED == True: pass else: try: print "Connecting..." self.tcpConnection = self.tcpManager.openTCPClientConnection( IP, tcpPORT, TIMEOUT) self.tcpReader.addConnection(self.tcpConnection) # Start the Handlers self.makeHandlers() self.handler.auth_REQ(user, passw) self.LOGGED = True except: print "Connection to server failed, Server offline..." self.game.gui.login_gui.popError3() self.LOGGED = False