Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Lars Kruse
aura-engine
Commits
070ffe17
Commit
070ffe17
authored
Feb 02, 2018
by
Gottfried Gaisbauer
Browse files
finally removed dead code, controller is gone. added logging. improved stability
parent
0a8175ac
Changes
52
Hide whitespace changes
Inline
Side-by-side
.gitignore
0 → 100644
View file @
070ffe17
.idea/
aura.py
View file @
070ffe17
...
...
@@ -2,32 +2,40 @@
import
signal
import
sys
import
threading
from
libraries.base.config
import
ConfigReader
from
modules.controller.controller
import
AuraController
from
modules.base.config
import
ConfigReader
from
modules.scheduling.scheduler
import
AuraScheduler
from
modules.communication.liquidsoap.communicator
import
LiquidSoapCommunicator
from
modules.communication.redis.adapter
import
ServerRedisAdapter
from
modules.web.routes
import
Routes
from
libraries.base.common
import
AuraCommon
class
Aura
():
class
Aura
(
AuraCommon
):
server
=
None
config
=
None
messenger
=
None
controller
=
None
# ------------------------------------------------------------------------------------------ #
def
__init__
(
self
):
self
.
config
=
ConfigReader
()
self
.
config
.
loadConfig
()
AuraCommon
.
__init__
(
self
,
name
=
"AuraEngine"
)
server
=
object
self
.
controller
=
AuraController
(
self
.
config
)
# self.controller = AuraController(self.config)
# create scheduler and ls_communicator
self
.
liquidsoapcommunicator
=
LiquidSoapCommunicator
(
self
.
config
)
self
.
scheduler
=
AuraScheduler
(
self
.
config
)
# give both a reference of each other
self
.
liquidsoapcommunicator
.
scheduler
=
self
.
scheduler
self
.
scheduler
.
liquidsoapcommunicator
=
self
.
liquidsoapcommunicator
# create the redis adapter
self
.
messenger
=
ServerRedisAdapter
()
self
.
messenger
.
set_controller
(
self
.
controller
)
self
.
messenger
.
set_config
(
self
.
config
)
self
.
messenger
.
config
=
self
.
config
self
.
messenger
.
scheduler
=
self
.
scheduler
self
.
messenger
.
liquidsoapcommunicator
=
self
.
liquidsoapcommunicator
def
receive_signal
(
signum
,
stack
):
print
(
"received signal"
)
...
...
@@ -35,13 +43,20 @@ class Aura():
signal
.
signal
(
signal
.
SIGUSR1
,
receive_signal
)
# addition initialization
self
.
scheduler
.
fetch_new_programme
()
def
join_comm
(
self
):
# start listener thread
self
.
messenger
.
start
()
def
start_web_service
(
self
):
r
=
Routes
()
#r.app.run()
try
:
Routes
()
except
OSError
as
e
:
self
.
messenger
.
halt
()
self
.
logger
.
critical
(
"AuraEngine already running? Exception: "
+
e
.
strerror
+
". Exiting..."
)
sys
.
exit
(
0
)
# # ## ## ## ## ## # #
...
...
configuration/aura.ini
View file @
070ffe17
[station]
station_name
=
"Radio FRO"
station_logo
=
"/etc/aura/stationlogo.jpg"
station_fallback_pool
=
"/var/audio/station_fallback_pool"
[user]
#Change this settings
daemongroup
=
"gg"
daemonuser
=
"gg"
[configfile]
scheduler_config_file
=
"/etc/aura/scheduler.xml"
# SOUND CARD SETTINGS
[soundcard]
line_in_count
=
1
line_out_count
=
1
input_device
[0]
="hw:0"
# make it comma separated!!
output_device
[0]
="hw:0"
# DATABASE SETTINGS
db_user
=
"aura"
db_name
=
"aura"
db_pass
=
"aura"
db_host
=
"localhost"
# ALSA SETTINGS
# if you have no idea what to do here => set use_alsa to "n", then pulseaudio is used
use_alsa
=
"y"
# alsa_buffer => int
alsa_buffer
=
"16000"
...
...
@@ -34,39 +28,25 @@ frame_duration="0.4"
# frame_size => int
frame_size
=
""
[database]
db_user
=
"aura"
db_name
=
"aura"
db_pass
=
"aura"
db_host
=
"localhost"
[socket]
socketdir
=
"/home/gg/PycharmProjects/engine/modules/liquidsoap"
[logging]
logdir
=
"/var/log/aura"
# possible values: debug, info, warning, error, critical
loglevel
=
"info"
# channelnames for mixing
[liquidsoap]
# leave this alone if you do not know what you are doing
http_channels
=
"http,http2"
line_in_channels
=
"live,live2"
filesystem_channels
=
"filesystem"
adminmail
=
"gogo@servus.at"
playlistdir
=
"/var/audio/playlists/"
#calendarurl="http://localhost/index.php?option=com_jimtawl&view=calendar&format=json&from=#datefrom#&to=#dateto#"
#calendarurl="http://bermudafunk-kalender.critmass.de/index.php?option=com_jimtawl&view=calendar&format=json&from=#datefrom#&to=#dateto#"
calendarurl
=
"http://localhost:8000/api/v1/playout"
importerurl
=
""
# how many days in future should the calendar be stored in database - default=7
#calendar_precache_days=7
audiobase
=
"/var/audio/rec"
altaudiobase
=
"/var/audio/preprod"
# hardware settings
# SOUNDCARD FROM STWST:
# HOME CARD
# was player_input_device:
# recinput="soundcard"
# altrecinput="soundcard"
# altrecorder_device="soundcard"
# recorder_device="soundcard"
# track_sensitive => fallback_folder track sensitivity
# max_blank => maximum time of blank from source
# min_noise => minimum duration of noise on source to switch back over
...
...
@@ -75,6 +55,27 @@ fallback_max_blank="5"
fallback_min_noise
=
"30"
fallback_threshold
=
"-40"
[mail]
mail_server
=
"mail.servus.at"
mail_user
=
"m_gottfried"
mail_pass
=
"n0idontw4ntthi5"
# multiple adminmails => space separated
admin_mail
=
"gogo@servus.at gottfried@servus.at"
from_mail
=
"engine@au.ra"
[dataurls]
# calendarurl="http://localhost/index.php?option=com_jimtawl&view=calendar&format=json&from=#datefrom#&to=#dateto#"
# calendarurl="http://bermudafunk-kalender.critmass.de/index.php?option=com_jimtawl&view=calendar&format=json&from=#datefrom#&to=#dateto#"
calendarurl
=
"http://localhost:8000/api/v1/playout"
importerurl
=
""
[folder]
audiobase
=
"/var/audio/rec"
altaudiobase
=
"/var/audio/preprod"
playlistdir
=
"/var/audio/playlists/"
install_dir
=
"/home/gg/PycharmProjects/engine"
[stream]
stream
=
"y"
stream_type
=
"harbor"
#stream_type="icecast"
...
...
@@ -90,16 +91,3 @@ stream_genre="mixed"
stream_description
=
"Test Stream"
stream_admin_user
=
"admin"
stream_admin_password
=
"ahZ4caeg"
# ZeroMessagingQueue SETTINGS
communication
=
"zmq"
zmqhostip
=
"127.0.0.1"
zmqport
=
"9099"
loglevel
=
"info"
webservice_mode
=
"apache"
#servername=""
#serviceport=""
install_dir
=
"/home/gg/PycharmProjects/engine"
debug
=
"y"
guru.py
View file @
070ffe17
...
...
@@ -7,77 +7,24 @@ import redis
from
argparse
import
ArgumentParser
# own libs
from
libraries.base.config
import
ConfigReader
from
modules.tools.padavan
import
Padavan
from
modules.cli_tool.padavan
import
Padavan
from
libraries.exceptions.auraexceptions
import
PlaylistException
from
libraries.base.common
import
AuraCommon
class
Guru
:
config
=
ConfigReader
()
config
.
loadConfig
()
class
Guru
(
AuraCommon
):
# ------------------------------------------------------------------------------------------ #
def
__init__
(
self
):
try
:
parser
=
ArgumentParser
()
# options
parser
.
add_argument
(
"-sep"
,
"--stop-execution-time"
,
action
=
"store_true"
,
dest
=
"stoptime"
,
default
=
False
,
help
=
"Prints the execution time at the end of the skript"
)
parser
.
add_argument
(
"-q"
,
"--quiet"
,
action
=
"store_true"
,
dest
=
"quiet"
,
default
=
False
,
help
=
"Just the result will outputed to stout"
)
# getter
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
=
"get_mixer_status"
,
default
=
False
,
help
=
"Prints all mixer sources and their states"
)
parser
.
add_argument
(
"-pap"
,
"--print-act-programme"
,
action
=
"store_true"
,
dest
=
"get_act_programme"
,
default
=
False
,
help
=
"Prints the actual Programme, the controller holds"
)
# liquid manipulation
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
=
"deselect_mixer"
,
default
=-
1
,
metavar
=
"MIXERNUM"
,
help
=
"Which mixer should be activated?"
,
type
=
int
)
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="add_source", default=False,
# help="Add new source to LiquidSoap mixer [Experimental]")
# playlist manipulation
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
(
"-spe"
,
"--swap-playlist-entries"
,
action
=
"store"
,
dest
=
"swap_playlist_entries"
,
default
=
0
,
metavar
=
(
"FROM"
,
"TO"
),
nargs
=
2
,
help
=
"Swaps two Playlistentries"
)
parser
.
add_argument
(
"-dpe"
,
"--delete-playlist-entry"
,
action
=
"store"
,
dest
=
"delete_playlist_entry"
,
default
=
0
,
metavar
=
"INDEX"
,
help
=
"Delete Playlistentry at INDEX"
)
parser
.
add_argument
(
"-ipe"
,
"--insert-playlist-entry"
,
action
=
"store"
,
dest
=
"insert_playlist_entry"
,
default
=
0
,
metavar
=
(
"FROMTIME"
,
"SOURCE"
),
nargs
=
2
,
help
=
"Add a new Playlistentry at a given index. Set fromtime with this format: 2017-12-31T13:30:00"
)
# , type=valid_playlist_entry)
parser
.
add_argument
(
"-pmq"
,
"--print-message-queue"
,
action
=
"store_true"
,
dest
=
"print_message_queue"
,
default
=
False
,
help
=
"Prints message queue"
)
# send a redis message
parser
.
add_argument
(
"-rm"
,
"--redis-message"
,
action
=
"store"
,
dest
=
"redis_message"
,
default
=
False
,
metavar
=
(
"CHANNEL"
,
"MESSAGE"
),
nargs
=
2
,
help
=
"Send a redis message to the Listeners"
)
# calls from liquidsoap
parser
.
add_argument
(
"-gnf"
,
"--get-next-file-for"
,
action
=
"store"
,
dest
=
"get_file_for"
,
default
=
False
,
metavar
=
"PLAYLISTTYPE"
,
help
=
"For which type you wanna GET a next audio file?"
)
parser
.
add_argument
(
"-snf"
,
"--set-next-file-for"
,
action
=
"store"
,
dest
=
"set_file_for"
,
default
=
False
,
metavar
=
(
"PLAYLISTTYPE"
,
"FILE"
),
nargs
=
2
,
help
=
"For which type you wanna SET a next audio file?"
)
parser
.
add_argument
(
"-np"
,
"--now-playing"
,
action
=
"store"
,
dest
=
"now_playing"
,
default
=
False
,
metavar
=
"NOWPLAYINGSOURCE"
,
help
=
"Which source is now playing"
)
parser
.
add_argument
(
"-ip"
,
"--init-player"
,
action
=
"store_true"
,
dest
=
"init_player"
,
default
=
False
,
help
=
"Reset liquidsoap volume and mixer activations?"
)
AuraCommon
.
__init__
(
self
,
name
=
"AuraGuru"
)
args
=
parser
.
parse_args
()
self
.
create_parser
()
self
.
init_argument_parser
()
if
len
(
sys
.
argv
)
==
1
:
raise
ValueError
(
"No Argument passed!"
)
def
init_argument_parser
(
self
):
try
:
parser
=
self
.
create_parser
()
args
=
parser
.
parse_args
()
except
ValueError
as
e
:
parser
.
print_help
()
...
...
@@ -124,10 +71,81 @@ class Guru:
exectime
=
end
-
start
print
(
"execution time: "
+
str
(
exectime
)
+
"s"
)
def
create_parser
(
self
):
parser
=
ArgumentParser
()
# options
parser
.
add_argument
(
"-sep"
,
"--stop-execution-time"
,
action
=
"store_true"
,
dest
=
"stoptime"
,
default
=
False
,
help
=
"Prints the execution time at the end of the skript"
)
parser
.
add_argument
(
"-q"
,
"--quiet"
,
action
=
"store_true"
,
dest
=
"quiet"
,
default
=
False
,
help
=
"Just the result will outputed to stout"
)
# getter
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
=
"get_mixer_status"
,
default
=
False
,
help
=
"Prints all mixer sources and their states"
)
parser
.
add_argument
(
"-pap"
,
"--print-act-programme"
,
action
=
"store_true"
,
dest
=
"get_act_programme"
,
default
=
False
,
help
=
"Prints the actual Programme, the controller holds"
)
# liquid manipulation
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
=
"deselect_mixer"
,
default
=-
1
,
metavar
=
"MIXERNUM"
,
help
=
"Which mixer should be activated?"
,
type
=
int
)
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="add_source", default=False,
# help="Add new source to LiquidSoap mixer [Experimental]")
# playlist manipulation
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
(
"-spe"
,
"--swap-playlist-entries"
,
action
=
"store"
,
dest
=
"swap_playlist_entries"
,
default
=
0
,
metavar
=
(
"FROM"
,
"TO"
),
nargs
=
2
,
help
=
"Swaps two Playlistentries"
)
parser
.
add_argument
(
"-dpe"
,
"--delete-playlist-entry"
,
action
=
"store"
,
dest
=
"delete_playlist_entry"
,
default
=
0
,
metavar
=
"INDEX"
,
help
=
"Delete Playlistentry at INDEX"
)
parser
.
add_argument
(
"-ipe"
,
"--insert-playlist-entry"
,
action
=
"store"
,
dest
=
"insert_playlist_entry"
,
default
=
0
,
metavar
=
(
"FROMTIME"
,
"SOURCE"
),
nargs
=
2
,
help
=
"Add a new Playlistentry at a given index. Set fromtime with this format: 2017-12-31T13:30:00"
)
# , type=valid_playlist_entry)
parser
.
add_argument
(
"-pmq"
,
"--print-message-queue"
,
action
=
"store_true"
,
dest
=
"print_message_queue"
,
default
=
False
,
help
=
"Prints message queue"
)
# send a redis message
parser
.
add_argument
(
"-rm"
,
"--redis-message"
,
action
=
"store"
,
dest
=
"redis_message"
,
default
=
False
,
metavar
=
(
"CHANNEL"
,
"MESSAGE"
),
nargs
=
2
,
help
=
"Send a redis message to the Listeners"
)
# calls from liquidsoap
parser
.
add_argument
(
"-gnf"
,
"--get-next-file-for"
,
action
=
"store"
,
dest
=
"get_file_for"
,
default
=
False
,
metavar
=
"PLAYLISTTYPE"
,
help
=
"For which type you wanna GET a next audio file?"
)
parser
.
add_argument
(
"-snf"
,
"--set-next-file-for"
,
action
=
"store"
,
dest
=
"set_file_for"
,
default
=
False
,
metavar
=
(
"PLAYLISTTYPE"
,
"FILE"
),
nargs
=
2
,
help
=
"For which type you wanna SET a next audio file?"
)
parser
.
add_argument
(
"-np"
,
"--now-playing"
,
action
=
"store_true"
,
dest
=
"now_playing"
,
default
=
False
,
help
=
"Which source is now playing"
)
parser
.
add_argument
(
"-ip"
,
"--init-player"
,
action
=
"store_true"
,
dest
=
"init_player"
,
default
=
False
,
help
=
"Reset liquidsoap volume and mixer activations?"
)
if
len
(
sys
.
argv
)
==
1
:
raise
ValueError
(
"No Argument passed!"
)
return
parser
def
valid_playlist_entry
(
argument
):
from
datetime
import
datetime
import
argparse
try
:
...
...
libraries/base/__pycache__/common.cpython-35.pyc
0 → 100644
View file @
070ffe17
File added
libraries/base/common.py
0 → 100644
View file @
070ffe17
import
logging
from
modules.base.config
import
ConfigReader
class
AuraCommon
:
logger
=
None
config
=
None
def
__init__
(
self
,
name
):
self
.
read_config
()
self
.
create_logger
(
name
)
def
read_config
(
self
):
self
.
config
=
ConfigReader
()
self
.
config
.
load_config
()
def
create_logger
(
self
,
name
):
lvl
=
self
.
config
.
get
(
"loglevel"
)
# create logger
self
.
logger
=
logging
.
getLogger
(
name
)
self
.
logger
.
setLevel
(
lvl
)
fh
=
logging
.
FileHandler
(
self
.
config
.
get
(
"logdir"
)
+
"/aura.log"
)
fh
.
setLevel
(
lvl
)
ch
=
logging
.
StreamHandler
()
ch
.
setLevel
(
lvl
)
formatter
=
logging
.
Formatter
(
"%(asctime)s:%(name)s:%(levelname)s - %(message)s - [%(filename)s:%(lineno)s-%(funcName)s()]"
)
fh
.
setFormatter
(
formatter
)
ch
.
setFormatter
(
formatter
)
self
.
logger
.
addHandler
(
fh
)
self
.
logger
.
addHandler
(
ch
)
\ No newline at end of file
libraries/base/schedulerconfig.py
deleted
100644 → 0
View file @
0a8175ac
from
xml.dom.minidom
import
parse
import
datetime
from
datetime
import
timedelta
import
simplejson
from
xml.etree
import
ElementTree
class
NotTextNodeError
(
BaseException
):
pass
class
AuraSchedulerConfig
():
def
__init__
(
self
,
xmlpath
):
self
.
jobs
=
{}
self
.
filename
=
xmlpath
self
.
playperiods
=
[]
self
.
recordperiods
=
[]
self
.
hasinstance
=
False
self
.
until
=
None
# -----------------------------------------------------------------------#
def
getPlayPeriods
(
self
):
if
not
self
.
hasinstance
:
self
.
getJobs
()
return
self
.
playperiods
# -----------------------------------------------------------------------#
def
getRecordPeriods
(
self
):
if
not
self
.
hasinstance
:
self
.
getJobs
()
return
self
.
recordperiods
# -----------------------------------------------------------------------#
def
getJobs
(
self
):
self
.
hasinstance
=
True
self
.
loadXml
()
for
job
in
self
.
jobs
:
if
'job'
not
in
job
:
continue
;
if
'until'
not
in
job
:
job
[
'until'
]
=
''
if
'day'
not
in
job
:
job
[
'day'
]
=
'all'
# self.jobs.sort(cmp=lambda x,y: cmp(x['time'], y['time']))
# self.jobs.sort(cmp=lambda x,y: cmp(x['day'], y['day']))
self
.
jobs
.
sort
(
key
=
lambda
job
:
job
[
'time'
])
self
.
jobs
.
sort
(
key
=
lambda
job
:
job
[
'day'
])
for
index
,
job
in
enumerate
(
self
.
jobs
):
if
job
[
'job'
]
==
'play_playlist'
:
job
[
'duration'
]
=
self
.
_calcDuration
(
job
[
'time'
],
job
[
'until'
])
self
.
playperiods
.
append
({
'from'
:
job
[
'time'
],
'until'
:
job
[
'until'
],
'duration'
:
job
[
'duration'
]})
day
=
None
if
'day'
in
job
:
day
=
job
[
'day'
]
self
.
addPlaylistLoadJob
(
job
[
'time'
],
job
[
'until'
],
day
)
if
job
[
'job'
]
==
'start_recording'
:
job
[
'duration'
]
=
self
.
_calcDuration
(
job
[
'time'
],
job
[
'until'
])
self
.
recordperiods
.
append
({
'from'
:
job
[
'time'
],
'until'
:
job
[
'until'
],
'duration'
:
job
[
'duration'
]})
return
self
.
jobs
# -----------------------------------------------------------------------#
def
addPlaylistLoadJob
(
self
,
playTime
,
untilTime
,
day
=
None
):
job
=
{}
playStart
=
datetime
.
datetime
.
strptime
(
'1901-01-01T'
+
playTime
,
'%Y-%m-%dT%H:%M'
);
loadTime
=
playStart
-
timedelta
(
minutes
=
3
)
loadTime
=
loadTime
.
strftime
(
'%H:%M'
)
job
[
'time'
]
=
loadTime
job
[
'from'
]
=
playTime
job
[
'until'
]
=
untilTime
job
[
'job'
]
=
'load_playlist'
if
day
and
not
day
==
'all'
and
loadTime
>
playTime
:
day
=
int
(
day
)
day
=
6
if
day
==
0
else
day
-
1
job
[
'day'
]
=
str
(
day
)
self
.
jobs
.
append
(
job
)
# -----------------------------------------------------------------------#
def
storeJsonToXml
(
self
,
json
):
try
:
jobs
=
simplejson
.
loads
(
json
)
except
:
return
False
xml
=
'<?xml version="1.0" encoding="UTF-8"?>'
+
"
\n
"
xml
+=
'<Config>'
+
"
\n
"
;
xml
+=
' <Jobs multiple="true">'
+
"
\n
"
;
xmlend
=
' </Jobs>'
+
"
\n
"
;
xmlend
+=
'</Config>'
;
for
job
in
jobs
:
xml
+=
' <job>'
+
"
\n
"
;
for
key
in
job
.
keys
():
xml
+=
' <'
+
key
+
'>'
+
str
(
job
[
key
])
+
'</'
+
key
+
'>'
+
"
\n
"
if
not
job
.
has_key
(
'params'
):
xml
+=
' <params></params>'
+
"
\n
"
if
not
job
.
has_key
(
'day'
):
xml
+=
' <day>all</day>'
+
"
\n
"
xml
+=
' </job>'
+
"
\n
"
# validate xml
try
:
x
=
ElementTree
.
fromstring
(
xml
+
xmlend
)
except
:
return
False
else
:
try
:
file
=
open
(
self
.
filename
,
"w"
)
file
.
write
(
xml
+
xmlend
)
file
.
close
()
except
:
return
False
else
:
return
True
# -----------------------------------------------------------------------#
def
loadXml
(
self
):
dom
=
parse
(
self
.
filename
)
config
=
self
.
nodeToDic
(
dom
)
self
.
jobs
=
config
[
'Config'
][
'Jobs'
]
# -----------------------------------------------------------------------#
def
getTextFromNode
(
self
,
node
):
t
=
""
for
n
in
node
.
childNodes
:
if
n
.
nodeType
==
n
.
TEXT_NODE
:
t
+=
n
.
nodeValue
else
:
raise
NotTextNodeError
return
t
# -----------------------------------------------------------------------#
def
nodeToDic
(
self
,
node
):
dic
=
{}
for
n
in
node
.
childNodes
:
if
n
.
nodeType
!=
n
.
ELEMENT_NODE
:
continue
if
n
.
getAttribute
(
"multiple"
)
==
"true"
:
# node with multiple children:
# put them in a list
l
=
[]
for
c
in
n
.
childNodes
:
if
c
.
nodeType
!=
n
.
ELEMENT_NODE
:
continue
l
.
append
(
self
.
nodeToDic
(
c
))
dic
.
update
({
n
.
nodeName
:
l
})
continue
try
:
text
=
self
.
getTextFromNode
(
n
)
except
NotTextNodeError
:
# 'normal' node
dic
.
update
({
str
(
n
.
nodeName
):
self
.
nodeToDic
(
n
)})
continue
# text node
dic
.
update
({
str
(
n
.
nodeName
):
str
(
text
)})
continue
return
dic
# -----------------------------------------------------------------------#
def
in_timeperiod
(
self
,
now
,
job
):
if
'until'
not
in
job
or
not
job
[
'until'
]:
print
(
"not in timeperiod"
)
return
False
(
hour1
,
minute1
)
=
job
[
'time'
].
split
(
':'
)
(
hour2
,
minute2
)
=
job
[
'until'
].
split
(
':'
)
if
job
[
'time'
]
>
job
[
'until'
]:
print
(
"in time period. time greater than until"
)
return
datetime
.
time
(
hour
=
int
(
hour1
),
minute
=
int
(
minute1
))
\
<=
now
.
time
()
else
:
print
(
"in time period. until greater than time"
)
return
datetime
.
time
(
hour
=
int
(
hour1
),
minute
=
int
(
minute1
))
\
<=
now
.
time
()
\
<=
datetime
.
time
(
hour
=
int
(
hour2
),
minute
=
int
(
minute2
))
# -----------------------------------------------------------------------#
def
_calcDuration
(
self
,
timestring1
,
timestring2
):
"""Berechnet Zeit in Sekunden aus zwei Time-Strings
"""
ftr
=
[
3600
,
60
,
1
]
sec1
=
sum
([
a
*
b
for
a
,
b
in
zip
(
ftr
,
map
(
int
,
timestring1
.
split
(
':'
)))])
sec2
=
sum
([
a
*
b
for
a
,
b
in
zip
(
ftr
,
map
(
int
,
timestring2
.
split
(
':'
)))])
offset
=
0
if
sec2
>
sec1
else
86400
return
(
sec2
+
offset
)
-
sec1
# -----------------------------------------------------------------------#