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

# Source Code for Module Gnumed.business.gmKeywordExpansion

      1  # -*- coding: utf-8 -*-
      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 = "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 % "pk_expansion = %s"
     31          _cmds_store_payload = [
     32                  """
     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                  'keyword',
     58                  'expansion',
     59                  'is_encrypted'
     60          ]
     61
     62          #--------------------------------------------------------
     63 -        def save_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': '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          #--------------------------------------------------------
    111 -        def update_data_from_file(self, filename=None):
    112                  if not (os.access(filename, os.R_OK) and os.path.isfile(filename)):
    113                          _log.error('[%s] is not a readable file' % filename)
    114                          return False
    115
    116                  gmPG2.file2bytea (
    117                          query = "UPDATE ref.keyword_expansion SET binary_data = %(data)s::bytea, textual_data = NULL WHERE pk = %(pk)s",
    118                          filename = filename,
    119                          args = {'pk': self.pk_obj}
    120                  )
    121
    122                  # must update XMIN now ...
    123                  self.refetch_payload()
    124
    125                  global __textual_expansion_keywords
    126                  __textual_expansion_keywords = None
    127                  global __keyword_expansions
    128                  __keyword_expansions = None
    129
    130                  return True
    131
    132          #--------------------------------------------------------
    133 -        def format(self):
    134                  txt = '%s            #%s\n' % (
    135                          gmTools.bool2subst (
    136                                  self._payload[self._idx['is_textual']],
    137                                  _('Textual keyword expansion'),
    138                                  _('Binary keyword expansion')
    139                          ),
    140                          self._payload[self._idx['pk_expansion']]
    141                  )
    142                  txt += ' %s%s\n' % (
    143                          gmTools.bool2subst (
    144                                  self._payload[self._idx['private_expansion']],
    145                                  _('private'),
    146                                  _('public')
    147                          ),
    148                          gmTools.bool2subst (
    149                                  self._payload[self._idx['is_encrypted']],
    150                                  ', %s' % _('encrypted'),
    151                                  ''
    152                          )
    153                  )
    154                  txt += _(' Keyword: %s\n') % self._payload[self._idx['keyword']]
    155                  txt += _(' Owner: %s\n') % self._payload[self._idx['owner']]
    156                  if self._payload[self._idx['is_textual']]:
    157                          txt += '\n%s' % self._payload[self._idx['expansion']]
    158                  else:
    159                          txt += ' Data: %s (%s Bytes)' % (gmTools.size2str(self._payload[self._idx['data_size']]), self._payload[self._idx['data_size']])
    160
    161                  return txt
    162
    163  #------------------------------------------------------------
    164  __keyword_expansions = None
    165
    166 -def get_keyword_expansions(order_by=None, force_reload=False, return_pks=False):
    167          global __keyword_expansions
    168          if not force_reload:
    169                  if __keyword_expansions is not None:
    170                          return __keyword_expansions
    171
    172          if order_by is None:
    173                  order_by = 'true'
    174          else:
    175                  order_by = 'true ORDER BY %s' % order_by
    176
    177          cmd = _SQL_get_keyword_expansions % order_by
    178          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True)
    179          if return_pks:
    180                  return [ r['pk_expansion'] for r in rows ]
    181          __keyword_expansions = [ cKeywordExpansion(row = {'data': r, 'idx': idx, 'pk_field': 'pk_expansion'}) for r in rows ]
    182          return __keyword_expansions
    183
    184  #------------------------------------------------------------
    185 -def get_expansion(keyword=None, textual_only=True, binary_only=False):
    186
    187          if False not in [textual_only, binary_only]:
    188                  raise ValueError('one of <textual_only> and <binary_only> must be False')
    189
    190          where_parts = ['keyword = %(kwd)s']
    191          args = {'kwd': keyword}
    192
    193          if textual_only:
    194                  where_parts.append('is_textual IS TRUE')
    195
    196          cmd = _SQL_get_keyword_expansions % ' AND '.join(where_parts)
    197          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
    198
    199          if len(rows) == 0:
    200                  return None
    201
    202          return cKeywordExpansion(row = {'data': rows[0], 'idx': idx, 'pk_field': 'pk_expansion'})
    203
    204  #------------------------------------------------------------
    205 -def create_keyword_expansion(keyword=None, text=None, data_file=None, public=True):
    206
    207          if text is not None:
    208                  if text.strip() == '':
    209                          text = None
    210
    211          if None not in [text, data_file]:
    212                  raise ValueError('either <text> or <data_file> must be non-NULL')
    213
    214          # already exists ?
    215          cmd = "SELECT 1 FROM ref.v_your_keyword_expansions WHERE public_expansion IS %(public)s AND keyword = %(kwd)s"
    216          args = {'kwd': keyword, 'public': public}
    217          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
    218          if len(rows) != 0:
    219                  # can't create duplicate
    220                  return False
    221
    222          if data_file is not None:
    223                  text = 'fake data'
    224          args = {'kwd': keyword, 'txt': text}
    225          if public:
    226                  cmd = """
    227                          INSERT INTO ref.keyword_expansion (keyword, textual_data, fk_staff)
    228                          VALUES (
    229                                  gm.nullify_empty_string(%(kwd)s),
    230                                  gm.nullify_empty_string(%(txt)s),
    231                                  null
    232                          )
    233                          RETURNING pk
    234                  """
    235          else:
    236                  cmd = """
    237                          INSERT INTO ref.keyword_expansion (keyword, textual_data, fk_staff)
    238                          VALUES (
    239                                  gm.nullify_empty_string(%(kwd)s),
    240                                  gm.nullify_empty_string(%(txt)s),
    241                                  (SELECT pk FROM dem.staff WHERE db_user = current_user)
    242                          )
    243                          RETURNING pk
    244                  """
    245          rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False)
    246          expansion = cKeywordExpansion(aPK_obj = rows[0]['pk'])
    247          if data_file is not None:
    248                  expansion.update_data_from_file(filename = data_file)
    249
    250          global __textual_expansion_keywords
    251          __textual_expansion_keywords = None
    252          global __keyword_expansions
    253          __keyword_expansions = None
    254
    255          return expansion
    256  #------------------------------------------------------------
    257 -def delete_keyword_expansion(pk=None):
    258          args = {'pk': pk}
    259          cmd = "DELETE FROM ref.keyword_expansion WHERE pk = %(pk)s"
    260          gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
    261
    262          global __textual_expansion_keywords
    263          __textual_expansion_keywords = None
    264          global __keyword_expansions
    265          __keyword_expansions = None
    266
    267          return True
    268
    269  #------------------------------------------------------------------------
    270  #------------------------------------------------------------------------
    271  #------------------------------------------------------------------------
    272  #------------------------------------------------------------------------
    273  __textual_expansion_keywords = None
    274
    275 -def get_textual_expansion_keywords():
    276          global __textual_expansion_keywords
    277          if __textual_expansion_keywords is not None:
    278                  return __textual_expansion_keywords
    279
    280          cmd = """SELECT keyword, public_expansion, private_expansion, owner FROM ref.v_keyword_expansions WHERE is_textual IS TRUE"""
    281          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}])
    282          __textual_expansion_keywords = rows
    283
    284          _log.info('retrieved %s textual expansion keywords', len(__textual_expansion_keywords))
    285
    286          return __textual_expansion_keywords
    287  #------------------------------------------------------------------------
    288 -def get_matching_textual_keywords(fragment=None):
    289
    290          if fragment is None:
    291                  return []
    292
    293          return [ kwd['keyword'] for kwd in get_textual_expansion_keywords() if kwd['keyword'].startswith(fragment) ]
    294
    295  #------------------------------------------------------------------------
    296 -def expand_keyword(keyword = None):
    297
    298          # Easter Egg ;-)
    299          if keyword == '$$steffi':
    300                  return 'Hai, play !  Versucht das ! (Keks dazu ?)  :-)'
    301
    302          cmd = """SELECT expansion FROM ref.v_your_keyword_expansions WHERE keyword = %(kwd)s"""
    303          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'kwd': keyword}}])
    304
    305          if len(rows) == 0:
    306                  return None
    307
    308          return rows[0]['expansion']
    309  #============================================================
    310  if __name__ == "__main__":
    311
    312          if len(sys.argv) < 2:
    313                  sys.exit()
    314
    315          if sys.argv[1] != 'test':
    316                  sys.exit()
    317
    318          logging.basicConfig(level=logging.DEBUG)
    319
    320          from Gnumed.pycommon import gmI18N
    321          gmI18N.install_domain('gnumed')
    322          gmI18N.activate_locale()
    323
    324          #--------------------------------------------------------------------
    325 -        def test_textual_expansion():
    326                  print("keywords, from database:")
    327                  print(get_textual_expansion_keywords())
    328                  print("keywords, cached:")
    329                  print(get_textual_expansion_keywords())
    330                  print("'$keyword' expands to:")
    331                  print(expand_keyword(keyword = '$dvt'))
    332
    333          #--------------------------------------------------------------------
    334 -        def test_kwd_expansions():
    335                  for k in get_keyword_expansions():
    336                          print(k.format())
    337                          print("")
    338          #--------------------------------------------------------------------
    339          #test_textual_expansion()
    340          test_kwd_expansions()
    341