#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Written by Bram Cohen
# Modified to include auto piece size setting by d0c 54v4g3
# see LICENSE.txt for license information
from sys import argv,version
from BitTorrent.btcompletedir import completedir
from threading import Event,Thread
from os.path import join
import wx
from traceback import print_exc
wxEVT_INVOKE = wx.NewEventType()
def EVT_INVOKE(win, func):
win.Connect(-1, -1, wxEVT_INVOKE, func)
class InvokeEvent(wx.PyEvent):
def __init__(self, func, args, kwargs):
wx.PyEvent.__init__(self)
self.SetEventType(wxEVT_INVOKE)
self.func = func
self.args = args
self.kwargs = kwargs
class DropTarget(wx.FileDropTarget):
def __init__(self, window):
wx.FileDropTarget.__init__(self)
self.win = window
def OnDropFiles(self, x, y, filenames):
for file in filenames:
files = self.win.dirCtl.GetLabel()
if files != '':
self.win.dirCtl.SetLabel("%s;%s" % (files, file))
else:
self.win.dirCtl.SetLabel(file)
class CreateTorrentDlg(wx.Frame):
def __init__(self, parent=None, btconfig=None, pos=wx.DefaultPosition, addtorrentfunc=None):
wx.Frame.__init__(self, parent, -1, _("Create a Torrent"), size = wx.Size(400, 300),
pos=pos)
self.AddTorrent = addtorrentfunc
panel = wx.Panel(self, -1)
dt = DropTarget(self)
self.SetDropTarget(dt)
gridSizer = wx.FlexGridSizer(cols = 1, vgap = 8, hgap = 8)
gridSizer.AddGrowableCol(0)
self.dirCtl = wx.TextCtrl(panel, -1, '')
tt = wx.ToolTip(_("Hint: You can drag and drop files here"))
self.dirCtl.SetToolTip(tt)
filebox = wx.StaticBox(panel, -1, _("File or Folder to include"))
fileboxer = wx.StaticBoxSizer(filebox, wx.VERTICAL)
annbox = wx.StaticBox(panel, -1, _("Announce URL"))
annboxer = wx.StaticBoxSizer(annbox, wx.VERTICAL)
commentbox = wx.StaticBox(panel, -1, _("Comment (Optional)"))
commentboxer = wx.StaticBoxSizer(commentbox, wx.VERTICAL)
piecebox = wx.StaticBox(panel, -1, _("Piece Size"))
pieceboxer = wx.StaticBoxSizer(piecebox, wx.VERTICAL)
b = wx.BoxSizer(wx.HORIZONTAL)
button = wx.Button(panel, -1, _("Add File"))
b.Add(button, 0, wx.EXPAND)
b.Add((5, 5))
c = wx.Button(panel, -1, _("Add Folder"))
b.Add(c, 0, wx.EXPAND)
wx.EVT_BUTTON(self, button.GetId(), self.select)
wx.EVT_BUTTON(self, c.GetId(), self.selectdir)
fileboxer.Add(self.dirCtl, 1, wx.EXPAND|wx.TOP, 2)
fileboxer.Add((-1,5))
fileboxer.Add(b, 1, wx.EXPAND)
gridSizer.Add(fileboxer, 1, wx.EXPAND)
self.annCtl = wx.TextCtrl(panel, -1, 'http://my.tracker:6969/announce')
annboxer.Add(self.annCtl, 1, wx.EXPAND|wx.TOP, 2)
gridSizer.Add(annboxer, 1, wx.EXPAND)
self.commentCtl = wx.TextCtrl(panel, -1, '')
commentboxer.Add(self.commentCtl, 1, wx.EXPAND|wx.TOP, 2)
gridSizer.Add(commentboxer, 1, wx.EXPAND)
## self.piece_length = wx.Choice(panel, -1, choices = ['2 ** 21', '2 ** 20', '2 ** 19',
## '2 ** 18', '2 ** 17', '2 ** 16', '2 ** 15'])
self.piece_length = wx.Choice(panel, -1, choices = [_('auto'), '2048 KB', '1024 KB', '512 KB',
'256 KB', '128 KB', '64 KB', '32 KB'])
self.piece_length_values = [0, 21, 20, 19, 18, 17, 16, 15]
self.piece_length.SetSelection(0)
pieceboxer.Add(self.piece_length, 1, wx.EXPAND|wx.TOP, 2)
gridSizer.Add(pieceboxer, 1, wx.EXPAND)
buttons = wx.BoxSizer(wx.HORIZONTAL)
nextbutt = wx.Button(panel, -1, _("Create"))
wx.EVT_BUTTON(self, nextbutt.GetId(), self.complete)
cancelbutt = wx.Button(panel, -1, _("Close"))
wx.EVT_BUTTON(self, cancelbutt.GetId(), self.cancel)
#border.Add(b2, 0, wx.ALIGN_CENTER | wx.SOUTH, 20)
buttons.Add(nextbutt)
buttons.Add(cancelbutt)
gridSizer.Add(buttons, 1, wx.ALIGN_CENTER)
border = wx.FlexGridSizer(cols = 1, vgap = 2, hgap = 2)
border.AddGrowableRow(0)
border.AddGrowableCol(0)
border.Add(gridSizer, 0, wx.EXPAND | wx.ALL, 8)
border.Add((10, 10))
panel.SetSizer(border)
panel.SetAutoLayout(True)
def cancel(self, event):
self.Destroy()
def select(self, x):
dl = wx.FileDialog(self, _("Choose files"), '/', "", '*.*', wx.OPEN | wx.MULTIPLE)
if dl.ShowModal() == wx.ID_OK:
x = self.dirCtl.GetValue() + ';' + ';'.join(dl.GetPaths())
if x[0] == ';':
x = x[1:]
self.dirCtl.SetValue(x)
def selectdir(self, x):
dl = wx.DirDialog(self, _("Choose directories"), '/')
if dl.ShowModal() == wx.ID_OK:
x = self.dirCtl.GetValue() + ';' + dl.GetPath()
if x[0] == ';':
x = x[1:]
self.dirCtl.SetValue(x)
def complete(self, x):
if self.dirCtl.GetValue() == '':
dlg = wx.MessageDialog(self, message = _("You have not selected any files or folders"),
caption = _("Error"), style = wx.OK | wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()
return
if self.annCtl.GetValue() == '':
dlg = wx.MessageDialog(self, message = _("You have not entered an announce URL"),
caption = _("Error"), style = wx.OK | wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()
return
try:
ps = self.piece_length_values[self.piece_length.GetSelection()]
files = self.dirCtl.GetValue().split(';')
for i in range(0, len(files)):
files[i] = files[i]
announce = self.annCtl.GetValue()
comment = self.commentCtl.GetValue()
CompleteDir(self, files, announce, ps, comment, self.AddTorrent)
except:
print_exc()
class CompleteDir:
def __init__(self, parent, d, a, pl, comment, addtorrentfunc=None):
self.AddTorrent = addtorrentfunc
self.parent = parent
self.comment = comment
self.responsefile = ""
self.d = d
self.a = a
self.pl = pl
self.flag = Event()
frame = wx.Frame(None, -1, _("Creating Torrent"), size = wx.Size(400, 150))
self.frame = frame
panel = wx.Panel(frame, -1)
gridSizer = wx.FlexGridSizer(cols = 1, vgap = 8, hgap = 8)
self.currentLabel = wx.StaticText(panel, -1, _("checking file sizes"))
gridSizer.Add(self.currentLabel, 0, wx.EXPAND)
self.gauge = wx.Gauge(panel, -1, range = 1000, style = wx.GA_SMOOTH)
gridSizer.Add(self.gauge, 0, wx.EXPAND)
gridSizer.Add((10, 10))
self.button = wx.Button(panel, -1, _("cancel"))
gridSizer.Add(self.button, 0, wx.ALIGN_CENTER)
gridSizer.AddGrowableRow(2)
gridSizer.AddGrowableCol(0)
g2 = wx.FlexGridSizer(cols = 1, vgap = 8, hgap = 8)
g2.Add(gridSizer, 1, wx.EXPAND | wx.ALL, 8)
g2.AddGrowableRow(0)
g2.AddGrowableCol(0)
panel.SetSizer(g2)
panel.SetAutoLayout(True)
wx.EVT_BUTTON(frame, self.button.GetId(), self.done)
wx.EVT_CLOSE(frame, self.done)
EVT_INVOKE(frame, self.onInvoke)
frame.Show(True)
Thread(target = self.complete).start()
def complete(self):
try:
completedir(self.d, self.a, self.flag, self.valcallback, self.filecallback, self.pl, comment=self.comment)
if not self.flag.isSet():
self.currentLabel.SetLabel(_("Done!"))
self.gauge.SetValue(1000)
self.button.SetLabel(_("Close"))
except (OSError, IOError), e:
self.currentLabel.SetLabel(_("Error!"))
self.button.SetLabel(_("Close"))
dlg = wx.MessageDialog(self.frame, message = _("Error - ") + str(e),
caption = _("Error"), style = wx.OK | wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()
def valcallback(self, amount):
self.invokeLater(self.onval, [amount])
def onval(self, amount):
self.gauge.SetValue(int(amount * 1000))
def filecallback(self, f):
self.invokeLater(self.onfile, [f])
def onfile(self, f):
self.responsefile = join(self.d, f) + '.torrent'
self.currentLabel.SetLabel(_("building ") + join(self.d, f) + '.torrent')
def onInvoke(self, event):
if not self.flag.isSet():
apply(event.func, event.args, event.kwargs)
def invokeLater(self, func, args = [], kwargs = {}):
if not self.flag.isSet():
wx.PostEvent(self.frame, InvokeEvent(func, args, kwargs))
def done(self, event):
self.flag.set()
self.frame.Destroy()
if self.currentLabel.GetLabel() == 'Done!':
if self.AddTorrent != None:
self.AddTorrent(self.responsefile)
self.parent.Destroy()
if __name__ == "__main__":
_ = lambda x: x # needed for gettext
app = wx.PySimpleApp()
frame = CreateTorrentDlg()
app.SetTopWindow(frame)
frame.Show(True)
app.MainLoop()
|