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!