Skip to content

Commit

Permalink
first pass at tidying up code using IDE warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
seb26 committed Mar 29, 2019
1 parent f87ce81 commit 404aab0
Showing 1 changed file with 84 additions and 51 deletions.
135 changes: 84 additions & 51 deletions mhl-compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import os
import argparse
import codecs
import operator
from datetime import datetime

import xmltodict
Expand All @@ -23,7 +22,7 @@
HASH_TYPES_ACCEPTABLE = [ 'xxhash64be', 'xxhash64', 'xxhash', 'md5', 'sha1' ]

LOG_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
LOG_VERBOSE = False # By default, don't show detail about which files changed
LOG_VERBOSE = False # By default, don't show detail about which files changed

LOG_COLOR_MHL_A = 'green'
LOG_COLOR_MHL_B = 'yellow'
Expand All @@ -37,11 +36,14 @@
LOG_APPTYPE = 'Python'

LOG_VERSION = '0.3d'
LOG_STARTUP_LINE = 'mhl-compare (v{}) ({})'.format( LOG_VERSION, LOG_APPTYPE ) + ' (Author: Sebastian Reategui) (MIT License)'
LOG_AUTHOR_AND_LICENSE = '(Author: Sebastian Reategui) (MIT License)'
LOG_STARTUP_LINE = 'mhl-compare (v{}) ({}) {}'.format(
LOG_VERSION, LOG_APPTYPE, LOG_AUTHOR_AND_LICENSE)

print('--------------')
print(LOG_STARTUP_LINE)


def showDate(dt):
if not isinstance(dt, datetime):
# If for some reason, a datetime object isn't passed,
Expand All @@ -50,17 +52,20 @@ def showDate(dt):
else:
return dt.strftime(LOG_TIME_FORMAT)

def showSize(bytes):
if bytes < 1024:

def showSize(numBytes):
if numBytes < 1024:
return str(bytes) + " bytes"
else:
return humanize.naturalsize(bytes, binary=True) + " ({} bytes)".format(bytes)
return humanize.naturalsize(numBytes, binary=True) + " ({} bytes)".format(numBytes)


def logDetail(*args, **kwargs):
if LOG_VERBOSE:
print(*args, **kwargs, end='\n')
return


def color(text, color, **kwargs):
# Only print in colour if inside a terminal
# Don't print colour codes if they go out to a file or other
Expand All @@ -69,11 +74,13 @@ def color(text, color, **kwargs):
else:
return text


def hashConvertEndian(hashString):
## Converts any given BE or LE hash, as a string
## And returns the opposite byte order
# Converts any given BE or LE hash, as a string
# And returns the opposite byte order
return codecs.encode(codecs.decode(hashString, 'hex')[::-1], 'hex').decode()


class MHL:
def __init__(self, listObj, filepath):
self.filepath = filepath
Expand All @@ -88,7 +95,7 @@ def __init__(self, listObj, filepath):
else:
self.creatorinfo = None

if not 'hash' in listObj['hashlist']:
if 'hash' not in listObj['hashlist']:
# No hash entries listed
print('There were no files found listed in this MHL file:\n {}\nAlternatively, there was a formatting issue in the file.'.format(self.filepath))
sys.exit(0)
Expand Down Expand Up @@ -262,6 +269,7 @@ def __lt__(self, other):
class HashNonexistent:
def __getattr__(self, attribute):
return None

def __setattr__(self, attribute):
return None

Expand All @@ -287,13 +295,13 @@ def __init__(self, mhlA, mhlB):

