| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- import unicodedata
- import subprocess
- import time
- def strip_accents(s):
- return "".join(
- c for c in unicodedata.normalize("NFD", s) if unicodedata.category(c) != "Mn"
- )
- GSM_7_ALPHABET = (
- "@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\x1bÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>"
- "?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑÜ`¿abcdefghijklmnopqrstuvwxyzäöñüà"
- )
- def is_gms_7(text: str) -> str:
- """Function that verify if the string is compatible with gsm 7 encoding"""
- for c in text:
- if not c in GSM_7_ALPHABET:
- return False
- return True
- def to_gsm_7(text: str) -> str:
- """Function that ensure the string is compatible with gsm 7 encoding"""
- return "".join([c if c in GSM_7_ALPHABET else strip_accents(c) for c in text])
- def get_index_of_last_space_before_nth_char(text, n):
- """Function that checks where to cut the message."""
- fragment = text[:n][::-1]
- # Split in on line feed
- if "\n" in fragment:
- return n - fragment.index("\n")
- # Split it on cariage return
- if "\r" in fragment:
- return n - fragment.index("\r")
- # Split it on white space
- if " " in fragment:
- return n - fragment.index(" ")
- # Split it anywhere
- return n
- def get_string_messages(msg, add_pagination=False):
- """Function that takes in a string message and returns
- an array of string messages with pagination if needed."""
- if is_gms_7(msg):
- SMS_MAX_LENGTH = 160
- SMS_CHUNK_LENGHT = 153
- else:
- SMS_MAX_LENGTH = 70
- SMS_CHUNK_LENGHT = 67
- if len(msg) <= SMS_MAX_LENGTH:
- # No pagination is needed
- return [msg]
- else:
- # Pagination is needed
- string_messages = []
- while msg:
- if len(msg) <= SMS_CHUNK_LENGHT:
- # if it's the last message then don't bother about not breaking words
- msg_len = len(msg)
- else:
- # check where is the last space before end of the sms to avoid breaking words
- msg_len = get_index_of_last_space_before_nth_char(msg, SMS_CHUNK_LENGHT)
- # generate new SMS
- msg_content = msg[:msg_len].strip()
- # append it to returned list
- string_messages.append(msg_content)
- # cut it out of the whole text
- msg = msg[msg_len:]
- # append pagination to each string message
- if add_pagination:
- for i in range(0, len(string_messages)):
- string_messages[i] += f"({i+1}/{len(string_messages)})"
- return string_messages
- # Android 9
- # adb shell service call isms 7 i32 0 s16 "com.android.mms.service" s16 "+1234567890" s16 "null" s16 "Hey\ you\ !" s16 "null" s16 "null"
- def send_sms(phone_number, content):
- number = phone_number.replace(" ", "")
- if type(content) == list:
- for msg in content:
- send_sms(phone_number, msg)
- else:
- message = content.replace("\n", "${NL}")
- command = (
- """adb shell "NL=$'\\n' ; service call isms 7 i32 0 s16 'com.android.mms.service' s16 \\\""""
- + number
- + "\\\" s16 'null' s16 \\\""
- + message
- + "\\\" s16 'null' s16 'null'\""
- )
- res = subprocess.check_output(command)
- if "Result: Parcel(00000000 '....')" in res.decode("utf-8"):
- return True
- else:
- raise Exception("Send SMS failed")
- def prepare_sms(phone_number: str, message: str, to_gsm=False):
- """Function that prepare the message to be send by SMS
- Convert it to GSM7 alphabet if required
- """
- msg = message
- if to_gsm:
- msg = to_gsm_7(msg)
- content = get_string_messages(msg)
- send_sms(phone_number, content)
|