def Init(self): """ This method does any kind of concrete initialization stuff, rather than doing it in __init__. Especially, the service_api must *not* be used in __init__, since all data relating to the plugin may not have been initialized on the API side. """ # TODO: smartly discover our own address IP # (this is where duplicated code starts to appear...) self.host = socket.gethostbyname(socket.gethostname()) self.port = random.randrange(7000, 7100) self.network = ProfileNetwork(self.service_api) # init facade. Views will be initialized in Enable # (views depend on graphical mode) self.facade = get_facade() # declare actions self.MAIN_ACTION = {"Modify ...": self.modify_profile, } self.POINT_ACTIONS = {"Get profile": self.get_profile, "Get files...": self.get_files, }
class Plugin(ServicePlugin): """This the working class for services plugins.""" def Init(self): """ This method does any kind of concrete initialization stuff, rather than doing it in __init__. Especially, the service_api must *not* be used in __init__, since all data relating to the plugin may not have been initialized on the API side. """ # TODO: smartly discover our own address IP # (this is where duplicated code starts to appear...) self.host = socket.gethostbyname(socket.gethostname()) self.port = random.randrange(7000, 7100) self.network = ProfileNetwork(self.service_api) # init facade. Views will be initialized in Enable # (views depend on graphical mode) self.facade = get_facade() # declare actions self.MAIN_ACTION = {"Modify ...": self.modify_profile, } self.POINT_ACTIONS = {"Get profile": self.get_profile, "Get files...": self.get_files, } # Service setup # FIXME: need to abstract action layer of plugins so that it does # not depend on navigator mode (in our case: netclient or # wxclient) def EnableBasic(self): """enable non graphic part""" # TODO: expose interface of facade to netClient # create views & doc file_doc = FileDocument() file_doc.load(os.path.join(PROFILE_DIR, PROFILE_FILE)) cache_doc = CacheDocument() cache_doc.import_document(file_doc) print_view = PrintView(cache_doc) self.facade.add_document(cache_doc) self.facade.add_view(print_view) # launch network self.network.start_listening() def Enable(self): """ All real actions involved in initializing the service should be defined here, not in the constructor. This includes e.g. opening sockets, collecting data from directories, etc. """ # init windows main_window = self.service_api.GetMainWindow() self.profile_frame = ProfileFrame(main_window, -1, "") # create views & doc file_doc = FileDocument() file_doc.load(os.path.join(PROFILE_DIR, PROFILE_FILE)) cache_doc = CacheDocument() cache_doc.import_document(file_doc) gui_view = GuiView(cache_doc, self.profile_frame) html_view = HtmlView(cache_doc, self.profile_frame.preview_tab.html_preview, True) self.facade.add_document(file_doc) self.facade.add_document(cache_doc) self.facade.add_view(gui_view) self.facade.add_view(html_view) self.facade.refresh_html_preview() # Set up main GUI hooks menu = wx.Menu() for action, method in self.MAIN_ACTION.iteritems(): item_id = wx.NewId() menu.Append(item_id, _(action)) def _clicked(event): """call profile from main menu""" method() wx.EVT_MENU(main_window, item_id, _clicked) self.service_api.SetMenu(self.GetTitle(), menu) # launch network self.network.start_listening() def Disable(self): """It is called when the user chooses to disable the service.""" self.network.stop_listening() # Service methods def modify_profile(self): self.profile_frame.Show() def _on_new_profile(self, pseudo, profile): """store and display file object corresponding to profile""" stream = StringIO(profile) document = FileDocument() document.read(stream) self.facade.fill_data((pseudo, document)) def get_profile(self, peer_id): self.network.get_profile(peer_id, self._on_new_profile) def get_files(self, peer_id, file_names): self.network.get_file(peer_id, file_names) # Service description methods def GetTitle(self): """Returns a short title of the plugin.""" return _("Profile") def GetDescription(self): """Returns a short description of the plugin. """ return _("Manage personal information and share it with people") def GetActions(self): """Returns an array of strings advertising possible actions with all peers, or None if no such action is allowed. """ return [_(desc) for desc in self.MAIN_ACTION] def GetPointToPointActions(self): """Returns an array of strings advertising point-to-point actions with another peer, or None if point-to-point actions are not allowed. """ return [_(desc) for desc in self.POINT_ACTIONS] def DescribeService(self, service): """ Fills the Service object used to describe the service to other peers. """ service.address = "%s:%d" % (self.host, self.port) # UI event responses def DoAction(self, it): """Called when the general action is invoked, if available.""" raise NotImplementedError def DoPointToPointAction(self, it, peer): """Called when a point-to-point action is invoked, if available.""" # retreive corect method actions = self.POINT_ACTIONS.values() # call method on peer actions[it](peer) # Peer management def NewPeer(self, peer, service): """delegate to network""" self.network.on_new_peer(peer, service) def ChangedPeer(self, peer, service): """delegate to network""" self.network.on_change_peer(peer, service) def LostPeer(self, peer_id): """delegate to network""" self.network.on_lost_peer(peer_id) def GotServiceData(self, peer_id, data): """delegate to network""" self.network.on_service_data(peer_id, data) def ChangedNode(self, node): # new IP ? what consequence on network? print "ChangedNode", node.id_