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