Changed new line and added QT GUI PoC

This commit is contained in:
JayPiKay 2017-10-26 08:48:42 +02:00
parent 641d26ce6a
commit 056e0845ef
4 changed files with 402 additions and 287 deletions

528
ED2K.py
View File

@ -1,257 +1,271 @@
#!/usr/bin/env python3
"""
#define FT_FILENAME 0x01 // <string>
#define FT_FILESIZE 0x02 // <uint32> (or <uint64> when supported)
#define FT_FILESIZE_HI 0x3A // <uint32>
#define FT_FILETYPE 0x03 // <string>
#define FT_FILEFORMAT 0x04 // <string>
#define FT_LASTSEENCOMPLETE 0x05 // <uint32>
#define TAG_PART_PATH "\x06" // <string>
#define TAG_PART_HASH "\x07"
#define FT_TRANSFERRED 0x08 // <uint32>
#define TAG_TRANSFERRED "\x08" // <uint32>
#define FT_GAPSTART 0x09 // <uint32>
#define TAG_GAPSTART "\x09" // <uint32>
#define FT_GAPEND 0x0A // <uint32>
#define TAG_GAPEND "\x0A" // <uint32>
#define FT_DESCRIPTION 0x0B // <string>
#define TAG_DESCRIPTION "\x0B" // <string>
#define TAG_PING "\x0C"
#define TAG_FAIL "\x0D"
#define TAG_PREFERENCE "\x0E"
#define FT_PARTFILENAME 0x12 // <string>
//#define FT_PRIORITY 0x13 // Not used anymore
#define FT_STATUS 0x14 // <uint32>
#define FT_SOURCES 0x15 // <uint32>
#define FT_PERMISSIONS 0x16 // <uint32>
//#define FT_ULPRIORITY 0x17 // Not used anymore
#define FT_DLPRIORITY 0x18 // Was 13
#define FT_ULPRIORITY 0x19 // Was 17
#define FT_COMPRESSION 0x1A
#define FT_CORRUPTED 0x1B
#define FT_KADLASTPUBLISHKEY 0x20 // <uint32>
#define FT_KADLASTPUBLISHSRC 0x21 // <uint32>
#define FT_FLAGS 0x22 // <uint32>
#define FT_DL_ACTIVE_TIME 0x23 // <uint32>
#define FT_CORRUPTEDPARTS 0x24 // <string>
#define FT_DL_PREVIEW 0x25
#define FT_KADLASTPUBLISHNOTES 0x26 // <uint32>
#define FT_AICH_HASH 0x27
#define FT_FILEHASH 0x28
#define FT_COMPLETE_SOURCES 0x30 // nr. of sources which share a complete version of the associated file (supported by eserver 16.46+)
#define FT_COLLECTIONAUTHOR 0x31
#define FT_COLLECTIONAUTHORKEY 0x32
#define FT_PUBLISHINFO 0x33 // <uint32>
#define FT_LASTSHARED 0x34 // <uint32>
#define FT_AICHHASHSET 0x35 // <uint32>
#define TAG_KADAICHHASHPUB "\x36" // <AICH Hash>
// statistic
#define FT_ATTRANSFERRED 0x50 // <uint32>
#define FT_ATREQUESTED 0x51 // <uint32>
#define FT_ATACCEPTED 0x52 // <uint32>
#define FT_CATEGORY 0x53 // <uint32>
#define FT_ATTRANSFERREDHI 0x54 // <uint32>
#define FT_MAXSOURCES 0x55 // <uint32>
#define FT_MEDIA_ARTIST 0xD0 // <string>
#define TAG_MEDIA_ARTIST "\xD0" // <string>
#define FT_MEDIA_ALBUM 0xD1 // <string>
#define TAG_MEDIA_ALBUM "\xD1" // <string>
#define FT_MEDIA_TITLE 0xD2 // <string>
#define TAG_MEDIA_TITLE "\xD2" // <string>
#define FT_MEDIA_LENGTH 0xD3 // <uint32> !!!
#define TAG_MEDIA_LENGTH "\xD3" // <uint32> !!!
#define FT_MEDIA_BITRATE 0xD4 // <uint32>
#define TAG_MEDIA_BITRATE "\xD4" // <uint32>
#define FT_MEDIA_CODEC 0xD5 // <string>
#define TAG_MEDIA_CODEC "\xD5" // <string>
#define FT_FILECOMMENT 0xF6 // <string>
#define FT_FILERATING 0xF7 // <uint8>
"""
import sys
import os
import binascii
from collections import namedtuple
MetEntry = namedtuple('met_entry',
['Filename', 'ED2KHash', 'LastChanged', 'Filesize', 'Transfered', 'Requested', 'Accepted',
'Transfered_HI', 'PartFilename', 'AICHashCount', 'AICHash'])
METENTRY_FIELDS = ('FT_FILENAME', 'ED2KHASH', 'NUMPARTS', 'LASTCHANGED', 'PARTHASHES', 'FT_FILESIZE',
'FT_ATTRANSFERRED', 'FT_ATREQUESTED', 'FT_ATACCEPTED', 'FT_ATTRANSFERREDHI', 'FT_PARTFILENAME',
'FT_AICHHASHSET', 'FT_AICH_HASH', 'FT_ULPRIORITY', 'FT_KADLASTPUBLISHSRC')
HEADER_KNOWN_MET_FILE = b'\x0e'
HEADER_PART_MET_FILE = b'\xe0'
FT_FILENAME = 0x01
FT_FILESIZE = 0x02
FT_PARTFILENAME = 0x12
FT_PERMISSIONS = 0x16
FT_ULPRIORITY = 0x19
FT_KADLASTPUBLISHKEY = 0x20
FT_KADLASTPUBLISHSRC = 0x21
FT_FLAGS = 0x22
FT_KADLASTPUBLISHNOTES = 0x26
FT_AICH_HASH = 0x27
FT_LASTSHARED = 0x34
FT_AICHHASHSET = 0x35
FT_ATTRANSFERRED = 0x50
FT_ATREQUESTED = 0x51
FT_ATACCEPTED = 0x52
FT_ATTRANSFERREDHI = 0x54
FT_MEDIA_ARTIST = 0xd0
FT_MEDIA_ALBUM = 0xd1
FT_MEDIA_TITLE = 0xd2
FT_MEDIA_LENGTH = 0xd3
FT_MEDIA_BITRATE = 0xd4
FT_MEDIA_CODEC = 0xd5
FT_STRING = (
0x03, 0x04, 0x06, 0x0b, 0x11, 0x24, 0x28, 0xf6
)
FT_INT = (
0x05, 0x08, 0x09, 0x0a, 0x14, 0x15, 0x18, 0x1a, 0x1b, 0x23, 0x25, 0x30, 0x33, 0x53, 0x55, 0xf7
)
def met_readstring(fd):
string_len = int.from_bytes(fd.read(2), byteorder='little')
return fd.read(string_len).decode('utf-8', errors='replace')
def met_readinteger(fd, size=4):
return int.from_bytes(fd.read(size), byteorder='little')
def record_last_changed(fd):
return met_readinteger(fd)
def record_read_hash16(fd):
aichash = fd.read(16)
return binascii.hexlify(aichash).decode('utf-8')
def record_tags(fd):
tags = {}
tags['TAGCOUNT'] = met_readinteger(fd)
print('Tags: {}'.format(tags['TAGCOUNT']))
for index in range(tags['TAGCOUNT']):
filetag = fd.read(4)
if filetag[:3] not in [b'\x02\x01\x00', b'\x03\x01\x00']:
print('<<< Premature end of record at offset 0x{:08X}'.format(fd.tell()))
return tags
tagid = filetag[-1]
if tagid == FT_FILENAME:
tags['FT_FILENAME'] = met_readstring(fd)
elif tagid == FT_FILESIZE:
tags['FT_FILESIZE'] = met_readinteger(fd)
elif tagid == FT_ATTRANSFERRED:
tags['FT_ATTRANSFERRED'] = met_readinteger(fd)
elif tagid == FT_ATREQUESTED:
tags['FT_ATREQUESTED'] = met_readinteger(fd)
elif tagid == FT_ATACCEPTED:
tags['FT_ATACCEPTED'] = met_readinteger(fd)
elif tagid == FT_ATTRANSFERREDHI:
tags['FT_ATTRANSFERREDHI'] = met_readinteger(fd)
elif tagid == FT_ULPRIORITY:
tags['FT_ULPRIORITY'] = met_readinteger(fd)
elif tagid == FT_KADLASTPUBLISHSRC:
tags['FT_KADLASTPUBLISHSRC'] = met_readinteger(fd)
elif tagid == FT_KADLASTPUBLISHNOTES:
print('FT_KADLASTPUBLISHNOTES')
met_readinteger(fd)
elif tagid == FT_FLAGS:
print('FT_FLAGS')
met_readinteger(fd)
elif tagid == FT_PERMISSIONS:
print('FT_PERMISSIONS')
met_readinteger(fd)
elif tagid == FT_KADLASTPUBLISHKEY:
print('FT_KADLASTPUBLISHKEY')
met_readinteger(fd)
elif tagid == FT_AICH_HASH:
tags['FT_AICH_HASH'] = met_readstring(fd)
elif tagid == FT_LASTSHARED:
tags['FT_LASTSHARED'] = met_readinteger(fd)
elif tagid == FT_AICHHASHSET:
tags['FT_AICHHASHSET'] = met_readinteger(fd, 1)
elif tagid == FT_PARTFILENAME:
tags['FT_PARTFILENAME'] = met_readstring(fd)
elif tagid == FT_MEDIA_LENGTH:
print('Media Length: {}'.format(met_readinteger(fd)))
elif tagid == FT_MEDIA_CODEC:
print('Media Codec: {}'.format(met_readstring(fd)))
elif tagid == FT_MEDIA_BITRATE:
print('Media Bitrate: {}'.format(met_readinteger(fd)))
elif tagid == FT_MEDIA_TITLE:
print('Media Title: {}'.format(met_readstring(fd)))
elif tagid == FT_MEDIA_ARTIST:
print('Media Artist: {}'.format(met_readstring(fd)))
elif tagid == FT_MEDIA_ALBUM:
print('Media Album: {}'.format(met_readstring(fd)))
elif tagid in FT_STRING:
print('... Reading data with tag: {}'.format(tagid))
met_readstring(fd)
elif tagid in FT_INT:
print('... Reading data with tag: {}'.format(tagid))
met_readstring(fd)
return tags
def record_num_parts(fd):
return met_readinteger(fd, 2)
def load_record(fd):
met_tags = {}
met_tags['LASTCHANGED'] = record_last_changed(fd)
met_tags['ED2KHASH'] = record_read_hash16(fd)
met_tags['NUMPARTS'] = record_num_parts(fd)
partshashes = []
for i in range(met_tags['NUMPARTS']):
partshashes.append(record_read_hash16(fd))
met_tags['PARTHASHES'] = partshashes
met_tags.update(record_tags(fd))
for field in METENTRY_FIELDS:
if field not in met_tags:
met_tags[field] = 0
#print(met_tags)
metentry = MetEntry(met_tags['FT_FILENAME'], met_tags['ED2KHASH'], met_tags['LASTCHANGED'], met_tags['FT_FILESIZE'],
met_tags['FT_ATTRANSFERRED'], met_tags['FT_ATREQUESTED'], met_tags['FT_ATACCEPTED'],
met_tags['FT_ATTRANSFERREDHI'], met_tags['FT_PARTFILENAME'], met_tags['FT_AICHHASHSET'],
met_tags['PARTHASHES'])
print(metentry)
return metentry
def load_knownfiles(filename):
with open(filename, 'rb') as fd:
magic = fd.read(1)
if os.path.basename(filename) == 'known.met':
count = int.from_bytes(fd.read(4), byteorder='little')
print('Number of records: {}'.format(count))
if magic == HEADER_KNOWN_MET_FILE:
for index in range(count):
print('>>> [{}] NEW RECORD ***'.format(index+1))
yield load_record(fd)
elif magic == HEADER_PART_MET_FILE:
print('>>> [{}] NEW RECORD ***'.format(0))
yield load_record(fd)
if __name__ == '__main__':
load_knownfiles('.\\data\\known.met')
# load_knownfiles('.\\data\\008.part.met')
#load_knownfiles(sys.argv[-1])
#!/usr/bin/env python3
"""
#define FT_FILENAME 0x01 // <string>
#define FT_FILESIZE 0x02 // <uint32> (or <uint64> when supported)
#define FT_FILESIZE_HI 0x3A // <uint32>
#define FT_FILETYPE 0x03 // <string>
#define FT_FILEFORMAT 0x04 // <string>
#define FT_LASTSEENCOMPLETE 0x05 // <uint32>
#define TAG_PART_PATH "\x06" // <string>
#define TAG_PART_HASH "\x07"
#define FT_TRANSFERRED 0x08 // <uint32>
#define TAG_TRANSFERRED "\x08" // <uint32>
#define FT_GAPSTART 0x09 // <uint32>
#define TAG_GAPSTART "\x09" // <uint32>
#define FT_GAPEND 0x0A // <uint32>
#define TAG_GAPEND "\x0A" // <uint32>
#define FT_DESCRIPTION 0x0B // <string>
#define TAG_DESCRIPTION "\x0B" // <string>
#define TAG_PING "\x0C"
#define TAG_FAIL "\x0D"
#define TAG_PREFERENCE "\x0E"
#define FT_PARTFILENAME 0x12 // <string>
//#define FT_PRIORITY 0x13 // Not used anymore
#define FT_STATUS 0x14 // <uint32>
#define FT_SOURCES 0x15 // <uint32>
#define FT_PERMISSIONS 0x16 // <uint32>
//#define FT_ULPRIORITY 0x17 // Not used anymore
#define FT_DLPRIORITY 0x18 // Was 13
#define FT_ULPRIORITY 0x19 // Was 17
#define FT_COMPRESSION 0x1A
#define FT_CORRUPTED 0x1B
#define FT_KADLASTPUBLISHKEY 0x20 // <uint32>
#define FT_KADLASTPUBLISHSRC 0x21 // <uint32>
#define FT_FLAGS 0x22 // <uint32>
#define FT_DL_ACTIVE_TIME 0x23 // <uint32>
#define FT_CORRUPTEDPARTS 0x24 // <string>
#define FT_DL_PREVIEW 0x25
#define FT_KADLASTPUBLISHNOTES 0x26 // <uint32>
#define FT_AICH_HASH 0x27
#define FT_FILEHASH 0x28
#define FT_COMPLETE_SOURCES 0x30 // nr. of sources which share a complete version of the associated file (supported by eserver 16.46+)
#define FT_COLLECTIONAUTHOR 0x31
#define FT_COLLECTIONAUTHORKEY 0x32
#define FT_PUBLISHINFO 0x33 // <uint32>
#define FT_LASTSHARED 0x34 // <uint32>
#define FT_AICHHASHSET 0x35 // <uint32>
#define TAG_KADAICHHASHPUB "\x36" // <AICH Hash>
// statistic
#define FT_ATTRANSFERRED 0x50 // <uint32>
#define FT_ATREQUESTED 0x51 // <uint32>
#define FT_ATACCEPTED 0x52 // <uint32>
#define FT_CATEGORY 0x53 // <uint32>
#define FT_ATTRANSFERREDHI 0x54 // <uint32>
#define FT_MAXSOURCES 0x55 // <uint32>
#define FT_MEDIA_ARTIST 0xD0 // <string>
#define TAG_MEDIA_ARTIST "\xD0" // <string>
#define FT_MEDIA_ALBUM 0xD1 // <string>
#define TAG_MEDIA_ALBUM "\xD1" // <string>
#define FT_MEDIA_TITLE 0xD2 // <string>
#define TAG_MEDIA_TITLE "\xD2" // <string>
#define FT_MEDIA_LENGTH 0xD3 // <uint32> !!!
#define TAG_MEDIA_LENGTH "\xD3" // <uint32> !!!
#define FT_MEDIA_BITRATE 0xD4 // <uint32>
#define TAG_MEDIA_BITRATE "\xD4" // <uint32>
#define FT_MEDIA_CODEC 0xD5 // <string>
#define TAG_MEDIA_CODEC "\xD5" // <string>
#define FT_FILECOMMENT 0xF6 // <string>
#define FT_FILERATING 0xF7 // <uint8>
"""
import sys
import os
import binascii
from collections import namedtuple
#MetEntry = namedtuple('met_entry',
# ['Filename', 'ED2KHash', 'LastChanged', 'Filesize', 'Transfered', 'Requested', 'Accepted',
# 'Transfered_HI', 'PartFilename', 'AICHashCount', 'AICHash'])
METENTRY_FIELDS = ('FT_FILENNAME', 'ED2KHASH', 'NUMPARTS', 'LASTCHANGED', 'PARTHASHES', 'FT_FILESIZE',
'FT_ATTRANSFERRED', 'FT_ATREQUESTED', 'FT_ATACCEPTED', 'FT_ATTRANSFERREDHI', 'FT_PARTFILENAME',
'FT_AICHHASHSET', 'FT_AICH_HASH', 'FT_ULPRIORITY', 'FT_KADLASTPUBLISHSRC')
MetEntry = namedtuple('met_entry', METENTRY_FIELDS)
HEADER_KNOWN_MET_FILE = b'\x0e'
HEADER_PART_MET_FILE = b'\xe0'
FT_FILENAME = 0x01
FT_FILESIZE = 0x02
FT_PARTFILENAME = 0x12
FT_PERMISSIONS = 0x16
FT_ULPRIORITY = 0x19
FT_KADLASTPUBLISHKEY = 0x20
FT_KADLASTPUBLISHSRC = 0x21
FT_FLAGS = 0x22
FT_KADLASTPUBLISHNOTES = 0x26
FT_AICH_HASH = 0x27
FT_LASTSHARED = 0x34
FT_AICHHASHSET = 0x35
FT_ATTRANSFERRED = 0x50
FT_ATREQUESTED = 0x51
FT_ATACCEPTED = 0x52
FT_ATTRANSFERREDHI = 0x54
FT_MEDIA_ARTIST = 0xd0
FT_MEDIA_ALBUM = 0xd1
FT_MEDIA_TITLE = 0xd2
FT_MEDIA_LENGTH = 0xd3
FT_MEDIA_BITRATE = 0xd4
FT_MEDIA_CODEC = 0xd5
FT_STRING = (
0x03, 0x04, 0x06, 0x0b, 0x11, 0x24, 0x28, 0xf6
)
FT_INT = (
0x05, 0x08, 0x09, 0x0a, 0x14, 0x15, 0x18, 0x1a, 0x1b, 0x23, 0x25, 0x30, 0x33, 0x53, 0x55, 0xf7
)
def met_readstring(fd):
string_len = int.from_bytes(fd.read(2), byteorder='little')
return fd.read(string_len).decode('utf-8', errors='replace')
def met_readinteger(fd, size=4):
return int.from_bytes(fd.read(size), byteorder='little')
def record_last_changed(fd):
return met_readinteger(fd)
def record_read_hash16(fd):
aichash = fd.read(16)
return binascii.hexlify(aichash).decode('utf-8')
def record_tags(fd):
tags = {}
tags['TAGCOUNT'] = met_readinteger(fd)
# print('Tags: {}'.format(tags['TAGCOUNT']))
for index in range(tags['TAGCOUNT']):
filetag = fd.read(4)
if filetag[:3] not in [b'\x02\x01\x00', b'\x03\x01\x00']:
print('<<< Premature end of record at offset 0x{:08X}'.format(fd.tell()))
return tags
tagid = filetag[-1]
if tagid == FT_FILENAME:
tags['FT_FILENAME'] = met_readstring(fd)
elif tagid == FT_FILESIZE:
tags['FT_FILESIZE'] = met_readinteger(fd)
elif tagid == FT_ATTRANSFERRED:
tags['FT_ATTRANSFERRED'] = met_readinteger(fd)
elif tagid == FT_ATREQUESTED:
tags['FT_ATREQUESTED'] = met_readinteger(fd)
elif tagid == FT_ATACCEPTED:
tags['FT_ATACCEPTED'] = met_readinteger(fd)
elif tagid == FT_ATTRANSFERREDHI:
tags['FT_ATTRANSFERREDHI'] = met_readinteger(fd)
elif tagid == FT_ULPRIORITY:
tags['FT_ULPRIORITY'] = met_readinteger(fd)
elif tagid == FT_KADLASTPUBLISHSRC:
tags['FT_KADLASTPUBLISHSRC'] = met_readinteger(fd)
elif tagid == FT_KADLASTPUBLISHNOTES:
print('FT_KADLASTPUBLISHNOTES')
met_readinteger(fd)
elif tagid == FT_FLAGS:
print('FT_FLAGS')
met_readinteger(fd)
elif tagid == FT_PERMISSIONS:
print('FT_PERMISSIONS')
met_readinteger(fd)
elif tagid == FT_KADLASTPUBLISHKEY:
print('FT_KADLASTPUBLISHKEY')
met_readinteger(fd)
elif tagid == FT_AICH_HASH:
tags['FT_AICH_HASH'] = met_readstring(fd)
elif tagid == FT_LASTSHARED:
tags['FT_LASTSHARED'] = met_readinteger(fd)
elif tagid == FT_AICHHASHSET:
tags['FT_AICHHASHSET'] = met_readinteger(fd, 1)
elif tagid == FT_PARTFILENAME:
tags['FT_PARTFILENAME'] = met_readstring(fd)
elif tagid == FT_MEDIA_LENGTH:
print('Media Length: {}'.format(met_readinteger(fd)))
elif tagid == FT_MEDIA_CODEC:
print('Media Codec: {}'.format(met_readstring(fd)))
elif tagid == FT_MEDIA_BITRATE:
print('Media Bitrate: {}'.format(met_readinteger(fd)))
elif tagid == FT_MEDIA_TITLE:
print('Media Title: {}'.format(met_readstring(fd)))
elif tagid == FT_MEDIA_ARTIST:
print('Media Artist: {}'.format(met_readstring(fd)))
elif tagid == FT_MEDIA_ALBUM:
print('Media Album: {}'.format(met_readstring(fd)))
elif tagid in FT_STRING:
print('... Reading data with tag: {}'.format(tagid))
met_readstring(fd)
elif tagid in FT_INT:
print('... Reading data with tag: {}'.format(tagid))
met_readstring(fd)
return tags
def record_num_parts(fd):
return met_readinteger(fd, 2)
def load_record(fd):
met_tags = {}
met_tags['LASTCHANGED'] = record_last_changed(fd)
met_tags['ED2KHASH'] = record_read_hash16(fd)
met_tags['NUMPARTS'] = record_num_parts(fd)
partshashes = []
for i in range(met_tags['NUMPARTS']):
partshashes.append(record_read_hash16(fd))
met_tags['PARTHASHES'] = partshashes
met_tags.update(record_tags(fd))
for field in METENTRY_FIELDS:
if field not in met_tags:
met_tags[field] = None
# print(met_tags)
# TODO: use new one
metentry = MetEntry(met_tags['FT_FILENAME'],
met_tags['ED2KHASH'],
met_tags['NUMPARTS'],
met_tags['LASTCHANGED'],
met_tags['PARTHASHES'],
met_tags['FT_FILESIZE'],
met_tags['FT_ATTRANSFERRED'],
met_tags['FT_ATREQUESTED'],
met_tags['FT_ATACCEPTED'],
met_tags['FT_ATTRANSFERREDHI'],
met_tags['FT_PARTFILENAME'],
met_tags['FT_AICHHASHSET'],
met_tags['FT_AICH_HASH'],
met_tags['FT_ULPRIORITY'],
met_tags['FT_KADLASTPUBLISHSRC']
)
print(metentry)
return metentry
def load_knownfiles(filename):
with open(filename, 'rb') as fd:
magic = fd.read(1)
if os.path.basename(filename) == 'known.met':
count = int.from_bytes(fd.read(4), byteorder='little')
# print('Number of records: {}'.format(count))
if magic == HEADER_KNOWN_MET_FILE:
for index in range(count):
# print('>>> [{}] NEW RECORD ***'.format(index+1))
yield load_record(fd)
elif magic == HEADER_PART_MET_FILE:
# print('>>> [{}] NEW RECORD ***'.format(0))
yield load_record(fd)
if __name__ == '__main__':
load_knownfiles('.\\data\\known.met')
# load_knownfiles('.\\data\\008.part.met')
#load_knownfiles(sys.argv[-1])

