Skip to content

Commit

Permalink
Merge pull request #8 from SonicRift/dev
Browse files Browse the repository at this point in the history
Release: Version 0.4.0
Update readme to reference pip3
  • Loading branch information
ShaneSutro authored Feb 12, 2021
2 parents 790f9fe + 1d6c4cf commit 24b7889
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 21 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ Once created, you will need to store your API Key and API Secret - you'll need t
- Download and install into your project file
- Via `pip`:

```pip install vestaboard```
```pip3 install vestaboard```
_Note: if using a virtual environment, use `pip` instead of `pip3`_

#### Usage

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="Vestaboard",
version="0.3.1",
version="0.4.0",
author="Shane Sutro",
author_email="[email protected]",
description="A Vestaboard Wrapper",
Expand Down
78 changes: 73 additions & 5 deletions tests/test_formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,88 @@ def test_word_conversion_with_invalid_characters_fails():
with pytest.raises(Exception):
Formatter().convert('test message^*', byWord=True)

def test_convert_line_fails_if_too_many_characters():
with pytest.raises(Exception):
Formatter().convertLine('This is too many characters for a line')

def test_convert_line_with_centering():
assert len(Formatter().convertLine('test message')) == 22, 'Should return a list with 22 elements'
assert Formatter().convertLine('test message') == [0, 0, 0, 0, 0, 20, 5, 19, 20, 0, 13, 5, 19, 19, 1, 7, 5, 0, 0, 0, 0, 0], 'Should add padding to reach 22 characters'

def test_convert_line_left_justified():
assert len(Formatter().convertLine('Oh hi!', left=True)) == 22, 'Should return a list with 22 elements'
assert Formatter().convertLine('Oh hi!', left=True) == [15, 8, 0, 8, 9, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'Should left justify up to 22 characters'
assert len(Formatter().convertLine('Oh hi!', justify='left')) == 22, 'Should return a list with 22 elements'
assert Formatter().convertLine('Oh hi!', justify='left') == [15, 8, 0, 8, 9, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'Should left justify up to 22 characters'

def test_convert_line_right_justified():
assert len(Formatter().convertLine('Oh hi!', right=True)) == 22, 'Should return a list with 22 elements'
assert Formatter().convertLine('Oh hi!', right=True) == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 8, 0, 8, 9, 37], 'Should left justify up to 22 characters'
assert len(Formatter().convertLine('Oh hi!', justify='right')) == 22, 'Should return a list with 22 elements'
assert Formatter().convertLine('Oh hi!', justify='right') == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 8, 0, 8, 9, 37], 'Should left justify up to 22 characters'

def test_valid_characters_should_pass():
assert Formatter()._isValid('abcdefghijklmnopqrstuvwxyz1234567890 !@#$()-+&=;:"%,./?°') == True

def test_with_character_code_at_beginning_of_string():
result = Formatter().convertLine('{23}{1} Test')
expected = [0, 0, 0, 0, 0, 0, 0, 0, 23, 1, 0, 20, 5, 19, 20, 0, 0, 0, 0, 0, 0, 0]
assert result == expected

def test_with_character_code_at_end_of_string():
result = Formatter().convertLine('Test {23}{1}')
expected = [0, 0, 0, 0, 0, 0, 0, 0, 20, 5, 19, 20, 0, 23, 1, 0, 0, 0, 0, 0, 0, 0]
assert result == expected

def test_with_character_code_in_middle_of_text():
result = Formatter().convertLine('Test {23}{1} Test')
expected = [0, 0, 0, 0, 0, 20, 5, 19, 20, 0, 23, 1, 0, 20, 5, 19, 20, 0, 0, 0, 0, 0]
assert result == expected

def test_with_text_between_character_codes():
result = Formatter().convertLine('{48}{3} Test {23}{1}')
expected = [0, 0, 0, 0, 0, 0, 48, 3, 0, 20, 5, 19, 20, 0, 23, 1, 0, 0, 0, 0, 0, 0]
assert result == expected

def test_invalid_characters_should_fail():
assert Formatter()._isValid('^*') == False
assert Formatter()._isValid('^*') == False

def test_regex_finds_valid_character_codes():
actual = Formatter()._getEmbeddedCharCodes('{24}{1}')
expected = ['{24}', '{1}']
assert actual == expected

def test_regex_returns_num_of_extra_characters():
t1 = Formatter()._numCharacterCodes('{13}{2}')
e1 = 5
t2 = Formatter()._numCharacterCodes('{23}{25}{25}')
e2 = 9
t3 = Formatter()._numCharacterCodes('There are no codes')
e3 = 0
assert t1 == e1
assert t2 == e2
assert t3 == e3

def test_formatter_accepts_padding_colors():
t1 = Formatter().convertLine('red', color='red')
e1 = [63, 63, 63, 63, 63, 63, 63, 63, 63, 18, 5, 4, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63]
t2 = Formatter().convertLine('orange', color='orange')
e2 = [64, 64, 64, 64, 64, 64, 64, 64, 15, 18, 1, 14, 7, 5, 64, 64, 64, 64, 64, 64, 64, 64]
t3 = Formatter().convertLine('yellow', color='yellow')
e3 = [65, 65, 65, 65, 65, 65, 65, 65, 25, 5, 12, 12, 15, 23, 65, 65, 65, 65, 65, 65, 65, 65]

assert t1 == e1
assert t2 == e2
assert t3 == e3

def test_formatter_fails_invalid_colors():
with pytest.raises(KeyError):
Formatter().convertLine('error', color='pink')

