Gnumed.business.gmKeywordExpansion

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):
    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
    180          __keyword_expansions = [ cKeywordExpansion(row = {'data': r, 'idx': idx, 'pk_field': 'pk_expansion'}) for r in rows ]
    181          return __keyword_expansions
    182
    183  #------------------------------------------------------------
    184 -def get_expansion(keyword=None, textual_only=True, binary_only=False):
    185
    186          if False not in [textual_only, binary_only]:
    187                  raise ValueError('one of <textual_only> and <binary_only> must be False')
    188
    189          where_parts = ['keyword = %(kwd)s']
    190          args = {'kwd': keyword}
    191
    192          if textual_only:
    193                  where_parts.append('is_textual IS TRUE')
    194
    195          cmd = _SQL_get_keyword_expansions % ' AND '.join(where_parts)
    196          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
    197
    198          if len(rows) == 0:
    199                  return None
    200
    201          return cKeywordExpansion(row = {'data': rows[0], 'idx': idx, 'pk_field': 'pk_expansion'})
    202
    203  #------------------------------------------------------------
    204 -def create_keyword_expansion(keyword=None, text=None, data_file=None, public=True):
    205
    206          if text is not None:
    207                  if text.strip() == '':
    208                          text = None
    209
    210          if None not in [text, data_file]:
    211                  raise ValueError('either <text> or <data_file> must be non-NULL')
    212
    213          # already exists ?
    214          cmd = "SELECT 1 FROM ref.v_your_keyword_expansions WHERE public_expansion IS %(public)s AND keyword = %(kwd)s"
    215          args = {'kwd': keyword, 'public': public}
    216          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
    217          if len(rows) != 0:
    218                  # can't create duplicate
    219                  return False
    220
    221          if data_file is not None:
    222                  text = 'fake data'
    223          args = {'kwd': keyword, 'txt': text}
    224          if public:
    225                  cmd = """
    226                          INSERT INTO ref.keyword_expansion (keyword, textual_data, fk_staff)
    227                          VALUES (
    228                                  gm.nullify_empty_string(%(kwd)s),
    229                                  gm.nullify_empty_string(%(txt)s),
    230                                  null
    231                          )
    232                          RETURNING pk
    233                  """
    234          else:
    235                  cmd = """
    236                          INSERT INTO ref.keyword_expansion (keyword, textual_data, fk_staff)
    237                          VALUES (
    238                                  gm.nullify_empty_string(%(kwd)s),
    239                                  gm.nullify_empty_string(%(txt)s),
    240                                  (SELECT pk FROM dem.staff WHERE db_user = current_user)
    241                          )
    242                          RETURNING pk
    243                  """
    244          rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False)
    245          expansion = cKeywordExpansion(aPK_obj = rows[0]['pk'])
    246          if data_file is not None:
    247                  expansion.update_data_from_file(filename = data_file)
    248
    249          global __textual_expansion_keywords
    250          __textual_expansion_keywords = None
    251          global __keyword_expansions
    252          __keyword_expansions = None
    253
    254          return expansion
    255  #------------------------------------------------------------
    256 -def delete_keyword_expansion(pk=None):
    257          args = {'pk': pk}
    258          cmd = "DELETE FROM ref.keyword_expansion WHERE pk = %(pk)s"
    259          gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
    260
    261          global __textual_expansion_keywords
    262          __textual_expansion_keywords = None
    263          global __keyword_expansions
    264          __keyword_expansions = None
    265
    266          return True
    267
    268  #------------------------------------------------------------------------
    269  #------------------------------------------------------------------------
    270  #------------------------------------------------------------------------
    271  #------------------------------------------------------------------------
    272  __textual_expansion_keywords = None
    273
    274 -def get_textual_expansion_keywords():
    275          global __textual_expansion_keywords
    276          if __textual_expansion_keywords is not None:
    277                  return __textual_expansion_keywords
    278
    279          cmd = """SELECT keyword, public_expansion, private_expansion, owner FROM ref.v_keyword_expansions WHERE is_textual IS TRUE"""
    280          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}])
    281          __textual_expansion_keywords = rows
    282
    283          _log.info('retrieved %s textual expansion keywords', len(__textual_expansion_keywords))
    284
    285          return __textual_expansion_keywords
    286  #------------------------------------------------------------------------
    287 -def get_matching_textual_keywords(fragment=None):
    288
    289          if fragment is None:
    290                  return []
    291
    292          return [ kwd['keyword'] for kwd in get_textual_expansion_keywords() if kwd['keyword'].startswith(fragment) ]
    293
    294  #------------------------------------------------------------------------
    295 -def expand_keyword(keyword = None):
    296
    297          # Easter Egg ;-)
    298          if keyword == '$$steffi':
    299                  return 'Hai, play !  Versucht das ! (Keks dazu ?)  :-)'
    300
    301          cmd = """SELECT expansion FROM ref.v_your_keyword_expansions WHERE keyword = %(kwd)s"""
    302          rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'kwd': keyword}}])
    303
    304          if len(rows) == 0:
    305                  return None
    306
    307          return rows[0]['expansion']
    308  #============================================================
    309  if __name__ == "__main__":
    310
    311          if len(sys.argv) < 2:
    312                  sys.exit()
    313
    314          if sys.argv[1] != 'test':
    315                  sys.exit()
    316
    317          logging.basicConfig(level=logging.DEBUG)
    318
    319          from Gnumed.pycommon import gmI18N
    320          gmI18N.install_domain('gnumed')
    321          gmI18N.activate_locale()
    322
    323          #--------------------------------------------------------------------
    324 -        def test_textual_expansion():
    325                  print("keywords, from database:")
    326                  print(get_textual_expansion_keywords())
    327                  print("keywords, cached:")
    328                  print(get_textual_expansion_keywords())
    329                  print("'$keyword' expands to:")
    330                  print(expand_keyword(keyword = '$dvt'))
    331
    332          #--------------------------------------------------------------------
    333 -        def test_kwd_expansions():
    334                  for k in get_keyword_expansions():
    335                          print(k.format())
    336                          print("")
    337          #--------------------------------------------------------------------
    338          #test_textual_expansion()
    339          test_kwd_expansions()
    340