View File

@ -24,19 +24,21 @@ class Ui_MainWindow(object):
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.tableView = QtWidgets.QTableView(self.tab)
self.tableView.setEnabled(True)
self.tableWidget = QtWidgets.QTableWidget(self.tab)
self.tableWidget.setEnabled(True)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Maximum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.tableView.sizePolicy().hasHeightForWidth())
self.tableView.setSizePolicy(sizePolicy)
self.tableView.setMinimumSize(QtCore.QSize(243, 100))
self.tableView.setMaximumSize(QtCore.QSize(16777215, 100))
self.tableView.setFrameShape(QtWidgets.QFrame.Box)
self.tableView.setFrameShadow(QtWidgets.QFrame.Plain)
self.tableView.setObjectName("tableView")
self.horizontalLayout.addWidget(self.tableView)
sizePolicy.setHeightForWidth(self.tableWidget.sizePolicy().hasHeightForWidth())
self.tableWidget.setSizePolicy(sizePolicy)
self.tableWidget.setMinimumSize(QtCore.QSize(243, 100))
self.tableWidget.setMaximumSize(QtCore.QSize(16777215, 100))
self.tableWidget.setFrameShape(QtWidgets.QFrame.Box)
self.tableWidget.setFrameShadow(QtWidgets.QFrame.Plain)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.horizontalLayout.addWidget(self.tableWidget)
self.verticalLayout_3 = QtWidgets.QVBoxLayout()
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.lblSearch = QtWidgets.QLabel(self.tab)
@ -83,6 +85,13 @@ class Ui_MainWindow(object):
self.statusBar = QtWidgets.QStatusBar(MainWindow)
self.statusBar.setObjectName("statusBar")
MainWindow.setStatusBar(self.statusBar)
self.actionFile_open = QtWidgets.QAction(MainWindow)
self.actionFile_open.setObjectName("actionFile_open")
self.actionExit = QtWidgets.QAction(MainWindow)
self.actionExit.setObjectName("actionExit")
self.menuFile.addAction(self.actionFile_open)
self.menuFile.addSeparator()
self.menuFile.addAction(self.actionExit)
self.menubar.addAction(self.menuFile.menuAction())
self.retranslateUi(MainWindow)
@ -96,4 +105,6 @@ class Ui_MainWindow(object):
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))
self.menuFile.setTitle(_translate("MainWindow", "File"))
self.actionFile_open.setText(_translate("MainWindow", "File open"))
self.actionExit.setText(_translate("MainWindow", "Exit"))