# Define the categories of outcomes.
count_values = [
'PERFECT', # Match hash and all filesystem attributes
'MINOR', # Match hash but one or more filesystem attributes are different
'HASH_TYPE_DIFFERENT', # Hash type is different, cannot be compared
'HASH_CHANGED', # Hash is different, indicating a file change
'MISSING', # Exists only in one list or the other
'DUPLICATE', # When there are multiple files listed with exactly the same hash
'IMPOSSIBLE' # For anomalies (like hash the same but size different)
'PERFECT', # Match hash and all filesystem attributes
'MINOR', # Match hash but one or more filesystem attributes are different
'HASH_TYPE_DIFFERENT', # Hash type is different, cannot be compared
'HASH_CHANGED', # Hash is different, indicating a file change
'MISSING', # Exists only in one list or the other
'DUPLICATE', # When there are multiple files listed with exactly the same hash
'IMPOSSIBLE' # For anomalies (like hash the same but size different)
]
# Create a place to store these numbers as we go along.
self.COUNT = {}
Expand Down Expand Up @@ -357,21 +365,31 @@ def checkCommon(self):
if not beenCounted:
self.COUNT['MINOR'] += 1
beenCounted = True
logDetail( ' Modified date: different (1st):', color( hashA.lastmodificationdate, LOG_COLOR_MHL_A ) )
logDetail( ' (2nd):', color( hashB.lastmodificationdate, LOG_COLOR_MHL_B ) )
logDetail(
' Modified date: different (1st):',
color( hashA.lastmodificationdate, LOG_COLOR_MHL_A )
)
logDetail(
' (2nd):',
color( hashB.lastmodificationdate, LOG_COLOR_MHL_B )
)

# Briefly explain to the user what attributes were added/removed
if len(dAdded) > 0:
dAddedList = ', '.join( str(i) for i in dAdded )
logDetail( ' These attributes exist in 1st only:',
color(dAddedList, LOG_COLOR_MHL_A ) )
logDetail(
' These attributes exist in 1st only:',
color(dAddedList, LOG_COLOR_MHL_A )
)
if len(dRemoved) > 0:
dRemovedList = ', '.join( str(i) for i in dRemoved )
logDetail( ' These attributes exist in 2nd only:',
color(dRemovedList, LOG_COLOR_MHL_B ) )
logDetail(
' These attributes exist in 2nd only:',
color(dRemovedList, LOG_COLOR_MHL_B )
)

def checkDelta(self, listA=False, listB=False):
if listA is True:
def checkDelta(self, letter):
if letter == 'A':
delta = self.deltaA
# Refer to the opposite MHL to access and perform searches on it
oppositeMHL = self.B
Expand All @@ -381,7 +399,7 @@ def checkDelta(self, listA=False, listB=False):
listLabelOpposite = '2nd'
listColor = LOG_COLOR_MHL_A
listColorOpposite = LOG_COLOR_MHL_B
elif listB is True:
elif letter == 'B':
delta = self.deltaB
oppositeMHL = self.A

Expand All @@ -395,7 +413,7 @@ def checkDelta(self, listA=False, listB=False):
return

# Quickly clean Nonexistent objects out if they exist
deltaClean = [ h for h in delta if not isinstance(h,HashNonexistent) ]
deltaClean = [ h for h in delta if not isinstance(h, HashNonexistent) ]
deltaClean.sort()

for hash in deltaClean:
Expand All @@ -405,12 +423,12 @@ def checkDelta(self, listA=False, listB=False):
# print('rh', hash.recordedHashes)

foundHashPossible = None
beenCounted = False # If this hash has been counted yet
beenCounted = False # If this hash has been counted yet

# Look for a match by other hash
for otherHashType, otherHashValue in hash.recordedHashes.items():
if otherHashType == hash.identifierType:
pass # to next hash in the list
pass # to next hash in the list

hashPossible = oppositeMHL.findByOtherHash( otherHashType, otherHashValue )
if isinstance(hashPossible, HashNonexistent):
Expand All @@ -428,7 +446,7 @@ def checkDelta(self, listA=False, listB=False):
foundHashPossible = True
break

if foundHashPossible == False:
if foundHashPossible is False:
# Searched but no matches by other hash.
# Look for a match by filename
hashPossible = oppositeMHL.findHashByAttribute( 'filename', hash.filename )
Expand All @@ -439,7 +457,7 @@ def checkDelta(self, listA=False, listB=False):
else:
foundHashPossible = True

if foundHashPossible == True:
if foundHashPossible is True:
# Compare the hash and the possible hash.
diff = DictDiffer(hash.__dict__, hashPossible.__dict__)
dAdded = diff.added()
Expand Down Expand Up @@ -485,11 +503,18 @@ def checkDelta(self, listA=False, listB=False):
logDetail(color(" Hash: These hashes are of different types. It's not possible to compare them.", LOG_COLOR_INFORMATION))

