Best Python code snippet using fMBT_python
smsaction.py
Source:smsaction.py
1#! python2# -*- coding: utf-8 -*-3# This is a utility module for integrating SMS providers into VizAlerts.4import os5import re6import phonenumbers7import twilio8# import local modules9from . import config10from . import log11from . import vizalert12# store the SMS client we get back from Twilio for use across all modules13smsclient = None14# regular expression used to split recipient number strings into separate phone numbers15SMS_RECIP_SPLIT_REGEX = '[;,]'16# appended to the bottom of all SMS messages, unless overidden17# expecting smsfooter.format(subscriber_email)18smsfooter = '\r\rThis VizAlert SMS sent on behalf of {}'19class SMS(object):20 """Represents an SMS to be sent"""21 def __init__(self, sms_from, sms_to, msgbody=None):22 self.sms_from = sms_from23 self.sms_to = sms_to24 self.msgbody = msgbody # REVISIT--why is it okay for this to be blank?25def get_sms_client():26 """Generic function get an SMS client object. This only works with Twilio at this time."""27 # check to see if there's a provider set28 if config.configs['smsaction.provider'] == None or len(config.configs['smsaction.provider']) == 0:29 errormessage = 'SMS Actions are enabled but smsaction.provider value is not set, exiting'30 log.logger.error(errormessage)31 raise ValueError(errormessage) 32 # load code for Twilio33 elif config.configs['smsaction.provider'].lower() == 'twilio': 34 # these need to be in the global name space to send SMS messages35 global twilio36 import twilio37 global twiliorest38 import twilio.rest as twiliorest39 40 global smsclient41 smsclient = twiliorest.Client(42 config.configs['smsaction.account_id'],43 config.configs['smsaction.auth_token'])44 45 return smsclient46 # unknown SMS provider error47 else:48 errormessage = 'SMS Actions are enabled but found unknown smsaction.provider {}, exiting'.format(49 config.configs['smsaction.provider'])50 log.logger.error(errormessage)51 raise ValueError(errormessage) 52def send_sms(sms_instance):53 """REVISIT: This and the other SMS methods should probably be members of the SMS class54 function to send an sms using Twilio's REST API, see https://www.twilio.com/docs/python/install for details.55 Presumes that numbers have gone through a first level of checks for validity56 Returns nothing on success, error string back on failure"""57 # shouldn't happen but setting content to '' if it's None58 if not sms_instance.msgbody:59 sms_instance.msgbody = ''60 log.logger.info('Sending SMS: {},{},{}'.format(sms_instance.sms_from, sms_instance.sms_to, sms_instance.msgbody))61 # now to send the message62 try:63 if sms_instance.sms_from.startswith('+'):64 # kinda kloogy, but if we think it's an E.164 number, assume it is...65 message = smsclient.messages.create(body=sms_instance.msgbody, to=sms_instance.sms_to,66 from_=sms_instance.sms_from)67 else:68 # if not, assume it must be a message service SID69 message = smsclient.messages.create(body=sms_instance.msgbody, to=sms_instance.sms_to,70 messaging_service_sid=sms_instance.sms_from)71 # this may never happen since the Twilio REST API throws exceptions, it's a failsafe check72 if message.status == 'failed':73 raise ValueError('Failed to deliver SMS message to {} with body {},'74 ' no additional information is available'.format(75 sms_instance.sms_to,76 sms_instance.msgbody))77 # check for Twilio REST API exceptions78 except twilio.base.exceptions.TwilioRestException as e:79 errormessage = 'Could not send SMS message to {} with body {}.\nHTTP status {} returned for request: ' \80 '{} {}\nWith error {}: {} '.format(81 sms_instance.sms_to,82 sms_instance.msgbody,83 e.status,84 e.method,85 e.uri,86 e.code,87 e.msg)88 log.logger.error(errormessage)89 raise UserWarning(errormessage)90 # check for ValueError from try 91 except ValueError as e:92 log.logger.error(e)93 raise UserWarning(errormessage)94 except Exception as e:95 errormessage = u'Could not send SMS message to {} with body {}, error {}, type {}'.format(96 sms_instance.sms_to,97 sms_instance.msgbody, e, e.__class__.__name__)98 log.logger.error(errormessage)99 raise UserWarning(errormessage)100 return None101def sms_append_body(body, vizcompleterefs, row, alert):102 """Generic function for filling SMS body text with the body & footers from the csv103 plus inserting content references"""104 body.append(row[alert.action_field_dict[vizalert.SMS_MESSAGE_FIELDKEY].field_name])105 # add the footer if needed106 if alert.action_field_dict[vizalert.SMS_FOOTER_FIELDKEY].field_name:107 body.append(row[alert.action_field_dict[vizalert.SMS_FOOTER_FIELDKEY].field_name].replace(108 vizalert.DEFAULT_FOOTER,109 smsfooter.format(alert.subscriber_email)))110 else:111 # no footer specified, add the default footer112 body.append(smsfooter.format(alert.subscriber_email))113 # find all distinct content references in the email body list114 # so we can replace each with an inline image or hyperlink text115 foundcontent = re.findall('VIZ_LINK\(.*?\)', ' '.join(body))116 foundcontentset = set(foundcontent)117 vizrefs = list(foundcontentset)118 if len(vizrefs) > 0:119 for vizref in vizrefs:120 # we're replacing #VIZ_LINK text121 if vizcompleterefs[vizref]['formatstring'] == 'LINK':122 # always use raw link, ignore presence or absence of RAWLINK argument123 replacestring = alert.get_view_url(vizcompleterefs[vizref]['view_url_suffix'])124 replaceresult = vizalert.replace_in_list(body, vizref, replacestring)125 if replaceresult['foundstring']:126 body = replaceresult['outlist']127 return body128def validate_smsnumbers(vizdata, sms_to_fieldname, allowed_recipient_numbers, iso2countrycode):129 """Loops through the viz data for an Advanced Alert and returns a list of dicts130 containing any errors found in recipients"""131 errorlist = []132 rownum = 2 # account for field header in CSV133 try:134 for row in vizdata:135 result = smsnumbers_are_invalid(row[sms_to_fieldname],136 False, # empty string not acceptable as a To number137 iso2countrycode,138 allowed_recipient_numbers)139 if result:140 errorlist.append(141 {'Row': rownum, 'Field': sms_to_fieldname, 'Value': result['number'], 'Error': result['errormessage']})142 rownum += 1143 except Exception as e:144 errormessage = 'Encountered error validating SMS numbers. Error: {}'.format(e.message)145 log.logger.error(errormessage)146 errorlist.append(errormessage)147 return errorlist148 return errorlist149def smsnumbers_are_invalid(sms_numbers, emptystringok, iso2countrycode, regex_eval=None):150 """Validates all SMS numbers found in a given string, optionally that conform to the regex_eval"""151 152 log.logger.debug('Validating SMS field value: {}'.format(sms_numbers))153 sms_number_list = [sms_number for sms_number in filter(None, re.split(SMS_RECIP_SPLIT_REGEX, sms_numbers)) if len(sms_number) > 0]154 155 for sms_number in sms_number_list:156 log.logger.debug('Validating presumed sms number: {}'.format(sms_number))157 try:158 # skip if we're okay with empty, and it is159 if sms_number == '':160 if not emptystringok:161 errormessage = 'SMS number is empty'162 else:163 continue164 else:165 errormessage = smsnumber_is_invalid(sms_number, iso2countrycode, regex_eval)166 if errormessage:167 log.logger.debug('SMS number is invalid: {}, Error: {}'.format(sms_number, errormessage))168 if len(sms_number) > 64:169 sms_number = sms_number[:64] + '...' # truncate a too-long address for error formattting purposes170 return {'number': sms_number, 'errormessage': errormessage}171 except Exception as e:172 errormessage = 'Encountered error validating an SMS number. Error: {}'.format(e.message)173 log.logger.error(errormessage)174 return {'number': sms_number, 'errormessage': errormessage}175 return None176def smsnumber_is_invalid(smsnumber, iso2countrycode, regex_eval=None):177 """Checks for a syntactically invalid phone number, returns None for success or an error message"""178 try:179 e164_number = smsnumber_to_e164(smsnumber, iso2countrycode)180 # looks valid, but it must be permitted by regex pattern if so specified181 if regex_eval:182 log.logger.debug("testing smsnumber {} against regex {}".format(e164_number, regex_eval))183 if not re.match(regex_eval, e164_number):184 errormessage = 'SMS number must match regex pattern set by the administrator: {}'.format(regex_eval)185 log.logger.error(errormessage)186 return errormessage187 except Exception as e:188 return e.message189 # looks like it was fine!190 return None191def get_e164numbers(sms_numbers, iso2countrycode):192 """Converts a delimited string or list of SMS numbers to E.164 format193 Returns a UNIQUE list of E.164 numbers194 NOTE: This method ASSUMES that they have all been validated already """195 sms_number_list = []196 e164_numbers = []197 if isinstance(sms_numbers, str) or isinstance(sms_numbers, str):198 sms_number_list.extend(re.split(SMS_RECIP_SPLIT_REGEX, sms_numbers.strip()))199 elif isinstance(sms_numbers, list):200 sms_number_list.extend(sms_numbers)201 else:202 # that's not what we expected203 errormessage = 'Input is neither a string nor a list: {}'.format(sms_numbers)204 log.logger.error(errormessage)205 raise UserWarning(errormessage)206 # convert and add each number to our return list207 for sms_number in sms_number_list:208 log.logger.debug('Converting {} to E.164 format'.format(sms_number))209 try:210 e164_number = smsnumber_to_e164(sms_number, iso2countrycode)211 if e164_number not in e164_numbers:212 e164_numbers.append(e164_number)213 except Exception as e:214 raise UserWarning(e.message)215 return e164_numbers216def smsnumber_to_e164(smsnumber, iso2countrycode):217 """Tries to convert a string into an E.164 formatted phone number218 Raises exception if it can't, returns the E.164 number as a string, if it can """219 try:220 log.logger.debug('Converting {} to E.164 format, country code {}'.format(smsnumber, iso2countrycode))221 try:222 if smsnumber.startswith('+'):223 smsnumber_obj = phonenumbers.parse(smsnumber)224 else:225 # country code not specified in number, so pass it in226 smsnumber_obj = phonenumbers.parse(smsnumber, iso2countrycode)227 except phonenumbers.NumberParseException as e:228 errormessage = 'SMS Unable to parse number {}. Error: {}'.format(smsnumber, e.message)229 log.logger.error(errormessage)230 raise UserWarning(errormessage)231 try:232 if not phonenumbers.is_possible_number(smsnumber_obj):233 errormessage = 'SMS Number is not possibly valid: {}.'.format(smsnumber)234 log.logger.error(errormessage)235 raise UserWarning(errormessage)236 except phonenumbers.NumberParseException as e:237 errormessage = 'SMS Unable to parse number {}. Error: {}'.format(smsnumber, e.message)238 log.logger.error(errormessage)239 raise UserWarning(errormessage)240 if not phonenumbers.is_valid_number(smsnumber_obj):241 errormessage = 'SMS Number is not valid: {}.'.format(smsnumber)242 log.logger.error(errormessage)243 raise UserWarning(errormessage)244 e164_number = phonenumbers.format_number(smsnumber_obj, phonenumbers.PhoneNumberFormat.E164)245 if not e164_number:246 errormessage = 'SMS number {} could not be converted to E.164 for an unknown reason.'.format(smsnumber)247 log.logger.error(errormessage)248 raise UserWarning(errormessage)249 # all good, return it!250 return e164_number251 except Exception as e:252 log.logger.error(e.message)...
smsStringUtils.py
Source:smsStringUtils.py
1#!/usr/bin/env python2# -*- coding: utf-8 -*-3import unicodedata4# Oreze diakritiku. Pozor v GSM se pro 160 znakove sms pouziva GSM 7-bit encoding, toto je ascii (8-bit) kompatibilni string. Ne kazdy ASCII se vejde do 7-bitove GSM abecedy.5def strip_accents(text):6 """7 Strip accents from input String.8 Takes Unicode string as an input. Unicode as output.9 """10 text = unicodedata.normalize('NFD', text)11 text = text.encode('ascii', 'ignore')12 text = text.decode("utf-8")13 return text14# Tables can be found at: http://en.wikipedia.org/wiki/GSM_03.38#GSM_7_bit_default_alphabet_and_extension_table_of_3GPP_TS_23.038_.2F_GSM_03.3815GSM7_ALL_CHARS = ('@£$¥èéùìòÃ\nÃø\rÃ
Ã¥Î_ΦÎÎΩΠΨΣÎÎ\x1bÃæÃà !\"#¤%&\'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÃÃÃÃ`¿abcdefghijklmnopqrstuvwxyzäöñüà ^{}\\[~]|â¬' + chr(0xFF) )16GSM7_BASIC = ('@£$¥èéùìòÃ\nÃø\rÃ
Ã¥Î_ΦÎÎΩΠΨΣÎÎ\x1bÃæÃà !\"#¤%&\'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÃÃÃÃ`¿abcdefghijklmnopqrstuvwxyzäöñüà ')17GSM7_EXTENDED = {chr(0xFF): 0x0A,18 #CR2: chr(0x0D),19 '^': chr(0x14),20 #SS2: chr(0x1B),21 '{': chr(0x28),22 '}': chr(0x29),23 '\\': chr(0x2F),24 '[': chr(0x3C),25 '~': chr(0x3D),26 ']': chr(0x3E),27 '|': chr(0x40),28 'â¬': chr(0x65)}29# Maximum message sizes for each data coding30MAX_MESSAGE_LENGTH = {0x00: 160, # GSM-731 0x04: 140, # 8-bit32 0x08: 70} # UCS233# Maximum multipart message sizes. Less characters are available for user text, because UDH takes 6-bytes34MAX_MULTIPART_MESSAGE_LENGTH = {0x00: 153, # GSM-735 0x04: 134, # 8-bit36 0x08: 67} # UCS237def isEncodableToGsm7Alphabet(plaintext):38 """39 Find out if the specified text string is encodable to GSM-7 characters.40 Takes Unicode string as an input.41 """42 # convert unicode string to utf8 bytestring43 plaintext = plaintext.encode("utf-8")44 # check char after char45 for char in plaintext:46 if GSM7_ALL_CHARS.find(char) == -1:47 return False48 return True49def stripNonGsm7Characters(plaintext):50 """51 Strips characters not in GSM-7 alphabet from given string 52 Takes Unicode string as an input.53 """54 # convert unicode string to utf8 bytestring55 plaintext = plaintext.encode("utf-8")56 gsm7_text = u''57 # check char after char and make a new string58 for char in plaintext:59 if GSM7_ALL_CHARS.find(char) != -1:60 gsm7_text += char61 62 return gsm7_text63def smsCharacterCounter(plaintext):64 """65 Count how many of 140-byte SMS messages will be needed for given text66 Takes Unicode string as an input.67 """68 gsm7alphabet = isEncodableToGsm7Alphabet(plaintext)69 length = len(plaintext) # sms length. The number will include all sms escape characters too, see below.70 plaintext = plaintext.encode("utf-8") # pro byte-by-byte operace71 if gsm7alphabet:72 # 7-bit encoding73 # some chars need to be escaped (+escape char) so they occupy one extra character74 for char in plaintext:75 if char in GSM7_EXTENDED:76 length+=177 # count # of SMS parts78 if (length <= 160):79 numberOfSMS = 180 charactersRemaining = 160 - length81 else:82 numberOfSMS = 1 + int(length / 153)83 charactersRemaining = 153 * numberOfSMS - length84 else:85 # USC-2 16-bit encoding86 # count # of SMS parts87 if (length <= 70):88 numberOfSMS = 189 charactersRemaining = 70 - length90 else:91 numberOfSMS = 1 + int(length / 67)92 charactersRemaining = 67 * numberOfSMS - length93 return numberOfSMS, length, charactersRemaining94def smsCropString(plaintext, maximum, cropMode = "characters", gsm7alphabet = True):95 """96 Crop sms string to maximum number of characters97 Crop sms string to maximum number of SMS parts (not implemented yet)98 """99 length = len(plaintext) # sms length. The number will include all sms escape characters too, see below.100 #plaintext = plaintext.encode("utf-8") # pro byte-by-byte operace101 if gsm7alphabet:102 # 7-bit encoding103 croppedtext = u''104 for char in plaintext:105 # add a character to croppedtext106 croppedtext += char107 length+=1108 # some chars need to be escaped (+escape char) so they occupy one extra character109 if char in GSM7_EXTENDED:110 length+=1111 # if we reach the maximum, then stop the iteration and return the croppedtext112 if length is maximum:113 return croppedtext114 break115 else:116 # USC-2 16-bit encoding117 # simply return stripped string118 return plaintext[:maximum]119def isDestinationNumberPermitted(smsNumber):120 """121 ==Need to be placed elsewhere==122 Pravidla pro povolena telefonni cisla, vraci False pro zakazane cisla123 """124 # make sure the phone number is string125 smsNumber = str(smsNumber)126 # replace + for 00127 if (smsNumber[:1] == "+"):128 smsNumber = "00" + smsNumber[1:]129 # povolime jen cisla vypadajici jako cesky operator130 if (len(smsNumber) == 14):131 if (smsNumber[:2] == "00" and smsNumber[:5] == "00420" and int(smsNumber[5:]) >= 601000000 and int(smsNumber[5:]) <= 799999999):132 return True133 else:134 return False135 elif (len(smsNumber) == 9):136 if (int(smsNumber) >= 601000000 and int(smsNumber) <= 799999999):137 return True138 else:139 return False140 else:141 return False142 return False143# sometimes can be useful144def whatisthis(s):145 if isinstance(s, str):146 print "ordinary string"147 elif isinstance(s, unicode):148 print "unicode string"149 else:...
friendly_voicemail.py
Source:friendly_voicemail.py
1#!/usr/bin/python2from googlevoice import Voice,util3from BeautifulSoup import BeautifulSoup4import urllib25import urllib6import re7import time8import string9while True:10 voice = Voice()11 print "logging in..."12 voice.login('***gmail****', ******'gmail password******')13 newMessage=False14 voiceRequest=False15 smsRequest=False16 if len(voice.sms().messages)>0:17 newMessage=True18 print "woohoo! sms!"19 sms_parse=BeautifulSoup(voice.sms_html())20 extractedText=sms_parse.find(attrs={"class":"gc-message-sms-text"});21 extractedSMSNumber=sms_parse.find(attrs={"class":"gc-message-sms-from"});22 HTMLtag = re.compile('<.*?>') # Matches HTML tags23 HTMLcom = re.compile('<!--.*?-->') # Matches HTML comments24 extractedText = HTMLtag.sub('', HTMLcom.sub('', str(extractedText)))25 extractedSMSNumber = HTMLtag.sub('', HTMLcom.sub('', str(extractedSMSNumber)))26 extractedSMSNumber=extractedSMSNumber.strip();27 extractedSMSNumber=extractedSMSNumber.replace(":","");28 extractedSMSNumber=extractedSMSNumber.replace("(","");29 extractedSMSNumber=extractedSMSNumber.replace(")","");30 extractedSMSNumber=extractedSMSNumber.replace("-","");31 extractedSMSNumber=extractedSMSNumber.replace(" ","");32 # print extractedText33 # print extractedSMSNumber34 message_text=extractedText35 number=extractedSMSNumber36 smsRequest=True37 if len(voice.voicemail().messages) > 0 and smsRequest==False:38 newMessage=True39 voiceRequest=True40 print "wa wa wee wa! We got a message!"41 #Take a peek into the voicemail folder42 voice_parse=BeautifulSoup(voice.voicemail_html()) 43# print(voice.voicemail_html())44 #Search for voicemail messages45 voice_content=voice_parse.find(attrs={"class":"gc-message-message-display"})46 extractednumber=voice_parse.find(attrs={"class":"gc-message-mni"})47 # Strip out the HTML 48 HTMLtag = re.compile('<.*?>') # Matches HTML tags49 HTMLcom = re.compile('<!--.*?-->') # Matches HTML comments50 voice_clean = HTMLtag.sub('', HTMLcom.sub('', str(voice_content)))51 print extractednumber52 if extractednumber is not None:53 number=HTMLtag.sub('',HTMLcom.sub('', str(extractednumber)))54 else:55 number=None56 message_text = voice_clean.replace("\n"," ")57 message_text=message_text.strip()58 message_text=message_text.replace(".","");59 print message_text60 print number61 fields=string.split(message_text,",")62 print fields63 print len(fields)64 if len(fields) > 1:65# number=fields[0]66 message_text=fields[1].strip()67 else:68 message_text=fields[0].replace("1","")69 message_text=message_text.replace("2","");70 message_text=message_text.replace("3","");71 message_text=message_text.replace("4","");72 message_text=message_text.replace("5","");73 message_text=message_text.replace("6","");74 message_text=message_text.replace("7","");75 message_text=message_text.replace("8","");76 message_text=message_text.replace("9","");77 message_text=message_text.replace("0","");78 message_text=message_text.replace("(","");79 message_text=message_text.replace(")","");80 message_text=message_text.replace("-","");81 message_text=message_text.strip()82 if(number is None):83 number=voice.voicemail().messages[0].phoneNumber 84 if(number is not None):85 number=number.replace("-","")86 number=number.replace("+","")87 number=number.replace("(","")88 number=number.replace(")","")89 number=number.replace(" ","")90 if newMessage==True:91 #check to see if we have a properly transcribed message92 #this will screw up if we ever request a song with 'transcript' in the name93 if re.match("Transcript", message_text) == None:94 print message_text95 print number96 if voiceRequest:97 voice.voicemail().messages[0].delete()98 if smsRequest:99 voice.sms().messages[0].delete()100 query="TranscriptionText="+urllib.quote(message_text)+"&Caller="+number;101 print query102 search=urllib2.Request("http://www.artiswrong.com/ampache/song_callback.php",query)103 response=urllib2.urlopen(search)104 if re.match("Transcript not available", message_text): #the transcript's not available, for whatever reason105 voice.voicemail().messages[0].delete()106 #send a message saying we're sorry, but the search is a dud?107 print "uh-oh! Transcript not available. Try again!"108 109 else:110 print "no new song requests"...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!