def test_space_buffer_adds_spaces_where_appropriate():
t1 = Formatter().convertLine('center', justify='center', spaceBuffer=True, color='white')
t2 = Formatter().convertLine('left', justify='left', spaceBuffer=True, color='white')
t3 = Formatter().convertLine('right', justify='right', spaceBuffer=True, color='white')
e1 = [69, 69, 69, 69, 69, 69, 69, 0, 3, 5, 14, 20, 5, 18, 0, 69, 69, 69, 69, 69, 69, 69]
e2 = [12, 5, 6, 20, 0, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69]
e3 = [69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 18, 9, 7, 8, 20]

assert t1 == e1, 'Should add spacing on both sides of centered text'
assert t2 == e2, 'Should add spacing to the right side of left-justified text'
assert t3 == e3, 'Should add spacing to the left side of right-justified text'
1 change: 1 addition & 0 deletions vestaboard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def __init__(self, apiKey=False, apiSecret=False, getSubscription=True, saveCred
apiKey: String (required) - your Vestaboard API Key
apiSecret: String (required) - your Vestaboard API Secret
getSubscripion: Bool (optional, default True) - If you already have your subscription ID, you may pass False into this method
saveCredentials: Bool (options, default True) - Choose whether or not to store your API keys in the home directory
"""
self.apiKey = apiKey
Expand Down
23 changes: 21 additions & 2 deletions vestaboard/characters.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,24 @@
'/': 59,
'?': 60,
# Missing 61
'°': 62
}
'°': 62,
63: 63,
64: 64,
65: 65,
66: 66,
67: 67,
68: 68,
69: 69,
0: 0
}

colors = {
'red': '{63}',
'orange': '{64}',
'yellow': '{65}',
'green': '{66}',
'blue': '{67}',
'violet': '{68}',
'white': '{69}',
'black': '{00}'
}
76 changes: 64 additions & 12 deletions vestaboard/formatter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from vestaboard.characters import characters
from vestaboard.characters import colors
import re

class Formatter:
Expand All @@ -17,10 +18,24 @@ def _raw(charList):
@staticmethod
def _isValid(inputString):
inputString = inputString.lower()
test = "^[A-Za-z0-9!@#$\(\)\-+&=;:'\"%,./?°\s ]*(?:\{[0-9]+\})*[A-Za-z0-9!@#$\(\)\-+&=;:'\"%,./?°\s ]*$"
test = "^(?:[A-Za-z0-9!@#$\(\)\-+&=;:'\"%,./?°\s ]*(?:\{[0-9]+\})*[A-Za-z0-9!@#$\(\)\-+&=;:'\"%,./?°\s ]*)*$"

return bool(re.match(test, inputString))

@staticmethod
def _getEmbeddedCharCodes(inputString):
test = "\{[0-9]+\}+"

return re.findall(test, inputString)

def _numCharacterCodes(self, inputString):
embeddedCharacterCodes = self._getEmbeddedCharCodes(inputString)
numCharacterCodes = 0
for match in embeddedCharacterCodes:
numCharacterCodes += 2 + (len(match) - 3)

return numCharacterCodes

def convert(self, inputString, byLetter=True, byWord=False):
if not self._isValid(inputString):
raise Exception('Your text contains one or more characters that the Vestaboard does not support.')
Expand All @@ -39,20 +54,57 @@ def convert(self, inputString, byLetter=True, byWord=False):

return converted

def convertLine(self, inputString, center=True, left=False, right=False):
def convertLine(self, inputString, justify='center', color=' ', spaceBuffer=False):
if not self._isValid(inputString):
raise Exception('Your text contains one or more characters that the Vestaboard does not support.')
numCharacterCodes = self._numCharacterCodes(inputString)
if spaceBuffer:
inputString = self._addSpaceBuffer(inputString, justify)
inputString = inputString.lower()
if color != ' ':
try:
color = colors[color]
except KeyError:
raise KeyError('Valid colors are red, orange, yellow, green, blue, violet, white, and black (default black).')
converted = []
if len(inputString) > 22:
return Exception('Convert line method takes in a string less than or equal to 22 characters.')
if left:
inputString = inputString.ljust(22)
elif right:
inputString = inputString.rjust(22)
elif center:
inputString = inputString.center(22)
for letter in inputString:
converted.append(characters[letter])
if len(inputString) - numCharacterCodes > 22:
raise Exception(f'Convert line method takes in a string less than or equal to 22 characters - string passed in was {len(inputString)} characters. Reduce size and try again (remember that setting spaceBuffer=True increases your line size by 2).')
inputString = self._justifyContent(inputString, justify, numCharacterCodes, color)

skipTo = 0
for index, letter in enumerate(inputString):
if index < skipTo:
continue
if letter == '{':
if inputString[index + 3] == '}': #two-digit character code like {63}
converted.append(int(inputString[index + 1: index + 3]))
skipTo = index + 4
elif inputString[index + 2] == '}': #one-digit character code like {4}
converted.append(int(inputString[index + 1: index + 2]))
skipTo = index + 3
else:
converted.append(characters[letter])

return converted

@staticmethod
def _addSpaceBuffer(inputString, justify):
if justify == 'left':
return inputString + ' '
elif justify == 'right':
return ' ' + inputString
else:
return ' ' + inputString + ' '

@staticmethod
def _justifyContent(inputString, justify, numCharacterCodes, color):
if justify == 'left':
inputString = inputString.ljust(22 + numCharacterCodes, '^')
elif justify == 'right':
inputString = inputString.rjust(22 + numCharacterCodes, '^')
elif justify == 'center':
inputString = inputString.center(22 + numCharacterCodes, '^')
inputString = inputString.replace('^', color)

return inputString

0 comments on commit 24b7889

Please sign in to comment.