From b283e57abd98638e64f351ac582ac08a2369bfb1 Mon Sep 17 00:00:00 2001 From: Adar Nimrod <nimrod@shore.co.il> Date: Mon, 25 Aug 2014 12:20:44 +0300 Subject: [PATCH] Changed folder structure. Automated build, publish and clean using Fabric. Added dependency python3-vlc, another packages I publish from VLC source (python3 binding to libvlc). --- .gitignore | 4 +- debian/changelog | 7 +++ debian/control | 2 +- debian/files | 2 +- debian/install | 4 +- debian/rules | 2 +- fabfile.py | 16 ++++++ {dcpman => source}/__init__.py | 0 {dcpman => source}/dcp.py | 66 +++++++++++++++++++------ dcpman.desktop => source/dcpman.desktop | 0 dcpman.ui => source/dcpman.ui | 14 +++--- {dcpman => source}/manager.py | 14 ++++-- 12 files changed, 96 insertions(+), 35 deletions(-) create mode 100644 fabfile.py rename {dcpman => source}/__init__.py (100%) rename {dcpman => source}/dcp.py (72%) rename dcpman.desktop => source/dcpman.desktop (100%) rename dcpman.ui => source/dcpman.ui (91%) rename {dcpman => source}/manager.py (84%) diff --git a/.gitignore b/.gitignore index dcc6945..6e4732f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,5 @@ debian/dcpman.links debian/dcpman.postinst.debhelper debian/dcpman.prerm.debhelper debian/dcpman.substvars -dcpman/__pycache__ -dcpman/ui.py +source/__pycache__ +source/ui.py diff --git a/debian/changelog b/debian/changelog index 53e33ee..7061fff 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,12 @@ +dcpman (0.1.1) UNRELEASED; urgency=medium + + * Adding better detection of encrypted DCPs by using avprobe to try and read the mxf files (still not 100% correct). + + -- Nimrod Adar <nimrod@nimrod.private> Mon, 14 Jul 2014 13:11:42 +0300 + dcpman (0.1) UNRELEASED; urgency=medium * Initial release. -- Nimrod Adar <nimrod@shore.co.il> Sun, 29 Jun 2014 16:19:53 +0300 + diff --git a/debian/control b/debian/control index 0a9f0b9..2146d4d 100644 --- a/debian/control +++ b/debian/control @@ -7,7 +7,7 @@ X-Python3-Version: >= 3.2 Standards-Version: 3.9.5.0 Package: dcpman -Depends: python3 (>= 3.2), python3-pyqt4 | python3-pyqt5, oxygen-icon-theme +Depends: python3 (>= 3.2), python3-pyqt4 | python3-pyqt5, oxygen-icon-theme, python3-vlc Architecture: all Description: Management tool for Digital Cinema Packages. A tool to manage DCPs (Digital Cinema Packages), although currently it only diff --git a/debian/files b/debian/files index 2791153..bd1ff25 100644 --- a/debian/files +++ b/debian/files @@ -1 +1 @@ -dcpman_0.1_all.deb video optional +dcpman_0.1.1_all.deb video optional diff --git a/debian/install b/debian/install index 27ee999..348d1a7 100644 --- a/debian/install +++ b/debian/install @@ -1,2 +1,2 @@ -dcpman/* usr/lib/python3/dist-packages/dcpman -dcpman.desktop usr/share/applications +source/*.py usr/lib/python3/dist-packages/dcpman +source/dcpman.desktop usr/share/applications diff --git a/debian/rules b/debian/rules index d63755b..2a92017 100755 --- a/debian/rules +++ b/debian/rules @@ -1,4 +1,4 @@ #!/usr/bin/make -f %: - pyuic4 dcpman.ui > dcpman/ui.py + pyuic4 source/dcpman.ui > source/ui.py dh $@ --with python3 diff --git a/fabfile.py b/fabfile.py new file mode 100644 index 0000000..ae2de68 --- /dev/null +++ b/fabfile.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +from fabric.api import task, local + +@task +def publish (): + build () + for dist in ['wheezy', 'jessie', 'sid']: + local ('''reprepro includedeb ''' + dist + ''' ../dcpman_*.deb''') + +@task +def build (): + local ('''dpkg-buildpackage''') + +@task +def clean () + local ('''rm ../dcpman_*''') diff --git a/dcpman/__init__.py b/source/__init__.py similarity index 100% rename from dcpman/__init__.py rename to source/__init__.py diff --git a/dcpman/dcp.py b/source/dcp.py similarity index 72% rename from dcpman/dcp.py rename to source/dcp.py index d2fd867..cf5a846 100755 --- a/dcpman/dcp.py +++ b/source/dcp.py @@ -4,6 +4,7 @@ from base64 import b64encode from os import stat, listdir from xml.dom.minidom import parse import sys +import vlc class Asset(object): '''A simple asset that's part of whole DCP package.''' @@ -31,8 +32,15 @@ class Asset(object): hash.update(buffer) buffer = fh.read(buffersize) 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): + 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:///': @@ -45,6 +53,8 @@ class Asset(object): self.hash = hash if size != None: self.size = size + if type != None: + self.type = type self.packinglist = packinglist @@ -76,35 +86,44 @@ class DCP: asset.filename) from e return True - def __init__(self, directory): - '''Parses the DCP in the directory specified.''' - self.root = directory - if 'ASSETMAP.xml' in listdir(directory): + def _parse_assetmap (self): + '''Adds the asset map file to the list of assets and parses it.''' + if 'ASSETMAP.xml' in listdir(self.directory): filename = 'ASSETMAP.xml' - elif 'ASSETMAP' in listdir(directory): + elif 'ASSETMAP' in listdir(self.directory): filename = 'ASSETMAP' else: raise RuntimeError ('Couldn\'t find assetmap file') - self.assets = [Asset(directory, filename)] + self.assets = [Asset(self.directory, filename, type='text/xml')] assetmap = self.assets[0].fullpath - if 'VOLINDEX.xml' in listdir(directory): - filename = 'VOLINDEX.xml' - elif 'VOLINDEX' in listdir(directory): - filename = 'VOLINDEX' - #else: - #raise RuntimeError ('Couldn\'t find volindex file') - self.assets.append(Asset(directory, filename)) try: assetmap = parse(assetmap).getElementsByTagName('Asset') - self.assets.append(Asset(directory, filename)) + 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 - self.assets.append(Asset(directory, filename, id=id, packinglist=packinglist)) + if packinglist: + 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)) except BaseException as e: raise RuntimeError ('Failed to parse assetmap file') from e + + def _add_volindex (self): + '''Adds the volume index file to the list of assets.''' + if 'VOLINDEX.xml' in listdir(self.directory): + filename = 'VOLINDEX.xml' + elif 'VOLINDEX' in listdir(self.directory): + filename = 'VOLINDEX' + else: + #raise RuntimeError ('Couldn\'t find volindex file') + return + self.assets.append(Asset(self.directory, filename, type='text/xml')) + + def _parse_packinglist (self): + '''Parses the packing list.''' try: pkls = (parse(x.fullpath) for x in self.assets if x.packinglist) for pkl in pkls: @@ -119,13 +138,27 @@ class DCP: 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 () except BaseException as e: raise RuntimeError ('Failed to parse packinglist file') from e + def __init__(self, directory): + '''Parses the DCP in the directory specified.''' + self.directory = directory + self._parse_assetmap () + self._add_volindex () + self._parse_packinglist () + try: + self.duration = max ([x.duration for x in self.assets if hasattr (x, 'duration')]) + except: + pass + if __name__ == '__main__': if (len(sys.argv) == 2): @@ -140,6 +173,7 @@ if __name__ == '__main__': print ('DCP is signed') else: print ('DCP is unsigned') + print ('Duration:', dcp.duration) if (dcp.verify()): print ('Verification succeeded.') else: diff --git a/dcpman.desktop b/source/dcpman.desktop similarity index 100% rename from dcpman.desktop rename to source/dcpman.desktop diff --git a/dcpman.ui b/source/dcpman.ui similarity index 91% rename from dcpman.ui rename to source/dcpman.ui index 312d646..af070f2 100644 --- a/dcpman.ui +++ b/source/dcpman.ui @@ -19,7 +19,7 @@ <rect> <x>11</x> <y>11</y> - <width>491</width> + <width>501</width> <height>131</height> </rect> </property> @@ -30,7 +30,7 @@ <widget class="QLabel" name="nameLabel"> <property name="minimumSize"> <size> - <width>45</width> + <width>65</width> <height>0</height> </size> </property> @@ -54,20 +54,20 @@ <item> <layout class="QHBoxLayout" name="horizontalLayout_3"> <item> - <widget class="QLabel" name="signedLabel"> + <widget class="QLabel" name="encryptedLabel"> <property name="minimumSize"> <size> - <width>45</width> + <width>65</width> <height>0</height> </size> </property> <property name="text"> - <string>Signed</string> + <string>Encrypted</string> </property> </widget> </item> <item> - <widget class="QLineEdit" name="signedLine"> + <widget class="QLineEdit" name="encryptedLine"> <property name="frame"> <bool>true</bool> </property> @@ -84,7 +84,7 @@ <widget class="QLabel" name="verifyLabel"> <property name="minimumSize"> <size> - <width>45</width> + <width>65</width> <height>0</height> </size> </property> diff --git a/dcpman/manager.py b/source/manager.py similarity index 84% rename from dcpman/manager.py rename to source/manager.py index 9839879..0aedaa8 100755 --- a/dcpman/manager.py +++ b/source/manager.py @@ -1,8 +1,10 @@ #!/usr/bin/env python3 from PyQt4 import QtGui from PyQt4 import QtCore -from dcpman.dcp import DCP -from dcpman import ui #autogenerated file from Qt Designer to setup the window +#from dcpman.dcp import DCP +#from dcpman import ui #autogenerated file from Qt Designer to setup the window +from dcp import DCP +import ui import sys class verifyThread(QtCore.QThread): @@ -51,10 +53,12 @@ if __name__ == '__main__': window.nameLine.setText(dcp.name) except AttributeError: window.nameLine.setText(directory.split('/')[-1]) - if dcp.signed: - window.signedLine.setText('Signed') + if dcp.signed and dcp.duration == 0: + window.encryptedLine.setText('Most likely') + elif dcp.signed or dcp.duration == 0: + window.encryptedLine.setText ('Probably') else: - window.signedLine.setText('Not signed') + window.encryptedLine.setText('Probably not') window.verifyLine.setText('Click button to start verification') window.verifyButton.clicked.connect(verify_in_thread) except BaseException as exception: -- GitLab