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