guru.py 7.49 KB
Newer Older
1
#!/usr/bin/env python3.7
2

3
#
David Trattnig's avatar
David Trattnig committed
4
# Aura Engine (https://gitlab.servus.at/aura/engine)
5
#
David Trattnig's avatar
David Trattnig committed
6
# Copyright (C) 2017-2020 - The Aura Engine Team.
7
#
David Trattnig's avatar
David Trattnig committed
8
9
10
11
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
12
#
David Trattnig's avatar
David Trattnig committed
13
14
15
16
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
17
#
David Trattnig's avatar
David Trattnig committed
18
19
20
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

21

22
import time
23
import sys
24
import redis
25

David Trattnig's avatar
David Trattnig committed
26
from pathlib import Path
27
28
from argparse import ArgumentParser

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
29
# own libs
30
from modules.cli_tool.padavan import Padavan
31
from modules.base.exceptions import PlaylistException
David Trattnig's avatar
David Trattnig committed
32
from modules.base.config import AuraConfig
33

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
34

David Trattnig's avatar
David Trattnig committed
35
class Guru():
David Trattnig's avatar
David Trattnig committed
36
37
38
    """
        Command Line Interface (CLI) for Aura Engine.
    """
39
40
    # config_path = "%s/configuration/engine.ini" % Path(__file__).parent.absolute()
    config = AuraConfig()
41
42
    parser = None
    args = None
43

44
    # ------------------------------------------------------------------------------------------ #
45
    def __init__(self):
46
47
        self.init_argument_parser()
        self.handle_arguments()
48

49
50
    def handle_arguments(self):
        if self.args.stoptime:
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
51
52
            start = time.time()

53
        if not self.args.quiet:
54
            print("Guru thinking...")
55

56
        try:
57
            p = Padavan(self.args, self.config)
58
            p.meditate()
59
60
        except PlaylistException as pe:
            # typically there is no next file found
61
            if not self.args.quiet:
62
63
64
                print(pe)
            else:
                print("")
65
            exit(4)
David Trattnig's avatar
David Trattnig committed
66
        except redis.exceptions.TimeoutError:
67
68
69
            print("Timeout when waiting for redis message. Is AURA daemon running? Exiting...")
            exit(3)

70
        if not self.args.quiet:
71
            print("...result: ")
72

73
        if p.stringreply != "":
74
            #print(p.stringreply)
75
76
77
78
            if p.stringreply[len(p.stringreply)-1] == "\n":
                print(p.stringreply[0:len(p.stringreply) - 1])
            else:
                print(p.stringreply[0:len(p.stringreply)])
79

80
        if self.args.stoptime:
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
81
82
83
84
            end = time.time()
            exectime = end-start
            print("execution time: "+str(exectime)+"s")

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
85
    def init_argument_parser(self):
86

Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
87
        try:
88
89
            self.create_parser()
            self.args = self.parser.parse_args()
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
90

91
92
93
        except (ValueError, TypeError) as e:
            if self.parser is not None:
                self.parser.print_help()
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
94
95
96
97
            print()
            print(e)
            exit(1)

98
    def create_parser(self):
99
        self.parser = ArgumentParser()
100
101

        # options
102
103
104
        self.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")
        self.parser.add_argument("-q",   "--quiet",               action="store_true", dest="quiet",      default=False, help="Just the result will outputed to stout")
        self.parser.add_argument("-rd",  "--recreate-database",   action="store_true", dest="recreatedb", default=False, help="Do you want to recreate the database?")
105
106

        # getter
107
        self.parser.add_argument("-pcs", "--print-connection-status", action="store_true", dest="get_connection_status",  default=False, help="Prints the status of the connection to liquidsoap, pv and tank")
David Trattnig's avatar
David Trattnig committed
108
109
        self.parser.add_argument("-gam", "--get-active-mixer",        action="store_true", dest="mixer_channels_selected",default=False, help="Which mixer channels are selected?")
        self.parser.add_argument("-pms", "--print-mixer-status",      action="store_true", dest="mixer_status",           default=False, help="Prints all mixer sources and their states")
110
        self.parser.add_argument("-pap", "--print-act-programme",     action="store_true", dest="get_act_programme",      default=False, help="Prints the actual Programme, the controller holds")
David Trattnig's avatar
David Trattnig committed
111
        self.parser.add_argument("-s",   "--status",                  action="store_true", dest="get_status",             default=False, help="Returns the Engine Status as JSON")
112
113

        # liquid manipulation
114
115
116
        self.parser.add_argument("-am", "--select-mixer",    action="store", dest="select_mixer",   default=-1, metavar="MIXERNAME",                     help="Which mixer should be activated?")
        self.parser.add_argument("-dm", "--de-select-mixer", action="store", dest="deselect_mixer", default=-1, metavar="MIXERNAME",                     help="Which mixer should be activated?")
        self.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)
117

118
119
        # shutdown server
        self.parser.add_argument("-sd", "--shutdown", action="store_true", dest="shutdown", default=False, help="Shutting down aura server")
120

121
        # playlist in/output
122
        self.parser.add_argument("-fnp", "--fetch-new-programmes",  action="store_true", dest="fetch_new_programme",   default=False, help="Fetch new programmes from api_steering_calendar in engine.ini")
123
124
        self.parser.add_argument("-pmq", "--print-message-queue",   action="store_true", dest="print_message_queue",   default=False, help="Prints message queue")

125
        # send a redis message
126
        self.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")
127
128

        # calls from liquidsoap
129
130
131
        self.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?")
        self.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?")
        self.parser.add_argument("-np",  "--now-playing",       action="store_true", dest="now_playing",  default=False,                                              help="Which source is now playing")
132
        
133
        self.parser.add_argument("-ip",  "--init-player",       action="store_true", dest="init_player",  default=False,                                              help="Reset liquidsoap volume and mixer activations?")
134
        self.parser.add_argument("-ts",  "--on_play",           action="store",      dest="on_play",      default=False, metavar="INFO",                              help="Event handling when some entry started playing")
135
136
137
138

        if len(sys.argv) == 1:
            raise ValueError("No Argument passed!")

139

140
def valid_playlist_entry(argument):
141
    from datetime import datetime
142
143

    try:
144

145
146
147
148
149
150
        index = int(argument[0])
        fromtime = datetime.strptime(argument[1], "%Y-%m-%d")
        source = argument[2]
        return index, fromtime, source
    except:
        msg = "Not a valid date: '{0}'.".format(argument[0])
David Trattnig's avatar
David Trattnig committed
151
        print(msg)
152
        raise
153
154


155
156
157
158
# # ## ## ## ## ## # #
# # ENTRY FUNCTION # #
# # ## ## ## ## ## # #
def main():
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
159
    Guru()
160
161
162
163
# # ## ## ## ## ## ## # #
# # End ENTRY FUNCTION # #
# # ## ## ## ## ## ## # #

164

165
166
if __name__ == "__main__":
    main()