Package Gnumed :: Package business :: Module gmKeywordExpansion |
[frames] | no frames]

# Source Code for Module Gnumed.business.gmKeywordExpansion

      1  # -*- coding: utf8 -*-
      2  """GNUmed keyword snippet expansions
      3
      4  Copyright: authors
      5  """
      6  #============================================================
      7  __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
      8  __license__ = 'GPL v2 or later (details at http://www.gnu.org)'
      9
     10  import sys
     11  import os
     12  import logging
     13
     14
     15  if __name__ == '__main__':
     16          sys.path.insert(0, '../../')
     17  from Gnumed.pycommon import gmPG2
     18  from Gnumed.pycommon import gmBusinessDBObject
     19  from Gnumed.pycommon import gmTools
     20  from Gnumed.pycommon import gmMimeLib
     21
     22
     23  _log = logging.getLogger('gm.kwd_exp')
     24
     25  #============================================================
     26  _SQL_get_keyword_expansions = u"SELECT * FROM ref.v_your_keyword_expansions WHERE %s"
     27
     28 -class cKeywordExpansion(gmBusinessDBObject.cBusinessDBObject):
     29          """Keyword indexed text snippets or chunks of data. Used as text macros or to put into documents."""
     30          _cmd_fetch_payload = _SQL_get_keyword_expansions % u"pk_expansion = %s"
     31          _cmds_store_payload = [
     32                  u"""
     33                          UPDATE ref.keyword_expansion SET
     34                                  keyword = gm.nullify_empty_string(%(keyword)s),
     35                                  textual_data = CASE
     36                                          WHEN gm.nullify_empty_string(%(expansion)s) IS NULL
     37                                                  THEN CASE
     38                                                          WHEN binary_data IS NULL THEN '---fake_data---'
     39                                                          ELSE NULL
     40                                                  END
     41                                          ELSE gm.nullify_empty_string(%(expansion)s)
     42                                  END,
     43                                  binary_data = CASE
     44                                          WHEN gm.nullify_empty_string(%(expansion)s) IS NULL THEN binary_data
     45                                          ELSE NULL
     46                                  END,
     47                                  encrypted = %(is_encrypted)s
     48                          WHERE
     49                                  pk = %(pk_expansion)s
     50                                          AND
     51                                  xmin = %(xmin_expansion)s
     52                          RETURNING
     53                                  xmin as xmin_expansion
     54                  """
     55          ]
     56          _updatable_fields = [
     57                  u'keyword',
     58                  u'expansion',
     59                  u'is_encrypted'
     60          ]
     61
     62          #--------------------------------------------------------
     63 -        def export_to_file(self, aChunkSize=0, target_mime=None, target_extension=None, ignore_conversion_problems=False):
     64
     65                  if self._payload[self._idx['is_textual']]:
     66                          return None
     67
     68                  if self._payload[self._idx['data_size']] == 0:
     69                          return None
     70
     71                  filename = gmTools.get_unique_filename(prefix = 'gm-data_snippet-')
     72                  success = gmPG2.bytea2file (
     73                          data_query = {
     74                                  'cmd': u'SELECT substring(binary_data from %(start)s for %(size)s) FROM ref.keyword_expansion WHERE pk = %(pk)s',
     75                                  'args': {'pk': self.pk_obj}
     76                          },
     77                          filename = filename,
     78                          chunk_size = aChunkSize,
     79                          data_size = self._payload[self._idx['data_size']]
     80                  )
     81
     82                  if not success:
     83                          return None
     84
     85                  if target_mime is None:
     86                          return filename
     87
     88                  if target_extension is None:
     89                          target_extension = gmMimeLib.guess_ext_by_mimetype(mimetype = target_mime)
     90
     91                  target_fname = gmTools.get_unique_filename (
     92                          prefix = 'gm-data_snippet-converted-',
     93                          suffix = target_extension
     94                  )
     95                  _log.debug('attempting conversion: [%s] -> [<%s>:%s]', filename, target_mime, target_fname)
     96                  if gmMimeLib.convert_file (
     97                          filename = filename,
     98                          target_mime = target_mime,
     99                          target_filename = target_fname
    100                  ):
    101                          return target_fname
    102
    103                  _log.warning('conversion failed')
    104                  if not ignore_conversion_problems:
    105                          return None
    106
    107                  _log.warning('programmed to ignore conversion problems, hoping receiver can handle [%s]', filename)
    108                  return filename
    109          #--------------------------------------------------------
    110 -        def update_data_from_file(self, filename=None):
    111                  if not (os.access(filename, os.R_OK) and os.path.isfile(filename)):
    112                          _log.error('[%s] is not a readable file' % filename)
    113                          return False
    114
    115                  gmPG2.file2bytea (
    116                          query = u"UPDATE ref.keyword_expansion SET binary_data = %(data)s::bytea, textual_data = NULL WHERE pk = %(pk)s",
    117                          filename = filename,
    118                          args = {'pk': self.pk_obj}
    119                  )
    120
    121                  # must update XMIN now ...
    122                  self.refetch_payload()
    123
    124                  global __textual_expansion_keywords
    125                  __textual_expansion_keywords = None
    126                  global __keyword_expansions
    127                  __keyword_expansions = None
    128
    129                  return True
    130          #--------------------------------------------------------
    131 -        def format(self):
    132                  txt = u'%s            #%s\n' % (
    133                          gmTools.bool2subst (
    134                                  self._payload[self._idx['is_textual']],
    135                                  _('Textual keyword expansion'),
    136                                  _('Binary keyword expansion')
    137                          ),
    138                          self._payload[self._idx['pk_expansion']]
    139                  )
    140                  txt += u' %s%s\n' % (
    141                          gmTools.bool2subst (
    142                                  self._payload[self._idx['private_expansion']],
    143                                  _('private'),
    144                                  _('public')
    145                          ),
    146                          gmTools.bool2subst (
    147                                  self._payload[self._idx['is_encrypted']],
    148                                  u', %s' % _('encrypted'),
    149                                  u''
    150                          )
    151                  )
    152                  txt += _(' Keyword: %s\n') % self._payload[self._idx['keyword']]
    153                  txt += _(' Owner: %s\n') % self._payload[self._idx['owner']]
    154                  if self._payload[self._idx['is_textual']]:
    155                          txt += u'\n%s' % self._payload[self._idx['expansion']]
    156                  else:
    157                          txt += u' Data: %s (%s Bytes)' % (gmTools.size2str(self._payload[self._idx['data_size']]), self._payload[self._idx['data_size']])
    158
    159                  return txt
    160
    161  #------------------------------------------------------------
    162  __keyword_expansions = None
    163
    164 -def get_keyword_expansions(order_by=None, force_reload=False):
    165          global __keyword_expansions
    166          if not force_reload:
    167                  if __keyword_expansions is not None:
    168                          return __keyword_expansions
    169
    170          if order_by is None:
    171                  order_by = u'true'
    172          else:
    173                  order_by = u'true ORDER BY %s' % order_by
    174
    175          cmd = _SQL_get_keyword_expansions % order_by
    176          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True)
    177
    178          __keyword_expansions = [ cKeywordExpansion(row = {'data': r, 'idx': idx, 'pk_field': 'pk_expansion'}) for r in rows ]
    179          return __keyword_expansions
    180
    181  #------------------------------------------------------------
    182 -def get_expansion(keyword=None, textual_only=True, binary_only=False):
    183
    184          if False not in [textual_only, binary_only]:
    185                  raise ValueError('one of <textual_only> and <binary_only> must be False')
    186
    187          where_parts = [u'keyword = %(kwd)s']
    188          args = {'kwd': keyword}
    189
    190          if textual_only:
    191                  where_parts.append(u'is_textual IS TRUE')
    192
    193          cmd = _SQL_get_keyword_expansions % u' AND '.join(where_parts)
    194          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
    195
    196          if len(rows) == 0:
    197                  return None
    198
    199          return cKeywordExpansion(row = {'data': rows[0], 'idx': idx, 'pk_field': 'pk_expansion'})
    200
    201  #------------------------------------------------------------
    202 -def create_keyword_expansion(keyword=None, text=None, data_file=None, public=True):
    203
    204          if text is not None:
    205                  if text.strip() == u'':
    206                          text = None
    207
    208          if None not in [text, data_file]:
    209                  raise ValueError('either <text> or <data_file> must be non-NULL')
    210
    211          # already exists ?
    212          cmd = u"SELECT 1 FROM ref.v_your_keyword_expansions WHERE public_expansion IS %(public)s AND keyword = %(kwd)s"
    213          args = {'kwd': keyword, 'public': public}
    214          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
    215          if len(rows) != 0:
    216                  # can't create duplicate
    217                  return False
    218
    219          if data_file is not None:
    220                  text = u'fake data'
    221          args = {u'kwd': keyword, u'txt': text}
    222          if public:
    223                  cmd = u"""
    224                          INSERT INTO ref.keyword_expansion (keyword, textual_data, fk_staff)
    225                          VALUES (
    226                                  gm.nullify_empty_string(%(kwd)s),
    227                                  gm.nullify_empty_string(%(txt)s),
    228                                  null
    229                          )
    230                          RETURNING pk
    231                  """
    232          else:
    233                  cmd = u"""
    234                          INSERT INTO ref.keyword_expansion (keyword, textual_data, fk_staff)
    235                          VALUES (
    236                                  gm.nullify_empty_string(%(kwd)s),
    237                                  gm.nullify_empty_string(%(txt)s),
    238                                  (SELECT pk FROM dem.staff WHERE db_user = current_user)
    239                          )
    240                          RETURNING pk
    241                  """
    242          rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False)
    243          expansion = cKeywordExpansion(aPK_obj = rows[0]['pk'])
    244          if data_file is not None:
    245                  expansion.update_data_from_file(filename = data_file)
    246
    247          global __textual_expansion_keywords
    248          __textual_expansion_keywords = None
    249          global __keyword_expansions
    250          __keyword_expansions = None
    251
    252          return expansion
    253  #------------------------------------------------------------
    254 -def delete_keyword_expansion(pk=None):
    255          args = {'pk': pk}
    256          cmd = u"DELETE FROM ref.keyword_expansion WHERE pk = %(pk)s"
    257          gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
    258
    259          global __textual_expansion_keywords
    260          __textual_expansion_keywords = None
    261          global __keyword_expansions
    262          __keyword_expansions = None
    263
    264          return True
    265
    266  #------------------------------------------------------------------------
    267  #------------------------------------------------------------------------
    268  #------------------------------------------------------------------------
    269  #------------------------------------------------------------------------
    270  __textual_expansion_keywords = None
    271
    272 -def get_textual_expansion_keywords():
    273          global __textual_expansion_keywords
    274          if __textual_expansion_keywords is not None:
    275                  return __textual_expansion_keywords
    276
    277          cmd = u"""SELECT keyword, public_expansion, private_expansion, owner FROM ref.v_keyword_expansions WHERE is_textual IS TRUE"""
    278          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}])
    279          __textual_expansion_keywords = rows
    280
    281          _log.info('retrieved %s textual expansion keywords', len(__textual_expansion_keywords))
    282
    283          return __textual_expansion_keywords
    284  #------------------------------------------------------------------------
    285 -def get_matching_textual_keywords(fragment=None):
    286
    287          if fragment is None:
    288                  return []
    289
    290          return [ kwd['keyword'] for kwd in get_textual_expansion_keywords() if kwd['keyword'].startswith(fragment) ]
    291
    292  #------------------------------------------------------------------------
    293 -def expand_keyword(keyword = None):
    294
    295          # Easter Egg ;-)
    296          if keyword == u'$$steffi':
    297                  return u'Hai, play !  Versucht das ! (Keks dazu ?)  :-)'
    298
    299          cmd = u"""SELECT expansion FROM ref.v_your_keyword_expansions WHERE keyword = %(kwd)s"""
    300          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'kwd': keyword}}])
    301
    302          if len(rows) == 0:
    303                  return None
    304
    305          return rows[0]['expansion']
    306  #============================================================
    307  if __name__ == "__main__":
    308
    309          if len(sys.argv) < 2:
    310                  sys.exit()
    311
    312          if sys.argv[1] != 'test':
    313                  sys.exit()
    314
    315          logging.basicConfig(level=logging.DEBUG)
    316
    317          from Gnumed.pycommon import gmI18N
    318          gmI18N.install_domain('gnumed')
    319          gmI18N.activate_locale()
    320
    321          #--------------------------------------------------------------------
    322 -        def test_textual_expansion():
    323                  print "keywords, from database:"
    324                  print get_textual_expansion_keywords()
    325                  print "keywords, cached:"
    326                  print get_textual_expansion_keywords()
    327                  print "'$keyword' expands to:"
    328                  print expand_keyword(keyword = u'$dvt')
    329
    330          #--------------------------------------------------------------------
    331 -        def test_kwd_expansions():
    332                  for k in get_keyword_expansions():
    333                          print k.format()
    334                          print ""
    335          #--------------------------------------------------------------------
    336          #test_textual_expansion()
    337          test_kwd_expansions()
    338