Package Gnumed :: Package pycommon :: Module gmDrugView
[frames] | no frames]

Source Code for Module Gnumed.pycommon.gmDrugView

  1  #======================================================== 
  2  import sys, string, re, types 
  3   
  4   
  5  from Gnumed.pycommon import gmCfg, gmDrugObject, gmExceptions 
  6  from Gnumed.business import gmSurgery 
  7   
  8   
  9  _log = gmLog.gmDefLog 
 10  _cfg = gmCfg.gmDefCfgFile 
 11   
 12  darkblue = '#00006C' 
 13  darkgreen = '#0106D0A' 
 14  darkbrown = '#841310' 
 15   
 16  #======================================================== 
17 -class DrugView:
18 """handles a given Interface to a drug database via the Drug object""" 19
20 - def __init__(self, aDatabaseName=None):
21 """ 22 Initialize the DrugView object with information supplied via 23 the standard config file. The data should be grouped together 24 in the group designated by the database name. 25 """ 26 27 if aDatabaseName == None: 28 raise gmExceptions.ConstructorError,"No database name specified." 29 30 # open configuration source 31 # if we are not inside gnumed we won't get a definite answer on 32 # who and where we are. in this case try to get config source 33 # from main config file (see gmCfg on how the name of this file 34 # is determined 35 currWorkplace = gmSurgery.gmCurrentPractice().active_workplace 36 if currWorkplace is None: 37 # assume we are outside gnumed 38 self.dbConfFile = _cfg.get(aDatabaseName, 'configfile') 39 else: 40 # 41 self.dbConfFile, match = gmCfg.getDBParam( 42 workplace=currWorkplace, 43 option="DrugReferenceBrowser.%s.configfile" % aDatabaseName 44 ) 45 46 _log.Log(gmLog.lInfo, "dbConfFile is [%s]" % str(self.dbConfFile)) 47 48 if self.dbConfFile is None: 49 _log.Log(gmLog.lErr, "No config information on drug database [%s] found." % aDatabaseName) 50 raise gmExceptions.ConstructorError,"No DrugDB config file specified." 51 52 try: 53 self.mDrugInterface = gmDrugObject.cDrug(queryCfgSource = self.dbConfFile) 54 except: 55 _log.LogException("Unhandled exception while opening config file", sys.exc_info(), verbose = 0) 56 raise gmExceptions.ConstructorError,"Couldn't initialize drug object for DB %s" % aDatabaseName 57 58 self.__mFormatString = {} # format strings 59 self.__mGroupPos = {} # query group on position x 60 self.__mFormatType = {} # format type 61 self.__mHeading = {} # the heading used (if any) 62 self.__mUsedVars = {} # parameters used from the query dict 63 # get configuration from file 64 self.__getFormatInfo() 65 66 # initialize DrugIds 67 self.mLastId = {} 68 self.mCurrId = -1
69
70 - def SearchIndex(self, aType=None, aName=None , aMode='exact', format=0):
71 """ 72 Search a for a certain drug. Possible values for index type include 73 0 (brand name index), 1 (generic name index) and 2 (indication index). 74 mode can be either exact matching (that is, match all given letters 75 using the LIKE operator), regular expression ('re') matching or 76 complete list ('complete'). 77 """ 78 79 if aName == None: 80 return None 81 82 # choose index name 83 if aType == 0: 84 index = 'brand_index' 85 elif aType == 1: 86 index = 'generic_index' 87 elif aType == 2: 88 index = 'indication_index' 89 else: 90 return None 91 92 searchExact = 0 93 searchAll = 0 94 searchRE = 0 95 96 if aMode == 'exact': 97 suffix = '_exact' 98 search_exact = 1 99 elif aMode == 're': 100 suffix = '_re' 101 searchRE = 1 102 elif aMode == 'complete': 103 suffix = '_all' 104 searchAll = 1 105 106 if not searchAll: 107 self.mDrugInterface.mVars['Key'] = aName 108 109 result = self.mDrugInterface.GetData(index + suffix,refresh=1) 110 return result
111
112 - def getBrandsForGeneric(self,aId):
113 """ 114 Returns a list of drugs for a given generic substance. 115 The substance is specified by aID. 116 """ 117 if aId is None: 118 return None 119 # set product Id 120 self.mDrugInterface.mVars['ID']=aId 121 122 result = self.mDrugInterface.GetData('brandsForGeneric',refresh=1) 123 return result
124
125 - def getProductInfo(self,aId):
126 """ 127 Returns an HTML-formatted drug information sheet for display 128 in the Pharmaceutical Reference Browser. 129 The drug is specified by aID. 130 """ 131 if aId is None: 132 return None 133 # set product Id 134 self.mDrugInterface.mVars['ID']=aId 135 self.mCurrId = aId 136 137 # get product info 138 piText='' 139 headings=[] 140 groupPosList = self.__mGroupPos.keys() 141 142 # DEBUG 143 # print "LIST",groupPosList 144 # get text parts in order of position and combine them 145 groupPosList.sort() 146 for pos in groupPosList: 147 textPart = self.__getTextPart(pos) 148 if textPart != '': 149 piText += textPart 150 if self.__mHeading.has_key(pos): 151 headings.append(self.__mHeading[pos]) 152 153 154 # if no part contained data, no info is available 155 piTotalLen = len(piText) 156 if piTotalLen == 0: 157 pitext = "<HTML><HEAD></HEAD><BODY BGCOLOR='#FFFFFF8'> <FONT SIZE=3>" 158 pitext = pitext + _("No product information available.") 159 pitext = pitext + "</FONT></BODY></HTML>" 160 return pitext 161 162 # in all other cases, construct the HTML frame 163 #---------------------------------------------------------------------- 164 # Start construction the html file to display 165 # First put up the header of the html file 166 # to put in hyperlink 167 #---------------------------------------------------------------------- 168 piTextComplete="<HTML><HEAD></HEAD><BODY BGCOLOR='#FFFFFF8'> <FONT SIZE=-1>" 169 #-------------------------------------------------------- 170 # For each field which is not null put a heading <B> </B> 171 #-------------------------------------------------------- 172 173 piTextComplete = piTextComplete + "<A NAME=\"Description\"></A><BR><FONT SIZE=4 COLOR='" + darkblue + "'><B>Description</B></FONT><BR>" 174 piTextComplete = piTextComplete + piText + "</FONT></BODY></HTML>" 175 176 return (piText,headings)
177 178 #--------------------------------------------------------------------
179 - def __getTextPart(self, pos = 0):
180 """ 181 get the formatted result of a numbered text entry. 182 Every entry has a number that is used as an pointer in several lists. 183 These lists hold the entry type (one of 'heading', 'noheading', 184 'single' or 'list'), the query group containing the parameters in a 185 dictionary, the format string and the names of the parameters used 186 (the latter is used to test for completely empty parameter sets that 187 wont be displayed). 188 Short explanation of types: 189 heading : holds only a heading, takes no parameters from dict 190 noheading : the contrary: no heading, only format string is used 191 single: has a heading and uses the format string 192 list: has a heading, but does not use the format string. Instead all 193 values found for an parameter are put in an itemized list. 194 195 All types using parameters from a query must supply a list of parameters 196 used via entry 'usedvars' in config file. 197 """ 198 199 # get query group and format format_type of current position 200 group = self.__mGroupPos[pos] 201 format_type = self.__mFormatType[pos] 202 203 # if the drug ID has not changed for this query group, use cached data 204 refresh=0 205 if not self.mLastId.has_key(group): 206 self.mLastId[group] = -1 207 if self.mLastId[group] != self.mCurrId: 208 refresh=1 209 self.mLastId[group] = self.mCurrId 210 211 # DEBUG 212 # print "TextPart: ",group, " ", format_type 213 214 # do the query 215 queryResult = self.mDrugInterface.GetData(group,refresh) 216 217 # check result for empty fields in UsedVarsList 218 # if all fields are empty, we wont show anything 219 resultTotalLen = 0 220 if format_type != 'heading': 221 usedVars = self.__mUsedVars[pos] 222 if not queryResult is None: 223 for item in usedVars: 224 if not queryResult.has_key(item): 225 _log.Log(gmLog.lWarn, "Variable name invalid: %s" % item) 226 else: 227 value = queryResult[item] 228 if value == []: 229 value = '' 230 resultTotalLen += len(str(value)) 231 # DEBUG 232 # print "ITEM",item, "LEN: ", len(queryResult[item]) 233 else: 234 resultTotalLen = -1 235 236 # if all fields are empty, return empty string 237 if queryResult is None or resultTotalLen == 0: 238 return '' 239 240 # if no heading is desired, just print the format string 241 if format_type == 'noheading': 242 formattedInfo = self.__mFormatString[pos] % queryResult 243 text = translateASCII2HTML(formattedInfo) 244 return text 245 else: 246 # handle all cases using a heading 247 heading = self.__mHeading[pos] 248 if heading != '': 249 text = "<A NAME=\"" + heading + "\"></A><BR><FONT SIZE=5 COLOR='" + darkblue + "'><B>" + heading + "</B></FONT><BR>" 250 else: 251 text = '' 252 253 if format_type == "heading": 254 return text 255 256 if format_type == 'single': 257 formattedInfo = self.__mFormatString[pos] % queryResult 258 text = text + translateASCII2HTML(formattedInfo) 259 elif format_type == 'list': 260 # we didn't check for empty items in list, 261 # so we have to do it here 262 resultTotalLen = 0 263 264 # the variable in question should contain a list of entries. 265 # we format them as an itemized list 266 # currently we only support one variable per entry 267 itemList = queryResult[usedVars[0]] 268 # if only one entry, cast to list 269 if not type(itemList) is types.ListType: 270 itemList = [itemList] 271 272 tmpText='' 273 # loop through all items 274 for item_raw in itemList: 275 # get item and it's length 276 item=str(item_raw) 277 itemLen = len(item) 278 # if item is not an empty string, format it as HTML 279 if itemLen > 0: 280 resultTotalLen += itemLen 281 tmpText = tmpText + "<li>" + item + "</li>" 282 283 # if at least one item contained data, return result as HTML list 284 if resultTotalLen > 0: 285 text += '<ul>' + tmpText + '</ul>' 286 else: 287 text = '' 288 else: 289 # unhandled format type, shouldn't happen 290 _log.Log(gmLog.lWarn, "Unknown format type: [%s]" % format_type) 291 text = '' 292 293 return text
294 295 296 #-----------------------------------------------------------------
297 - def __getFormatInfo(self):
298 """get info on how to format parameters returned by query groups""" 299 300 # open configuration source 301 try: 302 cfgSource = gmCfg.cCfgFile(aFile = self.dbConfFile, \ 303 flags=gmCfg.cfg_SEARCH_STD_DIRS | gmCfg.cfg_IGNORE_CMD_LINE) 304 # handle all exceptions including 'config file not found' 305 except: 306 exc = sys.exc_info() 307 _log.LogException("Unhandled exception while opening config file [%s]" % self.dbConfFile, exc, verbose = 0) 308 return None 309 310 cfgData = cfgSource.getCfg() 311 groups = cfgSource.getGroups() 312 313 # every info holds 314 # -an format string (presented as an list) 315 # -a heading 316 # -a format type ('none','single' or 'list') 317 # -a position in the product info (int >= 0) 318 # -the query group name that supplies the variables that are to be 319 # matched to the format string 320 # format infos are identified by the item 'type=format' 321 for entry_group in groups: 322 entry_type = cfgSource.get(entry_group, "type") 323 # groups not containing format strings are silently ignored 324 if entry_type != 'format': 325 continue 326 327 # group name 328 qname = cfgSource.get(entry_group, "querygroup") 329 if qname is None: 330 _log.Log(gmLog.lWarn,"query definition invalid in entry_group %s." % entry_group) 331 continue 332 333 # group format type 334 ftype = cfgSource.get(entry_group, "formattype") 335 if ftype is None: 336 _log.Log(gmLog.lWarn,"query definition invalid in entry_group %s." % entry_group) 337 continue 338 339 fposstring = cfgSource.get(entry_group, "position") 340 # check that the position is an valid int number 341 try: 342 fpos = int(fposstring) 343 except TypeError: 344 fpos = -1 345 346 if fpos is None or fpos < 0: 347 _log.Log(gmLog.lWarn,"query definition invalid in entry_group %s." % entry_group) 348 continue 349 350 if ftype != 'heading': 351 format = cfgSource.get(entry_group, "format") 352 if format is None or not type(format) == types.ListType: 353 _log.Log(gmLog.lWarn,"query definition invalid in entry_group %s." % entry_group) 354 continue 355 356 usedVars = cfgSource.get(entry_group, "usedvars") 357 if usedVars is None: 358 _log.Log(gmLog.lWarn,"query definition invalid in entry_group %s." % entry_group) 359 continue 360 361 362 if ftype != 'noheading': 363 heading = cfgSource.get(entry_group, "heading") 364 if format is None or not type(format) == types.ListType: 365 _log.Log(gmLog.lWarn,"query definition invalid in entry_group %s." % entry_group) 366 continue 367 368 # set the parameters read from config file 369 self.__mGroupPos[fpos] = qname 370 self.__mFormatType[fpos] = ftype 371 if ftype != 'heading': 372 fstring=string.join(format,'') 373 self.__mFormatString[fpos] = fstring 374 usedVarsList = string.split(usedVars,',') 375 self.__mUsedVars[fpos] = usedVarsList 376 if ftype != 'noheading': 377 fheading = string.join(heading,'') 378 self.__mHeading[fpos] = fheading 379 return 1
380 381 382 383 #======================================================== 384 if __name__ == "__main__": 385 print "please write unit test code" 386 387 #======================================================== 388 # $Log: gmDrugView.py,v $ 389 # Revision 1.13 2009-09-13 18:27:54 ncq 390 # - remove latin1 chars 391 # 392 # Revision 1.12 2008/04/13 14:41:40 ncq 393 # - old style logging is out 394 # 395 # Revision 1.11 2007/10/07 12:29:12 ncq 396 # - workplace property now on gmSurgery.gmCurrentPractice() borg 397 # 398 # Revision 1.10 2007/02/17 14:13:11 ncq 399 # - gmPerson.gmCurrentProvider().workplace now property 400 # 401 # Revision 1.9 2006/10/25 07:19:03 ncq 402 # - no more gmPG 403 # 404 # Revision 1.8 2006/05/14 21:44:22 ncq 405 # - add get_workplace() to gmPerson.gmCurrentProvider and make use thereof 406 # - remove use of gmWhoAmI.py 407 # 408 # Revision 1.7 2006/05/12 12:06:13 ncq 409 # - whoami -> whereami 410 # 411 # Revision 1.6 2005/03/17 20:32:14 hinnef 412 # -fixed module dependencies 413 # 414 # Revision 1.5 2004/09/18 13:52:41 ncq 415 # - properly use setDBParam() 416 # 417 # Revision 1.4 2004/08/20 13:34:48 ncq 418 # - getFirstMatchingDBSet() -> getDBParam() 419 # 420 # Revision 1.3 2004/07/19 11:50:42 ncq 421 # - cfg: what used to be called "machine" really is "workplace", so fix 422 # 423 # Revision 1.2 2004/03/10 00:14:04 ncq 424 # - fix imports 425 # 426 # Revision 1.1 2004/02/25 09:30:13 ncq 427 # - moved here from python-common 428 # 429 # Revision 1.4 2003/12/29 16:26:14 uid66147 430 # - use whoami.get_workplace() 431 # 432 # Revision 1.3 2003/11/17 10:56:36 sjtan 433 # 434 # synced and commiting. 435 # 436 # Revision 1.1 2003/10/23 06:02:39 sjtan 437 # 438 # manual edit areas modelled after r.terry's specs. 439 # 440 # Revision 1.2 2003/09/03 17:32:05 hinnef 441 # make use of gmWhoAmI, try to get config info from backend 442 # 443 # Revision 1.1 2003/08/24 13:38:24 hinnef 444 # moved to main-tree, some bug fixes 445 # 446 # Revision 1.6 2002/11/17 16:44:23 hinnef 447 # fixed some bugs regarding display of non-string items and list entries in PI 448 # 449 # Revision 1.5 2002/11/09 15:10:47 hinnef 450 # detect ID changes for every query group in GetTextPart 451 # 452