| Server IP : 209.209.40.120 / Your IP : 216.73.217.112 Web Server : Microsoft-IIS/10.0 System : Windows NT NEWWWW 10.0 build 17763 (Windows Server 2019) i586 User : NEWWWW$ ( 0) PHP Version : 8.3.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /Python312/Lib/site-packages/smpplib/ |
Upload File : |
# -*- coding: utf8 -*-
import random
import six
from smpplib import consts, exceptions
def make_parts(text, encoding=consts.SMPP_ENCODING_DEFAULT, use_udhi=True):
"""Returns tuple(parts, encoding, esm_class)"""
try:
# Try to encode with the user-defined encoding first.
encode, split_length, part_size = ENCODINGS[encoding]
encoded_text = encode(text)
except KeyError:
raise NotImplementedError('encoding is not supported: %s' % encoding)
except UnicodeError:
# Fallback to UCS-2.
encoding = consts.SMPP_ENCODING_ISO10646
encode, split_length, part_size = ENCODINGS[encoding]
encoded_text = encode(text)
if len(encoded_text) > split_length:
if use_udhi:
# Split the text into well-formed parts.
esm_class = consts.SMPP_GSMFEAT_UDHI
# FIXME: 7-bit encoding has variable-length characters.
# FIXME: it means that a character may be broken by splitting.
parts = make_parts_encoded(encoded_text, part_size)
else:
# We will have to use SaR to send the message
esm_class = consts.SMPP_MSGTYPE_DEFAULT
parts = split_sequence(encoded_text, part_size)
if len(parts) > 255:
raise exceptions.MessageTooLong()
else:
# Normal message.
esm_class = consts.SMPP_MSGTYPE_DEFAULT
parts = [encoded_text]
return parts, encoding, esm_class
# Source:
# http://stackoverflow.com/questions/2452861/python-library-for-converting-plain-text-ascii-into-gsm-7-bit-character-set
GSM_CHARACTER_TABLE = (
u"@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\x1bÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>"
u"?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑÜ`¿abcdefghijklmnopqrstuvwxyzäöñüà"
u"````````````````````^```````````````````{}`````\\````````````[~]`"
u"|````````````````````````````````````€``````````````````````````"
)
def gsm_encode(plaintext):
"""Performs default GSM 7-bit encoding. Beware it's vendor-specific and not recommended for use."""
try:
return b''.join(
six.int2byte(index) if index < 0x80 else b'\x1B' + six.int2byte(index - 0x80)
for index in map(GSM_CHARACTER_TABLE.index, plaintext)
)
except ValueError:
raise UnicodeError(plaintext)
# Map GSM encoding into a tuple of encode function, maximum single message size and a part size.
# Add new entry here should you need to use another encoding.
ENCODINGS = {
consts.SMPP_ENCODING_DEFAULT: (gsm_encode, consts.SEVENBIT_LENGTH, consts.SEVENBIT_PART_SIZE),
consts.SMPP_ENCODING_ISO88591: (lambda text: text.encode('iso-8859-1'), consts.EIGHTBIT_LENGTH, consts.EIGHTBIT_PART_SIZE),
consts.SMPP_ENCODING_ISO10646: (lambda text: text.encode('utf-16-be'), consts.UCS2_LENGTH, consts.UCS2_PART_SIZE),
}
def make_parts_encoded(encoded_text, part_size):
"""Splits encoded text into SMS parts"""
chunks = split_sequence(encoded_text, part_size)
if len(chunks) > 255:
raise exceptions.MessageTooLong()
uid = random.randint(0, 255)
header = b''.join((b'\x05\x00\x03', six.int2byte(uid), six.int2byte(len(chunks))))
return [b''.join((header, six.int2byte(i), chunk)) for i, chunk in enumerate(chunks, start=1)]
def split_sequence(sequence, part_size):
"""Splits the sequence into equal parts"""
return [sequence[i:i + part_size] for i in range(0, len(sequence), part_size)]