Esempio n. 1
0
 def handleRunQuery(self):
     self.myQuery = str(self.ui.mySearchLineEdit.text())
     if len(self.myQuery) > 0:
         self.ui.mySavePushButton.setEnabled(False)
         self.ui.myWatchPushButton.setEnabled(False)
         #create result depending on which linksite was checked
         if self.myAreResultsTvLinks:
             self.updateStatus("Searching TVLinks for %s" % (self.myQuery))
             self.createWebRequestThread(
                 self.updateSearchResults,
                 TVLinks.searchSite,
                 self.myQuery,
                 listWidget=self.ui.myResultsListWidget)
         else:
             self.updateStatus("Searching OneChannel for %s" %
                               (self.myQuery))
             if self.prefetchedKey is None:
                 print "not prefetched key"
                 searchMethod = OneChannel.searchSite
             else:
                 print "using prefetched key"
                 searchMethod = lambda query: OneChannel.searchSite(
                     query, self.prefetchedKey)
             self.createWebRequestThread(
                 self.updateSearchResults,
                 searchMethod,
                 self.myQuery,
                 listWidget=self.ui.myResultsListWidget)
Esempio n. 2
0
 def handleChoseResult(self):
     index = self.getFirstSelectedIndex(self.ui.myResultsListWidget)
     if index is None:
         return
     self.ui.mySavePushButton.setEnabled(False)
     self.ui.myWatchPushButton.setEnabled(False)
     url = self.myQueryResult[index][1]
     #            instansiate myLinkSite with correct
     #            this avoids the condition where the radio
     #            button is changed after the fact because we
     #            are referencing myAreResultsTvLinks, rather
     #            than the radio button itself.
     self.updateStatus("Finding seasons. Please wait...")
     if self.myAreResultsTvLinks:
         self.myLinkSite = TVLinks(url)
     else:
         self.myLinkSite = OneChannel(url)
     seasonUpdateMethod = lambda data: self.updateListWidget(data, self.ui.mySeasonListWidget)
     self.createWebRequestThread(seasonUpdateMethod, self.myLinkSite.getSeasons, listWidget=self.ui.mySeasonListWidget)
Esempio n. 3
0
 def handleChoseResult(self):
     index = self.getFirstSelectedIndex(self.ui.myResultsListWidget)
     if index is None:
         return
     self.ui.mySavePushButton.setEnabled(False)
     self.ui.myWatchPushButton.setEnabled(False)
     url = self.myQueryResult[index][1]
     #            instansiate myLinkSite with correct
     #            this avoids the condition where the radio
     #            button is changed after the fact because we
     #            are referencing myAreResultsTvLinks, rather
     #            than the radio button itself.
     self.updateStatus("Finding seasons. Please wait...")
     if self.myAreResultsTvLinks:
         self.myLinkSite = TVLinks(url)
     else:
         self.myLinkSite = OneChannel(url)
     seasonUpdateMethod = lambda data: self.updateListWidget(
         data, self.ui.mySeasonListWidget)
     self.createWebRequestThread(seasonUpdateMethod,
                                 self.myLinkSite.getSeasons,
                                 listWidget=self.ui.mySeasonListWidget)
def decide(show):
    #search onechannel for show
    oc_result = OneChannel.searchSite(show)[0]
    print oc_result
    #search tvlinks
    tl_result = TVLinks.searchSite(show)[0]
    print tl_result
    #instanciate both objects passing in the second part of the result tuple, the link
    oc = OneChannel(oc_result[1])
    tl = TVLinks(tl_result[1])
    all_sites = dict()
    #season is the last season of the show
    season =oc.getSeasons()[-1]
    #for all episodes in that season
    for episode in oc.getEpisodes(season):
        for type in oc.getHostSiteTypes(season, episode):
            if "daclips" in type:
                print season, episode, "onechannel"
            if type in all_sites:
                all_sites[type] = all_sites[type] + 1
            else:
                all_sites[type] = 1
            print all_sites
    season =tl.getSeasons()[-1]
    for episode in tl.getEpisodes(season):
        for type in tl.getHostSiteTypes(season, episode):
            if "daclips" in type:
                print season, episode, "tvlinks"
            if type in all_sites:
                all_sites[type] = all_sites[type] + 1
            else:
                all_sites[type] = 1
            print all_sites
    
    sorted_sites =  sorted(all_sites.iteritems(), key=operator.itemgetter(1))
    sorted_sites.reverse()
    print sorted_sites
