Пример #1
0
class CreateTorrent(wx.Dialog):
    def __init__(self,
                 parent,
                 configfile,
                 fileconfigfile,
                 suggestedTrackers,
                 toChannel=False):
        wx.Dialog.__init__(self,
                           parent,
                           -1,
                           'Create a .torrent',
                           size=(600, 200))
        self.guiutility = GUIUtility.getInstance()
        self.toChannel = toChannel

        vSizer = wx.BoxSizer(wx.VERTICAL)

        header = wx.StaticText(self, -1, 'Browse for a file or files')
        _set_font(header, fontweight=wx.FONTWEIGHT_BOLD)
        vSizer.Add(header, 0, wx.EXPAND | wx.BOTTOM, 3)

        self.locationText = StaticText(self, -1, '')
        vSizer.Add(self.locationText, 0, wx.EXPAND | wx.BOTTOM, 3)

        browseButton = wx.Button(self, -1, 'Browse')
        browseButton.Bind(wx.EVT_BUTTON, self.OnBrowse)

        browseDirButton = wx.Button(self, -1, 'Browse for a Directory')
        browseDirButton.Bind(wx.EVT_BUTTON, self.OnBrowseDir)

        hSizer = wx.BoxSizer(wx.HORIZONTAL)
        hSizer.Add(browseButton)
        hSizer.Add(browseDirButton)
        vSizer.Add(hSizer, 0, wx.ALIGN_RIGHT | wx.BOTTOM, 3)

        #self.recursive = wx.CheckBox(self, -1, 'Include all subdirectories')
        #self.recursive.Bind(wx.EVT_CHECKBOX, self.OnRecursive)
        #vSizer.Add(self.recursive, 0, wx.ALIGN_RIGHT|wx.BOTTOM, 3)

        vSizer.Add(wx.StaticLine(self, -1), 0,
                   wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)

        header = wx.StaticText(self, -1, '.Torrent details')
        _set_font(header, fontweight=wx.FONTWEIGHT_BOLD)
        vSizer.Add(header, 0, wx.EXPAND | wx.BOTTOM, 3)

        self.foundFilesText = StaticText(
            self, -1, 'Please select a file or files first')
        vSizer.Add(self.foundFilesText, 0, wx.EXPAND | wx.BOTTOM, 3)

        self.combineRadio = wx.RadioButton(
            self,
            -1,
            'Combine files into a single .torrent',
            style=wx.RB_GROUP)
        self.combineRadio.Bind(wx.EVT_RADIOBUTTON, self.OnCombine)
        self.combineRadio.Enable(False)

        self.sepRadio = wx.RadioButton(
            self, -1, 'Create separate .torrent for every file')
        self.sepRadio.Bind(wx.EVT_RADIOBUTTON, self.OnCombine)
        self.sepRadio.Enable(False)

        vSizer.Add(self.combineRadio, 0, wx.EXPAND | wx.BOTTOM, 3)
        vSizer.Add(self.sepRadio, 0, wx.EXPAND | wx.BOTTOM, 3)

        self.specifiedName = wx.TextCtrl(self, -1, '')
        self.specifiedName.Enable(False)
        hSizer = wx.BoxSizer(wx.HORIZONTAL)
        hSizer.Add(wx.StaticText(self, -1, 'Specify a name'), 0,
                   wx.ALIGN_CENTER_VERTICAL)
        hSizer.Add(self.specifiedName, 1, wx.EXPAND)
        vSizer.Add(hSizer, 0, wx.EXPAND | wx.BOTTOM, 3)

        vSizer.Add(StaticText(self, -1, 'Trackers'))
        self.trackerList = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE)
        self.trackerList.SetMinSize((500, -1))

        self.trackerHistory = wx.FileHistory(10)
        self.config = wx.FileConfig(appName="Tribler",
                                    localFilename=configfile)
        self.trackerHistory.Load(self.config)

        if self.trackerHistory.GetCount() > 0:
            trackers = [
                self.trackerHistory.GetHistoryFile(i)
                for i in range(self.trackerHistory.GetCount())
            ]
            if len(trackers) < len(suggestedTrackers):
                trackers.extend(suggestedTrackers[:len(suggestedTrackers) -
                                                  len(trackers)])
        else:
            trackers = suggestedTrackers

        for tracker in trackers:
            self.trackerList.AppendText(tracker + "\n")

        vSizer.Add(self.trackerList, 0, wx.EXPAND | wx.BOTTOM, 3)

        vSizer.Add(StaticText(self, -1, 'Comment'))
        self.commentList = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE)
        vSizer.Add(self.commentList, 0, wx.EXPAND, 3)

        vSizer.Add(wx.StaticLine(self, -1), 0,
                   wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10)

        header = wx.StaticText(self, -1, 'Advanced options')
        _set_font(header, fontweight=wx.FONTWEIGHT_BOLD)
        vSizer.Add(header, 0, wx.EXPAND | wx.BOTTOM | wx.TOP, 3)

        abbrev_mb = " " + self.guiutility.utility.lang.get('MB')
        abbrev_kb = " " + self.guiutility.utility.lang.get('KB')
        piece_choices = [
            self.guiutility.utility.lang.get('automatic'), '4' + abbrev_mb,
            '2' + abbrev_mb, '1' + abbrev_mb, '512' + abbrev_kb,
            '256' + abbrev_kb, '128' + abbrev_kb, '64' + abbrev_kb,
            '32' + abbrev_kb
        ]
        self.pieceChoice = wx.Choice(self, -1, choices=piece_choices)
        self.pieceChoice.SetSelection(0)
        hSizer = wx.BoxSizer(wx.HORIZONTAL)
        hSizer.Add(StaticText(self, -1, 'Piecesize'), 1)
        hSizer.Add(self.pieceChoice)
        vSizer.Add(hSizer, 0, wx.EXPAND | wx.BOTTOM, 3)

        vSizer.Add(StaticText(self, -1, 'Webseed'))
        self.webSeed = wx.TextCtrl(self, -1,
                                   'Please select a file or files first')
        self.webSeed.Enable(False)
        vSizer.Add(self.webSeed, 0, wx.EXPAND | wx.BOTTOM, 3)

        cancel = wx.Button(self, wx.ID_CANCEL)
        cancel.Bind(wx.EVT_BUTTON, self.OnCancel)

        create = wx.Button(self, wx.ID_OK, 'Create .torrent(s)')
        create.Bind(wx.EVT_BUTTON, self.OnOk)

        bSizer = wx.StdDialogButtonSizer()
        bSizer.AddButton(cancel)
        bSizer.AddButton(create)
        bSizer.Realize()
        vSizer.Add(bSizer, 0, wx.EXPAND)

        sizer = wx.BoxSizer()
        sizer.Add(vSizer, 1, wx.EXPAND | wx.ALL, 10)
        self.SetSizerAndFit(sizer)

        self.selectedPaths = []
        self.createdTorrents = []
        self.cancelEvent = Event()

        self.filehistory = wx.FileHistory(1)
        self.fileconfig = wx.FileConfig(appName="Tribler",
                                        localFilename=fileconfigfile)
        self.filehistory.Load(self.fileconfig)

        if self.filehistory.GetCount() > 0:
            self.latestFile = self.filehistory.GetHistoryFile(0)
        else:
            self.latestFile = ''
        self.paths = None

    def OnBrowse(self, event):
        dlg = wx.FileDialog(self,
                            "Please select the file(s).",
                            style=wx.FD_OPEN | wx.FD_MULTIPLE,
                            defaultDir=self.latestFile)
        if dlg.ShowModal() == wx.ID_OK:
            filenames = dlg.GetPaths()
            dlg.Destroy()

            self._browsePaths(filenames)
        else:
            dlg.Destroy()

    def OnBrowseDir(self, event):
        dlg = wx.DirDialog(self,
                           "Please a directory.",
                           style=wx.DD_DIR_MUST_EXIST,
                           defaultPath=self.latestFile)
        if dlg.ShowModal() == wx.ID_OK:
            filenames = [dlg.GetPath()]
            dlg.Destroy()

            self._browsePaths(filenames)
        else:
            dlg.Destroy()

    def OnRecursive(self, event):
        self._browsePaths()

    def OnCombine(self, event=None):
        combine = self.combineRadio.GetValue()
        self.specifiedName.Enable(False)
        if combine:
            path = ''

            nrFiles = len(
                [file for file in self.selectedPaths if os.path.isfile(file)])
            if nrFiles > 1:
                self.specifiedName.Enable(True)
                path = os.path.abspath(os.path.commonprefix(
                    self.selectedPaths))

            elif nrFiles > 0:
                path = self.selectedPaths[0]

            _, name = os.path.split(path)
            self.specifiedName.SetValue(name)

    def OnOk(self, event):
        #            if self.specifyNames.GetValue():
        #                dlg = wx.Dialog(self, -1, 'Please correct the names for the torrents.', size=(750,450))
        #                sizer = wx.BoxSizer(wx.VERTICAL)
        #                header = wx.StaticText(dlg, -1, 'Please modify the names for the .torrents.')
        #
        #                _set_font(header, fontweight=wx.FONTWEIGHT_BOLD)
        #                sizer.Add(header, 0, wx.EXPAND|wx.BOTTOM, 3)
        #
        #                flexSizer =  wx.FlexGridSizer(2,2,3,3)
        #                controls = []
        #                for name in names:
        #                    flexSizer.Add(wx.StaticText(dlg, -1, name), 0, wx.ALIGN_CENTER_VERTICAL)
        #                    control = wx.TextCtrl(dlg,-1, name)
        #                    control.SetMinSize((300,-1))
        #                    flexSizer.Add(control, 1, wx.EXPAND)
        #                    controls.append(control)
        #
        #                sizer.Add(flexSizer, 1, wx.EXPAND|wx.BOTTOM, 3)
        #
        #                cancel = wx.Button(dlg, wx.ID_CANCEL)
        #                ok = wx.Button(dlg, wx.ID_OK)
        #
        #                bSizer = wx.StdDialogButtonSizer()
        #                bSizer.AddButton(cancel)
        #                bSizer.AddButton(ok)
        #                bSizer.Realize()
        #                sizer.Add(bSizer, 0, wx.EXPAND|wx.BOTTOM, 3)
        #
        #                bsizer = wx.BoxSizer()
        #                bsizer.Add(sizer, 1, wx.EXPAND|wx.ALL, 10)
        #                dlg.SetSizerAndFit(bsizer)
        #
        #                if dlg.ShowModal() == wx.ID_OK:
        #                    for i, control in enumerate(controls):
        #                        names[i] = control.GetValue()
        #                    dlg.Destroy()
        #                else:
        #                    dlg.Destroy()
        #                    return

        max = 1 if self.combineRadio.GetValue() else len(self.selectedPaths)
        if self.toChannel:
            dlg = wx.MessageDialog(
                self,
                "This will add %d new .torrents to this Channel.\nDo you want to continue?"
                % max,
                "Are you sure?",
                style=wx.YES_NO | wx.ICON_QUESTION)
        else:
            dlg = wx.MessageDialog(
                self,
                "This will create %d new .torrents.\nDo you want to continue?"
                % max,
                "Are you sure?",
                style=wx.YES_NO | wx.ICON_QUESTION)

        if dlg.ShowModal() == wx.ID_YES:
            dlg.Destroy()

            params = {}
            params['comment'] = self.commentList.GetValue()
            params['created by'] = '%s version: %s' % (
                self.guiutility.utility.lang.get('title'),
                self.guiutility.utility.lang.get('version'))

            trackers = self.trackerList.GetValue()
            trackers = [tracker for tracker in trackers.split('\n') if tracker]

            for tracker in trackers:
                self.trackerHistory.AddFileToHistory(tracker)
            self.trackerHistory.Save(self.config)
            self.config.Flush()

            if len(self.selectedPaths) > 1:
                basedir = os.path.commonprefix(self.selectedPaths)
            else:
                basedir = os.path.dirname(self.selectedPaths[0])
            self.filehistory.Save(self.fileconfig)
            self.fileconfig.Flush()

            params['announce'] = trackers[0]
            params['announce-list'] = [trackers]

            if self.webSeed.GetValue():
                params['urllist'] = [self.webSeed.GetValue()]

            params['nodes'] = False
            params['httpseeds'] = False
            params['encoding'] = False
            params['makehash_md5'] = False
            params['makehash_crc32'] = False
            params['makehash_sha1'] = True
            params['createmerkletorrent'] = False
            params['torrentsigkeypairfilename'] = False
            params['thumb'] = False

            piece_length_list = [
                0, 2**22, 2**21, 2**20, 2**19, 2**18, 2**17, 2**16, 2**15
            ]
            if self.pieceChoice.GetSelection() != wx.NOT_FOUND:
                params['piece length'] = piece_length_list[
                    self.pieceChoice.GetSelection()]
            else:
                params['piece length'] = 0

            def do_gui():
                if self.cancelEvent.isSet():
                    self.OnCancel(event)
                else:
                    self.EndModal(wx.ID_OK)

            def create_torrents():
                try:
                    if self.combineRadio.GetValue():
                        params['name'] = self.specifiedName.GetValue()
                        make_meta_file(self.selectedPaths, params,
                                       self.cancelEvent, None,
                                       self._torrentCreated)
                    else:
                        for path in self.selectedPaths:
                            if os.path.isfile(path):
                                make_meta_file([path], params,
                                               self.cancelEvent, None,
                                               self._torrentCreated)
                except:
                    print_exc()

                wx.CallAfter(do_gui)

            def start():
                if self.combineRadio.GetValue():
                    self.progressDlg = wx.ProgressDialog(
                        "Creating new .torrents",
                        "Please wait while Tribler is creating your .torrents.\nThis could take a while due to creating the required hashes.",
                        maximum=max,
                        parent=self,
                        style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE)
                else:
                    self.progressDlg = wx.ProgressDialog(
                        "Creating new .torrents",
                        "Please wait while Tribler is creating your .torrents.\nThis could take a while due to creating the required hashes.",
                        maximum=max,
                        parent=self,
                        style=wx.PD_CAN_ABORT | wx.PD_APP_MODAL
                        | wx.PD_ELAPSED_TIME | wx.PD_AUTO_HIDE)
                self.progressDlg.Pulse()
                self.progressDlg.cur = 0

                self.guiserver = GUITaskQueue.getInstance()
                self.guiserver.add_task(create_torrents)

            if params['piece length']:
                total_size = 0
                if self.combineRadio.GetValue():
                    for path in self.selectedPaths:
                        total_size += os.path.getsize(path)
                else:
                    for path in self.selectedPaths:
                        total_size = max(total_size, os.path.getsize(path))

                nrPieces = total_size / params['piece length']
                if nrPieces > 2500:
                    dlg2 = wx.MessageDialog(
                        self,
                        "The selected piecesize will cause a torrent to have %d pieces.\nThis is more than the recommended max 2500 pieces.\nDo you want to continue?"
                        % nrPieces,
                        "Are you sure?",
                        style=wx.YES_NO | wx.ICON_QUESTION)
                    if dlg2.ShowModal() == wx.ID_YES:
                        start()
                    dlg2.Destroy()

                else:
                    start()
            else:
                start()
        else:
            dlg.Destroy()

    def OnCancel(self, event):
        self.EndModal(wx.ID_CANCEL)

    def _browsePaths(self, paths=None):
        if paths:
            self.paths = paths
        else:
            paths = self.paths

        if paths:
            label = ";".join(paths)
            self.locationText.SetLabel(label)

            if os.path.isdir(paths[0]):

                def addDir(path, recursive=False):
                    paths = [path]

                    for file in os.listdir(path):
                        absfile = os.path.join(path, file)

                        if os.path.isfile(absfile):
                            if file.lower().endswith('.torrent') or file.lower(
                            ).endswith('thumbs.db'):
                                continue
                            paths.append(absfile)

                        elif os.path.isdir(absfile) and recursive:
                            paths.extend(addDir(absfile, recursive))

                    return paths

                paths = addDir(paths[0], False)  #self.recursive.GetValue())

            self.selectedPaths = paths
            nrFiles = len([file for file in paths if os.path.isfile(file)])
            self.foundFilesText.SetLabel('Selected %d files' % nrFiles)

            if nrFiles == 1:
                self.webSeed.Enable(True)
                self.webSeed.SetValue('')
            else:
                self.webSeed.SetValue(
                    'Webseed will only work for a single file.')
                self.webSeed.Enable(False)

            self.combineRadio.Enable(nrFiles > 0)
            self.sepRadio.Enable(nrFiles > 1)

            self.combineRadio.SetValue(nrFiles == 1)
            self.sepRadio.SetValue(nrFiles > 1)

            self.OnCombine()

            self.Layout()

    @forceWxThread
    def _torrentCreated(self, path, correctedfilename, torrentfilename):
        self.progressDlg.cur += 1
        keepGoing, _ = self.progressDlg.Update(self.progressDlg.cur)
        if not keepGoing:
            self.cancelEvent.Set()

        self.createdTorrents.append((path, correctedfilename, torrentfilename))