if hash.isDuplicate is False:
logDetail(' Hash ({}):'.format(listLabel),
color('{} ({})'.format(hash.identifier, hash.identifierType), listColor)
logDetail(
' Hash ({}):'.format(listLabel),
color(
'{} ({})'.format(hash.identifier, hash.identifierType), listColor
)
)
logDetail(' Hash ({}):'.format(listLabelOpposite),
color('{} ({})'.format(hashPossible.identifier, hashPossible.identifierType), listColorOpposite)
logDetail(
' Hash ({}):'.format(listLabelOpposite),
color(
'{} ({})'.format(hashPossible.identifier, hashPossible.identifierType),
listColorOpposite
)
)

if { 'filename', 'directory', 'size', 'lastmodificationdate' }.issubset(dUnchanged):
Expand Down Expand Up @@ -520,7 +545,6 @@ def checkDelta(self, listA=False, listB=False):
else:
logDetail( ' Path: identical:', hash.directory )


if 'size' in dChanged:
# It is an anomaly if the size has changed, but not the hash.
# Report it as impossible, but also print it to the user anyway.
Expand All @@ -546,21 +570,27 @@ def checkDelta(self, listA=False, listB=False):
# Briefly explain to the user what attributes were added/removed
if len(dAdded) > 0:
dAddedList = ', '.join( str(i) for i in dAdded )
logDetail( ' These attributes exist in 1st only:',
color(dAddedList, LOG_COLOR_MHL_A ) )
logDetail(
' These attributes exist in 1st only:',
color(dAddedList, LOG_COLOR_MHL_A )
)
if len(dRemoved) > 0:
dRemovedList = ', '.join( str(i) for i in dRemoved )
logDetail( ' These attributes exist in 2nd only:',
color(dRemovedList, LOG_COLOR_MHL_B ) )
logDetail(
' These attributes exist in 2nd only:',
color(dRemovedList, LOG_COLOR_MHL_B )
)

pass

if foundHashPossible == False:
if foundHashPossible is False:
# Begin to print the results
self.COUNT['MISSING'] += 1
logDetail(' ' + color(hash.filename, listColor, attrs=LOG_COLOR_BOLD))
logDetail(' This file only exists in',
color(listLabel + ' MHL', listColor) + '.' )
logDetail(
' This file only exists in',
color(listLabel + ' MHL', listColor) + '.'
)
logDetail( ' ' + 'Path:', hash.directory )
logDetail( ' ' + 'Size:', hash.sizeHuman )
logDetail( ' ' + 'Hash:', hash.identifier, '({})'.format(hash.identifierType ) )
Expand Down Expand Up @@ -614,10 +644,10 @@ def printCount(self):
}
for label in outcomes.values():
# If a singular description ('was' vs. 'were') is not defined, just use the regular description.
if not 'desc_singular' in label.keys():
if 'desc_singular' not in label.keys():
label['desc_singular'] = label['desc']
# If a color is not defined, don't use any.
if not 'color' in label.keys():
if 'color' not in label.keys():
label['color'] = None

print('')
Expand Down Expand Up @@ -658,8 +688,11 @@ def printCount(self):
parser = argparse.ArgumentParser()
parser.add_argument( "PATH_A", help="path to list A", type=str)
parser.add_argument( "PATH_B", help="path to list B", type=str)
parser.add_argument( "-v", "--verbose", "--info",
help="gives greater detail on all files affected", action="store_true")
parser.add_argument(
"-v", "--verbose", "--info",
help="gives greater detail on all files affected",
action="store_true"
)
args = parser.parse_args()


Expand All @@ -671,14 +704,14 @@ def printCount(self):
foundA = os.path.isfile(args.PATH_A)
foundB = os.path.isfile(args.PATH_B)

if foundA == True and foundB == True:
if foundA is True and foundB is True:
file_path_A = args.PATH_A
file_path_B = args.PATH_B
else:
not_found_string = ''
if foundA == False:
if foundA is False:
not_found_string += " " + args.PATH_A + "\n"
if foundB == False:
if foundB is False:
not_found_string += " " + args.PATH_B + "\n"
raise FileNotFoundError('Could not find these MHL file(s). Check the path for typos?\n' + not_found_string)

Expand All @@ -702,7 +735,7 @@ def printCount(self):
compare = Comparison(MHL_FILE_A, MHL_FILE_B)
compare.printInfo()
compare.checkCommon()
compare.checkDelta(listA=True)
compare.checkDelta(listB=True)
compare.checkDelta('A')
compare.checkDelta('B')
compare.printCount()
print('--------------')

0 comments on commit 404aab0

Please sign in to comment.