Esempio n. 5
0
 def handleRunQuery(self):
     self.myQuery = str(self.ui.mySearchLineEdit.text())
     if len(self.myQuery) > 0:
         self.ui.mySavePushButton.setEnabled(False)
         self.ui.myWatchPushButton.setEnabled(False)
         #create result depending on which linksite was checked
         if self.myAreResultsTvLinks:
             self.updateStatus("Searching TVLinks for %s" % (self.myQuery))
             self.createWebRequestThread(self.updateSearchResults, TVLinks.searchSite, self.myQuery, listWidget=self.ui.myResultsListWidget)
         else:
             self.updateStatus("Searching OneChannel for %s" % (self.myQuery))
             if self.prefetchedKey is None:
                 print "not prefetched key"
                 searchMethod = OneChannel.searchSite
             else:
                 print "using prefetched key"
                 searchMethod = lambda query: OneChannel.searchSite(query, self.prefetchedKey)
             self.createWebRequestThread(self.updateSearchResults, searchMethod, self.myQuery, listWidget=self.ui.myResultsListWidget)
Esempio n. 6
0
def decide(show):
    #search onechannel for show
    oc_result = OneChannel.searchSite(show)[0]
    print oc_result
    #search tvlinks
    tl_result = TVLinks.searchSite(show)[0]
    print tl_result
    #instanciate both objects passing in the second part of the result tuple, the link
    oc = OneChannel(oc_result[1])
    tl = TVLinks(tl_result[1])
    all_sites = dict()
    #season is the last season of the show
    season = oc.getSeasons()[-1]
    #for all episodes in that season
    for episode in oc.getEpisodes(season):
        for type in oc.getHostSiteTypes(season, episode):
            if "daclips" in type:
                print season, episode, "onechannel"
            if type in all_sites:
                all_sites[type] = all_sites[type] + 1
            else:
                all_sites[type] = 1
            print all_sites
    season = tl.getSeasons()[-1]
    for episode in tl.getEpisodes(season):
        for type in tl.getHostSiteTypes(season, episode):
            if "daclips" in type:
                print season, episode, "tvlinks"
            if type in all_sites:
                all_sites[type] = all_sites[type] + 1
            else:
                all_sites[type] = 1
            print all_sites

    sorted_sites = sorted(all_sites.iteritems(), key=operator.itemgetter(1))
    sorted_sites.reverse()
    print sorted_sites
