7 from django.template import loader
8 import xml.etree.ElementTree as ET
10 from .models import Track, SomaLogLine, StreamedDiffusion, Jingle, LOCAL_BASE_PATH
13 class SomaException(Exception):
17 def get_current_nonstop_track():
19 soma_log_line = SomaLogLine.objects.select_related().order_by('-play_timestamp')[0]
23 if soma_log_line.play_timestamp < (datetime.datetime.now() - datetime.timedelta(hours=1)):
24 # last known line is way too old
26 if not soma_log_line.on_air:
27 # nonstop should be on air but it's not :/
30 current_nonstop_file = soma_log_line.filepath
31 if not 'Tranches/' in current_nonstop_file.filepath and (
32 not 'tracks/' in current_nonstop_file.filepath):
33 # nonstop is playing but it's not a nonstop track :/
35 current_track = soma_log_line.filepath.track
36 if current_track is None:
37 # nonstop is playing a nonstop track, but it's unknown :/
39 d = {'track_title': current_track.title}
40 if current_track.artist:
41 d['track_artist'] = current_track.artist.name
45 def get_diffusion_file_path(diffusion):
46 return u'diffusions-auto/%s--%s' % (
47 diffusion.datetime.strftime('%Y%m%d-%H%M'),
48 diffusion.episode.emission.slug)
50 def is_already_in_soma(diffusion):
51 if StreamedDiffusion.objects.filter(diffusion=diffusion).count():
53 return os.path.exists(os.path.join(LOCAL_BASE_PATH, get_diffusion_file_path(diffusion)))
55 class DuplicateDiffusionSlot(Exception):
58 def add_diffusion(diffusion, **kwargs):
60 streamed_diffusion = StreamedDiffusion.objects.filter(diffusion=diffusion).first()
61 if streamed_diffusion:
63 context['streamed_diffusion'] = streamed_diffusion
64 context['end'] = diffusion.end_datetime
65 context['jingle'] = streamed_diffusion.jingle
68 soundfile = diffusion.episode.soundfile_set.filter(fragment=False)[0]
69 diffusion_path = get_diffusion_file_path(diffusion)
72 if not os.path.exists(LOCAL_BASE_PATH):
73 raise SomaException('soma directory is not available')
74 if os.path.exists(os.path.join(LOCAL_BASE_PATH, diffusion_path)):
75 raise DuplicateDiffusionSlot()
76 os.mkdir(os.path.join(LOCAL_BASE_PATH, diffusion_path))
78 shutil.copyfile(soundfile.file.path,
79 os.path.join(LOCAL_BASE_PATH, diffusion_path, os.path.basename(soundfile.file.path)))
82 os.rmdir(os.path.join(LOCAL_BASE_PATH, diffusion_path))
85 raise SomaException('error copying file to soma')
87 context['diffusion_path'] = diffusion_path
88 # end should be a bit before the real end of file so the same file doesn't
89 # get repeated but shouldn't be less or equal than start date or soma would
91 context['end'] = diffusion.datetime + datetime.timedelta(seconds=
92 max(((soundfile.duration or 300) - 180), 60))
94 if 'jingle_id' in kwargs:
95 context['jingle'] = Jingle.objects.get(id=kwargs['jingle_id'])
98 palinsesti_template = loader.get_template('nonstop/soma_palinsesti.xml')
99 context['episode'] = diffusion.episode
100 context['start'] = diffusion.datetime
102 palinsesti = palinsesti_template.render(context)
103 palinsesti_xml = ET.fromstring(palinsesti.encode('utf-8'))
106 def soma_connection():
107 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
108 s.connect(('soma', 12521))
109 s.recv(1024) # -> b'soma 2.5 NO_SSL\n'
110 s.sendall(b'100 - Ok\n')
111 s.recv(1024) # -> b'100 - Welcome to soma daemon\n'
112 s.sendall(b'\n') # (empty password)
113 if s.recv(1024) != b'100 - Ok\n':
114 raise SomaException('failed to initialize soma connection')
117 with soma_connection() as s:
118 s.sendall(b'109 - Get the current palinsesto\n')
119 palinsesto_bytes = b''
121 new_bytes = s.recv(200000)
124 palinsesto_bytes += new_bytes
125 if not palinsesto_bytes.startswith(b'100 - Ok\n'):
126 raise SomaException('failed to get palinsesto')
127 palinsesto_bytes = palinsesto_bytes[9:]
129 palinsesto_xml = ET.fromstring(palinsesto_bytes)
130 palinsesto_xml.append(palinsesti_xml)
131 with soma_connection() as s:
132 s.sendall(b'106 - Switch to a New Palinsesto Request\n')
133 if s.recv(1024) != b'100 - Ok\n':
134 raise SomaException('failed to switch palinsesto')
135 s.sendall(ET.tostring(palinsesto_xml))
137 # give it some time (...)
139 with soma_connection() as s:
140 s.sendall(b'122 - Set the current Palinsesto as Default\n')
141 if s.recv(1024) != b'100 - Ok\n':
142 raise SomaException('failed to set current palinsesto as default')