Initial commit
This commit is contained in:
		
							
								
								
									
										0
									
								
								led_marquee_sign_client/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								led_marquee_sign_client/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										362
									
								
								led_marquee_sign_client/enums.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										362
									
								
								led_marquee_sign_client/enums.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,362 @@
 | 
			
		||||
import enum
 | 
			
		||||
import string
 | 
			
		||||
import warnings
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DefaultEnum(enum.Enum):
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def default():
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FontType(DefaultEnum):
 | 
			
		||||
    Font5x6Short = "q"
 | 
			
		||||
    Font5x11ShortAndWide = "r"
 | 
			
		||||
    Font7x6Default = "s"
 | 
			
		||||
    Font7x11Wide = "t"
 | 
			
		||||
    Font7x9 = "u"
 | 
			
		||||
    Font7x17ExtraWide = "v"
 | 
			
		||||
    FontSmallFont = "w"
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return f"\\{self.value}"
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def default():
 | 
			
		||||
        return FontType.Font7x6Default
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Brightness(DefaultEnum):
 | 
			
		||||
    Normal = "a"
 | 
			
		||||
    Bright = "b"
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return f"\\{self.value}"
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def default():
 | 
			
		||||
        return Brightness.Bright
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Transition(DefaultEnum):
 | 
			
		||||
    Cyclic = "A"
 | 
			
		||||
    Immediate = "B"
 | 
			
		||||
    OpenFromRight = "C"
 | 
			
		||||
    OpenFromLeft = "D"
 | 
			
		||||
    OpenFromCenter = "E"
 | 
			
		||||
    OpenToCenter = "F"
 | 
			
		||||
    CoverFromCenter = "G"
 | 
			
		||||
    CoverFromRight = "H"
 | 
			
		||||
    CoverFromLeft = "I"
 | 
			
		||||
    CoverToCenter = "J"
 | 
			
		||||
    ScrollUp = "K"
 | 
			
		||||
    ScrollDown = "L"
 | 
			
		||||
    InterlaceToCenter = "M"
 | 
			
		||||
    InterlaceCover = "N"
 | 
			
		||||
    CoverUp = "O"
 | 
			
		||||
    CoverDown = "P"
 | 
			
		||||
    ScanLine = "Q"
 | 
			
		||||
    Explode = "R"
 | 
			
		||||
    PacMan = "S"
 | 
			
		||||
    FallAndStack = "T"
 | 
			
		||||
    Shoot = "U"
 | 
			
		||||
    Flash = "V"
 | 
			
		||||
    Random = "W"
 | 
			
		||||
    SlideIn = "X"
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return self.value
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def default():
 | 
			
		||||
        return Transition.Cyclic
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# macros are literal characters prefixed by ^
 | 
			
		||||
class Macro(enum.Enum):
 | 
			
		||||
    CurrentTime12hWithoutAmPm = "D"
 | 
			
		||||
    CurrentTime12hWithAmPm = "E"
 | 
			
		||||
    CurrentTime24h = "F"
 | 
			
		||||
    CurrentDateMmDdYyyy = "A"
 | 
			
		||||
    CurrentDateYyyy_Mm_Dd = "B"
 | 
			
		||||
    CurrentDateMm_Dd_Yyyy = "C"
 | 
			
		||||
    CurrentDateDd_Mm_Yyyy = "a"
 | 
			
		||||
    Beep1 = "q"
 | 
			
		||||
    Beep2 = "r"
 | 
			
		||||
    Beep3 = "s"
 | 
			
		||||
    Temperature = "H"
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return f"^{self.value}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# symbols should be inserted as string representations of their numeric value prefixed by ^
 | 
			
		||||
class Symbol(enum.Enum):
 | 
			
		||||
    Sun = 66
 | 
			
		||||
    CloudOrWind = 67
 | 
			
		||||
    UmbrellaRaining = 68
 | 
			
		||||
    WallClock = 69
 | 
			
		||||
    Telephone = 70
 | 
			
		||||
    Glasses = 71
 | 
			
		||||
    Faucet = 72
 | 
			
		||||
    RocketOrSyringeOrSo = 73
 | 
			
		||||
    WhatTheHell = 74
 | 
			
		||||
    Key = 75
 | 
			
		||||
    Shirt = 76
 | 
			
		||||
    Helicopter = 77
 | 
			
		||||
    Car = 78
 | 
			
		||||
    Tank = 79
 | 
			
		||||
    House = 80
 | 
			
		||||
    Teapot = 81
 | 
			
		||||
    Trees = 82
 | 
			
		||||
    Duck = 83
 | 
			
		||||
    Scooter = 84
 | 
			
		||||
    Bicycle = 85
 | 
			
		||||
    Crown = 86
 | 
			
		||||
    AppleOrSo = 87
 | 
			
		||||
    ArrowRight = 88
 | 
			
		||||
    ArrowLeft = 89
 | 
			
		||||
    ArrowDownLeft = 90
 | 
			
		||||
    ArrowUpLeft = 91
 | 
			
		||||
    Cup = 92
 | 
			
		||||
    Chair = 93
 | 
			
		||||
    HighHeel = 94
 | 
			
		||||
    PrizeCup = 95
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return f"^{self.value}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# cartoons are represented as these characters prefixed by ^
 | 
			
		||||
