wiki:WidgetDeveloping/Tutorials/UsingTriblerNotifiers

 Visit forum
 Forum search "WidgetDeveloping/Tutorials/UsingTriblerNotifiers"
 Discuss "WidgetDeveloping/Tutorials/UsingTriblerNotifiers"

Using Tribler Notifiers tutorial

In this tutorial, we will explain how to respond to notification messages sent by the Tribler Core. Therefore, we will create a widget that displays the last 10 discovered torrents, with a download button. We will assume you already have a HelloWorld widget here.

Step 1: imports

import wx
import Tribler.Core.Widgets.widgets as widgets
from Tribler.Core.simpledefs import *
from Tribler.Core.exceptions import *
from Tribler.Core.TorrentDef import TorrentDef
from Tribler.Core.Session import Session
from Tribler.Core.CacheDB.CacheDBHandler import TorrentDBHandler
from threading import RLock

The imports are needed because:

  • We'll need wx for the GUI,
  • widgets because this is a widget.
  • Simpledefs, Session to observe added torrents,
  • TorrentDBHandler to retrieve information on the torrents
  • Session and TorrentDef? to start downloading
  • RLock to threadsafe modify the GUI torrentlist

Step 2: general information on the widget

Don't forget to add the general information!

__name__        = "Newest discovered torrents"
__author__      = "My Name"
__version__     = "0.1"
__description__    = "Displays newest discovered torrents"
width   = 300
height  = 200

Step 3: initialize the widget

    def __init__(self, *args, **kw):
        widgets.tribler_widget.__init__(self, *args, **kw)

        self.torrentdb = TorrentDBHandler.getInstance() # Get the torrent DB
        self.session = Session.get_instance()           # Get the session
        self.config = self.session.sessconfig           # Session config for the collected torrents dir
        self.lock = RLock()                             # Create the log        

        self.torrentFileDict = {}                       # A dictionary to store torrent_name -> torrent_file_name

        #Create the list of discovered torrents with one column
        self.torrentList = wx.ListCtrl(self, -1, (0,0),(width, height-20), wx.LC_REPORT)
        self.torrentList.InsertColumn(0, 'Torrent')
        self.torrentList.SetColumnWidth(0, width)


        #Create the download button        
        self.downloadButton = wx.Button(self,-1,"Download",(0,height-20))
        self.downloadButton.Bind(wx.EVT_LEFT_UP, self.OnDownloadClicked)


        # Observe insertions of torrents
        self.session.add_observer(self.OnNotify, NTFY_TORRENTS, [NTFY_INSERT])

Step 4: Remove observer when widget gets removed

When the widget is removed or tribler is shut down, the OnClose? method of each widget gets called to do any cleanup. We will have to remove our observer, otherwise a non existing function will be called when a torrent is discovered.

    def OnClose(self):
        self.session.remove_observer(self.OnNotify)

Step 5: Add discovered widgets to the GUI list

Now we make sure when OnNotify? gets called with an infohash, we insert the torrent name into the GUI and store the torrent filename for later use, when the user clicks on download

    def OnNotify(self, subject, type, infohash):
        # Acquire thread-safe lock 
        self.lock.acquire()

        try:
            # Retrieve name and torrent file name from database
            torrent = self.torrentdb.getTorrent(infohash, ('name', 'torrent_file_name'),include_mypref=False)

            # Insert the name into the GUI list
            self.torrentList.InsertStringItem(0, torrent['name'])

            # Store a mapping from name to filename in the dictionary, for easy retrieval when user clicked download
            self.torrentFileDict[torrent['name']] = torrent['torrent_file_name'] 
            
            # Purge list when size is to great
            size = self.torrentList.GetItemCount()
            if size > 10:
                self.torrentList.DeleteItem(size-1)
        finally:
            self.lock.release()

Step 6: Start downloading when the user clicks download

When the download button is clicked, we have to handle the event and start downloading the selected torrent.

    def OnDownloadClicked(self, event):
    
        self.lock.acquire()
        try:
            # Get the first item selected
            itemId = self.torrentList.GetFirstSelected()

            
            if itemId  != -1:
                # Get the torrent name from the list
                torrent_name = self.torrentList.GetItem(itemId, 0).GetText()

                # Get the torrent filename from the dictionary
                torrent_file = self.torrentFileDict[torrent_name]

                # Load the torrent file
                tdef=TorrentDef.load(os.path.join(self.config['torrent_collecting_dir'],torrent_file))
                # Start the download

                try:
                    d = self.session.start_download(tdef)
                except DuplicateDownloadException:
                    pass  # We could show a message to the user, but who cares: it is already downloading it.

            else:
                # No item has been selected, show the user
                test = wx.MessageDialog(self, "Please select an item to download first.", "Select item", wx.OK)
                result = test.ShowModal()
                test.Destroy()
        finally:
            self.lock.release()

Step 7: Test your widget!

Start Tribler, click the "Add widget" button and go to the "insert widget" tab. Select your widget file and select "Debug Widget". Test your widget, before inserting it into the repository!