@@ -176,13 +176,24 @@ def zc_unregister_service(self):
176
176
return True
177
177
178
178
179
+ class Theme :
180
+
181
+ def __init__ (self , name = "default" ):
182
+ self .name = name
183
+ self .img_bg = "background.jpg"
184
+ self .font = ""
185
+ self .font_face = "Monospace"
186
+
187
+
179
188
class Playlist :
180
189
181
- def __init__ (self , uris , default_play_time_s , location = None ):
190
+ def __init__ (self , uris , default_play_time_s , theme , location = None ):
182
191
self .download_path = "/tmp/"
183
192
self .location = location
184
193
self .default_play_time_s = default_play_time_s
185
194
self .news = None
195
+ self .theme = theme
196
+ self .img_bg = "themes/" + theme .name + "/background.jpg"
186
197
187
198
self .playlist = list ()
188
199
self .playlist = self .create (uris )
@@ -200,13 +211,6 @@ def create(self, uris):
200
211
item ["uri" ] = uri
201
212
item ["player" ] = "mediaplayer"
202
213
item ["play_time_s" ] = self .default_play_time_s
203
- elif uri .endswith (".svg" ):
204
- download_file (uri .strip (), self .download_path )
205
- file = uri .split ("/" )
206
- item ["num" ] = n
207
- item ["uri" ] = "file:///" + self .download_path + file [- 1 ]
208
- item ["player" ] = "imageviewer"
209
- item ["play_time_s" ] = self .default_play_time_s
210
214
elif uri .startswith ("https://" ):
211
215
item ["num" ] = n
212
216
item ["uri" ] = uri
@@ -234,6 +238,18 @@ def create(self, uris):
234
238
item ["uri" ] = uri
235
239
item ["player" ] = "weather"
236
240
item ["play_time_s" ] = self .default_play_time_s
241
+ elif uri .endswith (".svg" ):
242
+ download_file (uri .strip (), self .download_path )
243
+ file = uri .split ("/" )
244
+ item ["num" ] = n
245
+ item ["uri" ] = "file:///" + self .download_path + file [- 1 ]
246
+ item ["player" ] = "imageviewer"
247
+ item ["play_time_s" ] = self .default_play_time_s
248
+ elif uri .endswith (".jpg" ):
249
+ item ["num" ] = n
250
+ item ["uri" ] = uri
251
+ item ["player" ] = "imageviewer"
252
+ item ["play_time_s" ] = self .default_play_time_s
237
253
238
254
# Append if we found a valid playlist item
239
255
if "num" in item :
@@ -259,13 +275,13 @@ def start_player(self):
259
275
elif item ["player" ] == "clock" :
260
276
x = threading .Thread (target = self .start_clock , args = ())
261
277
elif item ["player" ] == "imageviewer" :
262
- x = threading .Thread (target = self .start_image_view , args = ())
278
+ x = threading .Thread (target = self .start_image_view , args = (item [ "uri" ], ))
263
279
elif item ["player" ] == "news" :
264
- x = threading .Thread (target = self .start_news_view , args = (self .news ,))
280
+ x = threading .Thread (target = self .start_news_view , args = (self .news , self . img_bg ))
265
281
elif item ["player" ] == "system" :
266
282
x = threading .Thread (target = self .start_system_view , args = ())
267
283
elif item ["player" ] == "weather" :
268
- x = threading .Thread (target = self .start_weather_view , args = (self .weather ,))
284
+ x = threading .Thread (target = self .start_weather_view , args = (self .weather , self . img_bg ))
269
285
270
286
x .start ()
271
287
if not x .is_alive ():
@@ -330,45 +346,42 @@ def start_mediaplayer(self, url):
330
346
def start_sys_view (self ):
331
347
texts = list ()
332
348
texts .append (System .list_processes (23 ))
333
- view = Wayland_view (display .res_x , display .res_y , len (texts ))
349
+ view = Wayland_view (display .res_x , display .res_y , len (texts ), theme )
334
350
view .s_objects [0 ]["font_size" ] = 14
335
351
view .s_objects [0 ]["alignment" ] = "left"
336
- self . render_text_view ( view , texts )
352
+ view . show_text ( texts )
337
353
338
- def start_weather_view (self , weather ):
354
+ def start_weather_view (self , weather , img_bg ):
339
355
texts = list ()
340
356
data = weather .current_weather ()
341
357
texts .append (data ["current_condition" ][0 ]["temp_C" ] + "°C" )
342
358
texts .append (data ["current_condition" ][0 ]["weatherDesc" ][0 ]["value" ] + " " + \
343
359
data ["current_condition" ][0 ]["windspeedKmph" ] + " km/h" )
344
360
texts .append (data ["nearest_area" ][0 ]["areaName" ][0 ]["value" ])
345
- view = Wayland_view (display .res_x , display .res_y , len (texts ))
361
+ view = Wayland_view (display .res_x , display .res_y , len (texts ), theme )
346
362
view .s_objects [0 ]["font_size" ] = 80
347
363
view .s_objects [0 ]["alignment" ] = "left"
348
364
view .s_objects [1 ]["font_size" ] = 40
349
365
view .s_objects [1 ]["alignment" ] = "left"
350
366
view .s_objects [2 ]["font_size" ] = 20
351
367
view .s_objects [2 ]["alignment" ] = "left"
352
- self . render_text_view ( view , texts )
368
+ view . show_text ( texts , img_bg )
353
369
354
- def start_news_view (self , news ):
370
+ def start_news_view (self , news , img_bg ):
355
371
texts = list ()
356
372
item = news .news_item ()
357
373
texts .append ("[HN]" )
358
374
texts .append (item ["title" ])
359
375
texts .append (item ["url" ])
360
376
logging .info ("News: " + item ["url" ])
361
- view = Wayland_view (display .res_x , display .res_y , len (texts ))
377
+ view = Wayland_view (display .res_x , display .res_y , len (texts ), theme )
362
378
view .s_objects [0 ]["font_size" ] = 30
363
379
view .s_objects [1 ]["font_size" ] = 60
364
380
view .s_objects [2 ]["font_size" ] = 30
365
- self .render_text_view (view , texts )
366
-
367
- def render_text_view (self , view , texts ):
368
- view .show_text (texts )
381
+ view .show_text (texts , img_bg )
369
382
370
- def start_image_view (self , view , files ):
371
- view = Wayland_view (display .res_x , display .res_y )
383
+ def start_image_view (self , file ):
384
+ view = Wayland_view (display .res_x , display .res_y , 1 , theme )
372
385
view .show_image (file )
373
386
374
387
@@ -518,8 +531,9 @@ def news_item(self):
518
531
n = {"title" : "" ,
519
532
"url" : "" }
520
533
521
- n ["title" ] = self .news .pop (0 ).get ('title' )
522
- n ["url" ] = self .news .pop (0 ).get ('url' )
534
+ n ["title" ] = self .news [0 ].get ('title' )
535
+ n ["url" ] = self .news [0 ].get ('url' )
536
+ self .news .pop (0 )
523
537
524
538
return n
525
539
@@ -568,7 +582,7 @@ def current_weather(self):
568
582
569
583
class Wayland_view :
570
584
571
- def __init__ (self , res_x , res_y , num_objects ):
585
+ def __init__ (self , res_x , res_y , num_objects , theme ):
572
586
# Load the main Wayland protocol.
573
587
wp_base = wayland .protocol .Protocol ("/usr/share/wayland/wayland.xml" )
574
588
wp_xdg_shell = wayland .protocol .Protocol ("/usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml" )
@@ -590,10 +604,12 @@ def __init__(self, res_x, res_y, num_objects):
590
604
s_object = {"alignment" : "center" ,
591
605
"offset_x" : 10 ,
592
606
"offset_y" : 10 ,
607
+ "bg_alpha" : 1 ,
593
608
"bg_colour_r" : 7 ,
594
609
"bg_colour_g" : 59 ,
595
610
"bg_colour_b" : 76 ,
596
- "font_face" : "monospace" ,
611
+ "font" : theme .font ,
612
+ "font_face" : theme .font_face ,
597
613
"font_size" : 60 ,
598
614
"font_colour_r" : 0 ,
599
615
"font_colour_g" : 0 ,
@@ -614,29 +630,34 @@ def create_window(self, w):
614
630
self .conn .disconnect ()
615
631
logging .info ("Exiting wayland view: {}" .format (view .shutdowncode ))
616
632
617
- def show_text (self , texts , fullscreen = False ):
633
+ def show_text (self , texts , img_bg = False , fullscreen = False ):
634
+ if img_bg :
635
+ self .s_objects [0 ]["file" ] = img_bg
636
+
618
637
logging .info ("view: Have {} text blocks" .format (len (texts )))
638
+
619
639
n = 0
620
640
for text in texts :
621
- logging .info (text )
641
+ logging .debug (text )
622
642
self .s_objects [n ]["text" ] = html .escape (text )
623
643
n += 1
624
644
625
645
w = view .Window (self .conn ,
626
646
self .window ,
627
647
self .s_objects ,
628
- redraw = view .draw_text_in_window ,
648
+ redraw = view .draw_img_with_text ,
629
649
fullscreen = fullscreen ,
630
650
class_ = "iss-view" )
631
651
632
652
self .create_window (w )
633
653
634
- def show_image (self , file , fullscreen = False ):
635
- self .s_object ["file" ] = file
654
+ def show_image (self , img_file , fullscreen = False ):
655
+ self .s_objects [0 ]["file" ] = file
656
+ self .s_objects [0 ]["bg_alpha" ] = 0
636
657
w = view .Window (self .conn ,
637
658
self .window ,
638
- self .s_object ,
639
- redraw = iew . draw_img_in_window ,
659
+ self .s_objects ,
660
+ redraw = view . draw_img_with_text ,
640
661
fullscreen = fullscreen ,
641
662
class_ = "iss-view" )
642
663
@@ -669,7 +690,7 @@ def __init__(self, address, port, res_x=1280, res_y=1024):
669
690
670
691
logging .info ("Blacklisted {} windows" .format (len (self .window_blacklist )))
671
692
672
- self .x = threading .Thread (target = self .focus_next_window , args = ())
693
+ self .x = threading .Thread (target = self .focus_next_window , args = (3 , ))
673
694
self .x .start ()
674
695
675
696
def get_socket_path (self ):
@@ -745,10 +766,9 @@ def workspace_nodes(self, workspace):
745
766
def active_window ():
746
767
cmd = 'swaymsg -s {} -t get_tree) | jq ".. | select(.type?) | select(.focused==true).id"' .format (self .socket_path )
747
768
748
- def focus_next_window (self ):
769
+ def focus_next_window (self , t_focus_s ):
749
770
while True :
750
- logging .info ("Focus change {}" .format (self .switching_windows ))
751
- time .sleep (3 )
771
+ time .sleep (t_focus_s )
752
772
if len (self .switching_windows ) == 0 :
753
773
self .switching_windows = self .get_windows_whitelist ()
754
774
if len (self .switching_windows ) == 0 :
@@ -893,6 +913,12 @@ def __init__(self, threads):
893
913
help = "The address to probe for" ,
894
914
type = str ,
895
915
default = "9.9.9.9" )
916
+ parser .add_argument ('--theme' ,
917
+ dest = 'theme_name' ,
918
+ env_var = 'THEME' ,
919
+ help = "The theme to use" ,
920
+ type = str ,
921
+ default = "default" )
896
922
parser .add_argument ('--zeroconf-publish-service' ,
897
923
dest = 'zeroconf_publish_service' ,
898
924
env_var = 'ZEROCONF_PUBLISH' ,
@@ -927,8 +953,9 @@ def __init__(self, threads):
927
953
img_path = args .img_path
928
954
listen_address = args .listen_address
929
955
listen_port = args .listen_port
930
- probe_ip = args .probe_ip
931
956
location = args .location
957
+ probe_ip = args .probe_ip
958
+ theme_name = args .theme_name
932
959
zeroconf_publish_service = args .zeroconf_publish_service
933
960
zc_service_name_prefix = args .zeroconf_service_name_prefix
934
961
zc_service_type = args .zeroconf_service_type
@@ -992,7 +1019,13 @@ def __init__(self, threads):
992
1019
#sys.exit(1)
993
1020
994
1021
hostname = socket .gethostname ()
995
- local_ip = System .net_local_iface_address (probe_ip )
1022
+ local_ip = ""
1023
+
1024
+ try :
1025
+ local_ip = System .net_local_iface_address (probe_ip )
1026
+ except :
1027
+ logging .error ("No network connection" )
1028
+ exit (1 )
996
1029
997
1030
display = Display (local_ip , listen_port )
998
1031
@@ -1001,7 +1034,8 @@ def __init__(self, threads):
1001
1034
logging .warning ("Expected no windows but found {}"
1002
1035
.format (nwins ))
1003
1036
1004
- playlist = Playlist (uris , 5 , location )
1037
+ theme = Theme (theme_name )
1038
+ playlist = Playlist (uris , 5 , theme , location )
1005
1039
threads = playlist .start_player ()
1006
1040
logging .info ("Started {} player" .format (len (threads )))
1007
1041
iss = Iss (threads )
0 commit comments