Esempio n. 7
0
class JankflixForm(QtGui.QWidget):
    def __init__(self, parent=None):
        super(JankflixForm, self).__init__(parent)

        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.ui.mySearchLineEdit.returnPressed.connect(self.handleRunQuery)
        self.ui.my1ChannelRadioButton.clicked.connect(
            lambda: self.handleRadioButton("1channel"))
        self.ui.myTVLinksRadioButton.clicked.connect(
            lambda: self.handleRadioButton("tvlinks"))
        self.ui.myResultsListWidget.clicked.connect(self.handleChoseResult)
        self.ui.mySeasonListWidget.clicked.connect(self.handleChoseSeason)
        self.ui.myEpisodeListWidget.clicked.connect(self.handleChoseEpisode)
        self.ui.mySavePushButton.clicked.connect(self.handleSave)
        self.ui.myWatchPushButton.clicked.connect(self.handleOpen)
        self.ui.mySearchLineEdit.setFocus()

        self.myDownloadThread = None
        self.myWebRequestThread = None
        self.myFilename = None

        if self.ui.myTVLinksRadioButton.isChecked():
            self.myAreResultsTvLinks = True
        else:
            self.myAreResultsTvLinks = False
        # if not hasattr(self, "prefetchedKey") or self.prefetchedKey is not None:
        #     self.createWebRequestThread(self.setPrefetchedKey, OneChannel.prefetchSearchKey)
        self.setPrefetchedKey(None)
        self.pc = ProgressCancel(self, self.ui.myProgressCancelVerticalLayout)

    def setPrefetchedKey(self, key):
        self.prefetchedKey = key

    def createWebRequestThread(self, updateMethod, httpMethod, *args,
                               **kwargs):
        """
        A way to make web calls without blocking the gui thread.
        @param updateMethod: Method to be called when the result is available. Will be called with the result as an arg.
        @param httpMethod: Method to be called asynchronously. After this is done, updateMethod is called.
        @param args: Args to be fed into httpMethod
        @param kwargs: optional listWidget or textBrowser to insert elipses into to indicate loading
        """
        #the or is because both updateMethod and httpMethod can be either methods specified in the class
        #or lambdas specified in the calling method
        assert isinstance(updateMethod, types.FunctionType) or isinstance(updateMethod, types.MethodType), \
            ("type is actually %s", type(updateMethod))
        assert isinstance(httpMethod, types.FunctionType) or isinstance(httpMethod, types.MethodType) \
            or isinstance(httpMethod, functools.partial), ("type is actually %s", type(httpMethod))
        assert isinstance(args, tuple)
        #if any webrequest is running, terminate it and start this one instead
        lvwidg = "listWidget"
        tb = "textBrowser"
        if lvwidg in kwargs:
            listWidget = kwargs[lvwidg]
            assert isinstance(listWidget, QtGui.QListWidget)
            self.updateListWidget(["..."], listWidget)
        elif tb in kwargs:
            textBrowser = kwargs[tb]
            assert isinstance(textBrowser, QtGui.QTextBrowser)
            textBrowser.setText("...")

        if self.myWebRequestThread is not None:
            self.myWebRequestThread.terminate()
        wrThread = WebRequestThread(self, httpMethod, *args)
        self.connect(wrThread, wrThread.updateListSignal, updateMethod)
        self.myWebRequestThread = wrThread
        wrThread.start()

    def updateSearchResults(self, runQueryResult):
        assert isinstance(runQueryResult, list)
        assert len(runQueryResult) > 0
        for result in runQueryResult:
            assert isinstance(result, tuple)
            assert len(result) == 2
            assert isinstance(result[0], str)
            assert isinstance(result[1], str)

        data = [name_url[0] for name_url in runQueryResult]
        self.updateListWidget(data, self.ui.myResultsListWidget)
        self.myQueryResult = runQueryResult
        #automatically select first result regardless of the number of search results
        item = self.ui.myResultsListWidget.item(0)
        self.ui.myResultsListWidget.setItemSelected(item, True)
        self.handleChoseResult()

    def updateListWidget(self, data, listWidget):
        assert isinstance(listWidget, QtGui.QListWidget)
        assert isinstance(data, list)
        assert len(data) > 0

        listWidget.clear()
        for element in data:
            listWidget.addItem(str(element))

    def updateStatus(self, status):
        assert isinstance(status, str)

        self.ui.myStatusLabel.setText(status)

    def getFirstSelectedIndex(self, ListWidget):
        assert isinstance(ListWidget, QtGui.QListWidget)

        indecies = ListWidget.selectedIndexes()
        if len(indecies) > 0:
            #gets the row of the selected value
            resultIndex = indecies[0].row()
            return resultIndex

    def getFirstSelectedItem(self, listWidget):
        assert isinstance(listWidget, QtGui.QListWidget)

        index = self.getFirstSelectedIndex(listWidget)
        print "first selected index returns %d" % (index)
        if index is not None:
            return listWidget.item(index)

    def handleRadioButton(self, whichButton):
        assert isinstance(whichButton, str)

        self.ui.mySavePushButton.setEnabled(False)
        self.ui.myWatchPushButton.setEnabled(False)
        if whichButton == "tvlinks":
            self.myAreResultsTvLinks = True
        else:
            self.myAreResultsTvLinks = False
        self.handleRunQuery()

    def handleRunQuery(self):
        self.myQuery = str(self.ui.mySearchLineEdit.text())
        if len(self.myQuery) > 0:
            self.ui.mySavePushButton.setEnabled(False)
            self.ui.myWatchPushButton.setEnabled(False)
            #create result depending on which linksite was checked
            if self.myAreResultsTvLinks:
                self.updateStatus("Searching TVLinks for %s" % (self.myQuery))
                self.createWebRequestThread(
                    self.updateSearchResults,
                    TVLinks.searchSite,
                    self.myQuery,
                    listWidget=self.ui.myResultsListWidget)
            else:
                self.updateStatus("Searching OneChannel for %s" %
                                  (self.myQuery))
                if self.prefetchedKey is None:
                    print "not prefetched key"
                    searchMethod = OneChannel.searchSite
                else:
                    print "using prefetched key"
                    searchMethod = lambda query: OneChannel.searchSite(
                        query, self.prefetchedKey)
                self.createWebRequestThread(
                    self.updateSearchResults,
                    searchMethod,
                    self.myQuery,
                    listWidget=self.ui.myResultsListWidget)

    def handleChoseResult(self):
        index = self.getFirstSelectedIndex(self.ui.myResultsListWidget)
        if index is None:
            return
        self.ui.mySavePushButton.setEnabled(False)
        self.ui.myWatchPushButton.setEnabled(False)
        url = self.myQueryResult[index][1]
        #            instansiate myLinkSite with correct
        #            this avoids the condition where the radio
        #            button is changed after the fact because we
        #            are referencing myAreResultsTvLinks, rather
        #            than the radio button itself.
        self.updateStatus("Finding seasons. Please wait...")
        if self.myAreResultsTvLinks:
            self.myLinkSite = TVLinks(url)
        else:
            self.myLinkSite = OneChannel(url)
        seasonUpdateMethod = lambda data: self.updateListWidget(
            data, self.ui.mySeasonListWidget)
        self.createWebRequestThread(seasonUpdateMethod,
                                    self.myLinkSite.getSeasons,
                                    listWidget=self.ui.mySeasonListWidget)

    def handleChoseSeason(self):
        item = self.getFirstSelectedItem(self.ui.mySeasonListWidget)
        print "selected season %s" % (item.text())
        if item:
            self.ui.mySavePushButton.setEnabled(False)
            self.ui.myWatchPushButton.setEnabled(False)
            self.mySeasonChosen = int(item.text())
            self.updateEpisodes()

    def updateEpisodes(self):
        episodes = self.myLinkSite.getEpisodes(self.mySeasonChosen)
        episodeNames = self.myLinkSite.getEpisodeNames(self.mySeasonChosen)
        self.ui.myEpisodeListWidget.clear()
        for i in range(len(episodes)):
            if episodeNames:
                self.ui.myEpisodeListWidget.addItem(
                    "%d : %s" % (episodes[i], episodeNames[i]))
            else:
                self.ui.myEpisodeListWidget.addItem("%d" % (episodes[i]))
            #using setAccessibleDescription as a place to store the episode number because can't find something cleaner.
            self.ui.myEpisodeListWidget.item(i).setStatusTip(str(episodes[i]))
        self.updateStatus("Please select an episode to watch...")

    def handleChoseEpisode(self):
        item = self.getFirstSelectedItem(self.ui.myEpisodeListWidget)
        if item:
            self.myEpisodeChosen = int(item.statusTip())
            self.ui.mySavePushButton.setEnabled(True)
            self.ui.myWatchPushButton.setEnabled(True)
            self.createWebRequestThread(
                self.updateSummary,
                self.myLinkSite.getSummary,
                self.mySeasonChosen,
                self.myEpisodeChosen,
                textBrowser=self.ui.mySummaryTextBrowser)

    def updateSummary(self, summary):
        self.ui.mySummaryTextBrowser.setText(summary)

    def handleSave(self):
        self.createWebRequestThread(self.doSave,
                                    hostsitepicker.pickFromLinkSite,
                                    self.myLinkSite, self.mySeasonChosen,
                                    self.myEpisodeChosen)

    def doSave(self, hostSite):
        if hostSite:
            metadata = hostSite.getMetadata()
            videoURL = hostSite.getVideo()
            filename = "%sS%sE%s.%s" % (self.myQuery, str(
                self.mySeasonChosen).zfill(2), str(
                    self.myEpisodeChosen).zfill(2), metadata["extension"])
            filename = str(
                QtGui.QFileDialog.getSaveFileName(self, "Save File",
                                                  "./" + filename))
            #            processs, status = downloadmanager.startDownloads([(videoURL, filename)])
            # self.myDownloadThread = self.createDownloadThread(videoURL, filename)
            self.pc.addFile(videoURL, filename)
        else:
            self.updateStatus(
                "Couldn't pick a host site. Try a different link site.")

    def handleOpen(self):
        self.createWebRequestThread(self.doOpen,
                                    hostsitepicker.pickFromLinkSite,
                                    self.myLinkSite, self.mySeasonChosen,
                                    self.myEpisodeChosen)

    def doOpen(self, hostSite):
        if hostSite:
            metadata = hostSite.getMetadata()
            videoURL = hostSite.getVideo()
            filename = "%sS%sE%s.%s" % (self.myQuery, str(
                self.mySeasonChosen).zfill(2), str(
                    self.myEpisodeChosen).zfill(2), metadata["extension"])
            #            processs, status = downloadmanager.startDownloads([(videoURL, filename)])
            # self.myDownloadThread = self.createDownloadThread(videoURL, filename)
            self.pc.addFile(videoURL, filename)
            self.myFilename = filename
            self.waitForFile(filename)
            #opens arbitrary file in a platform-independent way.
            if sys.platform.startswith('darwin'):
                subprocess.call(('open', filename))
            elif os.name == 'nt':
                #                os.startfile(filename) #@UndefinedVariable
                #alternatively, we could probably call:
                subprocess.call(('start', filename))
            elif os.name == 'posix':
                subprocess.call(('xdg-open', filename))
        else:
            self.updateStatus(
                "Couldn't pick a host site. Try a different link site.")

    def waitForFile(self, filename):
        assert isinstance(filename, str)

        self.updateStatus("Waiting for file to start downloading...")
        for _ in range(50):
            if os.path.isfile(filename):
                break
            else:
                time.sleep(.2)

    def closeEvent(self, event):
        self.updateStatus("Exiting...")
        if self.myDownloadThread:
            self.myDownloadThread.terminate()
        if self.myFilename and os.path.isfile(self.myFilename):
            os.remove(self.myFilename)
        event.accept()