15
main.ui
View File

@ -25,7 +25,7 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTableView" name="tableView">
<widget class="QTableWidget" name="tableWidget">
<property name="enabled">
<bool>true</bool>
</property>
@ -129,10 +129,23 @@
<property name="title">
<string>File</string>
</property>
<addaction name="actionFile_open"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
</widget>
<addaction name="menuFile"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionFile_open">
<property name="text">
<string>File open</string>
</property>
</action>
<action name="actionExit">
<property name="text">
<string>Exit</string>
</property>
</action>
</widget>
<resources/>
<connections/>

View File

@ -1,8 +1,9 @@
#! /usr/bin/env python3
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow
import locale
from PyQt5.QtCore import Qt, QDateTime, QLocale
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QAbstractItemView, QTableWidgetItem
from PyQt5.QtGui import QStandardItemModel
from MuleAnalyzerUI import Ui_MainWindow
@ -10,8 +11,24 @@ from ED2K import load_knownfiles
class MainWindow(QMainWindow, Ui_MainWindow):
TreeHeaders = ('Filename', 'ED2K Hash', 'Last Changed', 'Filesize', 'Transfered', 'Requested', 'Accepted',
'Transfered (HI)', 'Part Filename', 'Number of Parts', 'Parts Hashes')
# Todo: Replace TreeHeaders
Headers = (
('ID', None, None, 0, Qt.AlignRight),
('Filename', 'FT_FILENAME', str, '', Qt.AlignLeft),
('ED2K Hash', 'ED2KHASH', str, '', Qt.AlignLeft),
('Hashset', None, None, '', Qt.AlignLeft),
('Last Changed', 'LASTCHANGED', 'Never', QDateTime, Qt.AlignLeft),
('Filesize', 'FT_FILESIZE', int, 0, Qt.AlignRight),
('Transfered', 'FT_ATTRANSFERRED', int, 0, Qt.AlignRight),
('Transfered (HI)', 'FT_ATTRANSFERREDHI', int, 0, Qt.AlignRight),
('Requested', 'FT_ATREQUESTED', int, 0, Qt.AlignRight),
('Accepted', 'FT_ATACCEPTED', int, 0, Qt.AlignRight),
('AICHashes', 'FT_AICHHASHSET', str, '', Qt.AlignLeft),
('AICHash', 'FT_AICH_HASH', str, '', Qt.AlignLeft),
('Part Filename', 'FT_PARTFILENAME', str, '', Qt.AlignLeft),
('Number of Parts', 'NUMPARTS', int, 0, Qt.AlignRight),
('Parts Hash', 'PARTHASHES', list, '', Qt.AlignLeft),
)
def __init__(self):
super(MainWindow, self).__init__()
@ -21,35 +38,95 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.treeView.setModel(self.treeModel)
self.treeView.setRootIsDecorated(False)
self.treeView.setAlternatingRowColors(True)
self.treeView.setSortingEnabled(True)
self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers)
#self.treeView.setSelectionMode(QAbstractItemView.MultiSelection)
# TODO
self.loadMetFile(None)
self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.actionFile_open.setShortcut('Ctrl+O')
self.actionFile_open.triggered.connect(self.slot_load_met_file)
self.actionExit.triggered.connect(self.close)
def createED2KModel(self, parent):
model = QStandardItemModel(0, len(self.TreeHeaders), parent)
for i, title in enumerate(self.TreeHeaders):
model.setHeaderData(i, Qt.Horizontal, title)
model = QStandardItemModel(0, len(self.Headers), parent)
for i, fields in enumerate(self.Headers):
model.setHeaderData(i, Qt.Horizontal, fields[0])
return model
def addED2K(self, model, metinfo):
model.insertRow(0)
model.setData(model.index(0, 0), metinfo.Filename)
for i, field in enumerate(self.Headers):
print(i, field)
if field[2] is None:
if i == 0:
root = self.treeModel.invisibleRootItem()
row_count = root.rowCount()
model.setData(model.index(0, i), row_count+1)
if i == 3:
# TODO Hash lookup
model.setData(model.index(0, i), '<TODO>')
else:
value = getattr(metinfo, field[1]) or field[3]
if field[2] is QDateTime:
last_changed = QDateTime.fromSecsSinceEpoch(value, 0)
print(last_changed.toString('dd.MM.yyyy hh:mm:ss'))
model.setData(model.index(0, i), last_changed.toString('dd.MM.yyyy hh:mm:ss'))
elif field[2] is int:
print(value)
model.setData(model.index(0, i), '{0:,}'.format(value))
elif field[2] is list:
print(''.join(value))
model.setData(model.index(0, i), ''.join(value))
else:
print(value)
model.setData(model.index(0, i), value)
model.item(0, i).setTextAlignment(field[4])
"""model.setData(model.index(0, 0), metinfo.Filename)
model.setData(model.index(0, 1), metinfo.ED2KHash)
model.setData(model.index(0, 2), metinfo.LastChanged)
model.setData(model.index(0, 3), metinfo.Filesize)
model.setData(model.index(0, 4), metinfo.Transfered)
model.setData(model.index(0, 5), metinfo.Requested)
model.setData(model.index(0, 6), metinfo.Accepted)
model.setData(model.index(0, 7), metinfo.Transfered_HI)
last_changed = QDateTime.fromSecsSinceEpoch(metinfo.LastChanged)
model.setData(model.index(0, 2), last_changed.toString('dd.MM.yyyy hh:mm:ss'))
model.setData(model.index(0, 3), '{0:,}'.format(metinfo.Filesize))
model.item(0, 3).setTextAlignment(Qt.AlignRight)
model.setData(model.index(0, 4), '{0:,}'.format(metinfo.Transfered))
model.item(0, 4).setTextAlignment(Qt.AlignRight)
model.setData(model.index(0, 5), '{0:,}'.format(metinfo.Requested))
model.item(0, 5).setTextAlignment(Qt.AlignRight)
model.setData(model.index(0, 6), '{0:,}'.format(metinfo.Accepted))
model.item(0, 6).setTextAlignment(Qt.AlignRight)
model.setData(model.index(0, 7), '{0:,}'.format(metinfo.Transfered_HI))
model.item(0, 7).setTextAlignment(Qt.AlignRight)
model.setData(model.index(0, 8), metinfo.PartFilename)
model.setData(model.index(0, 9), metinfo.AICHashCount)
model.setData(model.index(0, 10), metinfo.AICHash)
model.item(0, 9).setTextAlignment(Qt.AlignRight)
print(metinfo.AICHash)
model.setData(model.index(0, 10), metinfo.AICHash)"""
def loadMetFile(self, filename):
for met_entry in load_knownfiles('.\\data\\known.met'):
for met_entry in load_knownfiles(filename):
self.addED2K(self.treeModel, met_entry)
def slot_load_met_file(self):
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
files, _ = QFileDialog.getOpenFileNames(self, 'Open .met files...', '', 'MET Files (*.met);;All Files (*)',
options=options)
for filename in files:
self.loadMetFile(filename)
root = self.treeModel.invisibleRootItem()
row_count = root.rowCount()
transfered = 0
for i in range(row_count):
row = self.treeModel.item(i, column=4)
transfered += int(row.text().replace(',', ''))
self.tableWidget.setRowCount(1)
self.tableWidget.setColumnCount(2)
self.tableWidget.setItem(0, 0, QTableWidgetItem('Transfered overall:'))
self.tableWidget.setItem(0, 1, QTableWidgetItem(str('{0:,}'.format(transfered))))
def main(argv):
app = QApplication(argv)