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

# Source Code for Module Gnumed.pycommon.gmDrugView

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