Esempio n. 8
0
def main():

    parser = argparse.ArgumentParser(
                    description = 'Jankflix - A jankier way to watch things!')
    parser.add_argument('query', type = str, help = 'A show you want to watch',
                        nargs = "?")
    parser.add_argument('-s', dest = 'season', type = int, 
                        help = 'season to watch')
    parser.add_argument('-e', dest = 'episode', type = int, 
                        help = 'episode to watch')
    parser.add_argument('-c', dest = 'command', type = str, 
                        help = 'command to run when the video starts downloading')
    args = parser.parse_args()
    query = args.query
    season = args.season
    episode = args.episode
    command = args.command
    while True:
        if not query:
            query = raw_input("What show do you want to watch: ")
        search_result = OneChannel.searchSite(query)
        if len(search_result) == 0:
            print "Search did not return any results."
            query = None
        else:
            break
    for i in range(len(search_result)):
        title, link = search_result[i]
        print "%i : %s    (%s)" % (i, title, link)
    if len(search_result) > 1:
        selnum = get_int_input("Which one do you want to watch: ", 
                               0, len(search_result) - 1)
    else:
        print "Automatically choosing %s" % (search_result[0][0])
        selnum = 0

    title, link = search_result[selnum]
    print "Accessing show page"
    oc = OneChannel(link)
    seasons = oc.getSeasons()
    if season and season not in seasons:
        print "Season does not exist. Please choose another."
        season = None
    if not season:
        print "Seasons: ", str(seasons)[1:-1]
        season = get_int_input("Which season do you want to watch: ", 
                               int(min(seasons)), int(max(seasons)))
        #this assumes that between the min and max of the season numbers, 
        #it is completely filled. 
    print "Selecting season %d" % (season)

    episodes = oc.getEpisodes(season)

    names = oc.getEpisodeNames(season)

    if episode and episode not in episodes:
        print "Episode does not exist. Please choose another."
        episode = None
    if not episode:
        #TODO: this doesn't work. Need to cast array to int to run min on it. 
        for i in range(len(episodes)):
            print episodes[i], ":", names[i]
        episode = get_int_input("Which episode do you want to watch: ", 
                                int(min(episodes)), int(max(episodes)))
        #this assumes that between the min and max of the season numbers,
        #it is completely filled. 
    print "Selecting episode %d" % (episode)

    if not command :
        save_or_run = get_int_input(
                    "Do you want to (0) save or (1) run the episode: ", 0, 1)
        if save_or_run == 1:
            command = raw_input("Run with which program? (vlc): ")
            if command == "":
                command = "vlc"

    print "Getting host site"
    host_site = hostsitepicker.pickFromLinkSite(oc, season, episode)
    metadata = host_site.getMetadata()
    video_url = host_site.getVideo()
    filename = "%sS%sE%s.%s" % (query, str(season).zfill(2), 
                                str(episode).zfill(2), metadata["extension"])
    if command:
        processs, status = downloadmanager.start_downloads([(video_url, 
                                                             filename)])
        atexit.register(onexit, proc = processs[0], rmFile = filename)

        for i in range(30):
            if os.path.isfile(filename) and os.stat(filename).st_size > 1000:
                break
            else:
                time.sleep(.2)
        subprocess.call([command, filename])
        processs[0].terminate()
    else:
        processs, status = downloadmanager.start_downloads([(video_url, 
                                                             filename)])
        atexit.register(onexit, proc = processs[0])
        while processs[0].is_alive:
            print status[0].get(True)
