-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMessageClass.py
182 lines (143 loc) · 6.93 KB
/
MessageClass.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
from PIL import Image, ImageFont, ImageDraw
import textwrap
from datetime import date
import locale
from PIL._imaging import font
from MessageClass import *
import random
import os
from strop import lowercase
### error handling
#error class that handles exceptions in pick_item routine
class GeneralException(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
#########################
# define usable fonts
fonts = []
font_folder = os.path.dirname(os.path.realpath(__file__)) + "/library/fonts/"
#populate font list with fonts
for dirname, dirnames, filenames in os.walk(font_folder):
for filename in filenames:
if filename.split(".")[1].lower() == "ttf":
fonts.append(os.path.join(dirname,filename))
print(fonts)
print font_folder+'ARIALBD.TTF'
font = ImageFont.truetype(font_folder+'ARIALBD.TTF', 14, encoding='unic')
header_font = ImageFont.truetype(font_folder+'VERDANA.TTF', 14, encoding='unic')
font2 = ImageFont.truetype(font_folder+'ELEPHNT.TTF', 14, encoding='unic')
# stores pictures usable for messages
symbol_folder = os.path.dirname(os.path.realpath(__file__)) + "/symbols"
Pics = []
#populate Pics list with symbols
for dirname, dirnames, filenames in os.walk(symbol_folder):
for filename in filenames:
if filename.split(".")[1] == "png":
Pics.append(os.path.join(dirname,filename))
#Pics["Rose"]="gfx/rose2.png"
#Pics["Schweinchen"]="gfx/Schweinchen.png"
#Pics["Kalender"]="gfx/calendar.png"
LEFT = 1
CENTER = 2
RIGHT = 3
msg_spacer = 10 # optional feed spacer between text elements
msg_header = "~~~~~~~~~ {:%d. %B %Y} ~~~~~~~~~".format(date.today())
msg_bottom = "~~~~~~~~~~~~~~~~~~~~~~~~~~~"
# Message Styles
Message_Style = {
# "Rose":[[msg_header,header_font], msg_spacer, ["png",Pics['Rose']], 30, "text", msg_spacer, [msg_bottom,header_font]],
# "Schweinchen":[[msg_header,header_font], msg_spacer, ["png",Pics['Schweinchen']], 30, "text", msg_spacer, [msg_bottom,header_font]],
"Random":[[msg_header,header_font], msg_spacer, ["png",random.choice(Pics)], 30, "text", msg_spacer, [msg_bottom,header_font]]
}
def align_x_left(line_x,canvas_x=1000):
return 0
def align_x_center(line_x,canvas_x=1000):
return (canvas_x/2) - (line_x / 2)
def align_x_right(line_x,canvas_x=1000):
return canvas_x - line_x
class Message:
def __init__(self,text,message_structure):
self.text = text
self.message_structure = message_structure
for index, element in enumerate(self.message_structure):
if element == "text":
self.message_structure[index] = self.text
def print_me(self):
print self.message_structure
# print text for real
def BuildMessage(self,font,wrap_limit=-1,offset_x=0,offset_y=0,file_handle='stdout.png',align=CENTER):
# turns a series of strings, feeders or picutres to a finished message block in png format
# initialize image
canvas_x = canvas_y = 1000
image = Image.new("1", [canvas_x,canvas_y], "white") # Working 'background' image
draw = ImageDraw.Draw(image)
#assign alignment calculation
if align == LEFT:
align_type = align_x_left
elif align == CENTER:
align_type = align_x_center
elif align == RIGHT:
align_type = align_x_right
offset_x = -offset_x
x_text = offset_x # initialize tracker for offset + textblock height
y_text = offset_y
# parse message components and collate
for element in self.message_structure:
print str(element) + " " + str(x_text) + " " + str(y_text)
active_font = font # sets or resets font (font can change if passed along with string as tuple)
if isinstance(element,list): # element contains complex info, e.g. a graph with element = (filetype, path), or a specially formatted string as element = (string, font)
if element[0] == "png": # consider png file with path in element[1]
try:
img = Image.open(element[1])
image.paste(img, (align_type(img.size[0],canvas_x)+offset_x,y_text))
y_text += img.size[1] # read image y size and add to counter
except GeneralException:
print "Could not open file '%x'passed as message component",element[1]
raise
elif isinstance(element[0], basestring): # consider all other strings in element[0] as text/font tuples
try:
active_font = element[1] # set passed font as active font
except GeneralException:
active_font = font
print "Could not process font."
raise
element = element[0] # dissolve tuple by assigning string (for further processing below
if isinstance(element, basestring): # is string?
# deconstruct string: 1) line break 2) word wrap
text_lines = element.splitlines()
output_lines = []
if len(text_lines)>1:
for line in text_lines:
if wrap_limit > 0:
output_lines.append(textwrap.wrap(line, width=wrap_limit))
else:
output_lines.append(line)
else:
if wrap_limit > 0:
output_lines.append(textwrap.wrap(text_lines[0], width=wrap_limit))
else:
output_lines = text_lines
for line in output_lines:
width, height = active_font.getsize(line)
draw.text((align_type(width,canvas_x)+offset_x, y_text), line, font=active_font)
y_text += height
x_text = max(x_text,width) # if line is longer than those before, this is the new max.
elif isinstance(element, (int,long)): # is feeder?
y_text += element
# crop
if align == LEFT:
crop_image = image.crop((0,0,x_text+offset_x, y_text+offset_y))
elif align == CENTER:
crop_image = image.crop((canvas_x/2 - (x_text/2),0,canvas_x/2 + (x_text/2) +offset_x, y_text+offset_y))
elif align == RIGHT:
crop_image = image.crop((canvas_x - (x_text), 0, canvas_x, y_text+offset_y))
# save output file
crop_image.save(file_handle)
return crop_image
# class Rose_Message("Hallo\n This is it!",[[msg_header,header_font], msg_spacer, ["png",Pics['Rose']], 30, "text", msg_spacer, [msg_bottom,header_font]]):
# def print_me(self):
# print
#X = Message("This is the text!",Message_Style["Rose"])
#X.print_me()