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 = NetworkManager(self.host, random.randrange(7100, 7200), self.service_api, get_facade()) # init facade. Views will be initialized in Enable # (views depend on graphical mode) self.facade = get_facade() self.profile_frame = None # declare actions self.MAIN_ACTION = {"Modify ...": self.show_profile, } self.POINT_ACTIONS = {"Get profile": self.get_profile, "Get blog": self.get_blog, "Get files...": self.select_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(False, 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 show_profile(self): if self.profile_frame: self.profile_frame.Show() def _on_new_profile(self, document): """store and display file object corresponding to profile""" self.facade.fill_data((document.get_pseudo(), document)) def _on_new_blog(self, pseudo, profile): """store and display file object corresponding to blog""" # TODO: fill method pass def get_profile(self, peer_id): self.network.get_profile(peer_id, self._on_new_profile) def get_blog(self, peer_id): self.network.get_blog(peer_id, self._on_new_blog) def get_files(self, peer_id, file_names): self.network.get_file(peer_id, file_names) def select_files(self, peer_id): # get profile # display dialog to select files pass # 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.id_) # Peer management # FIXME: reactivate when efficient def NewPeer(self, peer, service): """delegate to network""" print "NewPeer" self.network.on_new_peer(peer, service) def ChangedPeer(self, peer, service): """delegate to network""" print "ChangedPeer" self.network.on_change_peer(peer, service) def LostPeer(self, peer_id): """delegate to network""" print "LostPeer" self.network.on_lost_peer(peer_id) def GotServiceData(self, peer_id, data): """delegate to network""" print "GotServiceData" self.network.on_service_data(peer_id, data) def ChangedNode(self, node): # new IP ? what consequence on network? pass
class Plugin(ServicePlugin): """This the working class for services plugins.""" def Init(self, local_ip): """ 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. """ self.host = local_ip self.port = random.randrange(7000, 7100) self.network = None self.editor_frame = None self.filter_frame = None self.peer_services = {} # declare actions self.MAIN_ACTION = {"Modify Profile...": self.modify_profile, "Filter Profiles...": self.filter_profile, } self.POINT_ACTIONS = {#"View all...": self.show_profile, "View profile...": self.get_profile, "View blog...": self.get_blog_file, "Get files...": self.select_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""" set_solipsis_dir(self.service_api.GetDirectory()) self.network = NetworkManager(self.host, random.randrange(7100, 7200), self.service_api) self.activate(True) 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. """ set_solipsis_dir(self.service_api.GetDirectory()) # init windows main_window = self.service_api.GetMainWindow() options = {} options["standalone"] = False self.editor_frame = EditorFrame(options, main_window, -1, "", plugin=self) self.viewer_frame = ViewerFrame(options, main_window, -1, "", plugin=self) self.filter_frame = FilterFrame(options, main_window, -1, "", plugin=self) # 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)) wx.EVT_MENU(main_window, item_id, method) self.service_api.SetMenu(self.GetTitle(), menu) # launch network self.network = NetworkManager(self.host, random.randrange(7100, 7200), self.service_api, self.editor_frame.download_dlg) self.activate(True) def Disable(self): """It is called when the user chooses to disable the service.""" # ask for saving (ca not simply call Close() on editor frame # method because of multithreading and the frame is destroyed # before the user actually answer to the popup if self.editor_frame.modified: self.editor_frame.do_modified(False) dlg = wx.MessageDialog( self.editor_frame, 'Your profile has been modified. Do you want to save it?', 'Saving Profile', wx.YES_NO | wx.ICON_INFORMATION) if dlg.ShowModal() == wx.ID_YES: get_facade().save() if self.filter_frame.modified: self.filter_frame.do_modified(False) dlg = wx.MessageDialog( self.editor_frame, 'Your filters have been modified. Do you want to save them?', 'Saving Filters', wx.YES_NO | wx.ICON_INFORMATION) if dlg.ShowModal() == wx.ID_YES: get_filter_facade().save() self.activate(False) # Service methods def modify_profile(self, evt=None): """display profile once loaded""" if self.editor_frame: self.editor_frame.Show() def filter_profile(self, evt=None): """display profile once loaded""" if self.filter_frame: self.filter_frame.Show() def show_profile(self, peer_id): """display profile once loaded""" if self.viewer_frame: self.viewer_frame.Show(peer_id) def get_profile(self, peer_id): """request downwload of profile""" deferred = self.network.get_profile(peer_id) deferred and deferred.addCallback(self._on_new_profile, peer_id) def get_blog_file(self, peer_id): """request downwload of blog""" deferred = self.network.get_blog_file(peer_id) deferred and deferred.addCallback(self._on_new_blog, peer_id) def get_files(self, peer_id, file_descriptors): """request downwload of given files""" if self.editor_frame and get_prefs().get("display_dl"): self.editor_frame.download_dlg.init() self.editor_frame.download_dlg.Show() deferred = self.network.get_files(peer_id, file_descriptors, self._on_all_files) deferred and deferred.addCallback( lambda file_name: sys.stdout.write("%s downloaded\n"% file_name)) def select_files(self, peer_id): """request downwload of list of shared files""" deferred = self.network.get_shared_files(peer_id) deferred and deferred.addCallback(self._on_shared_files, peer_id) def activate(self, active=True): """eable/disable service""" if not active: self.network.stop_listening() self.network.disconnect() else: self.network.start_listening() for peer_id in self.peer_services.keys(): self.NewPeer(*self.peer_services[peer_id]) # callbacks methods def _on_new_profile(self, document, peer_id): """store and display file object corresponding to profile""" print "downloaded profile", peer_id get_facade().fill_data((peer_id, document)) if self.viewer_frame: self.viewer_frame.profile_dlg.activate() self.viewer_frame.profile_dlg.Show() def _on_new_blog(self, blog, peer_id): """store and display file object corresponding to blog""" if self.viewer_frame: self.viewer_frame.peer_dlg.activate() get_facade().fill_blog((peer_id, blog)) def _on_shared_files(self, files, peer_id): """store and display file object corresponding to blog""" if self.viewer_frame: self.viewer_frame.file_dlg.activate() get_facade().fill_shared_files((peer_id, files)) def _on_all_files(self): """store and display file object corresponding to blog""" if self.editor_frame: self.editor_frame.download_dlg.complete_all_files() else: print 'No more file to download' # 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.""" # retreive corect method actions = self.MAIN_ACTION.values() # call method on peer actions[it]() def DoPointToPointAction(self, it, peer): """Called when a point-to-point action is invoked, if available.""" if get_facade() and get_facade().is_activated(): # retreive corect method actions = self.POINT_ACTIONS.values() # call method on peer actions[it](peer.id_) # service not activated, do nothing else: print "service not activated" # Peer management # FIXME: check really need to call network method def NewPeer(self, peer, service): """delegate to network""" self.peer_services[peer.id_] = (peer, service) if get_facade() and get_facade().is_activated(): self.network.on_new_peer(peer, service) def ChangedPeer(self, peer, service): """delegate to network""" self.peer_services[peer.id_] = (peer, service) if get_facade() and get_facade().is_activated(): self.network.on_change_peer(peer, service) def LostPeer(self, peer_id): """delegate to network""" del self.peer_services[peer_id] if get_facade() and get_facade().is_activated(): self.network.on_lost_peer(peer_id) get_facade().set_connected((peer_id, False)) def GotServiceData(self, peer_id, data): """delegate to network""" if get_facade() and get_facade().is_activated(): self.network.on_service_data(peer_id, data) def ChangedNode(self, node): """need to update node_id""" # ChangedNode is call more than one time on change. Thus, be # careful not to do the job every time if get_facade() is None or get_facade().get_pseudo() != node.pseudo: facade = create_facade(node.pseudo) facade.load() if self.editor_frame: facade.add_view(EditorView(facade._desc, self.editor_frame)) self.editor_frame.on_change_facade() facade.add_view(ViewerView(facade._desc, self.viewer_frame)) self.viewer_frame.on_change_facade() filter_facade = create_filter_facade(node.pseudo) filter_facade.load() if self.filter_frame: filter_facade.add_view(FilterView(filter_facade._desc, self.filter_frame)) self.filter_frame.on_change_facade()
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 = NetworkManager(self.host, random.randrange(7100, 7200), self.service_api, get_facade()) # init facade. Views will be initialized in Enable # (views depend on graphical mode) self.facade = get_facade() self.profile_frame = None self.node_id = None # declare actions self.MAIN_ACTION = {"Modify ...": self.show_profile} self.POINT_ACTIONS = { "Get profile...": self.get_profile, "Get blog...": self.get_blog_file, "Get files...": self.select_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""" set_solipsis_dir(self.service_api.GetDirectory()) # TODO: expose interface of facade to netClient self.facade.load_profile(os.path.join(PROFILE_DIR, PROFILE_FILE)) # 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. """ set_solipsis_dir(self.service_api.GetDirectory()) # init windows main_window = self.service_api.GetMainWindow() options = {} options["standalone"] = False # profile_frame created at once since linked to facade & thus # needed for all actions (get_blog, get_files), even if not # displayed right at beginning self.profile_frame = ProfileFrame(options, main_window, -1, "", plugin=self) self.node_id = self.service_api.GetNode().pseudo # create views & doc self.facade.load_profile(os.path.join(PROFILE_DIR, PROFILE_FILE), self.profile_frame) 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.facade.save_profile() self.network.stop_listening() # Service methods def show_profile(self): """display profile once loaded""" if self.profile_frame: self.profile_frame.Show() self.profile_frame.blog_tab.on_update() # Transfer methods def _on_new_profile(self, document, peer_id): """store and display file object corresponding to profile""" print "downloaded profile", document.get_pseudo(), peer_id self.facade.fill_data((peer_id, document)) if self.profile_frame: self.profile_frame.display_profile(peer_id) def _on_new_blog(self, blog, peer_id): """store and display file object corresponding to blog""" self.facade.fill_blog((peer_id, blog)) def _on_shared_files(self, files, peer_id): """store and display file object corresponding to blog""" self.facade.fill_shared_files((peer_id, files)) def _on_all_files(self): """store and display file object corresponding to blog""" if self.profile_frame: def display_message(): dlg = wx.MessageDialog( self.service_api.GetMainWindow(), "Download complete!", "No more file to download", wx.OK | wx.ICON_INFORMATION, ) dlg.ShowModal() dlg.Destroy() wx.CallAfter(display_message) else: print "No more file to download" def get_profile(self, peer_id): """request downwload of profile""" deferred = self.network.get_profile(peer_id) deferred and deferred.addCallback(self._on_new_profile, peer_id) def get_blog_file(self, peer_id): """request downwload of blog""" deferred = self.network.get_blog_file(peer_id) deferred and deferred.addCallback(self._on_new_blog, peer_id) def get_files(self, peer_id, file_names): """request downwload of given files""" deferred = self.network.get_files(peer_id, file_names, self._on_all_files) deferred and deferred.addCallback(lambda file_name: sys.stdout.write("%s downloaded\n" % file_name)) def select_files(self, peer_id): """request downwload of list of shared files""" deferred = self.network.get_shared_files(peer_id) deferred and deferred.addCallback(self._on_shared_files, peer_id) # 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.""" self.show_profile() def DoPointToPointAction(self, it, peer): """Called when a point-to-point action is invoked, if available.""" if self.facade.is_activated(): # retreive corect method actions = self.POINT_ACTIONS.values() # call method on peer actions[it](peer.id_) # service not activated, do nothing else: print "service not activated" # Peer management # FIXME: reactivate when efficient def NewPeer(self, peer, service): """delegate to network""" if self.facade.is_activated(): self.network.on_new_peer(peer, service) def ChangedPeer(self, peer, service): """delegate to network""" if self.facade.is_activated(): self.network.on_change_peer(peer, service) def LostPeer(self, peer_id): """delegate to network""" if self.facade.is_activated(): self.network.on_lost_peer(peer_id) self.facade.set_connected(peer_id, False) def GotServiceData(self, peer_id, data): """delegate to network""" if self.facade.is_activated(): self.network.on_service_data(peer_id, data) def ChangedNode(self, node): """need to update node_id""" # FIXME new node_id ? what consequence on network? cache? pass