Esempio n. 9
0
class TestOneChannel(unittest.TestCase, TestLinkSite):
    link_site = OneChannel(
        "http://www.1channel.ch/watch-9583-Avatar-The-Last-Airbender")
Esempio n. 10
0
class OneChannelPickingTest(unittest.TestCase, TestHostSitePicker):
    link_site = OneChannel(
        "http://www.1channel.ch/watch-9583-Avatar-The-Last-Airbender")
Esempio n. 11
0
class JankflixForm(QtGui.QWidget):
    def __init__(self, parent=None):
        super(JankflixForm, self).__init__(parent)

        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.ui.mySearchLineEdit.returnPressed.connect(self.handleRunQuery)
        self.ui.my1ChannelRadioButton.clicked.connect(lambda: self.handleRadioButton("1channel"))
        self.ui.myTVLinksRadioButton.clicked.connect(lambda: self.handleRadioButton("tvlinks"))
        self.ui.myResultsListWidget.clicked.connect(self.handleChoseResult)
        self.ui.mySeasonListWidget.clicked.connect(self.handleChoseSeason)
        self.ui.myEpisodeListWidget.clicked.connect(self.handleChoseEpisode)
        self.ui.mySavePushButton.clicked.connect(self.handleSave)
        self.ui.myWatchPushButton.clicked.connect(self.handleOpen)
        self.ui.mySearchLineEdit.setFocus()

        self.myDownloadThread = None
        self.myWebRequestThread = None
        self.myFilename = None

        if self.ui.myTVLinksRadioButton.isChecked():
            self.myAreResultsTvLinks = True
        else:
            self.myAreResultsTvLinks = False
        # if not hasattr(self, "prefetchedKey") or self.prefetchedKey is not None:
        #     self.createWebRequestThread(self.setPrefetchedKey, OneChannel.prefetchSearchKey)
        self.setPrefetchedKey(None)
        self.pc = ProgressCancel(self, self.ui.myProgressCancelVerticalLayout)

    def setPrefetchedKey(self, key):
        self.prefetchedKey = key

    def createWebRequestThread(self, updateMethod, httpMethod, *args, **kwargs):
        """
        A way to make web calls without blocking the gui thread.
        @param updateMethod: Method to be called when the result is available. Will be called with the result as an arg.
        @param httpMethod: Method to be called asynchronously. After this is done, updateMethod is called.
        @param args: Args to be fed into httpMethod
        @param kwargs: optional listWidget or textBrowser to insert elipses into to indicate loading
        """
        #the or is because both updateMethod and httpMethod can be either methods specified in the class
        #or lambdas specified in the calling method
        assert isinstance(updateMethod, types.FunctionType) or isinstance(updateMethod, types.MethodType), \
            ("type is actually %s", type(updateMethod))
        assert isinstance(httpMethod, types.FunctionType) or isinstance(httpMethod, types.MethodType) \
            or isinstance(httpMethod, functools.partial), ("type is actually %s", type(httpMethod))
        assert isinstance(args, tuple)
        #if any webrequest is running, terminate it and start this one instead
        lvwidg = "listWidget"
        tb = "textBrowser"
        if lvwidg in kwargs:
            listWidget = kwargs[lvwidg]
            assert isinstance(listWidget, QtGui.QListWidget)
            self.updateListWidget(["..."], listWidget)
        elif tb in kwargs:
            textBrowser = kwargs[tb]
            assert isinstance(textBrowser, QtGui.QTextBrowser)
            textBrowser.setText("...")

        if self.myWebRequestThread is not None:
            self.myWebRequestThread.terminate()
        wrThread = WebRequestThread(self, httpMethod, *args)
        self.connect(wrThread, wrThread.updateListSignal, updateMethod)
        self.myWebRequestThread = wrThread
        wrThread.start()

    def updateSearchResults(self, runQueryResult):
        assert isinstance(runQueryResult, list)
        assert len(runQueryResult) > 0
        for result in runQueryResult:
            assert isinstance(result, tuple)
            assert len(result) == 2
            assert isinstance(result[0], str)
            assert isinstance(result[1], str)

        data = [name_url[0] for name_url in runQueryResult]
        self.updateListWidget(data, self.ui.myResultsListWidget)
        self.myQueryResult = runQueryResult
        #automatically select first result regardless of the number of search results
        item = self.ui.myResultsListWidget.item(0)
        self.ui.myResultsListWidget.setItemSelected(item, True)
        self.handleChoseResult()

    def updateListWidget(self, data, listWidget):
        assert isinstance(listWidget, QtGui.QListWidget)
        assert isinstance(data, list)
        assert len(data) > 0

        listWidget.clear()
        for element in data:
            listWidget.addItem(str(element))

    def updateStatus(self, status):
        assert isinstance(status, str)

        self.ui.myStatusLabel.setText(status)

    def getFirstSelectedIndex(self, ListWidget):
        assert isinstance(ListWidget, QtGui.QListWidget)

        indecies = ListWidget.selectedIndexes()
        if len(indecies) > 0:
            #gets the row of the selected value
            resultIndex = indecies[0].row()
            return resultIndex

    def getFirstSelectedItem(self, listWidget):
        assert isinstance(listWidget, QtGui.QListWidget)

        index = self.getFirstSelectedIndex(listWidget)
        print "first selected index returns %d" % (index)
        if index is not None:
            return listWidget.item(index)

    def handleRadioButton(self, whichButton):
        assert isinstance(whichButton, str)

        self.ui.mySavePushButton.setEnabled(False)
        self.ui.myWatchPushButton.setEnabled(False)
        if whichButton == "tvlinks":
            self.myAreResultsTvLinks = True
        else:
            self.myAreResultsTvLinks = False
        self.handleRunQuery()

    def handleRunQuery(self):
        self.myQuery = str(self.ui.mySearchLineEdit.text())
        if len(self.myQuery) > 0:
            self.ui.mySavePushButton.setEnabled(False)
            self.ui.myWatchPushButton.setEnabled(False)
            #create result depending on which linksite was checked
            if self.myAreResultsTvLinks:
                self.updateStatus("Searching TVLinks for %s" % (self.myQuery))
                self.createWebRequestThread(self.updateSearchResults, TVLinks.searchSite, self.myQuery, listWidget=self.ui.myResultsListWidget)
            else:
                self.updateStatus("Searching OneChannel for %s" % (self.myQuery))
                if self.prefetchedKey is None:
                    print "not prefetched key"
                    searchMethod = OneChannel.searchSite
                else:
                    print "using prefetched key"
                    searchMethod = lambda query: OneChannel.searchSite(query, self.prefetchedKey)
                self.createWebRequestThread(self.updateSearchResults, searchMethod, self.myQuery, listWidget=self.ui.myResultsListWidget)

    def handleChoseResult(self):
        index = self.getFirstSelectedIndex(self.ui.myResultsListWidget)
        if index is None:
            return
        self.ui.mySavePushButton.setEnabled(False)
        self.ui.myWatchPushButton.setEnabled(False)
        url = self.myQueryResult[index][1]
        #            instansiate myLinkSite with correct
        #            this avoids the condition where the radio
        #            button is changed after the fact because we
        #            are referencing myAreResultsTvLinks, rather
        #            than the radio button itself.
        self.updateStatus("Finding seasons. Please wait...")
        if self.myAreResultsTvLinks:
            self.myLinkSite = TVLinks(url)
        else:
            self.myLinkSite = OneChannel(url)
        seasonUpdateMethod = lambda data: self.updateListWidget(data, self.ui.mySeasonListWidget)
        self.createWebRequestThread(seasonUpdateMethod, self.myLinkSite.getSeasons, listWidget=self.ui.mySeasonListWidget)

    def handleChoseSeason(self):
        item = self.getFirstSelectedItem(self.ui.mySeasonListWidget)
        print "selected season %s" % (item.text())
        if item:
            self.ui.mySavePushButton.setEnabled(False)
            self.ui.myWatchPushButton.setEnabled(False)
            self.mySeasonChosen = int(item.text())
            self.updateEpisodes()

    def updateEpisodes(self):
        episodes = self.myLinkSite.getEpisodes(self.mySeasonChosen)
        episodeNames = self.myLinkSite.getEpisodeNames(self.mySeasonChosen)
        self.ui.myEpisodeListWidget.clear()
        for i in range(len(episodes)):
            if episodeNames:
                self.ui.myEpisodeListWidget.addItem("%d : %s" % (episodes[i], episodeNames[i]))
            else:
                self.ui.myEpisodeListWidget.addItem("%d" % (episodes[i]))
            #using setAccessibleDescription as a place to store the episode number because can't find something cleaner.
            self.ui.myEpisodeListWidget.item(i).setStatusTip(str(episodes[i]))
        self.updateStatus("Please select an episode to watch...")

    def handleChoseEpisode(self):
        item = self.getFirstSelectedItem(self.ui.myEpisodeListWidget)
        if item:
            self.myEpisodeChosen = int(item.statusTip())
            self.ui.mySavePushButton.setEnabled(True)
            self.ui.myWatchPushButton.setEnabled(True)
            self.createWebRequestThread(self.updateSummary, self.myLinkSite.getSummary, self.mySeasonChosen, self.myEpisodeChosen, textBrowser=self.ui.mySummaryTextBrowser)

    def updateSummary(self, summary):
        self.ui.mySummaryTextBrowser.setText(summary)

    def handleSave(self):
        self.createWebRequestThread(self.doSave, hostsitepicker.pickFromLinkSite, self.myLinkSite, self.mySeasonChosen, self.myEpisodeChosen)

    def doSave(self, hostSite):
        if hostSite:
            metadata = hostSite.getMetadata()
            videoURL = hostSite.getVideo()
            filename = "%sS%sE%s.%s" % (
                self.myQuery, str(self.mySeasonChosen).zfill(2), str(self.myEpisodeChosen).zfill(2),
                metadata["extension"])
            filename = str(QtGui.QFileDialog.getSaveFileName(self, "Save File", "./" + filename))
            #            processs, status = downloadmanager.startDownloads([(videoURL, filename)])
            # self.myDownloadThread = self.createDownloadThread(videoURL, filename)
            self.pc.addFile(videoURL,filename)
        else:
            self.updateStatus("Couldn't pick a host site. Try a different link site.")

    def handleOpen(self):
        self.createWebRequestThread(self.doOpen, hostsitepicker.pickFromLinkSite, self.myLinkSite, self.mySeasonChosen, self.myEpisodeChosen)

    def doOpen(self, hostSite):
        if hostSite:
            metadata = hostSite.getMetadata()
            videoURL = hostSite.getVideo()
            filename = "%sS%sE%s.%s" % (
                self.myQuery, str(self.mySeasonChosen).zfill(2), str(self.myEpisodeChosen).zfill(2),
                metadata["extension"])
            #            processs, status = downloadmanager.startDownloads([(videoURL, filename)])
            # self.myDownloadThread = self.createDownloadThread(videoURL, filename)
            self.pc.addFile(videoURL,filename)
            self.myFilename = filename
            self.waitForFile(filename)
            #opens arbitrary file in a platform-independent way. 
            if sys.platform.startswith('darwin'):
                subprocess.call(('open', filename))
            elif os.name == 'nt':
            #                os.startfile(filename) #@UndefinedVariable
                #alternatively, we could probably call:
                subprocess.call(('start', filename))
            elif os.name == 'posix':
                subprocess.call(('xdg-open', filename))
        else:
            self.updateStatus("Couldn't pick a host site. Try a different link site.")

    def waitForFile(self, filename):
        assert isinstance(filename, str)

        self.updateStatus("Waiting for file to start downloading...")
        for _ in range(50):
            if os.path.isfile(filename):
                break
            else:
                time.sleep(.2)

    def closeEvent(self, event):
        self.updateStatus("Exiting...")
        if self.myDownloadThread:
            self.myDownloadThread.terminate()
        if self.myFilename and os.path.isfile(self.myFilename):
            os.remove(self.myFilename)
        event.accept()