Commit 229a4cf2 authored by Gottfried Gaisbauer's avatar Gottfried Gaisbauer
Browse files

started eventqueue

parent 00f54fa8
This diff is collapsed.
......@@ -3,7 +3,7 @@ import sys
import threading
from libraries.base.config import ConfigReader
from libraries.reporting.messenger import AuraMessenger
from libraries.reporting.messenger import RedisMessenger
from modules.controller.controller import AuraController
from modules.communication.zmq.zmqadapter import ServerZMQAdapter
......@@ -18,7 +18,7 @@ class Aura():
self.config = ConfigReader()
self.config.loadConfig()
messenger = AuraMessenger()
messenger = RedisMessenger()
messenger.set_channel("aura")
server = object
......
......@@ -10,14 +10,17 @@ from argparse import ArgumentParser
from modules.communication.liquidsoap.LiquidSoapCommunicator import LiquidSoapCommunicator
from libraries.base.config import ConfigReader
from modules.communication.zmq.zmqadapter import ClientZMQAdapter
from modules.controller.controller import AuraController
class Guru:
config = ConfigReader()
config.loadConfig()
controller = AuraController(config, False)
# init liquidsoap communication
lsc = LiquidSoapCommunicator(config, False)
lsc = LiquidSoapCommunicator(controller, config, False)
# init internal zmq communication
zmqclient = ClientZMQAdapter(config.get('zmqhostip'), config.get('zmqport'), debug=False)
......@@ -28,28 +31,28 @@ class Guru:
# commands
parser.add_argument("-fnp", "--fetch-new-programmes", action="store_true", dest="fetch_new_programme",
default=False, help="Fetch new programmes from calendarurl in comba.ini")
parser.add_argument("-ip", "--init-player", action="store_true", dest="initplayer", default=False,
parser.add_argument("-ip", "--init-player", action="store_true", dest="init_player", default=False,
help="Checks what is the active source and stops everything else")
# getter
parser.add_argument("-gam", "--get-active-mixer", action="store_true", dest="getactivemixer", default=False,
parser.add_argument("-gam", "--get-active-mixer", action="store_true", dest="get_active_mixer", default=False,
help="Which mixer is activated?")
parser.add_argument("-pms", "--print-mixer-status", action="store_true", dest="printmixerstatus", default=False,
parser.add_argument("-pms", "--print-mixer-status", action="store_true", dest="print_mixer_status", default=False,
help="Prints all mixer sources and their states")
parser.add_argument("-pap", "--print-act-programme", action="store_true", dest="printactprog", default=False,
parser.add_argument("-pap", "--print-act-programme", action="store_true", dest="print_act_prog", default=False,
help="Prints the actual Programme, the controller holds")
# manipulation
parser.add_argument("-am", "--select-mixer", action="store", dest="selectmixer", default=-1, metavar="MIXERNUM",
parser.add_argument("-am", "--select-mixer", action="store", dest="select_mixer", default=-1, metavar="MIXERNUM",
help="Which mixer should be activated?", type=int)
parser.add_argument("-dm", "--de-select-mixer", action="store", dest="deselectmixer", default=-1, metavar="MIXERNUM",
parser.add_argument("-dm", "--de-select-mixer", action="store", dest="deselect_mixer", default=-1, metavar="MIXERNUM",
help="Which mixer should be activated?", type=int)
parser.add_argument("-vm", "--volume", action="store", dest="setvolume", default=0, metavar=("MIXERNUM","VOLUME"), nargs=2,
parser.add_argument("-vm", "--volume", action="store", dest="set_volume", default=0, metavar=("MIXERNUM","VOLUME"), nargs=2,
help="Set volume of a mixer source", type=int)
parser.add_argument("-as", "--add-source", action="store", dest="addsource", default="",
parser.add_argument("-as", "--add-source", action="store", dest="add_source", default="",
help="Add new source to LiquidSoap mixer [Experimental]")
args = parser.parse_args()
......@@ -67,25 +70,25 @@ class Guru:
if args.get_active_mixer:
self.get_active_mixer()
if args.printmixerstatus:
if args.print_mixer_status:
self.print_mixer_status()
if args.printactprog:
if args.print_act_prog:
self.print_act_program()
if args.addsource != "":
if args.add_source != "":
print("Guru still has to learn to add a source")
if args.selectmixer != -1:
if args.select_mixer != -1:
self.select_mixer(args.select_mixer)
if args.deselectmixer != -1:
if args.deselect_mixer != -1:
self.select_mixer(args.deselectmixer, False)
if args.setvolume:
if args.set_volume:
self.set_volume(args.setvolume[0], args.setvolume[1])
if args.initplayer:
if args.init_player:
self.init_player()
if len(sys.argv) == 1:
......@@ -128,7 +131,6 @@ class Guru:
def print_act_program(self):
jsonreply = self.zmqclient.send("get_act_programme")
reply = simplejson.loads(jsonreply)
for entry in reply:
print("schedule id #"+str(entry["schedule_id"])+" and entrynumber #"+str(entry["entry_num"])+" starting @ "+entry["entry_start"]+" playing "+entry["source"]+" and is going to stop @ "+entry["entry_end"])
......@@ -137,7 +139,7 @@ class Guru:
# # ENTRY FUNCTION # #
# # ## ## ## ## ## # #
def main():
guru = Guru()
Guru()
# # ## ## ## ## ## ## # #
# # End ENTRY FUNCTION # #
# # ## ## ## ## ## ## # #
......
......@@ -27,11 +27,11 @@ import queue
from datetime import datetime, timedelta
from libraries.database.broadcasts import Schedule, ScheduleEntry
from libraries.reporting.messenger import AuraMessenger
from libraries.reporting.messenger import RedisMessenger
class AuraCalendarService(threading.Thread):
messenger = AuraMessenger()
messenger = RedisMessenger()
calendarurl = ""
audiobase = ""
playlistdir = ""
......@@ -415,4 +415,4 @@ class AuraCalendarService(threading.Thread):
# ------------------------------------------------------------------------------------------ #
def get_calendar_data(self):
return simplejson.dumps(self.fetched_schedule_data)
return self.fetched_schedule_data
......@@ -2,6 +2,7 @@ __author__ = 'michel'
# -*- coding: utf-8 -*-
import datetime, os, urllib, sys
import time
import decimal
from sqlalchemy import Boolean, Column, Date, DateTime, Float, Integer, String, Text, Time, ForeignKey
......@@ -54,7 +55,12 @@ class ScheduleEntryModel(Model):
# ------------------------------------------------------------------------------------------ #
@staticmethod
def select_all():
return ScheduleEntry.query.filter().all()
all_entries = ScheduleEntry.query.filter().all()
for entry in all_entries:
entry.entry_start_unix = time.mktime(entry.entry_start.timetuple())
entry.entry_end_unix = time.mktime(entry.entry_end.timetuple())
return all_entries
@staticmethod
def select_one(playlist_id, entry_num):
......@@ -129,6 +135,9 @@ class ScheduleEntry(db.Model, ScheduleEntryModel):
tracknum = Column(String(256))
cdnum = Column(String(256))
year = Column(String(5)) # well should be int, but can also be ""
entry_start_unix = 0
entry_end_unix = 0
# def __init__(self, playlist_id, entry_num, schedule_id, entry_start, entry_end, source, artist, track, albumname, genre, tracknum, cdnum, year):
# self.playlist_id = playlist_id
......@@ -145,15 +154,32 @@ class ScheduleEntry(db.Model, ScheduleEntryModel):
# self.cdnum = cdnum
# self.year = year
@property
def serialize(self):
"""Return object data in easily serializeable format"""
return {
'schedule_id': self.schedule_id,
'entry_start': self.dump_datetime(self.entry_start),
'entry_end': self.dump_datetime(self.entry_end),
'source': self.source
}
@staticmethod
def create_from_json(playlist_id, entry_num, schedule_id, entry_start, entry_end, source, artist, track, albumname, genre, tracknum, cdnum, year):
e = ScheduleEntry()
e.playlist_id = playlist_id
e.entry_num = entry_num
e.schedule_id = schedule_id
e.entry_start = entry_start
e.entry_end = entry_end
e.source = source
e.artist = artist
e.track = track
e.albumname = albumname
e.genre = genre
e.tracknum = tracknum
e.cdnum = cdnum
e.year = year
# @property
# def serialize(self):
# """Return object data in easily serializeable format"""
# return {
# 'schedule_id': self.schedule_id,
# 'entry_start': self.dump_datetime(self.entry_start),
# 'entry_end': self.dump_datetime(self.entry_end),
# 'source': self.source
# }
#class Trackservice(db.Model, Model):
# """
......
......@@ -9,7 +9,7 @@ from libraries.reporting.mail import AuraMailer
"""
Meldungen an den StateStore schicken
"""
class AuraMessenger():
class RedisMessenger():
def __init__(self):
"""
Constructor
......
......@@ -3,6 +3,7 @@ import codecs
import urllib
import tempfile
import simplejson
import traceback
from libraries.base.parsexml import parsexml
from modules.communication.liquidsoap.LiquidSoapPlayerClient import LiquidSoapPlayerClient
......@@ -15,9 +16,10 @@ class LiquidSoapCommunicator:
lqcr = None
debug = None
transaction = False
controller = None
# ------------------------------------------------------------------------------------------ #
def __init__(self, config, debug=True):
def __init__(self, controller, config, debug=True):
"""
Constructor
......@@ -26,7 +28,7 @@ class LiquidSoapCommunicator:
@type lqs_recsocket: string
@param lqs_recsocket: Liquidsoap Recorder Socket
"""
self.controller = controller
# Der Liquidsoap Client
# print("lqs_socket: " + lqs_socket)
self.lqc = LiquidSoapPlayerClient(config.get('socketdir') + '/simplestmixer.sock', debug)
......@@ -453,8 +455,9 @@ class LiquidSoapCommunicator:
if channel == 'playlist':
channel = 'common'
# Liquidsoap Kommando
channels = self.__sendLqcCommand__(self.lqc, 'listChannels', False)
#channels = self.__sendLqcCommand__(self.lqc, 'listChannels', False)
channels = self.__sendLqcCommand__(self.lqc, "mixer", "inputs")
print(channels)
try:
index = channels.index(channel)
if len(channel) < 1:
......@@ -463,14 +466,12 @@ class LiquidSoapCommunicator:
self.error('03')
else:
message = self.__sendLqcCommand__(self.lqc, 'volume', str(index), str(int(volume)))
message = self.__sendLqcCommand__(self.lqc, 'mixer', 'volume', str(index), str(int(volume)))
if message.find('volume=' + str(volume) + '%'):
self.success('01', str(volume))
self.controller.success('01', str(volume))
else:
self.warning('01')
self.notifyClient()
self.controller.warning('01')
# ------------------------------------------------------------------------------------------ #
def current_data(self):
......@@ -889,7 +890,7 @@ class LiquidSoapCommunicator:
self.openConn(lqs_instance)
if self.debug:
print("LiquidSoapCommunicator trying to call " + namespace + "." + command + " " + str(args))
print("LiquidSoapCommunicator trying to call " + str(namespace) + "." + str(command) + " " + str(args))
# call wanted function ...
func = getattr(lqs_instance, namespace)
......@@ -908,7 +909,7 @@ class LiquidSoapCommunicator:
# else:
# raise e
# self.fatal('01')
print(e)
traceback.print_exc()
raise e
# Instanz/Thread zerstören - aufrufende Funktion wird nicht weiter abgearbeitet
......@@ -923,21 +924,29 @@ class LiquidSoapCommunicator:
return result
# ------------------------------------------------------------------------------------------ #
def enableTransaction(self):
def enableTransaction(self, connect=False):
self.transaction = True
if connect:
self.openConn()
# ------------------------------------------------------------------------------------------ #
def disableTransaction(self):
def disableTransaction(self, disconnect=False):
if disconnect:
self.closeConn()
self.transaction = False
# ------------------------------------------------------------------------------------------ #
def openConn(self, socket):
def openConn(self, socket=None):
if socket == None:
socket = self.lqc
if self.debug:
print("LiquidSoapCommunicator opened conn")
socket.connect()
# ------------------------------------------------------------------------------------------ #
def closeConn(self, socket):
def closeConn(self, socket=None):
if socket == None:
socket = self.lqc
if self.debug:
print("LiquidSoapCommunicator closed conn")
socket.byebye()
......@@ -276,4 +276,22 @@ class LiquidSoapPlayerClient(LiquidSoapClient):
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('remaining', 'playlist')
return self.message
\ No newline at end of file
return self.message
# ------------------------------------------------------------------------------------------ #
def list_channels(self):
"""
Channels auflisten (Simple JSON)
"""
# Liquidsoap Kommando
channels = self.sendLqcCommand(self.lqc, 'mixer', 'inputs')
if not isinstance(channels, list):
self.error('02')
elif len(channels) < 1:
self.warning('01')
else:
self.success('00', channels)
self.notifyClient()
\ No newline at end of file
......@@ -7,6 +7,7 @@ import redis
import random
import string
import simplejson
import traceback
from datetime import datetime
......@@ -85,28 +86,22 @@ class ServerZMQAdapter(threading.Thread):
exec("retval = " + statement)
except SyntaxError as e:
print(e)
traceback.print_exc()
msg = 'Warning: Syntax Error'
self.auracontroller.message(msg)
except AttributeError as e:
print(e)
#print(e.with_traceback())
import traceback
exc_info = sys.exc_info()
traceback.print_exception(*exc_info)
traceback.print_exc()
msg = 'Warning: Method ' + command + ' does not exist'
self.auracontroller.message(msg)
except TypeError as e:
import traceback
exc_info = sys.exc_info()
traceback.print_exception(*exc_info)
traceback.print_exc()
msg = 'Warning: Wrong number of params'
self.auracontroller.message(msg)
except Exception as e:
print(e)
traceback.print_exc()
msg = 'Warning: Unknown Error'
self.auracontroller.message(msg)
......
......@@ -7,13 +7,17 @@ import random
import string
# import tempfile
import sys
import os
import json
import datetime
import decimal
import traceback
import simplejson
from libraries.base.calendar import AuraCalendarService
# from libraries.utils.parsexml import parsexml
from libraries.base.schedulerconfig import AuraSchedulerConfig
from libraries.reporting.messenger import AuraMessenger
from libraries.reporting.messenger import RedisMessenger
from libraries.security.user import AuraUser
from libraries.exceptions.auraexceptions import NoProgrammeLoadedException
from libraries.database.broadcasts import ScheduleEntry
......@@ -21,13 +25,15 @@ from libraries.database.broadcasts import ScheduleEntry
from modules.communication.liquidsoap.LiquidSoapCommunicator import LiquidSoapCommunicator
from modules.scheduling.scheduler import AuraScheduler
"""
AuraController Class
Communicates with the liquidsoap server and the scheduler
"""
class AuraController():
messenger = AuraMessenger()
messenger = RedisMessenger()
liquidsoapcommunicator = None
scheduler = None
userdb = AuraUser()
......@@ -49,7 +55,7 @@ class AuraController():
@type lqs_recsocket: string
@param lqs_recsocket: Liquidsoap Recorder Socket
"""
self.liquidsoapcommunicator = LiquidSoapCommunicator(config)
self.liquidsoapcommunicator = LiquidSoapCommunicator(self, config)
self.debug = debug
# Felder die Liquidsoap fuer einen Track (rid) zurueckliefert
......@@ -62,7 +68,7 @@ class AuraController():
errors_file = config.get("install_dir")+"/errormessages/controller_error.js"
self.errorData = simplejson.load(open(errors_file))
self.scheduler = AuraScheduler(config, self.debug)
self.scheduler = AuraScheduler(config, self.liquidsoapcommunicator, self.debug)
self.config = config
# ------------------------------------------------------------------------------------------ #
......@@ -120,19 +126,36 @@ class AuraController():
# ------------------------------------------------------------------------------------------ #
def get_act_programme(self):
try:
programme = self.scheduler.get_act_programme_as_json()
programme = self.scheduler.get_act_programme()
except NoProgrammeLoadedException as e:
print("WARNING: no programme in memory. i have to reload it!")
# refetch the programme from pv and importer
self.fetch_new_programme()
# is the recursion here really needed, or an additional error source?
return self.get_act_programme()
except Exception as e:
print(e)
traceback.print_exc()
# exc_type, exc_obj, exc_tb = sys.exc_info()
# fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
# print(e.with_traceback(True)) # exc_type, fname, exc_tb.tb_lineno)
self.fatal("01")
else:
# entries = []
# for p in programme:
# entries.append(p["playlist"]["entries"])
# print(p)
# for p in programme["entries"]:
# print(p)
#retstring = json.dumps([p._asdict() for p in programme], default=alchemyencoder)
#retstring = json.dumps([p._asdict() for p in programme["entries"]], default=alchemyencoder)
#retstring = json.dumps(programme["entries"], default=alchemyencoder)
#retstring = json.dumps([p["playlist"]["entries"] for p in programme], default=alchemyencoder)
#print("WANNA SEND")
#print(retstring)
self.success("00")
return programme
return programme
# ------------------------------------------------------------------------------------------ #
def liquid_startup(self):
......
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment