Skip to content
Snippets Groups Projects
Commit 95f6a6a6 authored by nimrod's avatar nimrod
Browse files

- Correcting warnings generated by running flake8.

parent fe0c4929
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env python
from fabric.api import task, local, settings
@task
def publish ():
local ('git dch -R')
build ()
def publish():
local('git dch -R')
build()
for dist in ['wheezy', 'jessie', 'sid']:
local ('''reprepro includedeb ''' + dist + ''' ../dcpman_*.deb''')
local ('''fab -f $REPREPRO_BASE_DIR/fabfile.py publish''')
clean ()
local('''reprepro includedeb ''' + dist + ''' ../dcpman_*.deb''')
local('''fab -f $REPREPRO_BASE_DIR/fabfile.py publish''')
clean()
@task
def build ():
local ('''dpkg-buildpackage -us -uc''')
def build():
local('''dpkg-buildpackage -us -uc''')
@task
def clean ():
def clean():
with settings(warn_only=True):
local ('''rm ../dcpman_*''')
local ('''rm -r debian/dcpman.substvars debian/dcpman.prerm.debhelper\
local('''rm ../dcpman_*''')
local('''rm -r debian/dcpman.substvars debian/dcpman.prerm.debhelper\
debian/dcpman.postinst.debhelper debian/dcpman.debhelper.log\
debian/dcpman debian/files''')
local ('''rm fabfile.pyc''')
local('''rm fabfile.pyc''')
@task
def push ():
local ('''git push --all gitdaemon''')
def push():
local('''git push --all gitdaemon''')
......@@ -2,262 +2,266 @@
from hashlib import sha1
from base64 import b64encode
from os import stat, listdir, mkdir, statvfs
from os.path import isdir, basename,exists
from os.path import isdir, basename, exists
from shutil import copyfile
from xml.dom.minidom import parse
import sys
import vlc
class Asset (object):
class Asset(object):
'''A simple asset that's part of whole DCP package.'''
def verifySize (self):
def verifySize(self):
'''verify that the size of the file is correct, if present.'''
try:
return exists (self.fullpath) and stat (self.fullpath).st_size == self.size
return exists(self.fullpath) and stat(self.fullpath).st_size ==\
self.size
except AttributeError:
return True
def verifyHash (self):
def verifyHash(self):
'''verify that the hash is correct, if present.'''
if hasattr (self, 'hash') == False:
if not hasattr(self, 'hash'):
return True
#from os import stat
#try:
#buffersize = stat(self.fullpath).st_blksize
#except:
#buffersize = 2**16
# from os import stat
# try:
# buffersize = stat(self.fullpath).st_blksize
# except:
# buffersize = 2**16
buffersize = 2 ** 16
fh = open (self.fullpath, 'rb')
buffer = fh.read (buffersize)
hash = sha1 ()
fh = open(self.fullpath, 'rb')
buffer = fh.read(buffersize)
hash = sha1()
while buffer:
hash.update (buffer)
buffer = fh.read (buffersize)
fh.close ()
return (self.hash == b64encode (hash.digest ()).decode ())
hash.update(buffer)
buffer = fh.read(buffersize)
fh.close()
return(self.hash == b64encode(hash.digest()).decode())
def copyAndVerify (self, destination):
def copyAndVerify(self, destination):
'''Copies the file to the destination directory and verifies the hash
during.'''
newfilepath = destination + '/' + self.filename
if hasattr (self, 'hash') == False:
copyfile (self.fullpath, newfilepath)
if not hasattr(self, 'hash'):
copyfile(self.fullpath, newfilepath)
self.fullpath = newfilepath
self.rootpath = destination
return True
buffersize = 2 ** 16
in_fh = open (self.fullpath, 'rb')
out_fh = open (newfullpath, 'wb')
buffer = in_fh.read (buffersize)
hash = sha1 ()
in_fh = open(self.fullpath, 'rb')
out_fh = open(newfullpath, 'wb')
buffer = in_fh.read(buffersize)
hash = sha1()
while buffer:
hash.update (buffer)
out_fh.write (buffer)
buffer = in_fh.read (buffersize)
in_fh.close ()
out_fh.close ()
hash.update(buffer)
out_fh.write(buffer)
buffer = in_fh.read(buffersize)
in_fh.close()
out_fh.close()
self.rootpath = destination
self.fullpath = newfullpath
return (self.hash == b64encode (hash.digest ()).decode ())
return(self.hash == b64encode(hash.digest()).decode())
def add_duration (self):
if hasattr (self, 'type') and self.type.find ('mxf') > -1:
instance = vlc.Instance ()
media = instance.media_new ('file://' + self.fullpath)
media.parse ()
self.duration = media.get_duration ()
def __init__(self, rootpath, filename, id=None, hash=None, size=None,\
packinglist=False, type=None):
def add_duration(self):
if hasattr(self, 'type') and self.type.find('mxf') > -1:
instance = vlc.Instance()
media = instance.media_new('file://' + self.fullpath)
media.parse()
self.duration = media.get_duration()
def __init__(self, rootpath, filename, id=None, hash=None, size=None,
packinglist=False, type=None):
'''Initialize an asset, has to have a filename and path.'''
self.rootpath = rootpath
if filename[0:8] == 'file:///':
filename = filename[8:]
self.filename = filename
self.fullpath = rootpath + '/' + filename
if id != None:
if id is not None:
self.id = id
if hash != None:
if hash is not None:
self.hash = hash
if size != None:
if size is not None:
self.size = size
if type != None:
if type is not None:
self.type = type
self.packinglist = packinglist
class DCP:
'''A complete DCP package.'''
def verify (self):
def verify(self):
'''Verifies that all assets are of the correct size and have
the correct hash.'''
for asset in self.assets:
try:
if asset.verifySize () == False:
if not asset.verifySize():
return False
except BaseException as e:
raise RuntimeError ('Failed size comparisement for ' +\
asset.filename) from e
#Sort the assets by size before calculating hashes, for performance.
def sortkey(x):
try:
return x.size
except AttributeError:
return 0
self.assets.sort (key=sortkey)
raise RuntimeError('Failed size comparisement for ' +
asset.filename) from e
'''Sort the assets by size before calculating hashes, for
performance.'''
self.assets.sort(key=lambda x: try: return x.size except
AttributeError: return 0)
for asset in self.assets:
try:
if asset.verifyHash () == False:
if not asset.verifyHash():
return False
except BaseException as e:
raise RuntimeError ('Failed hash calculation for ' +\
asset.filename) from e
raise RuntimeError('Failed hash calculation for ' +
asset.filename) from e
return True
def _parse_assetmap (self):
def _parse_assetmap(self):
'''Adds the asset map file to the list of assets and parses it.'''
if 'ASSETMAP.xml' in listdir (self.directory):
if 'ASSETMAP.xml' in listdir(self.directory):
filename = 'ASSETMAP.xml'
elif 'ASSETMAP' in listdir (self.directory):
elif 'ASSETMAP' in listdir(self.directory):
filename = 'ASSETMAP'
else:
raise RuntimeError ('Couldn\'t find assetmap file')
self.assets = [Asset (self.directory, filename, type='text/xml')]
raise RuntimeError('Couldn\'t find assetmap file')
self.assets = [Asset(self.directory, filename, type='text/xml')]
assetmap = self.assets[0].fullpath
try:
assetmap = parse (assetmap).getElementsByTagName ('Asset')
self.assets.append (Asset (self.directory, filename))
assetmap = parse(assetmap).getElementsByTagName('Asset')
self.assets.append(Asset(self.directory, filename))
for element in assetmap:
id = element.getElementsByTagName ('Id')[0].firstChild.data
id = id.split (':')[-1]
filename = element.getElementsByTagName ('Path')[0].firstChild.data
packinglist = len (element.getElementsByTagName ('PackingList')) > 0
id = element.getElementsByTagName('Id')[0].firstChild.data
id = id.split(':')[-1]
filename = element.getElementsByTagName('Path')[0]\
.firstChild.data
packinglist = len(element.getElementsByTagName
('PackingList')) > 0
if packinglist:
self.assets.append (Asset (self.directory, filename,\
id=id, packinglist=packinglist, type='text/xml'))
self.assets.append(Asset(self.directory, filename,
id=id, packinglist=packinglist,
type='text/xml'))
else:
self.assets.append (Asset (self.directory, filename,\
id=id, packinglist=packinglist))
self.assets.append(Asset(self.directory, filename,
id=id, packinglist=packinglist))
except BaseException as e:
raise RuntimeError ('Failed to parse assetmap file') from e
raise RuntimeError('Failed to parse assetmap file') from e
def _add_volindex (self):
def _add_volindex(self):
'''Adds the volume index file to the list of assets.'''
if 'VOLINDEX.xml' in listdir (self.directory):
if 'VOLINDEX.xml' in listdir(self.directory):
filename = 'VOLINDEX.xml'
elif 'VOLINDEX' in listdir (self.directory):
elif 'VOLINDEX' in listdir(self.directory):
filename = 'VOLINDEX'
else:
#raise RuntimeError ('Couldn\'t find volindex file')
'''raise RuntimeError('Couldn\'t find volindex file')'''
return
self.assets.append (Asset (self.directory, filename, type='text/xml'))
self.assets.append(Asset(self.directory, filename, type='text/xml'))
def _parse_packinglist (self):
def _parse_packinglist(self):
'''Parses the packing list.'''
try:
pkls = (parse (x.fullpath) for x in self.assets if x.packinglist)
pkls = (parse(x.fullpath) for x in self.assets if x.packinglist)
for pkl in pkls:
if hasattr (self, 'signed') == False:
self.signed = len (pkl.getElementsByTagName ('Signer')) > 0
if not hasattr(self, 'signed'):
self.signed = len(pkl.getElementsByTagName('Signer')) > 0
try:
if hasattr (self, 'name') == False:
self.name = pkl.getElementsByTagName\
('AnnotationText')[0].firstChild.data.strip()
if not hasattr(self, 'name'):
self.name = pkl\
.getElementsByTagName('AnnotationText')[0]\
.firstChild.data.strip()
except:
pass
for element in pkl.getElementsByTagName ('Asset'):
id = element.getElementsByTagName ('Id')[0].firstChild.data
id = id.split (':')[-1]
hash = element.getElementsByTagName ('Hash')[0].firstChild.data
type = element.getElementsByTagName ('Type')[0].firstChild.data
size = int(element.getElementsByTagName ('Size')[0].firstChild.data)
asset = [x for x in self.assets if hasattr (x, 'id') and\
x.id == id][0]
for element in pkl.getElementsByTagName('Asset'):
id = element.getElementsByTagName('Id')[0].firstChild.data
id = id.split(':')[-1]
hash = element.getElementsByTagName('Hash')[0]\
.firstChild.data
type = element.getElementsByTagName('Type')[0]\
.firstChild.data
size = int(element.getElementsByTagName('Size')[0]
.firstChild.data)
asset = [x for x in self.assets if hasattr(x, 'id') and
x.id == id][0]
asset.hash = hash
asset.size = size
asset.type = type
asset.add_duration ()
asset.add_duration()
except BaseException as e:
raise RuntimeError ('Failed to parse packinglist file') from e
raise RuntimeError('Failed to parse packinglist file') from e
def _find_cpl (self):
def _find_cpl(self):
'''Goes through the xml files, finds the CPL and extracts the data from
it.'''
for asset in [x for x in self.assets if hasattr (x, 'type') and x.type.find ('xml') > -1]:
elements = (parse (asset.fullpath)).getElementsByTagName \
('CompositionPlaylist')
if len (elements) > 0:
for asset in [x for x in self.assets if hasattr(x, 'type') and x
.type.find('xml') > -1]:
elements = (parse(asset.fullpath))\
.getElementsByTagName('CompositionPlaylist')
if len(elements) > 0:
try:
self.cpl_id = elements[0].getElementsByTagName \
('Id')[0].firstChild.data
self.cpl_date = elements[0].getElementsByTagName \
('IssueDate')[0].firstChild.data
self.cpl_id = elements[0]\
.getElementsByTagName('Id')[0].firstChild.data
self.cpl_date = elements[0]\
.getElementsByTagName('IssueDate')[0].firstChild.data
except:
pass
def __init__ (self, directory):
def __init__(self, directory):
'''Parses the DCP in the directory specified.'''
self.directory = directory
self._parse_assetmap ()
self._add_volindex ()
self._parse_packinglist ()
self._parse_assetmap()
self._add_volindex()
self._parse_packinglist()
try:
self.duration = max ([x.duration for x in self.assets if hasattr\
(x, 'duration')])
self.duration = max([x.duration for x in self.assets if hasattr
(x, 'duration')])
except:
self.duration = 'Unknown'
self._find_cpl ()
self._find_cpl()
def copyAndVerify (self, destination):
def copyAndVerify(self, destination):
'''Copies the DCP to the destination directory and verifies during.'''
for asset in self.assets:
totalsize = stat (asset.fullpath).st_size
totalsize = stat(asset.fullpath).st_size
try:
if asset.verifySize () == False:
if not asset.verifySize():
return False
except BaseException as e:
raise RuntimeError ('Failed size comparisement for ' +\
asset.filename) from e
freespace = statvfs (destination).f_bavail * statvfs\
(destination).f_bsize
raise RuntimeError('Failed size comparisement for '
+ asset.filename) from e
freespace = statvfs(destination).f_bavail\
* statvfs(destination).f_bsize
if freespace < totalsize:
return False
#Sort the assets by size before calculating hashes, for performance.
def sortkey(x):
try:
return x.size
except AttributeError:
return 0
self.assets.sort (key=sortkey)
newdirectory = destination + '/' + basename (self.directory)
mkdir (newdirectory)
'''Sort the assets by size before calculating hashes, for
performance.'''
self.assets.sort(key=lambda x: try: return x.size except
AttributeError: return 0)
newdirectory = destination + '/' + basename(self.directory)
mkdir(newdirectory)
for asset in self.assets:
try:
if asset.copyAndVerify (newdirectory) == False:
if not asset.copyAndVerify(newdirectory):
return False
except BaseException as e:
raise RuntimeError ('Failed hash calculation for ' +\
asset.filename) from e
raise RuntimeError('Failed hash calculation for ' +
asset.filename) from e
self.directory = newdirectory
return True
if __name__ == '__main__':
if len (sys.argv) == 2:
dcp = DCP (sys.argv[1])
if len(sys.argv) == 2:
dcp = DCP(sys.argv[1])
else:
dcp = DCP ('./')
dcp = DCP('./')
try:
print ('Name:', dcp.name)
print('Name:', dcp.name)
except:
pass
if dcp.signed:
print ('DCP is signed')
print('DCP is signed')
else:
print ('DCP is unsigned')
print ('Duration:', dcp.duration)
if dcp.verify ():
print ('Verification succeeded.')
print('DCP is unsigned')
print('Duration:', dcp.duration)
if dcp.verify():
print('Verification succeeded.')
else:
print ('Verification failed.')
exit (0)
print('Verification failed.')
exit(0)
......@@ -5,8 +5,9 @@ try:
from dcpman.dcp import DCP
except:
from dcp import DCP
'''autogenerated file from Qt Designer to setup the window.'''
try:
from dcpman import ui #autogenerated file from Qt Designer to setup the window
from dcpman import ui
except:
import ui
import sys
......@@ -14,81 +15,82 @@ from os.path import basename
import syslog
import time
class verifyThread (QtCore.QThread):
'''A seperate thread to verify the DCP (IO intensive).
Verify the assets of DCP (reads all of the files to
class verifyThread(QtCore.QThread):
'''A seperate thread to verify the DCP(IO intensive).
Verify the assets of DCP(reads all of the files to
calculate the hash) in a seperate thread from the GUI to keep the GUI
responsive. At the end update the verifyLine test to reflect the result.'''
def run (self):
def run(self):
'''The action the thread takes.'''
result = dcp.verify ()
result = dcp.verify()
try:
result = dcp.verify ()
result = dcp.verify()
if result:
window.verifyLine.setText ('OK')
syslog.syslog (syslog.LOG_INFO, time.ctime () +\
directoryname + ' verification succeeded.')
window.verifyLine.setText('OK')
syslog.syslog(syslog.LOG_INFO, time.ctime() +
directoryname + ' verification succeeded.')
else:
window.verifyLine.setText ('Corrupted!')
syslog.syslog (syslog.LOG_INFO, time.ctime () +\
directoryname + ' verification failed.')
window.verifyLine.setText('Corrupted!')
syslog.syslog(syslog.LOG_INFO, time.ctime() +
directoryname + ' verification failed.')
except BaseException as exception:
window.verifyLine.setText (str (exception))
window.verifyLine.setText(str(exception))
def verify_in_thread():
'''Verifys the DCP in a differenet thread.
Firstly disable the button and change the verifyLine to reflect that the
verification is running (in the same thread to update the window immediately
verification is running(in the same thread to update the window immediately
then calls the seperate thread to verify the assets of DCP.'''
window.verifyLine.setText ('Verifying, please wait...')
window.verifyButton.setEnabled (False)
thread.start ()
window.verifyLine.setText('Verifying, please wait...')
window.verifyButton.setEnabled(False)
thread.start()
if __name__ == '__main__':
syslog.openlog (ident = 'dcpman', facility = syslog.LOG_USER)
app = QtGui.QApplication (sys.argv)
icon = QtGui.QIcon ('/usr/share/icons/oxygen/16x16/apps/kmplayer.png')
app.setWindowIcon (icon)
directory = QtGui.QFileDialog.getExistingDirectory ( \
caption='Please select the location of the DCP')
directoryname = basename (directory)
mainwindow = QtGui.QMainWindow ()
window = ui.Ui_MainWindow ()
window.setupUi (mainwindow)
thread = verifyThread ()
syslog.openlog(ident='dcpman', facility=syslog.LOG_USER)
app = QtGui.QApplication(sys.argv)
icon = QtGui.QIcon('/usr/share/icons/oxygen/16x16/apps/kmplayer.png')
app.setWindowIcon(icon)
directory = QtGui.QFileDialog.getExistingDirectory(
caption='Please select the location of the DCP')
directoryname = basename(directory)
mainwindow = QtGui.QMainWindow()
window = ui.Ui_MainWindow()
window.setupUi(mainwindow)
thread = verifyThread()
try:
dcp = DCP (directory)
dcp = DCP(directory)
try:
window.nameLine.setText (dcp.name)
syslog.syslog (syslog.LOG_INFO, time.ctime () + directoryname +\
' parsed.')
window.nameLine.setText(dcp.name)
syslog.syslog(syslog.LOG_INFO, time.ctime() + directoryname +
' parsed.')
except AttributeError as exception:
window.nameLine.setText (basename (directory))
syslog.syslog (syslog.LOG_INFO, time.ctime () + directoryname +\
exception)
window.nameLine.setText(basename(directory))
syslog.syslog(syslog.LOG_INFO, time.ctime() + directoryname +
exception)
if dcp.signed:
syslog.syslog (syslog.LOG_INFO, time.ctime () + directoryname +\
' is signed.')
syslog.syslog(syslog.LOG_INFO, time.ctime() + directoryname +
' is signed.')
else:
syslog.syslog (syslog.LOG_INFO, time.ctime () + directoryname +\
' is not sigend.')
syslog.syslog (syslog.LOG_INFO, time.ctime () + directoryname +\
' duration is ' + str (dcp.duration))
syslog.syslog(syslog.LOG_INFO, time.ctime() + directoryname +
' is not sigend.')
syslog.syslog(syslog.LOG_INFO, time.ctime() + directoryname +
' duration is ' + str(dcp.duration))
if dcp.signed and dcp.duration == 0:
window.encryptedLine.setText ('Most likely')
window.encryptedLine.setText('Most likely')
elif dcp.signed or dcp.duration == 0:
window.encryptedLine.setText ('Probably')
window.encryptedLine.setText('Probably')
else:
window.encryptedLine.setText ('Probably not')
window.verifyLine.setText ('Click button to start verification')
window.verifyButton.clicked.connect (verify_in_thread)
window.encryptedLine.setText('Probably not')
window.verifyLine.setText('Click button to start verification')
window.verifyButton.clicked.connect(verify_in_thread)
except BaseException as exception:
window.nameLine.setText (str (exception))
window.verifyButton.setEnabled (False)
mainwindow.show ()
mainwindow.activateWindow ()
exit(app.exec_ ())
window.nameLine.setText(str(exception))
window.verifyButton.setEnabled(False)
mainwindow.show()
mainwindow.activateWindow()
exit(app.exec_())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment