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