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

Source Code for Module Gnumed.business.gmDocuments

  1  """This module encapsulates a document stored in a GNUmed database. 
  2   
  3  @copyright: GPL 
  4  """ 
  5  #============================================================ 
  6  __version__ = "$Revision: 1.118 $" 
  7  __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>" 
  8   
  9  import sys, os, shutil, os.path, types, time, logging 
 10  from cStringIO import StringIO 
 11  from pprint import pprint 
 12   
 13   
 14  if __name__ == '__main__': 
 15          sys.path.insert(0, '../../') 
 16  from Gnumed.pycommon import gmExceptions, gmBusinessDBObject, gmPG2, gmTools, gmMimeLib 
 17   
 18   
 19  _log = logging.getLogger('gm.docs') 
 20  _log.info(__version__) 
 21   
 22  MUGSHOT=26 
 23  DOCUMENT_TYPE_VISUAL_PROGRESS_NOTE = u'visual progress note' 
 24  DOCUMENT_TYPE_PRESCRIPTION = u'prescription' 
 25  #============================================================ 
26 -class cDocumentFolder:
27 """Represents a folder with medical documents for a single patient.""" 28
29 - def __init__(self, aPKey = None):
30 """Fails if 31 32 - patient referenced by aPKey does not exist 33 """ 34 self.pk_patient = aPKey # == identity.pk == primary key 35 if not self._pkey_exists(): 36 raise gmExceptions.ConstructorError, "No patient with PK [%s] in database." % aPKey 37 38 # register backend notification interests 39 # (keep this last so we won't hang on threads when 40 # failing this constructor for other reasons ...) 41 # if not self._register_interests(): 42 # raise gmExceptions.ConstructorError, "cannot register signal interests" 43 44 _log.debug('instantiated document folder for patient [%s]' % self.pk_patient)
45 #--------------------------------------------------------
46 - def cleanup(self):
47 pass
48 #-------------------------------------------------------- 49 # internal helper 50 #--------------------------------------------------------
51 - def _pkey_exists(self):
52 """Does this primary key exist ? 53 54 - true/false/None 55 """ 56 # patient in demographic database ? 57 rows, idx = gmPG2.run_ro_queries(queries = [ 58 {'cmd': u"select exists(select pk from dem.identity where pk = %s)", 'args': [self.pk_patient]} 59 ]) 60 if not rows[0][0]: 61 _log.error("patient [%s] not in demographic database" % self.pk_patient) 62 return None 63 return True
64 #-------------------------------------------------------- 65 # API 66 #--------------------------------------------------------
68 cmd = u""" 69 SELECT pk_doc 70 FROM blobs.v_doc_med 71 WHERE 72 pk_patient = %(pat)s 73 AND 74 type = %(typ)s 75 AND 76 ext_ref = %(ref)s 77 ORDER BY 78 clin_when DESC 79 LIMIT 1 80 """ 81 args = { 82 'pat': self.pk_patient, 83 'typ': DOCUMENT_TYPE_PRESCRIPTION, 84 'ref': u'FreeDiams' 85 } 86 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 87 if len(rows) == 0: 88 _log.info('no FreeDiams prescription available for patient [%s]' % self.pk_patient) 89 return None 90 prescription = cDocument(aPK_obj = rows[0][0]) 91 return prescription
92 #--------------------------------------------------------
93 - def get_latest_mugshot(self):
94 cmd = u"select pk_obj from blobs.v_latest_mugshot where pk_patient=%s" 95 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_patient]}]) 96 if len(rows) == 0: 97 _log.info('no mugshots available for patient [%s]' % self.pk_patient) 98 return None 99 mugshot = cDocumentPart(aPK_obj=rows[0][0]) 100 return mugshot
101 #--------------------------------------------------------
102 - def get_mugshot_list(self, latest_only=True):
103 if latest_only: 104 cmd = u"select pk_doc, pk_obj from blobs.v_latest_mugshot where pk_patient=%s" 105 else: 106 cmd = u""" 107 select 108 vdm.pk_doc as pk_doc, 109 dobj.pk as pk_obj 110 from 111 blobs.v_doc_med vdm 112 blobs.doc_obj dobj 113 where 114 vdm.pk_type = (select pk from blobs.doc_type where name = 'patient photograph') 115 and vdm.pk_patient = %s 116 and dobj.fk_doc = vdm.pk_doc 117 """ 118 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_patient]}]) 119 return rows
120 #--------------------------------------------------------
121 - def get_doc_list(self, doc_type=None):
122 """return flat list of document IDs""" 123 124 args = { 125 'ID': self.pk_patient, 126 'TYP': doc_type 127 } 128 129 cmd = u""" 130 select vdm.pk_doc 131 from blobs.v_doc_med vdm 132 where 133 vdm.pk_patient = %%(ID)s 134 %s 135 order by vdm.clin_when""" 136 137 if doc_type is None: 138 cmd = cmd % u'' 139 else: 140 try: 141 int(doc_type) 142 cmd = cmd % u'and vdm.pk_type = %(TYP)s' 143 except (TypeError, ValueError): 144 cmd = cmd % u'and vdm.pk_type = (select pk from blobs.doc_type where name = %(TYP)s)' 145 146 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 147 doc_ids = [] 148 for row in rows: 149 doc_ids.append(row[0]) 150 return doc_ids
151 #--------------------------------------------------------
152 - def get_visual_progress_notes(self, episodes=None, encounter=None):
153 return self.get_documents ( 154 doc_type = DOCUMENT_TYPE_VISUAL_PROGRESS_NOTE, 155 episodes = episodes, 156 encounter = encounter 157 )
158 #--------------------------------------------------------
159 - def get_documents(self, doc_type=None, episodes=None, encounter=None):
160 """Return list of documents.""" 161 162 args = { 163 'pat': self.pk_patient, 164 'type': doc_type, 165 'enc': encounter 166 } 167 where_parts = [u'pk_patient = %(pat)s'] 168 169 if doc_type is not None: 170 try: 171 int(doc_type) 172 where_parts.append(u'pk_type = %(type)s') 173 except (TypeError, ValueError): 174 where_parts.append(u'pk_type = (SELECT pk FROM blobs.doc_type WHERE name = %(type)s)') 175 176 if (episodes is not None) and (len(episodes) > 0): 177 where_parts.append(u'pk_episode IN %(epi)s') 178 args['epi'] = tuple(episodes) 179 180 if encounter is not None: 181 where_parts.append(u'pk_encounter = %(enc)s') 182 183 cmd = u"%s\nORDER BY clin_when" % (_sql_fetch_document_fields % u' AND '.join(where_parts)) 184 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 185 186 return [ cDocument(row = {'pk_field': 'pk_doc', 'idx': idx, 'data': r}) for r in rows ]
187 #--------------------------------------------------------
188 - def add_document(self, document_type=None, encounter=None, episode=None):
189 return create_document(document_type = document_type, encounter = encounter, episode = episode)
190 #============================================================ 191 _sql_fetch_document_part_fields = u"select * from blobs.v_obj4doc_no_data where %s" 192
193 -class cDocumentPart(gmBusinessDBObject.cBusinessDBObject):
194 """Represents one part of a medical document.""" 195 196 _cmd_fetch_payload = _sql_fetch_document_part_fields % u"pk_obj = %s" 197 _cmds_store_payload = [ 198 u"""update blobs.doc_obj set 199 seq_idx = %(seq_idx)s, 200 comment = gm.nullify_empty_string(%(obj_comment)s), 201 filename = gm.nullify_empty_string(%(filename)s), 202 fk_intended_reviewer = %(pk_intended_reviewer)s 203 where 204 pk=%(pk_obj)s and 205 xmin=%(xmin_doc_obj)s""", 206 u"""select xmin_doc_obj from blobs.v_obj4doc_no_data where pk_obj = %(pk_obj)s""" 207 ] 208 _updatable_fields = [ 209 'seq_idx', 210 'obj_comment', 211 'pk_intended_reviewer', 212 'filename' 213 ] 214 #-------------------------------------------------------- 215 # retrieve data 216 #--------------------------------------------------------
217 - def export_to_file(self, aTempDir = None, aChunkSize = 0, filename=None):
218 219 if self._payload[self._idx['size']] == 0: 220 return None 221 222 if filename is None: 223 suffix = None 224 # preserve original filename extension if available 225 if self._payload[self._idx['filename']] is not None: 226 name, suffix = os.path.splitext(self._payload[self._idx['filename']]) 227 suffix = suffix.strip() 228 if suffix == u'': 229 suffix = None 230 # get unique filename 231 filename = gmTools.get_unique_filename ( 232 prefix = 'gm-doc_obj-page_%s-' % self._payload[self._idx['seq_idx']], 233 suffix = suffix, 234 tmp_dir = aTempDir 235 ) 236 237 success = gmPG2.bytea2file ( 238 data_query = { 239 'cmd': u'SELECT substring(data from %(start)s for %(size)s) FROM blobs.doc_obj WHERE pk=%(pk)s', 240 'args': {'pk': self.pk_obj} 241 }, 242 filename = filename, 243 chunk_size = aChunkSize, 244 data_size = self._payload[self._idx['size']] 245 ) 246 247 if success: 248 return filename 249 250 return None
251 #--------------------------------------------------------
252 - def get_reviews(self):
253 cmd = u""" 254 select 255 reviewer, 256 reviewed_when, 257 is_technically_abnormal, 258 clinically_relevant, 259 is_review_by_responsible_reviewer, 260 is_your_review, 261 coalesce(comment, '') 262 from blobs.v_reviewed_doc_objects 263 where pk_doc_obj = %s 264 order by 265 is_your_review desc, 266 is_review_by_responsible_reviewer desc, 267 reviewed_when desc 268 """ 269 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj]}]) 270 return rows
271 #--------------------------------------------------------
272 - def get_containing_document(self):
273 return cDocument(aPK_obj = self._payload[self._idx['pk_doc']])
274 #-------------------------------------------------------- 275 # store data 276 #--------------------------------------------------------
277 - def update_data_from_file(self, fname=None):
278 # sanity check 279 if not (os.access(fname, os.R_OK) and os.path.isfile(fname)): 280 _log.error('[%s] is not a readable file' % fname) 281 return False 282 283 gmPG2.file2bytea ( 284 query = u"UPDATE blobs.doc_obj SET data=%(data)s::bytea WHERE pk=%(pk)s", 285 filename = fname, 286 args = {'pk': self.pk_obj} 287 ) 288 289 # must update XMIN now ... 290 self.refetch_payload() 291 return True
292 #--------------------------------------------------------
293 - def set_reviewed(self, technically_abnormal=None, clinically_relevant=None):
294 # row already there ? 295 cmd = u""" 296 select pk 297 from blobs.reviewed_doc_objs 298 where 299 fk_reviewed_row = %s and 300 fk_reviewer = (select pk from dem.staff where db_user = current_user)""" 301 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj]}]) 302 303 # INSERT needed 304 if len(rows) == 0: 305 cols = [ 306 u"fk_reviewer", 307 u"fk_reviewed_row", 308 u"is_technically_abnormal", 309 u"clinically_relevant" 310 ] 311 vals = [ 312 u'%(fk_row)s', 313 u'%(abnormal)s', 314 u'%(relevant)s' 315 ] 316 args = { 317 'fk_row': self.pk_obj, 318 'abnormal': technically_abnormal, 319 'relevant': clinically_relevant 320 } 321 cmd = u""" 322 insert into blobs.reviewed_doc_objs ( 323 %s 324 ) values ( 325 (select pk from dem.staff where db_user=current_user), 326 %s 327 )""" % (', '.join(cols), ', '.join(vals)) 328 329 # UPDATE needed 330 if len(rows) == 1: 331 pk_row = rows[0][0] 332 args = { 333 'abnormal': technically_abnormal, 334 'relevant': clinically_relevant, 335 'pk_row': pk_row 336 } 337 cmd = u""" 338 update blobs.reviewed_doc_objs set 339 is_technically_abnormal = %(abnormal)s, 340 clinically_relevant = %(relevant)s 341 where 342 pk=%(pk_row)s""" 343 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 344 345 return True
346 #--------------------------------------------------------
347 - def set_as_active_photograph(self):
348 if self._payload[self._idx['type']] != u'patient photograph': 349 return False 350 # set seq_idx to current max + 1 351 rows, idx = gmPG2.run_ro_queries ( 352 queries = [{ 353 'cmd': u'select coalesce(max(seq_idx)+1, 1) from blobs.doc_obj where fk_doc=%(doc_id)s', 354 'args': {'doc_id': self._payload[self._idx['pk_doc']]} 355 }] 356 ) 357 self._payload[self._idx['seq_idx']] = rows[0][0] 358 self._is_modified = True 359 self.save_payload()
360 #--------------------------------------------------------
361 - def display_via_mime(self, tmpdir=None, chunksize=0, block=None):
362 363 fname = self.export_to_file(aTempDir = tmpdir, aChunkSize = chunksize) 364 if fname is None: 365 return False, '' 366 367 success, msg = gmMimeLib.call_viewer_on_file(fname, block = block) 368 if not success: 369 return False, msg 370 371 return True, ''
372 #============================================================ 373 _sql_fetch_document_fields = u"select * from blobs.v_doc_med where %s" 374
375 -class cDocument(gmBusinessDBObject.cBusinessDBObject):
376 """Represents one medical document.""" 377 378 _cmd_fetch_payload = _sql_fetch_document_fields % u"pk_doc = %s" 379 _cmds_store_payload = [ 380 u"""update blobs.doc_med set 381 fk_type = %(pk_type)s, 382 fk_episode = %(pk_episode)s, 383 fk_encounter = %(pk_encounter)s, 384 clin_when = %(clin_when)s, 385 comment = gm.nullify_empty_string(%(comment)s), 386 ext_ref = gm.nullify_empty_string(%(ext_ref)s) 387 where 388 pk = %(pk_doc)s and 389 xmin = %(xmin_doc_med)s""", 390 u"""select xmin_doc_med from blobs.v_doc_med where pk_doc = %(pk_doc)s""" 391 ] 392 393 _updatable_fields = [ 394 'pk_type', 395 'comment', 396 'clin_when', 397 'ext_ref', 398 'pk_episode', 399 'pk_encounter' # mainly useful when moving visual progress notes to their respective encounters 400 ] 401 #--------------------------------------------------------
402 - def refetch_payload(self, ignore_changes=False):
403 try: del self.__has_unreviewed_parts 404 except AttributeError: pass 405 406 return super(cDocument, self).refetch_payload(ignore_changes = ignore_changes)
407 #--------------------------------------------------------
408 - def get_descriptions(self, max_lng=250):
409 """Get document descriptions. 410 411 - will return a list of rows 412 """ 413 if max_lng is None: 414 cmd = u"SELECT pk, text FROM blobs.doc_desc WHERE fk_doc = %s" 415 else: 416 cmd = u"SELECT pk, substring(text from 1 for %s) FROM blobs.doc_desc WHERE fk_doc=%%s" % max_lng 417 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj]}]) 418 return rows
419 #--------------------------------------------------------
420 - def add_description(self, description=None):
421 cmd = u"insert into blobs.doc_desc (fk_doc, text) values (%s, %s)" 422 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj, description]}]) 423 return True
424 #--------------------------------------------------------
425 - def update_description(self, pk=None, description=None):
426 cmd = u"update blobs.doc_desc set text = %(desc)s where fk_doc = %(doc)s and pk = %(pk_desc)s" 427 gmPG2.run_rw_queries(queries = [ 428 {'cmd': cmd, 'args': {'doc': self.pk_obj, 'pk_desc': pk, 'desc': description}} 429 ]) 430 return True
431 #--------------------------------------------------------
432 - def delete_description(self, pk=None):
433 cmd = u"delete from blobs.doc_desc where fk_doc = %(doc)s and pk = %(desc)s" 434 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'doc': self.pk_obj, 'desc': pk}}]) 435 return True
436 #--------------------------------------------------------
437 - def _get_parts(self):
438 cmd = _sql_fetch_document_part_fields % u"pk_doc = %s" 439 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj]}], get_col_idx = True) 440 return [ cDocumentPart(row = {'pk_field': 'pk_obj', 'idx': idx, 'data': r}) for r in rows ]
441 442 parts = property(_get_parts, lambda x:x) 443 #--------------------------------------------------------
444 - def add_part(self, file=None):
445 """Add a part to the document.""" 446 # create dummy part 447 cmd = u""" 448 insert into blobs.doc_obj ( 449 fk_doc, fk_intended_reviewer, data, seq_idx 450 ) VALUES ( 451 %(doc_id)s, 452 (select pk_staff from dem.v_staff where db_user=CURRENT_USER), 453 ''::bytea, 454 (select coalesce(max(seq_idx)+1, 1) from blobs.doc_obj where fk_doc=%(doc_id)s) 455 )""" 456 rows, idx = gmPG2.run_rw_queries ( 457 queries = [ 458 {'cmd': cmd, 'args': {'doc_id': self.pk_obj}}, 459 {'cmd': u"select currval('blobs.doc_obj_pk_seq')"} 460 ], 461 return_data = True 462 ) 463 # init document part instance 464 pk_part = rows[0][0] 465 new_part = cDocumentPart(aPK_obj = pk_part) 466 if not new_part.update_data_from_file(fname=file): 467 _log.error('cannot import binary data from [%s] into document part' % file) 468 gmPG2.run_rw_queries ( 469 queries = [ 470 {'cmd': u"delete from blobs.doc_obj where pk = %s", 'args': [pk_part]} 471 ] 472 ) 473 return None 474 return new_part
475 #--------------------------------------------------------
476 - def add_parts_from_files(self, files=None, reviewer=None):
477 478 new_parts = [] 479 480 for filename in files: 481 new_part = self.add_part(file = filename) 482 if new_part is None: 483 msg = 'cannot instantiate document part object' 484 _log.error(msg) 485 return (False, msg, filename) 486 new_parts.append(new_part) 487 488 new_part['filename'] = filename 489 new_part['pk_intended_reviewer'] = reviewer # None == Null 490 491 success, data = new_part.save_payload() 492 if not success: 493 msg = 'cannot set reviewer to [%s]' % reviewer 494 _log.error(msg) 495 _log.error(str(data)) 496 return (False, msg, filename) 497 498 return (True, '', new_parts)
499 #--------------------------------------------------------
500 - def export_parts_to_files(self, export_dir=None, chunksize=0):
501 fnames = [] 502 for part in self.parts: 503 # FIXME: add guess_extension_from_mimetype 504 fname = os.path.basename(gmTools.coalesce ( 505 part['filename'], 506 u'%s%s%s_%s' % (part['l10n_type'], gmTools.coalesce(part['ext_ref'], '-', '-%s-'), _('part'), part['seq_idx']) 507 )) 508 if export_dir is not None: 509 fname = os.path.join(export_dir, fname) 510 fnames.append(part.export_to_file(aChunkSize = chunksize, filename = fname)) 511 return fnames
512 #--------------------------------------------------------
514 try: 515 return self.__has_unreviewed_parts 516 except AttributeError: 517 pass 518 519 cmd = u"SELECT EXISTS(SELECT 1 FROM blobs.v_obj4doc_no_data WHERE pk_doc = %(pk)s AND reviewed IS FALSE)" 520 args = {'pk': self.pk_obj} 521 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 522 self.__has_unreviewed_parts = rows[0][0] 523 524 return self.__has_unreviewed_parts
525 526 has_unreviewed_parts = property(_get_has_unreviewed_parts, lambda x:x) 527 #--------------------------------------------------------
528 - def set_reviewed(self, technically_abnormal=None, clinically_relevant=None):
529 # FIXME: this is probably inefficient 530 for part in self.parts: 531 if not part.set_reviewed(technically_abnormal, clinically_relevant): 532 return False 533 return True
534 #--------------------------------------------------------
535 - def set_primary_reviewer(self, reviewer=None):
536 for part in self.parts: 537 part['pk_intended_reviewer'] = reviewer 538 success, data = part.save_payload() 539 if not success: 540 _log.error('cannot set reviewer to [%s]' % reviewer) 541 _log.error(str(data)) 542 return False 543 return True
544 #------------------------------------------------------------
545 -def create_document(document_type=None, encounter=None, episode=None):
546 """Returns new document instance or raises an exception. 547 """ 548 cmd = u"""INSERT INTO blobs.doc_med (fk_type, fk_encounter, fk_episode) VALUES (%(type)s, %(enc)s, %(epi)s) RETURNING pk""" 549 try: 550 int(document_type) 551 except ValueError: 552 cmd = u""" 553 INSERT INTO blobs.doc_med ( 554 fk_type, 555 fk_encounter, 556 fk_episode 557 ) VALUES ( 558 coalesce ( 559 (SELECT pk from blobs.doc_type bdt where bdt.name = %(type)s), 560 (SELECT pk from blobs.doc_type bdt where _(bdt.name) = %(type)s) 561 ), 562 %(enc)s, 563 %(epi)s 564 ) RETURNING pk""" 565 566 args = {'type': document_type, 'enc': encounter, 'epi': episode} 567 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 568 doc = cDocument(aPK_obj = rows[0][0]) 569 return doc
570 #------------------------------------------------------------
571 -def search_for_document(patient_id=None, type_id=None):
572 """Searches for documents with the given patient and type ID. 573 574 No type ID returns all documents for the patient. 575 """ 576 # sanity checks 577 if patient_id is None: 578 raise ValueError('need patient id to search for document') 579 580 args = {'pat_id': patient_id, 'type_id': type_id} 581 if type_id is None: 582 cmd = u"SELECT pk_doc from blobs.v_doc_med WHERE pk_patient = %(pat_id)s" 583 else: 584 cmd = u"SELECT pk_doc from blobs.v_doc_med WHERE pk_patient = %(pat_id)s and pk_type = %(type_id)s" 585 586 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 587 588 docs = [] 589 for row in rows: 590 docs.append(cDocument(row[0])) 591 return docs
592 #------------------------------------------------------------
593 -def delete_document(document_id=None, encounter_id=None):
594 # will cascade to doc_obj and doc_desc 595 cmd = u"select blobs.delete_document(%(pk)s, %(enc)s)" 596 args = {'pk': document_id, 'enc': encounter_id} 597 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 598 return
599 #------------------------------------------------------------
600 -def reclassify_documents_by_type(original_type=None, target_type=None):
601 602 _log.debug('reclassifying documents by type') 603 _log.debug('original: %s', original_type) 604 _log.debug('target: %s', target_type) 605 606 if target_type['pk_doc_type'] == original_type['pk_doc_type']: 607 return True 608 609 cmd = u""" 610 update blobs.doc_med set 611 fk_type = %(new_type)s 612 where 613 fk_type = %(old_type)s 614 """ 615 args = {u'new_type': target_type['pk_doc_type'], u'old_type': original_type['pk_doc_type']} 616 617 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 618 619 return True
620 621 #============================================================
622 -class cDocumentType(gmBusinessDBObject.cBusinessDBObject):
623 """Represents a document type.""" 624 _cmd_fetch_payload = u"""select * from blobs.v_doc_type where pk_doc_type=%s""" 625 _cmds_store_payload = [ 626 u"""update blobs.doc_type set 627 name = %(type)s 628 where 629 pk=%(pk_obj)s and 630 xmin=%(xmin_doc_type)s""", 631 u"""select xmin_doc_type from blobs.v_doc_type where pk_doc_type = %(pk_obj)s""" 632 ] 633 _updatable_fields = ['type'] 634 #--------------------------------------------------------
635 - def set_translation(self, translation=None):
636 637 if translation.strip() == '': 638 return False 639 640 if translation.strip() == self._payload[self._idx['l10n_type']].strip(): 641 return True 642 643 rows, idx = gmPG2.run_rw_queries ( 644 queries = [ 645 {'cmd': u'select i18n.i18n(%s)', 'args': [self._payload[self._idx['type']]]}, 646 {'cmd': u'select i18n.upd_tx((select i18n.get_curr_lang()), %(orig)s, %(tx)s)', 647 'args': { 648 'orig': self._payload[self._idx['type']], 649 'tx': translation 650 } 651 } 652 ], 653 return_data = True 654 ) 655 if not rows[0][0]: 656 _log.error('cannot set translation to [%s]' % translation) 657 return False 658 659 return self.refetch_payload()
660 661 #------------------------------------------------------------
662 -def get_document_types():
663 rows, idx = gmPG2.run_ro_queries ( 664 queries = [{'cmd': u"SELECT * FROM blobs.v_doc_type"}], 665 get_col_idx = True 666 ) 667 doc_types = [] 668 for row in rows: 669 row_def = { 670 'pk_field': 'pk_doc_type', 671 'idx': idx, 672 'data': row 673 } 674 doc_types.append(cDocumentType(row = row_def)) 675 return doc_types
676 #------------------------------------------------------------
677 -def create_document_type(document_type=None):
678 # check for potential dupes: 679 cmd = u'select pk from blobs.doc_type where name = %s' 680 rows, idx = gmPG2.run_ro_queries ( 681 queries = [{'cmd': cmd, 'args': [document_type]}] 682 ) 683 if len(rows) == 0: 684 cmd1 = u"insert into blobs.doc_type (name) values (%s)" 685 cmd2 = u"select currval('blobs.doc_type_pk_seq')" 686 rows, idx = gmPG2.run_rw_queries ( 687 queries = [ 688 {'cmd': cmd1, 'args': [document_type]}, 689 {'cmd': cmd2} 690 ], 691 return_data = True 692 ) 693 return cDocumentType(aPK_obj = rows[0][0])
694 #------------------------------------------------------------
695 -def delete_document_type(document_type=None):
696 if document_type['is_in_use']: 697 return False 698 gmPG2.run_rw_queries ( 699 queries = [{ 700 'cmd': u'delete from blobs.doc_type where pk=%s', 701 'args': [document_type['pk_doc_type']] 702 }] 703 ) 704 return True
705 #------------------------------------------------------------
706 -def get_ext_ref():
707 """This needs *considerably* more smarts.""" 708 dirname = gmTools.get_unique_filename ( 709 prefix = '', 710 suffix = time.strftime(".%Y%m%d-%H%M%S", time.localtime()) 711 ) 712 # extract name for dir 713 path, doc_ID = os.path.split(dirname) 714 return doc_ID
715 #============================================================ 716 # main 717 #------------------------------------------------------------ 718 if __name__ == '__main__': 719 720 if len(sys.argv) < 2: 721 sys.exit() 722 723 if sys.argv[1] != u'test': 724 sys.exit() 725 726 #--------------------------------------------------------
727 - def test_doc_types():
728 729 print "----------------------" 730 print "listing document types" 731 print "----------------------" 732 733 for dt in get_document_types(): 734 print dt 735 736 print "------------------------------" 737 print "testing document type handling" 738 print "------------------------------" 739 740 dt = create_document_type(document_type = 'dummy doc type for unit test 1') 741 print "created:", dt 742 743 dt['type'] = 'dummy doc type for unit test 2' 744 dt.save_payload() 745 print "changed base name:", dt 746 747 dt.set_translation(translation = 'Dummy-Dokumenten-Typ fuer Unit-Test') 748 print "translated:", dt 749 750 print "deleted:", delete_document_type(document_type = dt) 751 752 return
753 #--------------------------------------------------------
754 - def test_adding_doc_part():
755 756 print "-----------------------" 757 print "testing document import" 758 print "-----------------------" 759 760 docs = search_for_document(patient_id=12) 761 doc = docs[0] 762 print "adding to doc:", doc 763 764 fname = sys.argv[1] 765 print "adding from file:", fname 766 part = doc.add_part(file=fname) 767 print "new part:", part 768 769 return
770 #--------------------------------------------------------
771 - def test_get_documents():
772 doc_folder = cDocumentFolder(aPKey=12) 773 774 #photo = doc_folder.get_latest_mugshot() 775 #print type(photo), photo 776 777 docs = doc_folder.get_documents() 778 for doc in docs: 779 print type(doc), doc 780 print doc.parts 781 pprint(gmBusinessDBObject.jsonclasshintify(docs))
782 #-------------------------------------------------------- 783 from Gnumed.pycommon import gmI18N 784 gmI18N.activate_locale() 785 gmI18N.install_domain() 786 787 #test_doc_types() 788 #test_adding_doc_part() 789 test_get_documents() 790 791 # print get_ext_ref() 792 793 #============================================================ 794