Sunday, 14 October 2018

Read Manifest file of a package without extracting the file in python

We can read the MANIFEST.MF or any file from a archive file without extracting the file.
With below code we can read the manifest file and retrieve the values for the key 'Plugin-Dependencies'. We can add more keys and if that key matches then it will return the values for that key.



import argparse
import os
import sys
import zipfile
import re
import logging

global manifestkeys = []
manifestkey = 'Plugin-Dependencies'

def getManifestkeys():
        manifestkeys.append(manifestkey.lower().strip().replace('-',''))
        return manifestkeys


def getAttributes(manifestFile):
        logging.debug('Parsing attributes from %s'%(manifestFile))
        manifestkeys = getManifestkeys()
        logging.debug('Manifest Key : ' + str(manifestkeys))
        manifest = []
        current = {}
        lines = manifestFile.split('\n')
        idx = 0
        while idx<len(lines):
                line = lines[idx].strip()               
                if len(line) > 0:
                        splits = line.split(':')
                        key = splits[0].lower().strip().replace('-','')
                        if key in manifestkeys:
                                logging.debug('Key matched for ' + key)
                                value = ':'.join(splits[1:]).strip()
                                current[key] = value
                                while len(line.encode('utf-8')) >= 70:
                                        if idx<len(lines)-1:
                                                next_line = lines[idx+1]
                                                if next_line[0] == ' ':
                                                        current[key] += next_line.strip()
                                                        idx += 1
                                                        line = next_line
                                                        continue
                                        break
                elif len(current)>0 :
                        count = len(current.values())
                        # We need to weed out name only entries
                        # We can manually interrogate packages
                        if count > 1 or (count==1 and 'name' not in current.keys()):
                                manifest.append(current)
                        current = {}
                idx += 1
        if current != {}:
                manifest.append(current)
        return manifest

def readManifest(jar_file_name):
  _MANIFEST_NAME = 'META-INF/MANIFEST.MF'
  with zipfile.ZipFile(jar_file_name) as jar:
    try:
      manifest_string = jar.read(_MANIFEST_NAME)
      return getAttributes(manifest_string)
    except KeyError:
      return None


if __name__ == "__main__":
    logging.basicConfig(level=logging.WARNING)
    parser = argparse.ArgumentParser(description='Provide arguments to script as below')
    parser.add_argument('artifact_name',help='A String positional argument as artifact name for which the manifest to be read.')
    args = parser.parse_args()
    readManifest(args.artifact_name)

No comments:

Post a Comment

Thank You for your valuable comment

Difference between class level and object locking and static object lock

1) Class level locking will lock entire class, so no other thread can access any of other synchronized blocks. 2) Object locking will lo...