def calculate_durations(): # # compute the duration of the call. # if globals4signal.has_key('call_duration'): callDur = globals4signal['call_duration'] else: endTime = datetime.datetime.now() startTime = globals4signal['start_time'] delta = endTime - startTime seconds = delta.seconds dsh_utils.db_print('dsh_django1.sys_exit: call duration: ' + str(seconds) + 's.', 95) callDur = seconds globals4signal['call_duration'] = seconds # # compute the duration of the recording. # if globals4signal.has_key('rec_duration'): recDur = globals4signal['rec_duration'] elif globals4signal.has_key('start_record'): startRecord = globals4signal['start_record'] delta = endTime - startRecord seconds = delta.seconds dsh_utils.db_print('dsh_django1.sys_exit: record duration: ' + str(seconds) + 's.', 95) recDur = seconds globals4signal['rec_duration'] = seconds else: recDur = None return (callDur,recDur)
def free_MB(path): """returns the amount of available space in MB. used to be in ryw.py""" #tested. dsh_utils.db_print('ryw_xp:free_MB() entered...', 49) path = os.path.normpath(path) if not dsh_utils.try_mkdir_ifdoesnt_exist(path, 'free_MB'): dsh_utils.give_bad_news( 'free_MB: try_mkdir_ifdoesnt_exist failed: ' + path, logging.critical) return 0 try: sectorsPerCluster,bytesPerSector,numFreeClusters,totalNumClusters = \ win32file.GetDiskFreeSpace(path) except: dsh_utils.give_bad_news( 'fatal_error: failed to determine free disk space: '+path, logging.critical) return 0 sectorsPerCluster = long(sectorsPerCluster) bytesPerSector = long(bytesPerSector) numFreeClusters = long(numFreeClusters) totalNumClusters = long(totalNumClusters) freeMB = (numFreeClusters * sectorsPerCluster * bytesPerSector) / \ (1024 * 1024) return freeMB
def patch_caller_as_DIET(caller, keyWordStr, keyWordTable, sessionID): """called by handle_staff_caller(). pretend the caller to be for DIET. patch its organization to add a DIET flag. somewhat modeled after: get_active_broadcast_item(). returns the patched caller. """ keyWords = keyWordTable.objects.filter(key_word=keyWordStr) if keyWords: dsh_utils.db_print( 'patch_caller_as_DIET: found keyword: '+ \ repr(keyWords), 136) keyWord = keyWords[0] else: message = 'dsh_common_test.patch_caller_as_DIET: ' + \ 'failed to locate this key word: ' + keyWordStr dsh_utils.give_bad_news(message, logging.error) dsh_agi.report_event(message, reportLevel='ERR', sessionID=sessionID) return None caller.organization.org_key_word = keyWord dsh_utils.db_print('patch_caller_as_DIET: caller patched!', 136) return caller
def sys_exit(code): """a wrapper for sys.exit()""" # # repeats the caller info: phone number, school, name. # if globals4signal.has_key('log_str'): logStr = globals4signal['log_str'] else: logStr = '' # # compute the duration of the call. # endTime = datetime.datetime.now() startTime = globals4signal['start_time'] delta = endTime - startTime seconds = delta.seconds dsh_utils.db_print('dsh_simple1.sys_exit: call duration: ' + str(seconds) + 's.', 95) logStr += str(seconds) + ' || ' # # compute the duration of the recording. # if globals4signal.has_key('start_record'): startRecord = globals4signal['start_record'] delta = endTime - startRecord seconds = delta.seconds dsh_utils.db_print('dsh_simple1.sys_exit: record duration: ' + str(seconds) + 's.', 95) logStr += str(seconds) + ' ||' dsh_utils.give_news('dsh_simple1.sys_exit: ' + logStr, logging.info) sys.exit(code)
def main(): global globals4signal globals4signal["session_id"] = dvoice.db.models.assign_dsh_uid() dsh_django2.init_log("dsh_failed: entered, session %s --------------------" % (get_session(),)) # # get the AGI environment variables. # chicken out if it's not due to .call failure. # env = dsh_agi.read_env() if env == {}: message = "dsh_failed: failed to read agi envs." dsh_utils.give_bad_news(message, logging.error) dsh_agi.report_event(message, reportLevel="ERR", sessionID=get_session()) sys.exit(1) if not env.has_key("agi_channel"): message = "dsh_failed: no agi_channel." dsh_utils.give_bad_news(message, logging.error) dsh_agi.report_event(message, reportLevel="ERR", sessionID=get_session()) sys.exit(1) if env["agi_channel"] != "OutgoingSpoolFailed": message = "dsh_failed: unexpected agi_channel: " + env["agi_channel"] dsh_utils.give_bad_news(message, logging.error) dsh_agi.report_event(message, reportLevel="ERR", sessionID=get_session()) sys.exit(1) dsh_config.init(env) # # get the dsh_uid of the callee from the command argument. # dsh_utils.db_print("dsh_failed: arguments are: " + repr(sys.argv), 116) if len(sys.argv) < 2: message = "dsh_failed: not enough arguments." dsh_utils.give_bad_news(message, logging.error) dsh_agi.report_event(message, reportLevel="ERR", sessionID=get_session()) sys.exit(1) calleeDshUid = sys.argv[1].strip() if not calleeDshUid: message = "dsh_failed: no dshUid found." dsh_utils.give_bad_news(message, logging.error) dsh_agi.report_event(message, reportLevel="ERR", sessionID=get_session()) sys.exit(1) dsh_utils.db_print("dsh_failed: calleeDshUid: " + calleeDshUid, 116) globals4signal["callee_dsh_uid"] = calleeDshUid # # let's sever ties with Asterisk. # this ensures the old .call file is deleted. # signal.signal(signal.SIGHUP, hangup_signal_handler) dsh_agi.send_command("HANGUP\n", caller="dsh_failed:") sys.exit(0)
def init_dirs(): global globals4signal # # set up logging. # logdir = dsh_config.lookup('log_file_dir') logName = dsh_config.lookup('log_file_name') dsh_utils.check_logging(logdir, logName) dsh_utils.give_news('dsh_simple1: entered --------------------', logging.info) # # set up directories. # success,outDir,inDir = setup_dirs() if not success: return (False,None,None,None) dsh_utils.db_print('dsh_simple1.init_dirs: ' + 'outdir: ' + outDir + ', indir: ' + inDir, 94) # # check existence of output file. # outFile = dsh_config.lookup('outgoing_voice_file') outFile = os.path.join(outDir, outFile) if not sound_exists(outFile): return (False,None,None,None) dsh_utils.db_print('dsh_simple1.init_dirs: ' + 'outFile: ' + outFile, 94) globals4signal['log_dir'] = logdir return (True,inDir,outDir,outFile)
def flock_unlock(flockSelf): #remove locks #tested dsh_utils.db_print('ryw_xp:flock_unlock() entered...', 49) fl = flockSelf win32file.UnlockFileEx(fl.hfile,0, fl.highbits, fl.ov) fl.hfile.Close()
def unlock(adRotateHandler, file): """used to be in ad.py.""" dsh_utils.db_print('ryw_xp:unlock() entered...', 49) ad = adRotateHandler ad.highbits=-0x7fff0000 ad.ov=pywintypes.OVERLAPPED() ad.hfile = win32file._get_osfhandle(file.fileno()) win32file.UnlockFileEx(ad.hfile,0,ad.highbits,ad.ov) #remove locks ad.hfile.Close()
def launch_explorer(path): """from explorer.launchExplorer()""" command = r"explorer" options = ["/n,","/root,",path] dsh_utils.db_print('launch_explorer: command is: ' + repr([command] + options), 46) ret = subprocess.call([command] + options) if ret != 1: dsh_utils.give_bad_news("launch_explorer: Error in launching explorer.", logging.error) return False return True
def check_personalized_followup_to(caller, msg, sessionID, sayPersonNameFunc=None): """ called by dsh_django2.check_personalized_messages(). if the followup_to field of the personalized message points to caller himself, we want to play the original question that resulted in this personalized message. modeled after check_personalized_messages(). sayPersonNameFunc is dsh_django2.say_message_from_name(). """ dsh_utils.db_print('check_personalized_followup_to: entered.', 151) if not msg or not caller or not msg.owner: dsh_utils.db_print('check_personalized_followup_to: nulls.', 151) return question = msg.followup_to if not question: dsh_utils.db_print('check_personalized_followup_to: no followup_to.', 151) return if question.owner.dsh_uid != caller.dsh_uid: #dsh_utils.db_print('check_personalized_followup_to: not same owner.', # 151) #return pass if question.owner.ptype != 'USR': # # we will read the question back ONLY if the question # was left by a "user." # dsh_utils.db_print('check_personalized_followup_to: '+\ 'question not by user type.', 151) return chopped = get_sln_path_for_asterisk(question) if not chopped: message = 'dsh_common_agi.check_personalized_followup_to: ' +\ 'unable to find .sln file: ' + repr(question) dsh_agi.report_event(message, reportLevel='ERR', sessionID=sessionID) dsh_utils.give_bad_news(message, logging.error) return say_date(question) if sayPersonNameFunc: dsh_utils.db_print('check_personalized_followup_to: saying name.', 151) sayPersonNameFunc(question.owner) dsh_agi.say_it(chopped) dsh_agi.say_it('beep')
def try_remove_prefix(phoneNum, prefix): """ called by chop_prefix_digits_for_local() above. does phoneNum have a leading 0? if not, try adding one. does prefix have a leading 0? if not, try adding one. chop off the prefix if there's a match. if there's no match, do nothing to phoneNum """ original = phoneNum if not prefix: return original l1 = len(phoneNum) if l1 < 2: # # I'm going to look at the first character so it better be at # at least that long. # return original if phoneNum[0] != '0': # # "normalize" the phone number, by adding a '0' # phoneNum = '0' + phoneNum l1 = len(phoneNum) if prefix[0] != '0': # # "normalize" the prefix too. # prefix = '0' + prefix l2 = len(prefix) if l1 <= l2: return phoneNum if phoneNum.startswith(prefix): phoneNum = phoneNum[l2:] dsh_utils.db_print( 'try_remove_prefix: chopped to: ' + phoneNum, 139) return phoneNum # # there's no match, do nothing to the original number. # dsh_utils.db_print('try_remove_prefix: no chop: ' + original, 139) return original
def flock_init(flockSelf, file): #tested. dsh_utils.db_print('ryw_xp:flock_init() entered...', 49) fl = flockSelf secur_att = win32security.SECURITY_ATTRIBUTES() secur_att.Initialize() fl.highbits=0x7fff0000 #high-order 32 bits of byte range to lock #make a handle with read/write and open or create if doesn't exist fl.hfile=win32file.CreateFile( fl.file, win32con.GENERIC_READ|win32con.GENERIC_WRITE, win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE, secur_att, win32con.OPEN_ALWAYS, win32con.FILE_ATTRIBUTE_NORMAL, 0)
def main(): init_log() overWrite = False if '--overwrite' in sys.argv: overWrite = True dsh_utils.give_news('overwrite flag on.') dsh_utils.db_print('dsh_load: entered...', 104) dsh_dump.load_all(dumpfile.SelectedKeyWords, dumpfile.SelectedOrgs, dumpfile.SelectedPersons, dumpfile.SelectedItems, dumpfile.SelectedEvents, overWrite)
def test_caller_has_any_message_at_all(caller, itemTable, keyWordTable, eventTable, sessionID=''): """ called by dsh_django2.handle_staff_caller(). tests dsh_common_agi.person_has_any_message_at_all(). """ hasStuff,message = dsh_common_agi.person_has_any_message_at_all( caller, itemTable, keyWordTable, eventTable, sessionID=sessionID) dsh_utils.db_print( 'test_caller_has_any_message_at_all: ' + repr(hasStuff), 165) dsh_utils.db_print( 'test_caller_has_any_message_at_all: ' + message, 165) return True
def main(): prefix = dsh_config.lookup('log_file_dir') logName = dsh_config.lookup('log_file_name') dsh_utils.check_logging(prefix, logName) dsh_utils.db_print('dsh_test1: entered...', 93) dsh_agi.read_env() testOut1 = prefix + 'test_out1' testOut2 = prefix + 'test_tanuja' testIn1 = prefix + 'test_in1' dsh_agi.say_it(testOut1) #dsh_agi.say_it(testOut2) #dsh_agi.say_it('/var/lib/asterisk/sounds/demo-congrats') dsh_agi.record(testIn1) dsh_agi.say_it(testIn1) dsh_utils.give_news('dsh_test1: done.')
def demo_reply_prompt_confirm(recent, itemTable, keyWordTable, eventTable, sessionID=''): """ 10/04/09: called by demo_reply(). modeled after dsh_django2.handle_staff_caller(). """ funcName = 'dsh_common_agi.demo_reply_prompt_confirm:' count = 0 promptDir = dsh_common_config.lookup('DSH_PROMPT_DIR') demoPress1 = dsh_common_config.lookup('DSH_PROMPT_DEMO_PRESS1_SEND') demoPress1 = os.path.join(promptDir, demoPress1) timeOut1 = dsh_config.lookup('DSH_PROMPT_WAIT1') maxRetries = dsh_common_config.lookup2('STAFF_RETRIES') demoSending = dsh_common_config.lookup('DSH_PROMPT_DEMO_SENDING_IN8') demoSending = os.path.join(promptDir, demoSending) while True: count += 1 if count > maxRetries: say_goodbye() return True choice = dsh_agi.get_digits(demoPress1, 1, timeOut=timeOut1) dsh_utils.db_print('%s the choice is: %s.' % (funcName, repr(choice)), 168) if choice == None or choice == '' or choice == '*': say_goodbye() return True if choice == '1': dsh_common_db.attempt_demo_reply_now( recent, itemTable, keyWordTable, eventTable, sessionID=sessionID) dsh_agi.say_it(demoSending) say_goodbye() return True continue return True
def remove_from_current_dial_if_no_message( caller, itemTable, keyWordTable, eventTable, noLogging=False, sessionID=''): """ called by somewhere from the signal handler in dsh_django2.py. see note100331. """ dsh_common_db.init_log(quiet=True) if not caller.current_dial: dsh_utils.db_print('remove_from_current_dial_if_no_message: ' +\ 'not in CDS.', 165) return hasMessage,whatStr = person_has_any_message_at_all( caller, itemTable, keyWordTable, eventTable, noLogging=noLogging, sessionID=sessionID) if hasMessage: dsh_utils.db_print('remove_from_current_dial_if_no_message: ' +\ 'has messages: ' + whatStr, 165) return caller.current_dial = False try: caller.save(noLogging=noLogging) except: message = 'dsh_common_agi.remove_from_current_dial_if_no_message: ' +\ 'failed to save person: ' + caller.dsh_uid dsh_django_utils.error_event(message, item=person, errorLevel='CRT') dsh_utils.give_bad_news(message, reportLevel='CRT') return message = 'dsh_common_agi.remove_from_current_dial_if_no_message: ' +\ 'removed from current dial: ' + caller.__unicode__() dsh_agi.report_event( message, action='RCDS', owner=caller, sessionID=sessionID) dsh_utils.give_news(message, logging.info)
def flock_lock(flockSelf): #tested. dsh_utils.db_print('ryw_xp:flock_lock() entered...', 49) fl = flockSelf if fl.type['LOCK_EX']: #exclusive locking if fl.type['LOCK_NB']: #don't wait, non-blocking lock_flags=win32con.LOCKFILE_EXCLUSIVE_LOCK| \ win32con.LOCKFILE_FAIL_IMMEDIATELY else: #wait for lock to free lock_flags=win32con.LOCKFILE_EXCLUSIVE_LOCK else: #shared locking if fl.type['LOCK_NB']: #don't wait, non-blocking lock_flags=win32con.LOCKFILE_FAIL_IMMEDIATELY else:#shared lock wait for lock to free lock_flags=0 #used to indicate starting region to lock fl.ov=pywintypes.OVERLAPPED() win32file.LockFileEx(fl.hfile,lock_flags,0,fl.highbits,fl.ov)
def lookup_number_in_db(env, debugCheat=False): """lookup the caller info in the django database. returns the tuple (pObj, phoneNumber)""" if debugCheat: env['agi_callerid'] = '06935237794' if not env.has_key('agi_callerid'): message = 'dsh_django1.lookup_number_in_db: ' + \ ' no phone number given by Asterisk.' dsh_utils.give_news(message, logging.info) dsh_agi.report_event(message, reportLevel='WRN') return None phoneNumber = env['agi_callerid'] persons = Person.objects.filter(phone_number=phoneNumber) if not persons: message = 'dsh_django1.lookup_number_in_db: ' + \ ' phone number not found in database: ' + phoneNumber dsh_utils.give_news(message, logging.info) dsh_agi.report_event(message, reportLevel='WRN', phone_number=phoneNumber) return (None, phoneNumber) if len(persons) > 1: message = 'dsh_django1.lookup_number_in_db: ' + \ 'more than one person in the db has this number: ' + \ phoneNumber + \ ', the list of people are: ' + \ repr(persons) dsh_utils.give_news(message, logging.info) dsh_agi.report_event(message, reportLevel='INF', phone_number=phoneNumber) #p = persons[0] p = persons.latest() answer = (p, phoneNumber) dsh_utils.db_print('dsh_django1.lookup_number_in_db: ' + repr(answer), 98) return answer
def field_to_sln_path(field, sessionID=None): """ moved from dsh_django2.py fix up the file name: from the database, it's an mp3 URL. django should have taken the trouble of converting it to sln alredy. we call some function to get the path name of the sln file. """ #mp3FilePath = item.file.url mp3FilePath = field.url pathStuff = dsh_agi.figure_out_sln_names(mp3FilePath) if not pathStuff: message = 'dsh_django1.get_sln_path_for_asterisk: ' + \ 'failed to find path stuff for: ' + repr(mp3FilePath) dsh_agi.report_event(message, reportLevel='CRT', sessionID=sessionID) dsh_utils.give_bad_news(message, logging.critical) return None slnDir,slnBaseName,wavBaseName,fullSlnName,fullWavName = pathStuff dsh_utils.db_print('dsh_django1.get_sln_path_for_asterisk: ' + fullSlnName, 97) # # do a sanity check of the .sln file. # if not dsh_utils.is_valid_file(fullSlnName, msg='', silent=True): message = 'dsh_django.get_sln_path_for_asterisk: ' + \ 'not a valid file: ' + fullSlnName dsh_agi.report_event(message, reportLevel='ERR', sessionID=sessionID) dsh_utils.give_bad_news(message, logging.error) return None # # Asterisk doesn't like to be told the .sln extension so get rid of it. # chopped = fullSlnName.replace('.sln', '') dsh_utils.db_print('dsh_django1.get_sln_path_for_asterisk: success: ' + chopped, 108) return chopped
def get_outgoing_voice_from_db(): # # look up in the django database. # look for items that are "active" and are of the "broadcast" type. # activeBroadcastItems = Item.objects.filter(active=True, itype='B') if not activeBroadcastItems: message = 'dsh_django1.get_outgoing_voice_from_db: ' + \ 'no currently active broadcast message.' dsh_agi.report_event(message, reportLevel='ERR') dsh_utils.give_bad_news(message, logging.error) return None item = activeBroadcastItems[0] dsh_utils.db_print('dsh_django1.get_outgoing_voice_from_db: ' + repr(item), 97) chopped = get_sln_path_for_asterisk(item) if chopped == None: return None return (item,chopped)
def hangup_signal_handler(signum, frame): """called after the hangup signal is received.""" global globals4signal dsh_utils.db_print2('dsh_failed.signal_handler: entered...', 116) time.sleep(1) calleeDshUid = globals4signal['callee_dsh_uid'] if is_triggered_by_dial_now(calleeDshUid): sys.exit(0) callee = dsh_django_utils.get_foreign_key(Person, calleeDshUid) if not callee: message = 'dsh_failed: no such callee found: ' + calleeDshUid dsh_utils.give_bad_news(message, logging.error) dsh_agi.report_event(message, reportLevel = 'ERR', sessionID=get_session()) sys.exit(1) else: dsh_utils.db_print('dsh_failed: found callee: ' + repr(callee), 116) event = Event( owner=callee, phone_number=callee.phone_number, action='NOPU', etype='INF', description='.call not picked up. re-arming.', session=get_session()) event.save() dsh_django_utils.check_auto_timed_calls_for_person( callee, sessionID=get_session()) calleeInfo = dsh_django_utils.callee_info(callee) dsh_utils.give_news('dsh_failed.signal_handler: rearming callee: '+\ calleeInfo, logging.info)
def maybe_deactivate_personal_message(item): """if all the intended audience has heard this item, de-activate it.""" allAudience = item.intended_audience.all() if not allAudience: dsh_utils.db_print('dsh_django1.maybe_deactivate_personal_message: '+\ item.dsh_uid, 108) return for caller in allAudience: heardEvents = Event.objects.filter( action='HERD',owner=caller.id, dsh_uid_concerned=item.dsh_uid) if not heardEvents: dsh_utils.db_print( 'dsh_django1.maybe_deactivate_personal_message: ' +\ 'not heard by this caller yet: ' + caller.phone_number, 108) return item.active = False item.save() message = 'dsh_django1.maybe_deactivate_personal_message: deactivated: '+\ item.dsh_uid dsh_utils.give_news(message, logging.info) dsh_agi.report_event(message, item=item)
def chop_prefix_digits_for_local(callNum, callee): """ 10/02/02: chopping of the leading zero is moved from dsh_django_utils.generate_dot_call_file(). also adding code to remove 0522. """ dsh_common_db.init_log(quiet=True) #if callee.phone_std: # # 10/03/13: # dial as is. # #return callNum dsh_utils.db_print( 'chop_prefix_digits_for_local: enter: callNum: ' + callNum, 152) if len(callNum) > 1 and (not callee.phone_std) and \ (not callee.phone_landline) and callNum[0] == '0' and \ (callNum[1] == '9' or callNum[1] == '8'): # # it looks like Asterisk doesn't like the leading 0 # for cell phone numbers, chop it off. # 10/03/14: # now dealing with phone numbers that start with 8. # callNum = callNum[1:] dsh_utils.db_print( 'chop_prefix_digits_for_local: return1: callNum: ' + callNum, 152) return callNum localLandLinePrefix = dsh_db_config.get('local_land_line_prefix') if not localLandLinePrefix: message = 'chop_prefix_digits_for_local: no local land line prefix.' dsh_utils.give_bad_news(message, logging.warning) dsh_agi.report_event(message, reportLevel='WRN') # # try_remove_prefix() will deal with null prefix # so no need to worry about anything else than logging message. # # 10/03/14: # should look at the callee.phone_landline flag. # but I'm not: it's still legit to look for 0522 and kill it # even if it was not explicitly marked as a landline. # callNum = try_remove_prefix(callNum, localLandLinePrefix) dsh_utils.db_print( 'chop_prefix_digits_for_local: returned ' + callNum, 152) return callNum
def test_call_say_time(caller): """called by handler_staff_caller(). test spoken dates. """ dsh_utils.db_print('test_call: entered...', 134) answer = dsh_django2.get_outgoing_voice_from_db(caller) if not answer: dsh_utils.give_bad_news( 'test_call: get_outgoing_voice_from_db() failed.', logging.critical) return False outVobj,outgoingVoice,allSharedHeard,playShared = answer dsh_utils.db_print('test_call: outgoingVoice: ' + outgoingVoice, 134) time = outVobj.modify_datetime timeStr = time.strftime('%#Y-%#m-%#d') dsh_utils.db_print('test_call: timeStr: ' + timeStr, 134) dsh_common_agi.say_date(outVobj) return True
def main(): global globals4signal globals4signal['start_time'] = datetime.datetime.now() # # check the voice data directories. # success,inDir,outDir,outFile = init_dirs() if not success: sys_exit(1) # # get the AGI environment variables. # env = dsh_agi.read_env() if env == {}: dsh_utils.give_bad_news('dsh_simple1: failed to read agi envs.', logging.error) sys_exit(1) # # log the caller info. # and construct a recorded file name based on caller info. # phoneNumber,callerInfo = lookup_number(env) logStr = dsh_map.log_caller_info(phoneNumber, callerInfo) globals4signal['log_str'] = logStr callerInfoStr = dsh_map.info2str(phoneNumber, callerInfo) callerInfoStr = dsh_utils.date_time_rand2() + '_' + callerInfoStr # # looks like: 090702_200101_38_09935237793_DSH_Randy-Wang.gsm # dsh_utils.db_print('dsh_simple1: callerInfoStr: ' + callerInfoStr, 94) # # setting up signal handler for hangup. # the handler will attempt to do the file format conversion. # signal.signal(signal.SIGHUP, hangup_signal_handler) # # play the out file. # dsh_agi.say_it(outFile) # # record it. # inFile = os.path.join(inDir, callerInfoStr) globals4signal['in_file'] = inFile globals4signal['start_record'] = datetime.datetime.now() dsh_agi.record(inFile) # # say it back. # #dsh_agi.say_it(inFile) dsh_utils.give_news('dsh_simple1: recording done.') # # convert file format too with a proper hangup (pressing the # key). # hangup_signal_handler(0, None)
def load_pointers_for_one(dump, whatKind, overWrite, itemsToSkip): """going through the dumped object the second round to set all the pointers within. for example, the 'followup_to' field in the Item table. """ dsh_utils.db_print('dsh_dump.load_pointers_for_one: entered... ' +\ repr(dump), 105) if not dump.has_key('dsh_uid'): return False dshUid = dump['dsh_uid'][1] # # this means that the first round of loading items has decided that # this item should not proceed to a second round. # if dshUid in itemsToSkip: return True # # set the "overWrite" arg to True. # success,newObj,obj = check_new_or_old(dump, whatKind, True) if not success or obj == None: dsh_utils.give_bad_news( 'dsh_dump.load_pointers_for_one: check_new_or_old failed.', logging.error) return success # # take all the fields from the dump file. # for fieldName,fieldContent in dump.iteritems(): fieldType,fieldValue = fieldContent if fieldType == 'OptionalFollowUpsType': # # fieldValue is a dsh_uid. # get the item that has this dsh_uid. # followItem = get_foreign_key( dvoice.db.models.Item, fieldValue) if not followItem: dsh_utils.give_bad_news( 'dsh_dump.load_pointers_for_one: ' + \ 'cannot find followup_to item: '+\ fieldValue, logging.error) # # because it's optional, we'll just move on. # not a big deal. # continue setattr(obj, fieldName, followItem) continue if fieldType == 'OptionalKeyWordsType': # # instead of a single foreign key, # now we're dealing with a list of foreign keys # in a many-to-many relationship. # # this also has to be dealt with in a second round because... # it turns out I must do a save to obtain a primary key, # otherwise I can't set many-to-many attr. # and unfortunately, the dump "spec," which is just a dictionary, # when you iterate through it, it goes in an unpredictable order, # so the owner and such required keys could be encountered after # this field. # this is why this field is moved here. # keyWords = get_foreign_key_list(dvoice.db.models.KeyWord, fieldValue) if keyWords == None: # # this shouldn't happen. in the worst case, it should've # been an empty list. # dsh_utils.give_bad_news( 'dsh_dump.load_one: something bad happened with ' +\ 'loading key words: ' + repr(keyWords), logging.critical) continue if keyWords == []: continue # # it turns out I must do a save to obtain a primary key, # otherwise I can't set many-to-many attr. # #if newObj: # obj.save() setattr(obj, fieldName, keyWords) continue if fieldType == 'OptionalPersonsType': # # like the KeyWord type above. # I should've tried to reduce repetition. # audience = get_foreign_key_list(dvoice.db.models.Person, fieldValue) if audience == None: # # this shouldn't happen. in the worst case, it should've # been an empty list. # dsh_utils.give_bad_news( 'dsh_dump.load_one: something bad happened with ' +\ 'loading audience: ' + repr(audience), logging.critical) continue if audience == []: continue # # it turns out I must do a save to obtain a primary key, # otherwise I can't set many-to-many attr. # #if newObj: # obj.save() setattr(obj, fieldName, audience) continue # # do nothing with any other types of fields. # # # finally, put it in the django database. # try: obj.save() dsh_utils.db_print('dsh_dump.load_pointers_for_one: obj is saved.', 105) except: dsh_utils.give_bad_news( 'dsh_dump.load_pointers_for_one: obj.save() failed: ' +\ dshUid, logging.critical) return False return True
def load_one(dump, whatKind, overWrite, itemsToSkip=None): """called by dsh_load.py, to load one dumped object into the django db. 'dump' is a dictionary, read from the dump file. of the form: fieldName: [fieldType, fieldValue], 'whatKind' is the Class. like: KeyWord, Organization, Person, Item. """ dsh_utils.db_print('dsh_dump.load_one: entered... ' + repr(dump), 105) success,newObj,obj = check_new_or_old(dump, whatKind, overWrite, itemsToSkip=itemsToSkip) if not success or obj == None: return success dshUid = dump['dsh_uid'][1] # # take all the fields from the dump file. # for fieldName,fieldContent in dump.iteritems(): fieldType,fieldValue = fieldContent # # some fields take some work to load. # if fieldType == 'RequiredForeignOrgType': # # fieldValue is a dsh_uid. # get the org that has this dsh_uid. # org = get_foreign_key(dvoice.db.models.Organization, fieldValue) if not org: dsh_utils.give_bad_news( 'dsh_dump.load_one: failed on RequiredForeignOrgType: '+\ fieldValue, logging.error) # # because it's a required field, # there's no point continuing---loading is aborted. # return False setattr(obj, fieldName, org) continue if fieldType == 'RequiredForeignPersonType': # # similar to the case above. # person = get_foreign_key(dvoice.db.models.Person, fieldValue) if not person: dsh_utils.give_bad_news( 'dsh_dump.load_one: ' +\ 'failed on RequiredForeignPersonType: ' +\ fieldValue, logging.error) return False setattr(obj, fieldName, person) continue if fieldType == 'OptionalFollowUpsType' or \ fieldType == 'OptionalKeyWordsType' or \ fieldType == 'OptionalPersonsType': # # this is to be dealt with in a second round. # so we skip it in this round. # if I don't say something here, however, # it falls through the default case at the bottom. # the default case is for trivial field types. # continue if fieldType == 'OptionalOwnerType': # # this is used by the Event table. # like owner of the Item table. # except it's optional this time. # person = get_foreign_key(dvoice.db.models.Person, fieldValue) if not person: continue setattr(obj, fieldName, person) continue # # all other types of fields (like string and int) are easy to set. # setattr(obj, fieldName, fieldValue) dsh_utils.db_print('dsh_dump.load_one: obj is: ' + repr(obj), 105) # # finally, put it in the django database. # try: obj.save() dsh_utils.db_print('dsh_dump.load_one: obj is saved.', 105) except: dsh_utils.give_bad_news('dsh_dump.load_one: obj.save() failed: ' +\ dshUid, logging.critical) return False return True
def check_new_or_old(dump, whatKind, overWrite, itemsToSkip=None): """upon loading, see if we need to make a new object, or we are overwriting an existing old object. returns (success, newObj, obj) called by load_one() and load_pointers_for_one()""" # # check the dsh_uid. # to see if it's already in the database. # if not dump.has_key('dsh_uid'): dsh_utils.give_bad_news('dsh_dump.check_new_or_old: ' + \ 'failed to find dsh_uid', logging.critical) return (False, False, None) dshUid = dump['dsh_uid'][1] existingObjs = whatKind.objects.filter(dsh_uid=dshUid) howMany = len(existingObjs) if howMany > 1: dsh_utils.give_bad_news( 'dsh_dump.check_new_or_old: found multiple dsh_uids: ' + \ dshUid, logging.critical) if itemsToSkip != None: itemsToSkip.append(dshUid) return (False, False, None) # # if it's already in the database... # if howMany == 1: dsh_utils.db_print('dsh_dump.check_new_or_old: dsh_uid found 1: ' + \ dshUid, 105) if not overWrite: # # give up if we don't want to overwrite it. # dsh_utils.give_news( 'dsh_dump.check_new_or_old: not overwriting dsh_uid: ' + \ dshUid, logging.info) if itemsToSkip != None: itemsToSkip.append(dshUid) return (True, False, None) # # we will overwrite the existing object. # dsh_utils.give_news( 'dsh_dump.check_new_or_old: ' + \ 'overwriting dsh_uid: ' + dshUid, logging.info) obj = existingObjs[0] return (True, False, obj) else: # # it's not in the existing database. # so we'll make a new one. # dsh_utils.give_news('dsh_dump.check_new_or_old: dsh_uid to save: ' + \ dshUid, logging.info) obj = whatKind() return (True, True, obj)
def init_unknown_org_person(sessionID=''): """moved from dsh_django2. if the database doesn't have a default unknown organization, make one. if the database doesn't have a default unknown person (for no number), make one.""" # # see if we could find the unknown org. if not, make one. # unknownOrgAlias = dsh_config.lookup('UNKNOWN_ORG_ALIAS') unknownOrgs = dvoice.db.models.Organization.objects.filter( alias=unknownOrgAlias) if unknownOrgs: unknownOrg = unknownOrgs.latest() if len(unknownOrgs) > 1: message = 'dsh_django1.init_unknown_org_person: ' + \ 'more than one unknown org found.' dsh_utils.give_news(message, logging.warning) report_event(message, reportLevel='WRN', sessionID=sessionID) dsh_utils.db_print('dsh_django1: found existing unknown org.', 99) else: unknownOrg = dvoice.db.models.Organization( name='Unknown Organization', alias=unknownOrgAlias, language='OTH', description="""This is a place holder organization for unknown callers, automatically added by Asterisk.""") unknownOrg.save() dsh_utils.db_print('dsh_django1: created new unknown org.', 99) dsh_utils.db_print('dsh_django1: unknownOrg: ' + repr(unknownOrg), 99) # # see if we could find the unknown person. if not, make one. # unknownNumber = dsh_config.lookup('UNKNOWN_PHONE_NUMBER') unknownPersonName = dsh_config.lookup('UNKNOWN_PERSON_NAME') unknownPersons = dvoice.db.models.Person.objects.filter( first_name=unknownPersonName, phone_number=unknownNumber) if unknownPersons: unknownPerson = unknownPersons.latest() if len(unknownPersons) > 1: message = 'dsh_django1.init_unknown_org_person: ' + \ 'more than one unknown person found.' dsh_utils.give_news(message, logging.warning) report_event(message, reportLevel='WRN', phone_number=unknownPerson.phone_number, sessionID=sessionID) dsh_utils.db_print('dsh_django1: found existing unknown person.', 99) else: unknownPerson = dvoice.db.models.Person( first_name=unknownPersonName, phone_number=unknownNumber, organization=unknownOrg, ptype='OTH', gender='F', description="""This is the place-holder person for callers whose phone numbers we don't know, automatically added by Asterisk.""") unknownPerson.save() dsh_utils.db_print('dsh_django1: created new unknown person.', 99) dsh_utils.db_print('dsh_django1: unknownPerson: ' + repr(unknownPerson), 99) return (unknownOrg,unknownPerson)