3,699
edits
m (→Introduction) |
No edit summary |
||
Line 13: | Line 13: | ||
==Changelog== | ==Changelog== | ||
<pre> | <pre> | ||
v2.00 - 03.06.2011 | |||
Avdump2 Build 4260 added | |||
rewrote the whole lot and simplified it | |||
v1.07 - 06.04.2008 | v1.07 - 06.04.2008 | ||
Avdump 0.34 added | Avdump 0.34 added | ||
Line 49: | Line 53: | ||
<pre style="font-size: 60%;"> | <pre style="font-size: 60%;"> | ||
import | import sys, os, platform, subprocessw, ConfigParser, string, unicodedata | ||
from time import time | |||
# Import Qt modules | |||
from PyQt4 import QtCore, QtGui | |||
# Import the compiled UI module | |||
from gui import Ui_MainWindow | |||
# Create a class for our main window | |||
class Main(QtGui.QMainWindow): | |||
def __init__(self): | |||
QtGui.QMainWindow.__init__(self) | |||
self._ui = Ui_MainWindow() | |||
self._ui.setupUi(self) | |||
self._filelist = {} | |||
self._paths = {} | |||
self._done_files = [] | |||
self._worker = None | |||
self._export_filename = 'exports/export_' + str(int(time())) + '.txt' | |||
self._allowed_extensions = ('avi', 'mpg', 'mpeg', 'ts', 'm2ts', 'rm', 'rmvb', 'asf', 'wmv', 'mov', 'qt', 'ogm', | |||
'mp4', 'mkv', 'swf', 'flv', 'ogv', 'webm', 'mk3d', 'srt', 'sub', 'ssa', 'smi', 'idx', 'ass', | |||
'txt', 'mks', 'lrc', 'rt', 'tmp', 'js', 'pjs', 'tts', 'xss', 'mp3', 'aac', 'ac3', 'dts', 'wav', | |||
'flac', 'wma', 'mka', 'ra', 'ogg', 'm4a', 'dtshd', 'thd', 'rar', 'zip', 'ace', '7z', 'smil') | |||
tmp = [] | |||
for ext in self._allowed_extensions: | |||
tmp.append('*.' + ext) | |||
self._allowed_extensions_str = "; ".join(tmp) | |||
self._ui.datatable.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) | |||
self._ui.datatable.setColumnWidth(0, 90) | |||
self._ui.datatable.setColumnWidth(1, 250) | |||
self._ui.datatable.setColumnWidth(2, 40) | |||
self.connect(self._ui.files_button, QtCore.SIGNAL("clicked()"), self._slotFile) | |||
self.connect(self._ui.folder_button, QtCore.SIGNAL("clicked()"), self._slotFolder) | |||
self.connect(self._ui.start_button, QtCore.SIGNAL("clicked()"), self._run) | |||
self.connect(self._ui.stop_button, QtCore.SIGNAL("clicked()"), self._stop) | |||
self.connect(QtGui.QAction(self), QtCore.SIGNAL('triggered()'), QtCore.SLOT('close()')) | |||
self._enable_elements() | |||
self._read_config() | |||
self._read_done() | |||
################################################# | |||
# # | |||
# GUI FUNCTIONS # | |||
# # | |||
################################################# | |||
def _disable_elements(self): | |||
self._ui.username.setDisabled(True) | |||
self._ui.apikey.setDisabled(True) | |||
self._ui.files_button.setDisabled(True) | |||
self._ui.folder_button.setDisabled(True) | |||
self._ui.done.setDisabled(True) | |||
self._ui.exp.setDisabled(True) | |||
self._ui.start_button.setDisabled(True) | |||
self._ui.stop_button.setEnabled(True) | |||
def _enable_elements(self): | |||
self._ui.username.setEnabled(True) | |||
self._ui.apikey.setEnabled(True) | |||
self._ui.files_button.setEnabled(True) | |||
self._ui.folder_button.setEnabled(True) | |||
self._ui.done.setEnabled(True) | |||
self._ui.exp.setEnabled(True) | |||
self._ui.start_button.setEnabled(True) | |||
self._ui.stop_button.setDisabled(True) | |||
def _output_export(self): | |||
self._ui.ed2k_export.setText("".join(file(self._export_filename).readlines())) | |||
def _calculate_progress(self): | |||
if self._ui.datatable.rowCount() == 0: | |||
return 0 | |||
done = 0 | |||
for i in range(self._ui.datatable.rowCount()): | |||
if unicode(self._ui.datatable.item(i,2).text()) == 'done': | |||
done += 1 | |||
return done*100/self._ui.datatable.rowCount() | |||
################################################# | |||
# # | |||
# EVENT HANDLER # | |||
# # | |||
################################################# | |||
def _closeEvent(self,event): | |||
self._stop() | |||
self._write_config() | |||
event.accept() | |||
def _done(self, path): | |||
i = self._paths[path] | |||
item = QtGui.QTableWidgetItem('done') | |||
self._ui.datatable.setItem(i, 2, item) | |||
if self._ui.exp.isChecked(): | |||
self._output_export() | |||
self._ui.progressBar.setValue(self._calculate_progress()) | |||
def _finished(self): | |||
self._paths = {} | |||
self._ui.progressBar.setValue(self._calculate_progress()) | |||
self._worker = None | |||
self._enable_elements() | |||
if self._ui.exp.isChecked(): | |||
self._output_export() | |||
def _stop(self): | |||
if self._worker is not None: | |||
self._worker.stop() | |||
self._output_export() | |||
self._enable_elements() | |||
def _slotFile(self): | |||
files = QtGui.QFileDialog.getOpenFileNames(self, 'File select', os.getcwd(), self._allowed_extensions_str) | |||
for path in files: | |||
self._add_file(unicode(path)) | |||
def | def _slotFolder(self): | ||
path = unicode(QtGui.QFileDialog.getExistingDirectory(self, "Select Directory")) | |||
if path != '': | |||
for root, dir, files in os.walk(path): | |||
for filename in files: | |||
self._add_file(os.path.join(root, filename)) | |||
self. | |||
def | def _add_file(self, fileloc): | ||
if len(fileloc) == 0: | |||
return | |||
elif unicodedata.normalize('NFKC', fileloc) in self._done_files: | |||
return | |||
no = self._ui.datatable.rowCount() | |||
if platform.system().lower() == 'windows': | |||
fileloc = fileloc.replace("/", "\\") | |||
filepath, filename = fileloc.rsplit("\\", 1) | |||
else: | else: | ||
filepath, filename = fileloc.rsplit("/", 1) | |||
tmp, ext = filename.rsplit('.', 1) | |||
self. | if ext not in self._allowed_extensions: | ||
return | |||
if fileloc not in self._filelist.keys(): | |||
self._filelist[fileloc] = 1 | |||
self._ui.datatable.insertRow(no) | |||
item = QtGui.QTableWidgetItem(filepath) | |||
self._ui.datatable.setItem(no, 0, item) | |||
self. | |||
item = QtGui.QTableWidgetItem(filename) | |||
self._ui.datatable.setItem(no, 1, item) | |||
item = QtGui.QTableWidgetItem('new') | |||
self._ui.datatable.setItem(no, 2, item) | |||
self._ui.progressBar.setValue(self._calculate_progress()) | |||
def | def _run(self): | ||
if | if self._ui.datatable.rowCount() == 0: | ||
QtGui.QMessageBox.information(self, "Error!", "No files to scan in list.", QtGui.QMessageBox.Ok) | |||
return | |||
elif not os.path.exists('avdump2cl.exe'): | |||
QtGui.QMessageBox.information(self, "Error!", "Avdump2cl.exe not found.", QtGui.QMessageBox.Ok) | |||
return | |||
paths = [] | |||
for i in range(self._ui.datatable.rowCount()): | |||
if unicode(self._ui.datatable.item(i,2).text()) == 'new': | |||
path = os.path.join(unicode(self._ui.datatable.item(i,0).text()), unicode(self._ui.datatable.item(i,1).text())) | |||
paths.append(path) | |||
self._paths[path] = i | |||
if len(paths) > 0: | |||
self._ui.progressBar.setValue(self._calculate_progress()) | |||
self._disable_elements() | |||
self. | username = unicode(self._ui.username.text()) | ||
self. | apikey = unicode(self._ui.apikey.text()) | ||
done = '' | |||
if self._ui.done.isChecked() is True: | |||
done = '-done:done.txt' | |||
exp = '' | |||
if self._ui.exp.isChecked() is True: | |||
exp = '-exp:' + self._export_filename | |||
self. | |||
self. | self._worker = avdump_worker(username, apikey, done, exp, paths) | ||
self.connect(self._worker, QtCore.SIGNAL("done"), self._done) | |||
self.connect(self._worker, QtCore.SIGNAL("finished"), self._finished) | |||
self._worker.start() | |||
def | ################################################# | ||
# # | |||
# CONFIG READ/WRITE # | |||
# # | |||
self. | ################################################# | ||
def _read_config(self): | |||
if os.path.exists('options.ini'): | |||
config = ConfigParser.ConfigParser() | |||
config.read('options.ini') | |||
self._ui.username.setText(config.get('DEFAULT', 'username')) | |||
self._ui.apikey.setText(config.get('DEFAULT', 'apikey')) | |||
if config.get('DEFAULT', 'done') == '1': | |||
self._ui.done.setChecked(True) | |||
else: | |||
self._ui.done.setChecked(False) | |||
if config.get('DEFAULT', 'exp') == '1': | |||
self._ui.exp.setChecked(True) | |||
else: | |||
self._ui.exp.setChecked(False) | |||
self. | |||
def | def _write_config(self): | ||
self. | config = ConfigParser.ConfigParser() | ||
if self. | config.set("DEFAULT", "username", str(self._ui.username.text())) | ||
config.set("DEFAULT", "apikey", str(self._ui.apikey.text())) | |||
if self._ui.done.isChecked(): | |||
config.set("DEFAULT", "done", 1) | |||
else: | |||
config.set("DEFAULT", "done", 0) | |||
if self._ui.exp.isChecked(): | |||
config.set("DEFAULT", "exp", 1) | |||
else: | else: | ||
config.set("DEFAULT", "exp", 0) | |||
config.write(file("options.ini", "w")) | |||
def | def _read_done(self): | ||
if os.path.exists("done.txt"): | |||
for line in file("done.txt"): | |||
self._done_files.append(unicodedata.normalize('NFKC', line.decode("utf8").strip())) | |||
def | class avdump_worker(QtCore.QThread): | ||
self. | def __init__(self, username, apikey, done, exp, paths): | ||
QtCore.QThread.__init__(self, parent=None) | |||
self._username = username | |||
self._apikey = apikey | |||
self._done = done | |||
self._exp = exp | |||
self._paths = paths | |||
self._was_stopped = False | |||
self._avdump = None | |||
def | def stop(self): | ||
self. | self._was_stopped = True | ||
self._avdump.terminate() | |||
self. | |||
def | def run(self): | ||
self. | for path in self._paths: | ||
if self._was_stopped is True: | |||
break | |||
self._avdump = subprocessw.Popen((u'avdump2cl.exe -ac:%s:%s %s %s "%s"') %(self._username, self._apikey, self._done, self._exp, path)) | |||
self._avdump.communicate() | |||
if self._was_stopped is False: | |||
self.emit(QtCore.SIGNAL('done'), path) | |||
self. | |||
if self._was_stopped is False: | |||
self.emit(QtCore.SIGNAL('finished')) | |||
def main(): | |||
app = QtGui.QApplication(sys.argv) | |||
window=Main() | |||
window.show() | |||
sys.exit(app.exec_()) | |||
if __name__ == | if __name__ == "__main__": | ||
main() | |||
</pre> | </pre> | ||
Line 446: | Line 384: | ||
if startupinfo == None: | if startupinfo == None: | ||
startupinfo = STARTUPINFOW() | startupinfo = STARTUPINFOW() | ||
startupinfo.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW | |||
startupinfo.wShowWindow = subprocess._subprocess.SW_HIDE | |||
else: | else: | ||
raise NotImplementedError("Can't pass startup stuff") | raise NotImplementedError("Can't pass startup stuff") |