from deefuzzer.station import *
from deefuzzer.tools import *
-mimetypes.add_type('application/x-yaml','.yaml')
+mimetypes.add_type('application/x-yaml', '.yaml')
class DeeFuzzer(Thread):
self.conf_file = conf_file
self.conf = get_conf_dict(self.conf_file)
- if not 'deefuzzer' in self.conf.keys():
+ if 'deefuzzer' not in self.conf.keys():
return
# Get the log setting first (if possible)
self._info('Using libshout version %s' % shout.version())
self._info('Number of stations : ' + str(len(self.station_settings)))
-
def _log(self, level, msg):
try:
- obj = {}
- obj['msg'] = 'Core: ' + str(msg)
- obj['level'] = level
+ obj = {'msg': 'Core: ' + str(msg), 'level': level}
self.logqueue.put(obj)
except:
pass
m3u.write('#EXTM3U\n')
for k in self.station_instances.keys():
s = self.station_instances[k]
- m3u.write('#EXTINF:%s,%s - %s\n' % ('-1',s.short_name, s.channel.name))
+ m3u.write('#EXTINF:%s,%s - %s\n' % ('-1', s.short_name, s.channel.name))
m3u.write('http://' + s.channel.host + ':' + str(s.channel.port) + s.channel.mount + '\n')
m3u.close()
self._info('Writing M3U file to : ' + self.m3u)
"""Scan a folder for subfolders containing media, and make stations from them all."""
options = self.watchfolder
- if not 'folder' in options.keys():
+ if 'folder' not in options.keys():
# We have no folder specified. Bail.
return
if self.mainLoop:
- if not 'livecreation' in options.keys():
+ if 'livecreation' not in options.keys():
# We have no folder specified. Bail.
return
# This makes the log file a lot more verbose. Commented out since we report on new stations anyway.
# self._info('Scanning folder ' + folder + ' for stations')
- if not 'infos' in options.keys():
+ if 'infos' not in options.keys():
options['infos'] = {}
- if not 'short_name' in options['infos'].keys():
+ if 'short_name' not in options['infos'].keys():
options['infos']['short_name'] = '[name]'
files = os.listdir(folder)
- for file in files:
- filepath = os.path.join(folder, file)
+ for f in files:
+ filepath = os.path.join(folder, f)
if os.path.isdir(filepath):
if folder_contains_music(filepath):
self.create_station(filepath, options)
def station_exists(self, name):
try:
for s in self.station_settings:
- if not 'infos' in s.keys():
+ if 'infos' not in s.keys():
continue
- if not 'short_name' in s['infos'].keys():
+ if 'short_name' not in s['infos'].keys():
continue
if s['infos']['short_name'] == name:
return True
if self.station_exists(name):
return
self._info('Creating station for folder ' + folder)
- d = dict(path=folder,name=name)
+ d = dict(path=folder, name=name)
for i in options.keys():
- if not 'folder' in i:
+ if 'folder' not in i:
s[i] = replace_all(options[i], d)
- if not 'media' in s.keys():
+ if 'media' not in s.keys():
s['media'] = {}
s['media']['source'] = folder
-
+
self.add_station(s)
def load_stations_fromconfig(self, folder):
self._info('Loading station config files in ' + folder)
files = os.listdir(folder)
- for file in files:
- filepath = os.path.join(folder, file)
+ for f in files:
+ filepath = os.path.join(folder, f)
if os.path.isfile(filepath):
self.load_station_config(filepath)
- def load_station_config(self, file):
+ def load_station_config(self, f):
"""Load station configuration(s) from a config file."""
- self._info('Loading station config file ' + file)
- stationdef = get_conf_dict(file)
+ self._info('Loading station config file ' + f)
+ stationdef = get_conf_dict(f)
if isinstance(stationdef, dict):
if 'station' in stationdef.keys():
if isinstance(stationdef['station'], dict):
while True:
self.create_stations_fromfolder()
ns_new = len(self.station_settings)
- if(ns_new > ns):
+ if ns_new > ns:
self._info('Loading new stations')
-
+
for i in range(0, ns_new):
+ name = ''
try:
- name = ''
if 'station_name' in self.station_settings[i].keys():
name = self.station_settings[i]['station_name']
-
- if not 'retries' in self.station_settings[i].keys():
+
+ if 'retries' not in self.station_settings[i].keys():
self.station_settings[i]['retries'] = 0
-
+
try:
if 'station_instance' in self.station_settings[i].keys():
# Check for station running here
# Station exists and is alive. Don't recreate.
self.station_settings[i]['retries'] = 0
continue
-
+
if self.maxretry >= 0 and self.station_settings[i]['retries'] <= self.maxretry:
# Station passed the max retries count is will not be reloaded
- if not 'station_stop_logged' in self.station_settings[i].keys():
+ if 'station_stop_logged' not in self.station_settings[i].keys():
self._err('Station ' + name + ' is stopped and will not be restarted.')
self.station_settings[i]['station_stop_logged'] = True
continue
-
- self.station_settings[i]['retries'] = self.station_settings[i]['retries'] + 1
- self._info('Restarting station ' + name + ' (try ' + str(self.station_settings[i]['retries']) + ')')
+
+ self.station_settings[i]['retries'] += 1
+ self._info('Restarting station ' + name + ' (try ' + str(
+ self.station_settings[i]['retries']) + ')')
except Exception as e:
self._err('Error checking status for ' + name)
self._err(str(e))
- if not ignoreErrors:
+ if not self.ignoreErrors:
raise
# Apply station defaults if they exist
if 'stationdefaults' in self.conf['deefuzzer']:
if isinstance(self.conf['deefuzzer']['stationdefaults'], dict):
- self.station_settings[i] = merge_defaults(self.station_settings[i], self.conf['deefuzzer']['stationdefaults'])
+ self.station_settings[i] = merge_defaults(self.station_settings[i],
+ self.conf['deefuzzer']['stationdefaults'])
if name == '':
name = 'Station ' + str(i)
name = self.station_settings[i]['infos']['short_name']
y = 1
while name in self.station_instances.keys():
- y = y + 1
+ y += 1
name = self.station_settings[i]['infos']['short_name'] + " " + str(y)
self.station_settings[i]['station_name'] = name
self._err('Error validating station ' + name)
except Exception:
self._err('Error initializing station ' + name)
- if not ignoreErrors:
+ if not self.ignoreErrors:
raise
continue
if self.m3u:
self.set_m3u_playlist()
-
+
ns = ns_new
self.mainLoop = True
self.statusfile = station['station_statusfile']
try:
if os.path.exists(self.statusfile):
- f = open(self.statusfile,'r')
+ f = open(self.statusfile, 'r')
self.starting_id = int(f.read())
f.close()
except:
if 'base_dir' in self.station:
self.base_directory = self.station['base_dir'].strip()
-
+
# Media
if 'm3u' in self.station['media'].keys():
if not self.station['media']['m3u'].strip() == '':
self.media_source = self._path_add_base(self.station['media']['m3u'])
-
+
if 'dir' in self.station['media'].keys():
if not self.station['media']['dir'].strip() == '':
self.media_source = self._path_add_base(self.station['media']['dir'])
-
+
if 'source' in self.station['media'].keys():
if not self.station['media']['source'].strip() == '':
self.media_source = self._path_add_base(self.station['media']['source'])
-
+
self.media_format = self.station['media']['format']
self.shuffle_mode = int(self.station['media']['shuffle'])
self.bitrate = int(self.station['media']['bitrate'])
self.appendtype = int(self.station['server']['appendtype'])
if 'type' in self.station['server']:
- self.type = self.station['server']['type'] # 'icecast' | 'stream-m'
+ self.type = self.station['server']['type'] # 'icecast' | 'stream-m'
else:
self.type = 'icecast'
self.channel.password = self.station['server']['sourcepassword']
self.channel.public = int(self.station['server']['public'])
if self.channel.format == 'mp3':
- self.channel.audio_info = { 'bitrate': str(self.bitrate),
- 'samplerate': str(self.samplerate),
- 'channels': str(self.voices),}
+ self.channel.audio_info = {'bitrate': str(self.bitrate),
+ 'samplerate': str(self.samplerate),
+ 'channels': str(self.voices), }
else:
- self.channel.audio_info = { 'bitrate': str(self.bitrate),
- 'samplerate': str(self.samplerate),
- 'quality': str(self.ogg_quality),
- 'channels': str(self.voices),}
+ self.channel.audio_info = {'bitrate': str(self.bitrate),
+ 'samplerate': str(self.samplerate),
+ 'quality': str(self.ogg_quality),
+ 'channels': str(self.voices), }
self.server_url = 'http://' + self.channel.host + ':' + str(self.channel.port)
self.channel_url = self.server_url + self.channel.mount
# Jingling between each media.
if 'jingles' in self.station:
if 'mode' in self.station['jingles']:
- self.jingles_mode = int(self.station['jingles']['mode'])
+ self.jingles_mode = int(self.station['jingles']['mode'])
if 'shuffle' in self.station['jingles']:
self.jingles_shuffle = int(self.station['jingles']['shuffle'])
if 'frequency' in self.station['jingles']:
self.twitter_tags = self.station['twitter']['tags'].split(' ')
try:
self.twitter_messages = self.station['twitter']['message']
- if isinstance(self.twitter_messages, dict):
+ if isinstance(self.twitter_messages, dict):
self.twitter_messages = list(self.twitter_messages)
except:
pass
self.record_callback('/record', [1])
self.valid = True
-
+
def _path_add_base(self, a):
return os.path.join(self.base_directory, a)
-
+
def _path_m3u_rel(self, a):
return os.path.join(os.path.dirname(self.source), a)
-
+
def _log(self, level, msg):
try:
- obj = {}
- obj['msg'] = 'Station ' + str(self.channel_url) + ': ' + str(msg)
- obj['level'] = str(level)
+ obj = {'msg': 'Station ' + str(self.channel_url) + ': ' + str(msg), 'level': str(level)}
self.logqueue.put(obj)
except:
pass
self.twitter = Twitter(self.twitter_key, self.twitter_secret)
self.twitter_mode = value
message = "received OSC message '%s' with arguments '%d'" % (path, value)
-
+
# IMPROVEMENT: The URL paths should be configurable because they're
# server-implementation specific
self.m3u_url = self.channel.url + '/m3u/' + self.m3u.split(os.sep)[-1]
if value:
if not os.path.exists(self.record_dir):
os.makedirs(self.record_dir)
- self.rec_file = self.short_name.replace('/', '_') + '-' + \
- datetime.datetime.now().strftime("%x-%X").replace('/', '_') + \
- '.' + self.channel.format
+ self.rec_file = self.short_name.replace('/', '_') + '-'
+ self.rec_file += datetime.datetime.now().strftime("%x-%X").replace('/', '_')
+ self.rec_file += '.' + self.channel.format
self.recorder = Recorder(self.record_dir)
self.recorder.open(self.rec_file)
else:
if self.channel.format == 'ogg':
media = Ogg(self.record_dir + os.sep + self.rec_file)
media.metadata = {'artist': self.artist.encode('utf-8'),
- 'title': self.title.encode('utf-8'),
- 'album': self.short_name.encode('utf-8'),
- 'genre': self.channel.genre.encode('utf-8'),
- 'date' : date.encode('utf-8'),}
+ 'title': self.title.encode('utf-8'),
+ 'album': self.short_name.encode('utf-8'),
+ 'genre': self.channel.genre.encode('utf-8'),
+ 'date': date.encode('utf-8'), }
media.write_tags()
self.record_mode = value
def get_playlist(self):
file_list = []
-
+
try:
if os.path.isdir(self.media_source):
self.q.get(1)
for root, dirs, files in os.walk(self.media_source):
for file in files:
s = file.split('.')
- ext = s[len(s)-1]
- if ext.lower() == self.channel.format and not os.sep+'.' in file:
+ ext = s[len(s) - 1]
+ if ext.lower() == self.channel.format and not os.sep + '.' in file:
file_list.append(root + os.sep + file)
file_list.sort()
except:
pass
self.q.task_done()
-
+
if os.path.isfile(self.media_source):
self.q.get(1)
try:
self.q.task_done()
except:
pass
-
+
return file_list
def get_jingles(self):
for root, dirs, files in os.walk(self.jingles_dir):
for file in files:
s = file.split('.')
- ext = s[len(s)-1]
- if ext.lower() == self.channel.format and not os.sep+'.' in file:
+ ext = s[len(s) - 1]
+ if ext.lower() == self.channel.format and not os.sep + '.' in file:
file_list.append(root + os.sep + file)
file_list.sort()
return file_list
artist = artist.encode('utf-8')
artist_names = artist.split(' ')
- artist_tags = ' #'.join(list(set(artist_names)-set(['&', '-'])))
+ artist_tags = ' #'.join(list(set(artist_names) - {'&', '-'}))
message = '#NEWTRACK ! %s #%s on #%s RSS: ' % \
- (song.replace('_', ' '), artist_tags, self.short_name)
+ (song.replace('_', ' '), artist_tags, self.short_name)
message = message[:113] + self.feeds_url
self.update_twitter(message)
if not self.counter:
self.id = 0
- if self.starting_id > -1 and self.starting_id < lp_new:
+ if -1 < self.starting_id < lp_new:
self.id = self.starting_id
self.playlist = new_playlist
self.lp = lp_new
new_tracks = new_playlist_set - playlist_set
self.new_tracks = list(new_tracks.copy())
- if self.twitter_mode == 1 and self.counter:
+ if self.twitter_mode == 1 and self.counter:
self.tweet()
# Shake it, Fuzz it !
self._info('Generating new playlist (' + str(self.lp) + ' tracks)')
-
if self.jingles_mode and not (self.counter % self.jingles_frequency) and self.jingles_length:
media = self.jingles_list[self.jingle_id]
self.jingle_id = (self.jingle_id + 1) % self.jingles_length
except:
continue
if self.feeds_showfilename:
- file_meta.metadata['filename'] = file_name.decode( "utf-8" ) #decode needed for some weird filenames
+ file_meta.metadata['filename'] = file_name.decode("utf-8") # decode needed for some weird filenames
if self.feeds_showfilepath:
- file_meta.metadata['filepath'] = media.decode( "utf-8" ) #decode needed for some weird filenames
+ file_meta.metadata['filepath'] = media.decode("utf-8") # decode needed for some weird filenames
except:
pass
self.q.task_done()
media_link = self.feeds_media_url + media.file_name
media_link = media_link.decode('utf-8')
rss_item_list.append(RSSItem(
- title = song,
- link = media_link,
- description = media_description,
- enclosure = Enclosure(media_link, str(media.size), 'audio/mpeg'),
- guid = Guid(media_link),
- pubDate = media_date,)
- )
+ title=song,
+ link=media_link,
+ description=media_description,
+ enclosure=Enclosure(media_link, str(media.size), 'audio/mpeg'),
+ guid=Guid(media_link),
+ pubDate=media_date, )
+ )
else:
media_link = self.metadata_url + '/' + media.file_name + '.xml'
try:
except:
continue
rss_item_list.append(RSSItem(
- title = song,
- link = media_link,
- description = media_description,
- guid = Guid(media_link),
- pubDate = media_date,)
- )
+ title=song,
+ link=media_link,
+ description=media_description,
+ guid=Guid(media_link),
+ pubDate=media_date, )
+ )
json_data.append(json_item)
- rss = RSS2(title = channel_subtitle, \
- link = self.channel.url, \
- description = self.channel.description.decode('utf-8'), \
- lastBuildDate = date_now, \
- items = rss_item_list,)
+ rss = RSS2(title=channel_subtitle,
+ link=self.channel.url,
+ description=self.channel.description.decode('utf-8'),
+ lastBuildDate=date_now,
+ items=rss_item_list, )
self.q.get(1)
try:
if self.feeds_rss:
try:
if self.feeds_json:
f = open(rss_file + '.json', 'w')
- f.write(json.dumps(json_data, separators=(',',':')))
+ f.write(json.dumps(json_data, separators=(',', ':')))
f.close()
except:
pass
self.artist = self.artist.encode('utf-8')
self.metadata_file = self.metadata_dir + os.sep + self.current_media_obj[0].file_name + '.xml'
self.update_feeds(self.current_media_obj, self.feeds_current_file, '(currently playing)')
- self._info('DeeFuzzing: id = %s, name = %s' \
- % (self.id, self.current_media_obj[0].file_name))
+ self._info('DeeFuzzing: id = %s, name = %s'
+ % (self.id, self.current_media_obj[0].file_name))
self.player.set_media(self.media)
self.q.get(1)
self.channel.set_callback(FileReader(self.media).read_callback)
def update_twitter_current(self):
+ if not self.__twitter_should_update():
+ return
artist_names = self.artist.split(' ')
- artist_tags = ' #'.join(list(set(artist_names)-set(['&', '-'])))
+ artist_tags = ' #'.join(list(set(artist_names) - {'&', '-'}))
message = '%s %s on #%s' % (self.prefix, self.song, self.short_name)
tags = '#' + ' #'.join(self.twitter_tags)
message = message + ' ' + tags
return True
except:
self._err('channel could not be opened')
-
+
return False
def channel_close(self):
self.counter = (self.counter % self.jingles_frequency) + self.jingles_frequency
if self.relay_mode:
self.set_relay_mode()
- elif os.path.exists(self.media) and not os.sep+'.' in self.media:
+ elif os.path.exists(self.media) and not os.sep + '.' in self.media:
if self.lp == 0:
self._err('has no media to stream !')
return False
self._err('icecastloop_nextmedia: Error: ' + str(e))
return False
+ def __twitter_should_update(self):
+ """Returns whether or not an update should be sent to Twitter"""
+ if not self.twitter_mode:
+ # Twitter posting disabled. Return false.
+ return False
+
+ if self.relay_mode:
+ # We are in relay mode. Return true.
+ return True
+
+ if self.jingles_mode and (self.counter % self.jingles_frequency):
+ # We should be playing a jingle, and we don't send jingles to Twiitter.
+ return False
+ return True
+
+
def icecastloop_metadata(self):
try:
- if (not (self.jingles_mode and (self.counter % self.jingles_frequency)) or \
- self.relay_mode) and self.twitter_mode:
- self.update_twitter_current()
+ self.update_twitter_current()
self.channel.set_metadata({'song': self.song, 'charset': 'utf-8'})
return True
except Exception, e:
# first = True
for self.chunk in self.stream:
# if first:
- # first = False
+ # first = False
# else:
- # break
+ # break
if self.next_media or not self.run_mode:
break
self.recorder.close()
return
try:
- self.channel.set_metadata({'song': self.song, 'charset': 'utf8',})
+ self.channel.set_metadata({'song': self.song, 'charset': 'utf8', })
self._info('channel restarted')
self.channel.send(self.chunk)
self.channel.sync()
self.recorder.close()
return
- # send chunk loop end
+ # send chunk loop end
# while run_mode loop end
self._info("Play mode ended. Stopping stream.")