class Cartoon(enum.Enum):
 | 
			
		||||
    MerryXMas = "i"
 | 
			
		||||
    HappyNewYear = "j"
 | 
			
		||||
    FourthOfJuly = "k"
 | 
			
		||||
    HappyEaster = "l"
 | 
			
		||||
    HappyHalloween = "m"
 | 
			
		||||
    DontDrinkAndDrive = "n"
 | 
			
		||||
    NoSmoking = "o"
 | 
			
		||||
    Welcome = "p"
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return f"^{self.value}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# the descriptions originate from the UTF-16 specification, https://www.ssec.wisc.edu/~tomw/java/unicode.html
 | 
			
		||||
# the extended charset starts where ASCII ends enum
 | 
			
		||||
class ExtendedChar(enum.Enum):
 | 
			
		||||
    # Ç
 | 
			
		||||
    LatinCapitalLetterCWithCedilla = 0x80
 | 
			
		||||
    # ü
 | 
			
		||||
    LatinSmallLetterUWithDiaeresis = 0x81
 | 
			
		||||
    # é
 | 
			
		||||
    LatinSmallLetterEWithAcute = 0x82
 | 
			
		||||
    # â
 | 
			
		||||
    LatinSmallLetterAWithCircumflex = 0x83
 | 
			
		||||
    # ä
 | 
			
		||||
    LatinSmallLetterAWithDiaeresis = 0x84
 | 
			
		||||
    # á
 | 
			
		||||
    LatinSmallLetterAWithGrave = 0x85
 | 
			
		||||
    # å
 | 
			
		||||
    LatinSmallLetterAWithRingAbove = 0x86
 | 
			
		||||
    # ç
 | 
			
		||||
    LatinSmallLetterCWithCedilla = 0x87
 | 
			
		||||
    # ê
 | 
			
		||||
    LatinSmallLetterEWithCircumflex = 0x88
 | 
			
		||||
    # ë
 | 
			
		||||
    LatinSmallLetterEWithDiaeresis = 0x89
 | 
			
		||||
    # è
 | 
			
		||||
    LatinSmallLetterEWithGrave = 0x8A
 | 
			
		||||
    # Ï
 | 
			
		||||
    LatinCapitalLetterIWithDiaeresis = 0x8B
 | 
			
		||||
    # Î
 | 
			
		||||
    LatinCapitalLetterIWithCircumflex = 0x8C
 | 
			
		||||
    # Ì
 | 
			
		||||
    LatinCapitalLetterIWithGrave = 0x8D
 | 
			
		||||
    # Ä
 | 
			
		||||
    LatinCapitalLetterAWithDiaeresis = 0x8F
 | 
			
		||||
    # Å
 | 
			
		||||
    LatinCapitalLetterAWithRingAbove = 0x8F
 | 
			
		||||
    # É
 | 
			
		||||
    LatinCapitalLetterEWithAcute = 0x90
 | 
			
		||||
    # æ
 | 
			
		||||
    LatinSmallLetterAe = 0x91
 | 
			
		||||
    # Æ
 | 
			
		||||
    LatinCapitalLetterAe = 0x92
 | 
			
		||||
    # ô
 | 
			
		||||
    LatinSmallLetterOWithCircumflex = 0x93
 | 
			
		||||
    # ö
 | 
			
		||||
    LatinSmallLetterOWithDiaeresis = 0x94
 | 
			
		||||
    # ò
 | 
			
		||||
    LatinSmallLetterOWithGrave = 0x95
 | 
			
		||||
    # û
 | 
			
		||||
    LatinSmallLetterUWithCircumflex = 0x96
 | 
			
		||||
    # ù
 | 
			
		||||
    LatinSmallLetterUWithGrave = 0x97
 | 
			
		||||
    # ÿ
 | 
			
		||||
    LatinSmallLetterYWithDiaeresis = 0x98
 | 
			
		||||
    # Ö
 | 
			
		||||
    LatinCapitalLLetterOWithDiaeresis = 0x99
 | 
			
		||||
    # Ü
 | 
			
		||||
    LatinCapitalLetterUWithDiaeresis = 0x9A
 | 
			
		||||
    # ¢
 | 
			
		||||
    CentSign = 0x9B
 | 
			
		||||
    # £
 | 
			
		||||
    PoundSign = 0x9C
 | 
			
		||||
    # ¥
 | 
			
		||||
    YenSign = 0x9D
 | 
			
		||||
    # urm...
 | 
			
		||||
    UnknownPCurrencySign = 0x9E
 | 
			
		||||
    # ƒ
 | 
			
		||||
    LatinSmallLetterFWithHook = 0x9F
 | 
			
		||||
    # á
 | 
			
		||||
    LatinSmallLetterAWithAcute = 0xA0
 | 
			
		||||
    # Í
 | 
			
		||||
    LatinCapitalLetterIWithAcute = 0xA1
 | 
			
		||||
    # Ó
 | 
			
		||||
    LatinCapitalLetterOWithAcute = 0xA2
 | 
			
		||||
    # ú
 | 
			
		||||
    LatinSmallLetterUWithAcute = 0xA3
 | 
			
		||||
    # ñ
 | 
			
		||||
    LatinSmallLetterNWithTilde = 0xA4
 | 
			
		||||
    # Ñ
 | 
			
		||||
    LatinCapitalLetterNWithTilde = 0xA5
 | 
			
		||||
    # a̱
 | 
			
		||||
    LatinSmallLetterAWithMacronBelow = 0xA6
 | 
			
		||||
    # couldn't find that one in the UTF-16 table
 | 
			
		||||
    LatinSmallLetterOWithMacronBelow = 0xA7
 | 
			
		||||
    # ¿
 | 
			
		||||
    InvertedQuestionMark = 0xA8
 | 
			
		||||
    # you can probably imagine what it'll look like
 | 
			
		||||
    LatinCapitalLetterZWithRingAbove = 0xA9
 | 
			
		||||
    # Ź
 | 
			
		||||
    LatinCapitalLetterZWithAcute = 0xAA
 | 
			
		||||
    # ń
 | 
			
		||||
    LatinSmallLetterNWithAcute = 0xAB
 | 
			
		||||
    # some weird L with a diagonal line
 | 
			
		||||
    AnotherWeirdSign = 0xAC
 | 
			
		||||
    # Ś or ś can't tell for sure let's assume capital
 | 
			
		||||
    LatinCapitalLetterSWithAcute = 0xAB
 | 
			
		||||
    # Ć
 | 
			
		||||
    LatinCapitalLetterCWithAcute = 0xAC
 | 
			
		||||
    # ȩ
 | 
			
		||||
    LatinSmallLetterEWithCedilla = 0xAD
 | 
			
		||||
    # well you can imagine what it'll look like
 | 
			
		||||
    LatinSmallLetterAWithCedilla = 0xB0
 | 
			
		||||
    # €
 | 
			
		||||
    EuroSign = 0xB1
 | 
			
		||||
    # E with some vertical line below
 | 
			
		||||
    LatinCapitalLetterEWithSomeLineBelow = 0xB3
 | 
			
		||||
    # a with some vertical line below
 | 
			
		||||
    LatinSmallLetterAWithSomeWeirdLineBelow = 0xB4
 | 
			
		||||
    # α
 | 
			
		||||
    GreekSmallLetterAlpha = 0xE0
 | 
			
		||||
    # β
 | 
			
		||||
    GreekSmallLetterBeta = 0xE1
 | 
			
		||||
    # Γ
 | 
			
		||||
    GreekCapitalLetterGamma = 0xE2
 | 
			
		||||
    # π
 | 
			
		||||
    GreekSmallLetterPi = 0xE3
 | 
			
		||||
    # Σ
 | 
			
		||||
    GreekCapitalLetterSigma = 0xE4
 | 
			
		||||
    # σ
 | 
			
		||||
    GreekSmallLetterSigma = 0xE5
 | 
			
		||||
    # μ
 | 
			
		||||
    GreekSmallLetterMu = 0xE6
 | 
			
		||||
    # τ
 | 
			
		||||
    GreekSmallLetterTau = 0xE7
 | 
			
		||||
    # Φ
 | 
			
		||||
    GreekCapitalLetterPhi = 0xE8
 | 
			
		||||
    # θ
 | 
			
		||||
    GreekSmallLetterTheta = 0xE9
 | 
			
		||||
    # Ω
 | 
			
		||||
    GreekCapitalLetterOmega = 0xEA
 | 
			
		||||
    # δ
 | 
			
		||||
    GreekSmallLetterDelta = 0xEB
 | 
			
		||||
    # ∞
 | 
			
		||||
    Infinity = 0xEC
 | 
			
		||||
    # φ
 | 
			
		||||
    GreekSmallLetterPhi = 0xED
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return chr(self.value)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def translateUtf16(input):
 | 
			
		||||
        table = {
 | 
			
		||||
            "Ç": ExtendedChar.LatinCapitalLetterCWithCedilla,
 | 
			
		||||
            "ü": ExtendedChar.LatinSmallLetterUWithDiaeresis,
 | 
			
		||||
            "é": ExtendedChar.LatinSmallLetterEWithAcute,
 | 
			
		||||
            "â": ExtendedChar.LatinSmallLetterAWithCircumflex,
 | 
			
		||||
            "ä": ExtendedChar.LatinSmallLetterAWithDiaeresis,
 | 
			
		||||
            "à": ExtendedChar.LatinSmallLetterAWithGrave,
 | 
			
		||||
            "å": ExtendedChar.LatinSmallLetterAWithRingAbove,
 | 
			
		||||
            "ç": ExtendedChar.LatinSmallLetterCWithCedilla,
 | 
			
		||||
            "ê": ExtendedChar.LatinSmallLetterEWithCircumflex,
 | 
			
		||||
            "ë": ExtendedChar.LatinSmallLetterEWithDiaeresis,
 | 
			
		||||
            "è": ExtendedChar.LatinSmallLetterEWithGrave,
 | 
			
		||||
            "Ï": ExtendedChar.LatinCapitalLetterIWithDiaeresis,
 | 
			
		||||
            "Î": ExtendedChar.LatinCapitalLetterIWithCircumflex,
 | 
			
		||||
            "Ì": ExtendedChar.LatinCapitalLetterIWithGrave,
 | 
			
		||||
            "Ä": ExtendedChar.LatinCapitalLetterAWithDiaeresis,
 | 
			
		||||
            "Å": ExtendedChar.LatinCapitalLetterAWithRingAbove,
 | 
			
		||||
            "É": ExtendedChar.LatinCapitalLetterEWithAcute,
 | 
			
		||||
            "æ": ExtendedChar.LatinSmallLetterAe,
 | 
			
		||||
            "Æ": ExtendedChar.LatinCapitalLetterAe,
 | 
			
		||||
            "ô": ExtendedChar.LatinSmallLetterOWithCircumflex,
 | 
			
		||||
            "ö": ExtendedChar.LatinSmallLetterOWithDiaeresis,
 | 
			
		||||
            "ò": ExtendedChar.LatinSmallLetterOWithGrave,
 | 
			
		||||
            "û": ExtendedChar.LatinSmallLetterUWithCircumflex,
 | 
			
		||||
            "ù": ExtendedChar.LatinSmallLetterUWithGrave,
 | 
			
		||||
            "ÿ": ExtendedChar.LatinSmallLetterYWithDiaeresis,
 | 
			
		||||
            "Ö": ExtendedChar.LatinCapitalLLetterOWithDiaeresis,
 | 
			
		||||
            "Ü": ExtendedChar.LatinCapitalLetterUWithDiaeresis,
 | 
			
		||||
            "¢": ExtendedChar.CentSign,
 | 
			
		||||
            "£": ExtendedChar.PoundSign,
 | 
			
		||||
            "¥": ExtendedChar.YenSign,
 | 
			
		||||
            "ƒ": ExtendedChar.LatinSmallLetterFWithHook,
 | 
			
		||||
            "á": ExtendedChar.LatinSmallLetterAWithAcute,
 | 
			
		||||
            "Í": ExtendedChar.LatinCapitalLetterIWithAcute,
 | 
			
		||||
            "Ó": ExtendedChar.LatinCapitalLetterOWithAcute,
 | 
			
		||||
            "ú": ExtendedChar.LatinSmallLetterUWithAcute,
 | 
			
		||||
            "ñ": ExtendedChar.LatinSmallLetterNWithTilde,
 | 
			
		||||
            "Ñ": ExtendedChar.LatinCapitalLetterNWithTilde,
 | 
			
		||||
            "¿": ExtendedChar.InvertedQuestionMark,
 | 
			
		||||
            "Ź": ExtendedChar.LatinCapitalLetterZWithAcute,
 | 
			
		||||
            "ń": ExtendedChar.LatinSmallLetterNWithAcute,
 | 
			
		||||
            "Ś": ExtendedChar.LatinCapitalLetterSWithAcute,
 | 
			
		||||
            "Ć": ExtendedChar.LatinCapitalLetterCWithAcute,
 | 
			
		||||
            "ȩ": ExtendedChar.LatinSmallLetterEWithCedilla,
 | 
			
		||||
            "€": ExtendedChar.EuroSign,
 | 
			
		||||
            "α": ExtendedChar.GreekSmallLetterAlpha,
 | 
			
		||||
            "β": ExtendedChar.GreekSmallLetterBeta,
 | 
			
		||||
            "Γ": ExtendedChar.GreekCapitalLetterGamma,
 | 
			
		||||
            "π": ExtendedChar.GreekSmallLetterPi,
 | 
			
		||||
            "Σ": ExtendedChar.GreekCapitalLetterSigma,
 | 
			
		||||
            "σ": ExtendedChar.GreekSmallLetterSigma,
 | 
			
		||||
            "μ": ExtendedChar.GreekSmallLetterMu,
 | 
			
		||||
            "τ": ExtendedChar.GreekSmallLetterTau,
 | 
			
		||||
            "Φ": ExtendedChar.GreekCapitalLetterPhi,
 | 
			
		||||
            "θ": ExtendedChar.GreekSmallLetterTheta,
 | 
			
		||||
            "Ω": ExtendedChar.GreekCapitalLetterOmega,
 | 
			
		||||
            "δ": ExtendedChar.GreekSmallLetterDelta,
 | 
			
		||||
            "∞": ExtendedChar.Infinity,
 | 
			
		||||
            "φ": ExtendedChar.GreekSmallLetterPhi,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        output = []
 | 
			
		||||
        supported_ascii = set(
 | 
			
		||||
            string.ascii_letters + string.digits + "^°!\"§$%&/()=?\\+*#'-_.:,;<>|@ "
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        for char in input:
 | 
			
		||||
            if char in supported_ascii:
 | 
			
		||||
                output.append(char)
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            try:
 | 
			
		||||
                output.append(table[char])
 | 
			
		||||
            except KeyError:
 | 
			
		||||
                warnings.warn(f"Could not translate unknown character {char}")
 | 
			
		||||
 | 
			
		||||
        return "".join((str(i) for i in output))
 | 
			
		||||
							
								
								
									
										62
									
								
								led_marquee_sign_client/line.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								led_marquee_sign_client/line.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
from led_marquee_sign_client.enums import *
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Line:
 | 
			
		||||
    """
 | 
			
		||||
    Builds a line step for the sign step by step. Renders into a formatted string.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(
 | 
			
		||||
        self,
 | 
			
		||||
        transition: Transition = Transition.default(),
 | 
			
		||||
        brightness: Brightness = Brightness.default(),
 | 
			
		||||
        font_type: FontType = FontType.default(),
 | 
			
		||||
    ):
 | 
			
		||||
        # every line may have just one transition method
 | 
			
		||||
        # we make it a public property
 | 
			
		||||
        self.transition = transition
 | 
			
		||||
 | 
			
		||||
        # our internal state
 | 
			
		||||
        self._data = []
 | 
			
		||||
 | 
			
		||||
        # every line has an initial brightness and font type set
 | 
			
		||||
        # these can be changed at any time
 | 
			
		||||
        self.add(brightness)
 | 
			
		||||
        self.add(font_type)
 | 
			
		||||
 | 
			
		||||
    def add(
 | 
			
		||||
        self,
 | 
			
		||||
        data: str | FontType | Brightness | Macro | Symbol | Cartoon | ExtendedChar,
 | 
			
		||||
    ):
 | 
			
		||||
        if isinstance(data, str):
 | 
			
		||||
            data = ExtendedChar.translateUtf16(data)
 | 
			
		||||
 | 
			
		||||
        self._data.append(data)
 | 
			
		||||
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        components = [str(self.transition)]
 | 
			
		||||
        components += map(str, self._data)
 | 
			
		||||
        components.append("\r")
 | 
			
		||||
        return "".join(components)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Message:
 | 
			
		||||
    """
 | 
			
		||||
    Builds a message for the sign step by step. Renders into a formatted string.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, address: int = 128):
 | 
			
		||||
        self.address = address
 | 
			
		||||
        self._lines = []
 | 
			
		||||
 | 
			
		||||
    def add(self, line: Line):
 | 
			
		||||
        self._lines.append(line)
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        components = [f"~{self.address}~f01"]
 | 
			
		||||
        components += self._lines
 | 
			
		||||
        components.append("\r\r\r")
 | 
			
		||||
        return "".join(map(str, components))
 | 
			
		||||
		Reference in New Issue
	
	Block a user