-
Notifications
You must be signed in to change notification settings - Fork 3
/
pp_livelistfetcher.py
174 lines (131 loc) · 6.1 KB
/
pp_livelistfetcher.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
import os
from tkinter import Tk, StringVar,Frame,Label,Button,Scrollbar,Listbox,Entry,Text
from tkinter import Y,END,TOP,BOTH,LEFT,RIGHT,VERTICAL,SINGLE,NONE,NORMAL,DISABLED
import glob, os, shutil, time
class LiveListFetcher():
"""
MODE (modify in code below)
async - updates to the live tracks directory will take place while the liveshow
is running, potentially during playing of the track.
This is the old behaviour. No special protocol is required but there is risk of
the liveshow reporting an error and PP stopping.
sync - files are moved from a cache directory into the live tracks directory 2.
only between playing of the tracks so problems should not occur.
Syncing is only available for Live Tracks Directory 2. The location of this directory
can be set in the profile or in the -l command line option.
First change the mode, create a cache directory, and tell PP about it by modifying the code below.
For syncing the protocol below is required:
Place the required new tracks in the cache directory
create a file named .lock in the cache directory.
PP tests .lock between each track. If present:
PP deletes all the tracks from the Live Tracks 2 directory and
moves the new tracks from the cache directory to the Live Tracks 2 directory
PP will then delete the .lock file
The sender must not update the cache directory while the .lock file is present.
Provided the two directories are on the same filesystem move is a very fast
operation as it only changes directory entries and does not copy the files.
Otherwise a copy may be performed which may be too slow for the reason
described in the next paragraph.
You could have a more sophisticated update_tracks() technique but it must be fast
as it is a blocking operation and the remainder of PP, being cooperatively scheduled,
may not like being blocked for more than a few mS.
Experiment with your particular application
"""
mode = 'async'
# mode = 'sync'
cache_dir = '/home/pi/PPCache/'
def __init__(self):
# called at the start of a Liveshow or Artliveshow (they use the same Livelist Class)
return
def live_tracks(self,dir1,dir2):
#called at start of liveshow or artliveshow to pass the directories
# create_new_livelist tests both directories for changes
# but uploader only use live_dir2
# if the path does not exist then do not use it
self.pp_live_dir = dir2
# initial population of livelist from cache
if os.path.exists(LiveListFetcher.cache_dir):
if LiveListFetcher.mode == 'sync':
if self.detect_signal(LiveListFetcher.cache_dir,'lock') is True:
self.update_tracks()
self.send_signal(LiveListFetcher.cache_dir,'lock',False)
return
# self.send_signal(LiveListFetcher.cache_dir,'lock',False)
def fetch_livelist(self):
# called after each track by create_new_livelist()
if LiveListFetcher.mode == 'async':
# no lock protocol so just return
# print ('async')
return
if not os.path.exists(LiveListFetcher.cache_dir):
# no cache directory, just return
return
if LiveListFetcher.mode == 'sync':
if self.detect_signal(LiveListFetcher.cache_dir,'lock') is True:
self.update_tracks()
self.send_signal(LiveListFetcher.cache_dir,'lock',False)
return
else:
print('unknown Live List Fetcher mode: '+ LiveListFetcher.mode )
return
def update_tracks(self):
#time.sleep(5) # see what happens if the update takes a long time
paths = glob.glob(self.pp_live_dir +'/*')
for f in paths:
# print ('deleting',f)
os.remove(f)
source_dir = LiveListFetcher.cache_dir
dest = self.pp_live_dir +'/'
files = os.listdir(source_dir)
for f in files:
if f[0] != '.':
# print ('MOVING', f)
shutil.move(source_dir+f, dest)
def send_signal(self,directory,signal,state):
if state == True:
try:
f = open(directory+'.'+signal,'x').close()
# print ('sent ',directory,signal,state)
except:
# print(directory + '.'+ signal+ ' already exists')
pass
else:
if os.path.exists(directory +'.'+signal):
os.remove(directory + '.'+signal)
# print ('sent ',directory,signal,state)
else:
# print( directory+'.'+signal+ ' already deleted')
pass
def detect_signal(self,directory,signal):
if os.path.exists(directory+'.'+signal):
# print (signal, 'is True')
return True
else:
# print (signal, 'is False')
return False
# **************************
# Test harness
# **************************
# !!!! create a cache directory first !!!
# and uncomment the print statements.
class PiPresents(object):
def __init__(self):
# root is the Tkinter root widget
self.root = Tk()
self.root.title("Livelist Fetcher")
self.root.resizable(False,False)
# define response to main window closing
self.root.protocol ("WM_DELETE_WINDOW", self.app_exit)
self.root.bind('<Break>',self.app_exit)
self.llf=LiveListFetcher()
self.llf.live_tracks('','/home/pi/pp_home/pp_live_tracks')
self.root.after(1,self.do_track_loop)
self.root.mainloop()
def app_exit(self,event=None):
self.root.destroy()
exit()
def do_track_loop(self):
self.llf.fetch_livelist()
self.root.after(5000,self.do_track_loop)
if __name__ == '__main__':
pp= PiPresents()