| 1 |
"""
|
| 2 |
|
| 3 |
MCP_Case_Scan.py
|
| 4 |
|
| 5 |
Created by
|
| 6 |
Emanuel Borges
|
| 7 |
04.08.2009
|
| 8 |
|
| 9 |
This program will run in batch mode and automatically add the SendToIpro menu item to any databases
|
| 10 |
that it finds, which do not have the menu item. This might be changed to add other things to the
|
| 11 |
menu too, in the future.
|
| 12 |
|
| 13 |
NOTE: This needs to be changed so that it actually checks the line. There have been instances where
|
| 14 |
the line is there but it's not complete.
|
| 15 |
|
| 16 |
|
| 17 |
UPDATE: on 7-31-2010 changed name from Concordance_MenuItem_Adder.py to MCP_Case_Scan.py
|
| 18 |
to reflect the fact that it's now a part of th MCP and to add functions.
|
| 19 |
|
| 20 |
UPDATE: In May 2013, started to add a davita specific section that populates a webpage. goal is to track
|
| 21 |
[deals and their dbs, tag sets, number of records in each db, number of records in each deal,
|
| 22 |
redaction report info and date, sizes of ipro project files (with warning when getting close), which ipro
|
| 23 |
each deal goes with, link to prod page, a description of each deal and maybe even of each db (this is editbl from
|
| 24 |
mchai in dbs.
|
| 25 |
]
|
| 26 |
"""
|
| 27 |
|
| 28 |
import ConfigParser,os,ConcordanceHelperTools,MCP_Lib,directorySize2
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
def ProcessCasesMain(caseToProcess = 'ALL'):
|
| 33 |
responsibleCases,activeCases,officeCases,allCases,casesDir,casePathStyleMatrix = MCP_Lib.GetCaseList()
|
| 34 |
responsibleCasesMatrix = {}
|
| 35 |
if caseToProcess == 'ALL':
|
| 36 |
pass
|
| 37 |
else:
|
| 38 |
responsibleCases = [caseToProcess]
|
| 39 |
for i in responsibleCases:
|
| 40 |
caseName,clientMatterNumber = i.split("_(")
|
| 41 |
clientMatterNumber = clientMatterNumber[:-1]
|
| 42 |
responsibleCasesMatrix[clientMatterNumber] = caseName
|
| 43 |
responsibleCLMList = responsibleCasesMatrix.keys()
|
| 44 |
|
| 45 |
## if the case is Davita, turn the davita flag on.
|
| 46 |
if '039323-0308' in responsibleCLMList:
|
| 47 |
davitaFlag = True
|
| 48 |
print "davita! Running extra stuff"
|
| 49 |
|
| 50 |
for cliMatt in responsibleCLMList:
|
| 51 |
fullDatabaseList = []
|
| 52 |
fullDatabaseMatrix = {}
|
| 53 |
catDatabaseMatrix = {}
|
| 54 |
globalTagDatabaseMatrix = {}
|
| 55 |
print "-"*32
|
| 56 |
print
|
| 57 |
print "Now processing %s"% responsibleCasesMatrix[cliMatt]
|
| 58 |
#os.path.walk(ConcordanceHelperTools.ParseClientMatter(cliMatt), CheckForMenuItem, args)
|
| 59 |
for root, dirs, files in os.walk(ConcordanceHelperTools.ParseClientMatter(cliMatt)):
|
| 60 |
if "Match" in root:
|
| 61 |
print "match folder skipping"
|
| 62 |
elif "Tag_Databases" in root:
|
| 63 |
print "tags db folder skiping"
|
| 64 |
tagDatabaseList = ConcordanceHelperTools.EnumerateConcordanceDatabases(root, files)
|
| 65 |
for tagdb in tagDatabaseList:
|
| 66 |
tagList = GatherGlobalTags(os.path.join(root,tagdb))
|
| 67 |
globalTagDatabaseMatrix[os.path.join(root,tagdb)] = tagList
|
| 68 |
else:
|
| 69 |
CheckForMenuItem(root, files)
|
| 70 |
databaseList = ConcordanceHelperTools.EnumerateConcordanceDatabases(root, files)
|
| 71 |
fullDatabaseList.extend(databaseList)
|
| 72 |
## If this is davita, grab db names with folder path, grab contents of the cats and contents of global tag dbs.
|
| 73 |
for dbi in databaseList:
|
| 74 |
fullDatabaseMatrix[dbi] = root
|
| 75 |
if dbi[-8:] == '_CAT.DCB':
|
| 76 |
catDbList = []
|
| 77 |
catContents = open(os.path.join(root,dbi.replace(".DCB",".CAT"))).readlines()
|
| 78 |
for catDb in catContents:
|
| 79 |
catDbList.append(catDb)
|
| 80 |
catDatabaseMatrix[os.path.join(root,dbi.replace(".DCB",""))] = catDbList
|
| 81 |
|
| 82 |
currentDatabaseList = []
|
| 83 |
databaseListFile = os.path.join(casesDir,responsibleCasesMatrix[cliMatt]+"_("+cliMatt+")","DatabaseList.txt")
|
| 84 |
databaseWithPathListFile = os.path.join(casesDir,responsibleCasesMatrix[cliMatt]+"_("+cliMatt+")","DatabaseListWithPaths.txt")
|
| 85 |
print "Checking the database list file..."
|
| 86 |
if os.path.isfile(databaseListFile):
|
| 87 |
currentDatabaseList = open(databaseListFile).readlines()
|
| 88 |
missingFiles = False
|
| 89 |
for db in fullDatabaseList:
|
| 90 |
if db+"\n" in currentDatabaseList:
|
| 91 |
pass
|
| 92 |
else:
|
| 93 |
missingFiles = True
|
| 94 |
if missingFiles:
|
| 95 |
print "Incomplete database list file found. Updating..."
|
| 96 |
outputFile = open(databaseListFile,'w')
|
| 97 |
outputFile2 = open(databaseWithPathListFile,'w')
|
| 98 |
for i in fullDatabaseList:
|
| 99 |
outputFile.write(i+"\n")
|
| 100 |
outputFile2.write(fullDatabaseMatrix[i].replace(ConcordanceHelperTools.ParseClientMatter(cliMatt)+"\\","")+"|"+i+"\n")
|
| 101 |
outputFile.close()
|
| 102 |
outputFile2.close()
|
| 103 |
print "Updating complete."
|
| 104 |
else:
|
| 105 |
print "All databases in list file accounted for."
|
| 106 |
else:
|
| 107 |
print "No database list file found, making a new one.."
|
| 108 |
outputFile = open(databaseListFile,'w')
|
| 109 |
outputFile2 = open(databaseWithPathListFile,'w')
|
| 110 |
for i in fullDatabaseList:
|
| 111 |
outputFile.write(i+"\n")
|
| 112 |
outputFile2.write(fullDatabaseMatrix[i].replace(ConcordanceHelperTools.ParseClientMatter(cliMatt)+"\\","")+"|"+i+"\n")
|
| 113 |
outputFile.close()
|
| 114 |
outputFile2.close()
|
| 115 |
print "File created."
|
| 116 |
CreateHTMLReport(fullDatabaseList, fullDatabaseMatrix, catDatabaseMatrix, globalTagDatabaseMatrix,cliMatt)
|
| 117 |
|
| 118 |
def GatherGlobalTags(databasePath):
|
| 119 |
iniPath = os.path.splitext(databasePath)[0] + ".ini"
|
| 120 |
cp = ConfigParser.ConfigParser()
|
| 121 |
cp.read(iniPath)
|
| 122 |
if cp.has_section('Tags'):
|
| 123 |
rawTagList = cp.items('Tags')
|
| 124 |
tagList = []
|
| 125 |
for tag in rawTagList:
|
| 126 |
tagList.append(tag[1])
|
| 127 |
return tagList
|
| 128 |
else:
|
| 129 |
return []
|
| 130 |
|
| 131 |
def CreateHTMLReport(fullDatabaseList, fullDatabaseMatrix, catDatabaseMatrix, globalTagDatabaseMatrix,cliMatt):
|
| 132 |
"""This is davita specific for now but if you make it more global, remove these hard coded values."""
|
| 133 |
dealMatrix ={}
|
| 134 |
iproToDBMatrix = {}
|
| 135 |
mediaPath = r"W:\Manny\Client\39323308\__MCP_Data"
|
| 136 |
iproProjectPaths = [r"\\entpvt71\data\Ipro\PROJECTS\39323308_Review_Documents_1\I2KMPAGE.IDB",
|
| 137 |
r"\\entpvt71\data\Ipro\PROJECTS\39323308_Review_Documents_2\I2KMPAGE.IDB",
|
| 138 |
r"\\entpvt71\data\Ipro\PROJECTS\39323308_Review_Documents_3\I2KMPAGE.IDB",
|
| 139 |
r"\\entpvt71\data\Ipro\PROJECTS\39323308_GJ_Production_Docs\I2KMPAGE.IDB"]
|
| 140 |
iproProjectSizesList = []
|
| 141 |
for projPath in iproProjectPaths:
|
| 142 |
iproProjectSizesList.append(directorySize2.pretty_filesize2(os.path.getsize(projPath)))
|
| 143 |
redactionReportPath = r"\\lisdisdss01\dis29\C_D\39323308\Requests\_Redaction_Reports"
|
| 144 |
for redactionReport in os.listdir(redactionReportPath):
|
| 145 |
if "Review_ALL_redactionReport_CLEAN_.txt" in redactionReport:
|
| 146 |
redactionReportDate = redactionReport[:8]
|
| 147 |
redactionReportLink = os.path.join(redactionReportPath,redactionReport)
|
| 148 |
rContents = open(redactionReportLink).readlines()
|
| 149 |
redactionDocCount = len(rContents)
|
| 150 |
localRedactionReportLink = os.path.join(mediaPath,redactionReport)
|
| 151 |
rOutputFile = open(localRedactionReportLink,'w')
|
| 152 |
rOutputFile.writelines(rContents)
|
| 153 |
rOutputFile.close()
|
| 154 |
else:
|
| 155 |
redactionReportDate = "None"
|
| 156 |
for db in fullDatabaseList:
|
| 157 |
fullPath = fullDatabaseMatrix[db]
|
| 158 |
partialPath = fullPath.replace(ConcordanceHelperTools.ParseClientMatter(cliMatt),"")
|
| 159 |
## first open the MCP_Ipro file
|
| 160 |
try:
|
| 161 |
#print os.path.join(os.path.join(os.path.split(fullPath)[0],partialPath[1:]),partialPath[1:]+".mcp_ipro")
|
| 162 |
iproProj = open(os.path.join(os.path.join(os.path.split(fullPath)[0],partialPath[1:]),partialPath[1:]+".mcp_ipro")).readline()
|
| 163 |
iproToDBMatrix[os.path.split(partialPath)[1]] = iproProj
|
| 164 |
except:
|
| 165 |
pass
|
| 166 |
if partialPath:
|
| 167 |
partialPath = partialPath[1:]
|
| 168 |
try:
|
| 169 |
dealMatrix[partialPath].append(db)
|
| 170 |
except:
|
| 171 |
dealMatrix[partialPath] = [db,]
|
| 172 |
else:
|
| 173 |
try:
|
| 174 |
dealMatrix['_root_'].append(db)
|
| 175 |
except:
|
| 176 |
dealMatrix['_root_'] = [db,]
|
| 177 |
htmlPage = open(os.path.join(mediaPath,'index.html'),'w')
|
| 178 |
htmlPage.write(r"""<html>
|
| 179 |
<head>
|
| 180 |
<title>MCP: DaVita-Dallas_(039323-0308) Production Report</title>
|
| 181 |
<style type="text/css" media="screen">
|
| 182 |
|
| 183 |
div#Rsidebar {
|
| 184 |
float: right;
|
| 185 |
width: 20%;
|
| 186 |
}
|
| 187 |
div#Lsidebar {
|
| 188 |
float: left;
|
| 189 |
width:20%;
|
| 190 |
height:380px;
|
| 191 |
}
|
| 192 |
|
| 193 |
</style>
|
| 194 |
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
|
| 195 |
<meta name="author" content="Emanuel Borges">
|
| 196 |
</head>
|
| 197 |
<body>
|
| 198 |
|
| 199 |
<h3><br>
|
| 200 |
</h3>
|
| 201 |
<center><h1>DaVita-Dallas_(039323-0308) Case Organizer</h1></center><center><hr width="40%"><p><a href="#docProds">Document Production Information</a><br><a href="#GlobalTags">Global Tag Sets</a><br><a href="#catDBs">Listing of Concatenated Database Sources</a><br><a href="#dealsDbs">Listing if Deals and Databases</a><br><br><br><br></center>""")
|
| 202 |
htmlPage.write('<div id="Rsidebar">\n<table border=1 cellspacing=0 cellpadding=5>\n<tr>\n<td>\n<center><b>iPro Status</b><br>(2GB is max size)</center>\n<dl>\n<dt>Redaction Report Date:</dt>\n<dd>- %s</dd>\n<dt>Redaction Doc Count:</dt>\n<dd>- %s</dd>\n<dt>Redaction Report Link:</dt>\n<dd>- <a href="%s">report</a></dd>\n<dt>Review 1 size:</dt>\n<dd>- %s</dd>\n<dt>Review 2 size:</dt>\n<dd>- %s</dd>\n<dt>Review 3 size:</dt>\n<dd>- %s</dd>\n<dt>Grand Jury size:</dt>\n<dd>- %s</dd>\n</dl>\n</td>\n</tr>\n</table>\n</div>'%(redactionReportDate,redactionDocCount,localRedactionReportLink,iproProjectSizesList[0],iproProjectSizesList[1],iproProjectSizesList[2],iproProjectSizesList[3]))
|
| 203 |
|
| 204 |
htmlPage.write("""<a name=docProds><h2>Document productions:</h2></a>\n<ul><li><a href="./MCP_Production_Report.html">Document Production Page</a></li></ul><br><br><br>""")
|
| 205 |
|
| 206 |
if globalTagDatabaseMatrix:
|
| 207 |
htmlPage.write("<a name=GlobalTags><h2>Listing of Davita Global Tag Sets:</h2></a>\n<ul>\n")
|
| 208 |
for tagDB in globalTagDatabaseMatrix.keys():
|
| 209 |
tagName = tagDB.replace(r"\\lisdisdss01\ERCDIS06\E\Data\Concordance\03\039\39323308","")
|
| 210 |
tagName = tagName.replace("\\Tag_Databases\\","")
|
| 211 |
tagName = tagName.replace('.DCB','')
|
| 212 |
htmlPage.write("<li><b>%s</b></li>\n<ul>\n"%tagName)
|
| 213 |
globalTagList = globalTagDatabaseMatrix[tagDB]
|
| 214 |
globalTagList.sort()
|
| 215 |
for tg in globalTagList:
|
| 216 |
htmlPage.write("<li>%s</li>\n"%tg)
|
| 217 |
htmlPage.write("</ul>\n")
|
| 218 |
htmlPage.write("</ul><br><br><br>\n")
|
| 219 |
|
| 220 |
if catDatabaseMatrix:
|
| 221 |
htmlPage.write("<a name=catDBs><h2>Listing of Davita Concatentations:</h2></a>\n<ul>\n")
|
| 222 |
for catDb in catDatabaseMatrix.keys():
|
| 223 |
htmlPage.write("<li><b>%s</b></li>\n<ul>\n"%catDb.replace(r"\\lisdisdss01\ERCDIS06\E\Data\Concordance\03\039\39323308",""))
|
| 224 |
for ct in catDatabaseMatrix[catDb]:
|
| 225 |
htmlPage.write("<li>%s</li>\n"%ct)
|
| 226 |
htmlPage.write("</ul>\n")
|
| 227 |
htmlPage.write("</ul><br><br><br>\n")
|
| 228 |
|
| 229 |
htmlPage.write("<a name=dealsDbs><h2>Listing of Davita Deals and their databases:</h2></a>\n<ul>\n")
|
| 230 |
dealDatabaseList = dealMatrix.keys()
|
| 231 |
dealDatabaseList.sort()
|
| 232 |
for dl in dealDatabaseList:
|
| 233 |
try:
|
| 234 |
htmlPage.write("<li><b>%s</b></li><br><sup>[%s]</sup>\n<ul>\n"%(dl,iproToDBMatrix[dl]))
|
| 235 |
except:
|
| 236 |
htmlPage.write("<li><b>%s</b></li><ul>\n"%dl)
|
| 237 |
dealList = dealMatrix[dl]
|
| 238 |
dealList.sort()
|
| 239 |
for dbDeal in dealList:
|
| 240 |
htmlPage.write("<li>%s</li>\n"%dbDeal)
|
| 241 |
htmlPage.write("</ul><br>\n")
|
| 242 |
|
| 243 |
htmlPage.write("</ul>\n")
|
| 244 |
|
| 245 |
#htmlPage.write("<p>Current redaction report date: %s</p>"%redactionReportDate)
|
| 246 |
htmlPage.write("""
|
| 247 |
<div id="footer">
|
| 248 |
<p><span>© 2013 <a href="#">Emanuel Borges</a></span><br />
|
| 249 |
Website automatically generated by the MCP program.</p></div></body></html>""")
|
| 250 |
|
| 251 |
|
| 252 |
def UpdateDatabaseList(dirName, filesInDir):
|
| 253 |
databaseList = ConcordanceHelperTools.EnumerateConcordanceDatabases(dirName, filesInDir)
|
| 254 |
|
| 255 |
def CheckForMenuItem(dirName, filesInDir):
|
| 256 |
for file in filesInDir:
|
| 257 |
if os.path.isfile(os.path.join(dirName, file)):
|
| 258 |
if os.path.splitext(file)[1].upper() == '.DCB':
|
| 259 |
if os.path.splitext(file)[0][-6:].upper() == '-NOTES':
|
| 260 |
pass
|
| 261 |
elif os.path.splitext(file)[0][-9:].upper() == '-REDLINES':
|
| 262 |
pass
|
| 263 |
elif os.path.exists(os.path.join(dirName,os.path.splitext(file)[0] +'.ini')) == False:
|
| 264 |
print "There is no ini file for %s!!"%file
|
| 265 |
else:
|
| 266 |
iniFile = os.path.splitext(file)[0] +'.ini'
|
| 267 |
## Check to see if it's already there
|
| 268 |
cp = ConfigParser.ConfigParser()
|
| 269 |
cp.read(os.path.join(dirName, iniFile))
|
| 270 |
## I'm only checking for the entire section here, so this needs to
|
| 271 |
## change, if you use it for more than this.
|
| 272 |
if cp.has_section('AddedMenuItems'):
|
| 273 |
if cp.get('AddedMenuItems','default') == "":
|
| 274 |
menuBool = True
|
| 275 |
else:
|
| 276 |
menuBool = False
|
| 277 |
if 'Find Attachments' in cp.get('AddedMenuItems','default'):
|
| 278 |
menuBool = False
|
| 279 |
else:
|
| 280 |
menuBool = True
|
| 281 |
else:
|
| 282 |
menuBool = True
|
| 283 |
if cp.has_section('Settings'):
|
| 284 |
settingsBool = False
|
| 285 |
else:
|
| 286 |
settingsBool = True
|
| 287 |
if menuBool or settingsBool:
|
| 288 |
print
|
| 289 |
print "Missing Menu item from %s. Adding..."%file
|
| 290 |
AddMenuItem(os.path.join(dirName, iniFile), menuBool, settingsBool)
|
| 291 |
|
| 292 |
else:
|
| 293 |
print
|
| 294 |
print "Skipping %s"% file
|
| 295 |
|
| 296 |
|
| 297 |
def AddMenuItem(iniFile,menuBool, settingsBool):
|
| 298 |
#value = """default=Search(Send Query to IPRO,H:\cpl\DDEIQRY.CPL,-1)"""
|
| 299 |
cp = ConfigParser.ConfigParser()
|
| 300 |
cp.read(iniFile)
|
| 301 |
if menuBool:
|
| 302 |
if cp.has_section('AddedMenuItems'):
|
| 303 |
pass
|
| 304 |
else:
|
| 305 |
cp.add_section("AddedMenuItems")
|
| 306 |
cp.set('AddedMenuItems', "default", r"Search(Send Query to IPRO,H:\cpl\DDEIQRY.CPL,-1),Search(Find Attachments, H:\cpl\findattachments.cpl, -1)")
|
| 307 |
if settingsBool:
|
| 308 |
cp.add_section("Settings")
|
| 309 |
cp.set('Settings', "Viewer", r"L:\app\IPRO\i2kprem.exe")
|
| 310 |
cp.set('Settings', "ViewerCPL", r"H:\cpl\DDEIVIEW.CPL")
|
| 311 |
## Back up the ini
|
| 312 |
try:
|
| 313 |
os.rename(iniFile,os.path.splitext(iniFile)[0] + "ini.BAK")
|
| 314 |
except:
|
| 315 |
os.remove(os.path.splitext(iniFile)[0] + "ini.BAK")
|
| 316 |
os.rename(iniFile,os.path.splitext(iniFile)[0] + "ini.BAK")
|
| 317 |
|
| 318 |
|
| 319 |
## Add to the ini
|
| 320 |
outputFile = open(iniFile,'w')
|
| 321 |
cp.write(outputFile)
|
| 322 |
outputFile.close()
|
| 323 |
print
|
| 324 |
print "Added line to %s"% iniFile
|
| 325 |
|
| 326 |
if __name__ == '__main__':
|
| 327 |
ProcessCasesMain('ALL')
|
| 328 |
#responsibleCases,casesDir = MCP_Lib.GetCaseList()
|
| 329 |
#responsibleCasesMatrix = {}
|
| 330 |
#for i in responsibleCases:
|
| 331 |
# caseName,clientMatterNumber = i.split("_(")
|
| 332 |
# clientMatterNumber = clientMatterNumber[:-1]
|
| 333 |
# responsibleCasesMatrix[clientMatterNumber] = caseName
|
| 334 |
#responsibleCLMList = responsibleCasesMatrix.keys()
|
| 335 |
#
|
| 336 |
#
|
| 337 |
#
|
| 338 |
#for cliMatt in responsibleCLMList:
|
| 339 |
# fullDatabaseList = []
|
| 340 |
# print "-"*32
|
| 341 |
# print
|
| 342 |
# print "Now processing %s"% responsibleCasesMatrix[cliMatt]
|
| 343 |
# #os.path.walk(ConcordanceHelperTools.ParseClientMatter(cliMatt), CheckForMenuItem, args)
|
| 344 |
# for root, dirs, files in os.walk(ConcordanceHelperTools.ParseClientMatter(cliMatt)):
|
| 345 |
# if os.path.split(root)[1] == "Match":
|
| 346 |
# pass
|
| 347 |
# else:
|
| 348 |
# CheckForMenuItem(root, files)
|
| 349 |
# databaseList = ConcordanceHelperTools.EnumerateConcordanceDatabases(root, files)
|
| 350 |
# fullDatabaseList.extend(databaseList)
|
| 351 |
# currentDatabaseList = []
|
| 352 |
# databaseListFile = os.path.join(casesDir,responsibleCasesMatrix[cliMatt]+"_("+cliMatt+")","DatabaseList.txt")
|
| 353 |
# print "Checking the database list file..."
|
| 354 |
# if os.path.isfile(databaseListFile):
|
| 355 |
# currentDatabaseList = open(databaseListFile).readlines()
|
| 356 |
# missingFiles = False
|
| 357 |
# for db in fullDatabaseList:
|
| 358 |
# if db+"\n" in currentDatabaseList:
|
| 359 |
# pass
|
| 360 |
# else:
|
| 361 |
# missingFiles = True
|
| 362 |
# if missingFiles:
|
| 363 |
# print "Incomplete database list file found. Updating..."
|
| 364 |
# outputFile = open(databaseListFile,'w')
|
| 365 |
# for i in fullDatabaseList:
|
| 366 |
# outputFile.write(i+"\n")
|
| 367 |
# outputFile.close()
|
| 368 |
# print "Updating complete."
|
| 369 |
# else:
|
| 370 |
# print "All databases in list file accounted for."
|
| 371 |
# else:
|
| 372 |
# print "No database list file found, making a new one.."
|
| 373 |
# outputFile = open(databaseListFile,'w')
|
| 374 |
# for i in fullDatabaseList:
|
| 375 |
# outputFile.write(i+"\n")
|
| 376 |
# outputFile.close()
|
| 377 |
# print "File created."
|
| 378 |
# |