Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • dev-old
  • dev-old-david
  • develop
  • lars-tests
  • master
  • master-old
  • topic/filesystem-fallbacks
  • topic/tank_connection
  • topic/tank_connection_david
  • user/equinox/docker
10 results

Target

Select target project
  • aura/engine
  • hermannschwaerzler/engine
  • sumpfralle/aura-engine
3 results
Select Git revision
  • 122-synchronized-ci
  • feat-use-docker-main-tag
  • fix-aura-sysuser
  • fix-broken-pipe-153
  • fix-docker-release
  • fix-push-latest-with-tag
  • fix-streamchannel-retries
  • gitlab-templates
  • improve-test-coverage-137
  • improve-test-coverage-143
  • main
  • orm-less-scheduling
  • remove-mailer
  • update-changelog-alpha3
  • virtual-timeslots-131
  • 1.0.0-alpha1
  • 1.0.0-alpha2
  • 1.0.0-alpha3
  • 1.0.0-alpha4
  • 1.0.0-alpha5
20 results
Show changes
Showing
with 1200 additions and 0 deletions
class NoProgrammeLoadedException(Exception):
pass
class LQConnectionError(Exception):
value = None
message = ""
def __init__(self, value, message=""):
self.value = value
self.message = message
def __str__(self):
return repr(self.value)
class RedisConnectionException(Exception):
pass
class FallbackException(Exception):
pass
import simplejson
class ExceptionLogger:
# ------------------------------------------------------------------------------------------ #
def __get_error__(self, job, errornumber, data):
"""
Privat: Ermittelt Fehlermeldung, Job-Name (Klassenmethode) und Fehlercode für den Job aus error/controller_error.js
@type errornumber: string
@param errornumber: Die interne Fehlernummer der aufrufenden Methode
"""
### weil es eine "bound method" ist, kommmt data als string an!???
if data == None:
data = {}
if type(data) == type(str()):
data = simplejson.loads(data)
hasData = isinstance(data, (dict)) and len(data) > 0
if job in self.errorData:
errMsg = self.errorData[job][errornumber]
errID = self.errorData[job]['id'] + str(errornumber)
if hasData:
for key in data.keys():
errMsg = errMsg.replace('::' + key + '::', str(data[key]))
data['message'] = errMsg
data['job'] = job
data['code'] = errID
return data
# ------------------------------------------------------------------------------------------ #
def success(self, job, data=None, errnum='00', value='', section='execjob'):
"""
Erfolgsmeldung loggen
@type errnum: string
@param errnum: Errornummer der aufrufenden Funktion
@type value: string
@param value: Optionaler Wert
@type section: string
@param section: Gültigkeitsbereich
"""
error = self.__get_error__(job, errnum, data)
self.job_result = {'message': error['message'], 'code': error['code'], 'success': 'success',
'job': error['job'], 'value': value, 'section': section}
self.redismessenger.send(error['message'], error['code'], 'success', error['job'], value, section)
# ------------------------------------------------------------------------------------------ #
def info(self, job, data=None, errnum='01', value='', section='execjob'):
"""
Info loggen
@type errnum: string
@param errnum: Errornummer der aufrufenden Funktion
@type value: string
@param value: Optionaler Wert
@type section: string
@param section: Gültigkeitsbereich
"""
error = self.__get_error__(job, errnum, data)
self.job_result = {'message': error['message'], 'code': error['code'], 'success': 'info', 'job': error['job'],
'value': value, 'section': section}
self.redismessenger.send(error['message'], error['code'], 'info', error['job'], value, section)
# ------------------------------------------------------------------------------------------ #
def warning(self, job, data=None, errnum='01', value='', section='execjob'):
"""
Warnung loggen
@type errnum: string
@param errnum: Errornummer der aufrufenden Funktion
@type value: string
@param value: Optionaler Wert
@type section: string
@param section: Gültigkeitsbereich
"""
error = self.__get_error__(job, errnum, data)
self.job_result = {'message': error['message'], 'code': error['code'], 'success': 'warning',
'job': error['job'], 'value': value, 'section': section}
self.redismessenger.send(error['message'], error['code'], 'warning', error['job'], value, section)
# ------------------------------------------------------------------------------------------ #
def error(self, job, data=None, errnum='01', value='', section='execjob'):
"""
Error loggen
@type errnum: string
@param errnum: Errornummer der aufrufenden Funktion
@type value: string
@param value: Optionaler Wert
@type section: string
@param section: Gültigkeitsbereich
"""
error = self.__get_error__(job, errnum, data)
self.job_result = {'message': error['message'], 'code': error['code'], 'success': 'error', 'job': error['job'],
'value': value, 'section': section}
self.redismessenger.send(error['message'], error['code'], 'error', error['job'], value, section)
# ------------------------------------------------------------------------------------------ #
def fatal(self, job, data=None, errnum='01', value='', section='execjob'):
"""
Fatal error loggen
@type errnum: string
@param errnum: Errornummer der aufrufenden Funktion
@type value: string
@param value: Optionaler Wert
@type section: string
@param section: Gültigkeitsbereich
"""
error = self.__get_error__(job, errnum, data)
self.job_result = {'message': error['message'], 'code': error['code'], 'success': 'fatal', 'job': error['job'],
'value': value, 'section': section}
self.redismessenger.send(error['message'], error['code'], 'fatal', error['job'], value, section)
# ------------------------------------------------------------------------------------------ #
def __check_result__(self, result):
"""
Fehlerbehandlung
@type result: string
@param result: Ein Json-String
"""
try:
self.lq_error = simplejson.loads(result)
except:
return False
try:
if self.lq_error['success'] == 'success':
return True
else:
return False
except:
return False
\ No newline at end of file
__author__ = 'michel'
import os
class AuraMailer():
def __init__(self, adminMails, fromMail):
self.adminMails = adminMails
self.fromMail = fromMail
def sendAdminMail(self, subject, body):
adminMails = self.adminMails.split()
for mailTo in adminMails:
self.send(self.fromMail, mailTo, subject, body)
def send(self, mailFrom, mailTo, subject, body):
sendmail_location = "/usr/sbin/sendmail"
p = os.popen("%s -t" % sendmail_location, "w")
p.write("From: %s\n" % mailFrom)
p.write("To: %s\n" % mailTo)
p.write("Subject: " + subject + "\n")
p.write("\n") # blank line separating headers from body
p.write(body)
status = p.close()
return status
\ No newline at end of file
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# user.py
#
"""
Aura User Class - Benutzerverwaltung
"""
import os
import sys
import redis
import random
import string
## current directory
scriptdir = os.path.dirname(os.path.abspath(__file__))
# Hier stecken unsere eigenen Python libraries
package_dir = os.path.join(scriptdir, 'python')
path = list(sys.path)
# Das package_dir zu den Systempfaden hinzufügen, damit wir Importe durchführen können
sys.path.insert(0, package_dir)
"""
User verwalten
"""
class AuraUser(object):
def __init__(self):
self.db = redis.Redis()
self.dbname = 'aurausers'
self.userprefix = 'aurauser:'
pass
# ------------------------------------------------------------------------------------------ #
def delete(self, username):
"""
Delete an user
:param username:
:return: boolean
"""
userid = self.db.hget(self.dbname,username).decode("utf-8")
if not userid:
return False
else:
self.db.delete(self.userprefix + userid)
self.db.hdel(self.dbname,username)
return True
# ------------------------------------------------------------------------------------------ #
def setPassword(self,username, password):
"""
Set users password
:param username: string
:param password: string
:return: boolean
"""
userid = self.db.hget(self.dbname,username).decode("utf-8")
if not userid:
return False
self.db.hset(self.userprefix + userid, 'password', password)
return True
# ------------------------------------------------------------------------------------------ #
def hasRole(self, username, role):
"""
Compare users role
:param username: string
:param role: string
:return:boolean
"""
userid = self.db.hget(self.dbname,username).decode("utf-8")
dbrole = self.db.hget(self.userprefix + str(userid), 'role').decode("utf-8")
if(dbrole == "admin"):
return True
print("username: " + username + " - userid: " + userid + " - role: " + role + " - dbrole: " + dbrole)
return (dbrole == role)
# ------------------------------------------------------------------------------------------ #
def hasPassword(self,username, password):
"""
Compare users password with the given one
:param username: string
:param password: string
:return:
"""
userid = self.db.hget(self.dbname,username).decode("utf-8")
dbpassword = self.db.hget(self.userprefix + userid, 'password').decode("utf-8")
print("username: "+username+" - userid: "+userid+" - password: "+password+" - dbpassword: "+dbpassword)
print(dbpassword == password)
return (dbpassword == password)
# ------------------------------------------------------------------------------------------ #
def hasAdminRights(self, username, password):
"""
Check admin rights
:param username: username
:param password: password
:return:
"""
return (self.hasPassword(username,password) and self.hasRole(username, 'admin'))
# ------------------------------------------------------------------------------------------ #
def insertUser(self, username, password, role="user"):
"""
Insert or update user
:param username: string
:param password: string
:param role: string
:return: string - the password
"""
userid = self.db.hget(self.dbname,username).decode("utf-8")
if not userid:
userid = self.db.incr("next_aurauser_id")
self.db.hset(self.dbname,username,userid)
self.db.hmset(self.userprefix + userid, {"username" : username,"password" :password, "role" : role})
return password
# ------------------------------------------------------------------------------------------ #
def getUser(self, username):
"""
Get users data
:param username: string
:return: dict - userdata
"""
userid = self.db.hget(self.dbname,username).decode("utf-8")
return self.db.hgetall(self.userprefix + userid)
# ------------------------------------------------------------------------------------------ #
def getUserlist(self):
"""
get all users
:return: list - the userlist
"""
accounts=[]
keys = self.db.keys(self.userprefix + "*")
for key in keys:
accounts.append(self.db.hgetall(key))
return accounts
# ------------------------------------------------------------------------------------------ #
def getLogins(self):
"""
get usernames passwords as dict in format {username1:password1, username2;password2, ...}
:return:
"""
accounts={}
keys = self.db.keys(self.userprefix + "*")
for key in keys:
account = self.db.hgetall(key)
try:
accounts[account['username']] = account['password']
except:
pass
return accounts
# ------------------------------------------------------------------------------------------ #
def createPassword(self):
"""
create a new passoword
:return: string - the password
"""
password = ''.join(random.sample(string.lowercase+string.uppercase+string.digits,14))
return password
\ No newline at end of file
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# aurawhitelist
#
"""
Aura Whitelist - IP-Adressen oder Domains aus der Whitelist holen
"""
import os
import sys
import redis
"""
Whitelisting ips or hostnames
"""
class AuraWhitelist(object):
def __init__(self):
self.db = redis.Redis()
self.dbname = 'aurawhitelist'
pass
# ------------------------------------------------------------------------------------------ #
def getList(self):
"""
get the whitelist
:return: list - list of whitelisted ip's
"""
return self.db.lrange(self.dbname, 0, -1)
# ------------------------------------------------------------------------------------------ #
def add(self,address):
"""
Add ip/host to whitelist
:param address: string - ip or hostname
:return: boolean
"""
list = self.getList()
for item in list:
if item == address:
return False
self.db.lpush(self.dbname, address)
return True
# ------------------------------------------------------------------------------------------ #
def remove(self,address):
"""
Remove an ip or host from whitelist
:param address: string - ip or hostname
:return: boolean
"""
if not address:
return False
self.db.lrem(self.dbname, address, 1)
return True
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
import time
import socket
import urllib.parse
import configparser
from io import StringIO
from libraries.exceptions.auraexceptions import LQConnectionError
""" LiquidSoapClient Class
Repräsentiert alle Kommandos, die Soundserver und Recorder kennen
"""
class LiquidSoapClient:
debug = False
socket_path = ""
def __init__(self, config, socket_filename):
"""
Constructor
@type socket_path: string
@param socket_path: Der Pfad zum Socket des Liquidsoap-Scripts
"""
self.socket_path = config.get('socketdir') + '/' + socket_filename
self.debug = config.get("debug")
if self.debug > 2:
print("socketpath: " + self.socket_path)
# init
self.connected = False
self.can_connect = True
self.message = ''
self.client = None
if sys.version_info <= (3, 2):
self.metareader = configparser.ConfigParser({'strict': False, 'interpolation': None})
else:
self.metareader = configparser.ConfigParser()
# ------------------------------------------------------------------------------------------ #
def connect(self):
"""
Verbindung herstellen
"""
try:
self.client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.client.connect(self.socket_path)
except socket.error as e:
self.connected = False
print(self.socket_path)
raise LQConnectionError(e, self.socket_path)
return False
else:
self.can_connect = True
self.connected = True
return True
# ------------------------------------------------------------------------------------------ #
def is_connected(self):
return self.connected
# ------------------------------------------------------------------------------------------ #
def write(self, data):
"""
Auf den Socket schreiben
@type data: string
@param data: Der String der gesendet wird
"""
if self.connected:
self.client.sendall(data.decode("UTF-8"))
# ------------------------------------------------------------------------------------------ #
def read_all(self, timeout=2):
"""
Vom Socket lesen, bis dieser "END" sendet
@type timeout: int
@param timeout: Ein optionales Timeout
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
# make socket non blocking
# self.client.setblocking(0)
data = '';
self.client.settimeout(3)
# recv something
# while True:
try:
time.sleep(0.1)
raw = self.client.recv(8192)
data = raw.decode()
except Exception as e:
print(e)
pass
return data
# ------------------------------------------------------------------------------------------ #
def read(self):
"""
read from socket and store return value in self.message
@rtype: string
@return: The answer of liquidsoap server
"""
if self.connected:
ret = self.read_all().splitlines()
try:
last = ret.pop()
if last == 'Bye!':
ret.append(last)
elif last != "END":
print("got no end from liquidsoap")
self.message = str.join("\r\n", ret)
except Exception as e:
print(e)
return self.message
# ------------------------------------------------------------------------------------------ #
def close(self):
"""
Quit senden und Verbindung schließen
"""
if self.connected:
message = "quit\r"
self.client.sendall(message.decode("UTF-8"))
self.client.close()
self.connected = False
# ------------------------------------------------------------------------------------------ #
def command(self, namespace, command, param=""):
"""
Kommando an Liquidosap senden
@type command: string
@param command: Kommando
@type namespace: string
@param namespace: Namespace/Kanal der angesprochen wird
@type param: mixed
@param param: ein optionaler Parameter
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
param = (param.strip() if param.strip() == "" else " " + urllib.parse.unquote(param.strip()))
if self.connected:
# print namespace + '.' + command + param + "\n"
if namespace is "":
message = str(command) + str(param) + str('\n')
else:
message = str(namespace) + str('.') + str(command) + str(param) + str('\n')
try:
if self.debug > 2:
print("LiquidSoapClient sending to LiquidSoap Server: "+message[0:len(message)-1])
# send all the stuff over the socket to liquidsoap server
self.client.sendall(message.encode())
if self.debug > 2:
print("LiquidSoapClient waiting for reply from LiquidSoap Server")
# wait for reply
self.read()
if self.debug > 2:
print("LiquidSoapClient got reply")
# self.client.close()
except:
print("Unexpected error:", sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])
raise
return self.message
else:
if self.debug:
print("LiquidSoapClient not connected to LiquidSoap Server")
return False
# ------------------------------------------------------------------------------------------ #
def simplecommand(self, command):
"""
Parameterloses Kommando ohne Namespace senden
@type command: string
@param command: Kommando
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
if self.connected:
message = str(command) + '\n'
self.client.sendall(message.decode("UTF-8"))
self.read()
# self.client.close()
return self.message
# ------------------------------------------------------------------------------------------ #
def getMetadata(self, rid):
"""
Parameterloses Kommando ohne Namespace senden
@type rid: string/int
@param rid: Die ID eines Requests
@rtype: dict
@return: Die Metadaten als dict
"""
meta = self.command('metadata ' + str(rid), 'request')
meta = '[root]\n' + meta
if sys.version_info <= (3, 2):
meta = StringIO.StringIO(meta)
try:
self.metareader.readfp(meta)
except configparser.ParsingError:
return False
else:
try:
self.metareader.read_string(meta)
except configparser.ParsingError:
return False
return self.metareader
# ------------------------------------------------------------------------------------------ #
def help(self):
"""
get liquidsoap server help
@rtype: string
@return: the response of the liquidsoap server
"""
if self.connected:
self.command('help', '')
print('read (' + str(len(self.message)) + ' bytes): ' + self.message)
return self.message
# ------------------------------------------------------------------------------------------ #
def version(self):
"""
Liquidsoap get version
@rtype: string
@return: the response of the liquidsoap server
"""
if self.connected:
message = 'version'
self.command(message, '')
return self.message
# ------------------------------------------------------------------------------------------ #
def uptime(self):
"""
Liquidsoap get uptime
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
if self.connected:
self.command('uptime', '')
print('read (' + str(len(self.message)) + ' bytes): ' + self.message)
return self.message
# ------------------------------------------------------------------------------------------ #
def byebye(self):
"""
Liquidsoap say byebye
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
if self.connected:
message = 'quit'
self.command("", message) # client.sendall(message.encode())
# self.read()
# print("read: " + self.message)
return self.message
\ No newline at end of file
This diff is collapsed.
import time
import threading
import traceback
from libraries.exceptions.auraexceptions import LQConnectionError
class LiquidSoapInitThread(threading.Thread):
socket = None
liquidsoapcommunicator = None
def __init__(self, liquidsoapcommunicator):
threading.Thread.__init__(self)
self.liquidsoapcommunicator = liquidsoapcommunicator
def run(self):
try:
# sleep needed, because the socket is created to slow by liquidsoap
time.sleep(5)
# enable lqs transaction
self.liquidsoapcommunicator.enable_transaction(True)
# reset channels and reload them
self.liquidsoapcommunicator.channels = None
channels = self.liquidsoapcommunicator.get_all_channels()
# set every volume to 0
for c in channels:
self.liquidsoapcommunicator.channel_volume(c, "0")
self.liquidsoapcommunicator.playlist_push(self.liquidsoapcommunicator.config.get("install_dir")+"/configuration/blank.flac")
self.liquidsoapcommunicator.set_http_url("http://stream.fro.at/fro-128.ogg")
# select all channels
for c in channels:
self.liquidsoapcommunicator.channel_activate(c, True)
time.sleep(3)
activechannel = self.liquidsoapcommunicator.get_active_channel()
if self.liquidsoapcommunicator.debug > 2:
print("LiquidSoapInitThread sets activechannel: "+str(activechannel))
if activechannel != "" and activechannel is not None:
self.liquidsoapcommunicator.channel_volume(activechannel.value, 100)
#self.liquidsoapcommunicator.__send_lqc_command__(self.socket, "mixer", "volume", activechannel, 100)
self.liquidsoapcommunicator.disable_transaction(True)
except LQConnectionError as e:
print("Liquidsoap connection ERROR! Restart LQ Server!")
print(e.message)
print(e)
except Exception as e:
traceback.print_exc()
print(e)
from modules.communication.liquidsoap.client import LiquidSoapClient
class LiquidSoapPlayerClient(LiquidSoapClient):
# ------------------------------------------------------------------------------------------ #
def mixer(self, command, *args):
if command == "status":
return self.mixerstatus(*args)
if command == "inputs":
return self.mixerinputs()
if command == "volume":
return self.mixervolume(*args)
if command == "select":
if len(args) == 2:
return self.mixerselect(args[0], args[1])
return "LiquidSoapPlayerClient does not understand mixer."+command+str(args)
# ------------------------------------------------------------------------------------------ #
def http(self, command, *args):
if command == "url":
return self.set_http_url(*args)
return "LiquidSoapPlayerClient does not understand http." + command + str(args)
# ------------------------------------------------------------------------------------------ #
def fs(self, command, *args):
if command == "push":
return self.fs_push(*args)
return "LiquidSoapPlayerClient does not understand fs." + command + str(args)
# ------------------------------------------------------------------------------------------ #
def fs_push(self, uri):
self.command('fs', 'push', uri)
return self.message
# ------------------------------------------------------------------------------------------ #
def set_http_url(self, uri):
self.command('http', 'url', uri)
return self.message
# ------------------------------------------------------------------------------------------ #
def mixerinputs(self):
"""
List all channels on the mixer
@type namespace: string
@param namespace: lqs namespace
@rtype: list
@return: answer of our lqs server
"""
# self.logger.info("listchannels modules/controller/liquidsoap.py")
# send command
self.command("mixer", "inputs")
# convert to list and return it
return self.message.strip().split(' ')
# ------------------------------------------------------------------------------------------ #
def mixerstatus(self, pos=""):
"""
Get state of a source in the mixer
@type pos: string
@param pos: Mixerposition
@rtype: string
@return: Response from LiquidSoap
"""
self.command("mixer", "status", str(pos))
return self.message
# ------------------------------------------------------------------------------------------ #
def mixerselect(self, pos, activate):
"""
Kanal/Source aktivieren
@type pos: string
@param pos: Die Position
@type namespace: string
@param namespace: Namespace der Source
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command("mixer", "select", str(pos) + " " + str(activate).lower())
return self.message
# ------------------------------------------------------------------------------------------ #
def mixervolume(self, pos, volume):
"""
set channel volume
:param pos:
:param volume:
:return:
"""
self.command("mixer", "volume", str(pos) + " " + str(volume))
return self.message
# ------------------------------------------------------------------------------------------ #
def skip(self, namespace="playlist", pos=""):
"""
Source skippen
@type namespace: string
@param namespace: Namespace der Source
@type pos: string
@param pos: Die Position - optional - Position des Channels vom Mixer benötigt
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('skip', namespace, pos)
return self.message
# ------------------------------------------------------------------------------------------ #
def remove(self, pos, namespace="playlist"):
"""
Track aus der secondary_queue oder der Playlist entfernen
@type pos: string
@param pos: Die Position
@type namespace: string
@param namespace: Namespace der Source
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('remove', namespace, str(pos))
return self.message
# ------------------------------------------------------------------------------------------ #
def insert(self, uri, pos='0', namespace="playlist"):
"""
Track einfügen
@type uri: string
@param uri: Uri einer Audiodatei
@type pos: string
@param pos: Die Position
@type namespace: string
@param namespace: Namespace der Source
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('insert', namespace, str(pos) + ' ' + uri)
return self.message
# ------------------------------------------------------------------------------------------ #
def move(self, fromPos, toPos, namespace="playlist"):
"""
Track von Position fromPos nach Position toPos verschieben
@type fromPos: string/int
@param fromPos: Position des zu verschiebenden Tracks
@type toPos: string
@param toPos: Die Position zu der verschoben werden soll
@type namespace: string
@param namespace: Namespace der Source
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('move', namespace, str(fromPos) + ' ' + str(toPos))
return self.message
# ------------------------------------------------------------------------------------------ #
def play(self, namespace="playlist"):
"""
Source abspielen - funktioniert nur bei Playlist
@type namespace: string
@param namespace: Namespace der Source
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('play', namespace)
return self.message
# ------------------------------------------------------------------------------------------ #
def pause(self, namespace="playlist"):
"""
Source pausieren/stoppen - funktioniert nur bei Playlist
@type namespace: string
@param namespace: Namespace der Source
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('pause', namespace)
return self.message
# ------------------------------------------------------------------------------------------ #
def flush(self, namespace="playlist"):
"""
Playlist leeren
@type namespace: string
@param namespace: Namespace der Source
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('flush', namespace)
return self.message
# ------------------------------------------------------------------------------------------ #
def playlistData(self):
"""
Metadaten der Playlist ausgeben
@rtype: string
@return: Ein Json-String
"""
self.command('data', 'playlist')
return self.message
# ------------------------------------------------------------------------------------------ #
def seek(self, duration, namespace="playlist"):
"""
Aktuell laufenen Track des Kanals vorspulen
@type duration: string/int
@param duration: Dauer in Sekunden
@type namespace: string
@param namespace: Namespace der Source
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('seek', namespace, str(duration))
return self.message
# ------------------------------------------------------------------------------------------ #
def get_queue(self, namespace="ch1", queue='queue'):
"""
Queue eines Kanals ausgeben
@type namespace: string
@param namespace: Namespace der Source
@type queue: string
@param queue: Name des queues (queue, primary_queue, secondary_queue)
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command(queue, namespace)
return self.message
# ------------------------------------------------------------------------------------------ #
def loadPlaylist(self, uri, params="", namespace="playlist"):
"""
Playlist laden
@type uri: string
@param uri: Uri einer Playlist im XSPF-Format
@type params: string
@param params: obsolete
@type namespace: string
@param namespace: Namespace der Source - hier nur playlist
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('load', namespace, uri + params)
return self.message
# ------------------------------------------------------------------------------------------ #
def currentTrack(self, namespace="request"):
"""
Das oder die ID(s) der gerade abgespielten requests erhalten
@type namespace: string
@param namespace: Namespace der Source
@rtype: string
@return: Die Antwort des Liquidsoap-Servers (als String)
"""
self.command('on_air', namespace)
return self.message
# ------------------------------------------------------------------------------------------ #
def volume(self, pos, volume, namespace="mixer"):
"""
Lautstärke eines Kanals setzen
@type pos: int/string
@param pos: Die Position/ Nummer des Kanals (playlist=0)
@type volume: int/string
@param volume: Zahl von 1 -100
@type namespace: string
@param namespace: Namespace der Source (immer mixer)
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('volume', namespace, str(pos) + ' ' + str(volume))
return self.message
# ------------------------------------------------------------------------------------------ #
def playlist_remaining(self):
"""
Wie lange läuft der aktuelle Track der Playlist noch
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('remaining', 'playlist')
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
from modules.communication.liquidsoap.client import LiquidSoapClient
class LiquidSoapRecorderClient(LiquidSoapClient):
# ------------------------------------------------------------------------------------------ #
def recorder_setfilename(self, filename):
"""
Dateinamen für Aufnahme (Vorproduktion) definieren
@type filename: string
@param filename: Dateiname - Angabe ohne Verzeichnis und mit Extension
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('setfilename', 'record', str(filename))
return self.message
# ------------------------------------------------------------------------------------------ #
def stop_record(self):
"""
Recorder stoppen
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
message = self.command('stop', 'record')
return self.message
# ------------------------------------------------------------------------------------------ #
def start_record(self):
"""
Recorder starten
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('start', 'record')
return self.message
# ------------------------------------------------------------------------------------------ #
def recorder_data(self):
"""
Daten des recorders erhalten
@rtype: string
@return: Die Antwort des Liquidsoap-Servers
"""
self.command('curfile', 'record')
return self.message
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
__author__ = 'michel'
set("log.file.path", "./<script>.log")
set("server.telnet", true)
set("server.telnet.bind_addr", "0.0.0.0")
set("server.telnet.port", 1234)
# ALSA / pulse settings
# durch ausprobieren herausgefunden für asus xonar dgx 5.1
# chip: CMI8788
# driver: snd_oxygen
set("frame.duration", 0.30)
set("alsa.alsa_buffer", 8192) # 7168) # 6144) # 8192) # 10240) #15876
set("alsa.buffer_length", 25)
set("alsa.periods", 0) # assertion error when setting periods other than 0 => alsa default
input_linein = input.alsa(id="linein", bufferize = false)
input_fs = single(id="fs", "/var/audio/fallback/output.flac")
input_http = input.http(id="http", "http://stream.fro.at/fro-128.ogg")
mixer = mix(id="mixer", [input_fs, input_http, input_linein])
output.alsa(id="lineout", bufferize = false, mixer)
This diff is collapsed.
__author__ = 'michel'
import os
import sys
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import getopt
scriptdir = os.path.dirname(os.path.abspath(__file__))
# import our libraries
package_dir = os.path.join(scriptdir, '../../../')
path = list(sys.path)
sys.path.insert(0, package_dir)
#from libraries.reporting.messenger import AuraMessenger
from libraries.base.config import ConfigReader
from modules.communication.zmq.adapter import ClientZMQAdapter
def main(argv):
#m = AuraMessenger()
task = ''
channel = ''
name= ''
value = ''
time = ''
config = ConfigReader()
config.loadConfig()
zmqclient = ClientZMQAdapter(config.get('zmqhostip'), config.get('zmqport'))
try:
opts, args = getopt.getopt(argv,"c:t:n:v:t",["channel=","task=", "name=","value=","time="])
except getopt.GetoptError:
print('message.py -c <channel> -t <task> [-n <name> -v <value> [-t <time>]]')
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print('message.py -c <channel> -t <task>')
sys.exit()
elif opt in ("-c", "--channel"):
channel = arg
elif opt in ("-t", "--task"):
task = arg
elif opt in ("-n", "--name"):
name = arg
elif opt in ("-v", "--value"):
value = arg
elif opt in ("-t", "--time"):
eventtime = arg
#m.setChannel(channel)
if task == 'setEvent':
#setEvent(self, name, eventtime, value)
#opts, args = getopt.getopt(argv,"c:t:",["channel=","task="])
pass
elif task == 'setState':
if name == '':
sys.exit(2)
zmqclient.send("startup")
# m.setState(name, value)
elif task == 'liquid_startup':
zmqclient.send(task, False)
else:
print(task)
#zmqclient.send(task)
# m.sayAlive()
if __name__ == "__main__":
main(sys.argv[1:])
sys.path[:] = path
\ No newline at end of file
This diff is collapsed.