Пример #1
0
def start_web_interface(addr, port):
    global formatter
    import interface

    # setup logger
    werkzeug_logger = logging.getLogger('werkzeug')
    logfile = util.solve_filepath(var.config.get('webinterface', 'web_logfile'))
    if logfile:
        handler = logging.handlers.RotatingFileHandler(logfile, mode='a', maxBytes=10240)  # Rotate after 10KB
    else:
        handler = logging.StreamHandler()

    werkzeug_logger.addHandler(handler)

    interface.init_proxy()
    interface.web.env = 'development'
    interface.web.run(port=port, host=addr)
Пример #2
0
    def __init__(self, args):
        self.log = logging.getLogger("bot")
        self.log.info(f"bot: botamusique version {self.get_version()}, starting...")
        signal.signal(signal.SIGINT, self.ctrl_caught)
        self.cmd_handle = {}

        self.stereo = var.config.getboolean('bot', 'stereo', fallback=True)

        if args.channel:
            self.channel = args.channel
        else:
            self.channel = var.config.get("server", "channel", fallback=None)

        var.user = args.user
        var.is_proxified = var.config.getboolean(
            "webinterface", "is_web_proxified")

        # Flags to indicate the bot is exiting (Ctrl-C, or !kill)
        self.exit = False
        self.nb_exit = 0

        # Related to ffmpeg thread
        self.thread = None
        self.thread_stderr = None
        self.read_pcm_size = 0
        self.pcm_buffer_size = 0
        self.last_ffmpeg_err = ""

        # Play/pause status
        self.is_pause = False
        self.pause_at_id = ""
        self.playhead = -1  # current position in a song.
        self.song_start_at = -1
        self.wait_for_ready = False  # flag for the loop are waiting for download to complete in the other thread

        #
        self.on_interrupting = False

        if args.host:
            host = args.host
        else:
            host = var.config.get("server", "host")

        if args.port:
            port = args.port
        else:
            port = var.config.getint("server", "port")

        if args.password:
            password = args.password
        else:
            password = var.config.get("server", "password")

        if args.channel:
            self.channel = args.channel
        else:
            self.channel = var.config.get("server", "channel")

        if args.certificate:
            certificate = args.certificate
        else:
            certificate = util.solve_filepath(var.config.get("server", "certificate"))

        if args.tokens:
            tokens = args.tokens
        else:
            tokens = var.config.get("server", "tokens")
            tokens = tokens.split(',')

        if args.user:
            self.username = args.user
        else:
            self.username = var.config.get("bot", "username")

        if args.bandwidth:
            self.bandwidth = args.bandwidth
        else:
            self.bandwidth = var.config.getint("bot", "bandwidth")

        self.mumble = pymumble.Mumble(host, user=self.username, port=port, password=password, tokens=tokens,
                                      stereo=self.stereo,
                                      debug=var.config.getboolean('debug', 'mumbleConnection'),
                                      certfile=certificate)
        self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_TEXTMESSAGERECEIVED, self.message_received)

        self.mumble.set_codec_profile("audio")
        self.mumble.start()  # start the mumble thread
        self.mumble.is_ready()  # wait for the connection

        if self.mumble.connected >= pymumble.constants.PYMUMBLE_CONN_STATE_FAILED:
            exit()

        self.set_comment()
        self.mumble.users.myself.unmute()  # by sure the user is not muted
        self.join_channel()
        self.mumble.set_bandwidth(self.bandwidth)

        # ====== Volume ======
        self.volume_helper = util.VolumeHelper()

        _volume = var.config.getfloat('bot', 'volume', fallback=0.8)
        if var.db.has_option('bot', 'volume'):
            _volume = var.db.getfloat('bot', 'volume')
        self.volume_helper.set_volume(_volume)

        self.is_ducking = False
        self.on_ducking = False
        self.ducking_release = time.time()
        self.last_volume_cycle_time = time.time()

        self._ducking_volume = 0
        _ducking_volume = var.config.getfloat("bot", "ducking_volume", fallback=0.50)
        _ducking_volume = var.db.getfloat("bot", "ducking_volume", fallback=_ducking_volume)
        self.volume_helper.set_ducking_volume(_ducking_volume)

        self.ducking_threshold = var.config.getfloat("bot", "ducking_threshold", fallback=5000)
        self.ducking_threshold = var.db.getfloat("bot", "ducking_threshold", fallback=self.ducking_threshold)

        if not var.db.has_option("bot", "ducking") and var.config.getboolean("bot", "ducking", fallback=False) \
                or var.config.getboolean("bot", "ducking"):
            self.is_ducking = True
            self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_SOUNDRECEIVED,
                                               self.ducking_sound_received)
            self.mumble.set_receive_sound(True)

        assert var.config.get("bot", "when_nobody_in_channel") in ['pause', 'pause_resume', 'stop', 'nothing', ''], \
            "Unknown action for when_nobody_in_channel"

        if var.config.get("bot", "when_nobody_in_channel", fallback='') in ['pause', 'pause_resume', 'stop']:
            user_change_callback = \
                lambda user, action: threading.Thread(target=self.users_changed,
                                                      args=(user, action), daemon=True).start()
            self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_USERREMOVED, user_change_callback)
            self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_USERUPDATED, user_change_callback)

        # Debug use
        self._loop_status = 'Idle'
        self._display_rms = False
        self._max_rms = 0

        self.redirect_ffmpeg_log = var.config.getboolean('debug', 'redirect_ffmpeg_log', fallback=True)

        if var.config.getboolean("bot", "auto_check_update"):
            def check_update():
                nonlocal self
                new_version, changelog = util.check_update(self.get_version())
                if new_version:
                    self.send_channel_msg(tr('new_version_found', new_version=new_version, changelog=changelog))

            th = threading.Thread(target=check_update, name="UpdateThread")
            th.daemon = True
            th.start()

        last_startup_version = var.db.get("bot", "version", fallback=None)
        if not last_startup_version or version.parse(last_startup_version) < version.parse(self.version):
            var.db.set("bot", "version", self.version)
            if var.config.getboolean("bot", "auto_check_update"):
                changelog = util.fetch_changelog()
                self.send_channel_msg(tr("update_successful", version=self.version, changelog=changelog))
Пример #3
0
    parser.add_argument("-c", "--channel", dest="channel",
                        type=str, help="Default channel for the bot")
    parser.add_argument("-C", "--cert", dest="certificate",
                        type=str, default=None, help="Certificate file")
    parser.add_argument("-b", "--bandwidth", dest="bandwidth",
                        type=int, help="Bandwidth used by the bot")

    args = parser.parse_args()

    # ======================
    #     Load Config
    # ======================

    config = configparser.ConfigParser(interpolation=None, allow_no_value=True)
    var.config = config
    parsed_configs = config.read([util.solve_filepath('configuration.default.ini'), util.solve_filepath(args.config)],
                                 encoding='utf-8')
    if len(parsed_configs) == 0:
        logging.error('Could not read configuration from file \"{}\"'.format(args.config))
        sys.exit()

    # ======================
    #     Setup Logger
    # ======================

    bot_logger = logging.getLogger("bot")
    bot_logger.setLevel(logging.INFO)

    if args.verbose:
        bot_logger.setLevel(logging.DEBUG)
        bot_logger.debug("Starting in DEBUG loglevel")
Пример #4
0
    def __init__(self, args):
        self.log = logging.getLogger("bot")
        self.log.info("bot: botamusique version %s, starting..." %
                      self.version)
        signal.signal(signal.SIGINT, self.ctrl_caught)
        self.cmd_handle = {}
        self.volume_set = var.config.getfloat('bot', 'volume')
        if var.db.has_option('bot', 'volume'):
            self.volume_set = var.db.getfloat('bot', 'volume')

        self.volume = self.volume_set

        if args.channel:
            self.channel = args.channel
        else:
            self.channel = var.config.get("server", "channel", fallback=None)

        var.user = args.user
        var.music_folder = util.solve_filepath(
            var.config.get('bot', 'music_folder'))
        var.tmp_folder = util.solve_filepath(
            var.config.get('bot', 'tmp_folder'))
        var.is_proxified = var.config.getboolean("webinterface",
                                                 "is_web_proxified")
        self.exit = False
        self.nb_exit = 0
        self.thread = None
        self.thread_stderr = None
        self.is_pause = False
        self.pause_at_id = ""
        self.playhead = -1
        self.song_start_at = -1
        self.last_ffmpeg_err = ""
        self.read_pcm_size = 0
        # self.download_threads = []
        self.wait_for_ready = False  # flag for the loop are waiting for download to complete in the other thread
        self.on_killing = threading.Lock(
        )  # lock to acquire when killing ffmpeg thread is asked but ffmpeg is not
        # killed yet

        if args.host:
            host = args.host
        else:
            host = var.config.get("server", "host")

        if args.port:
            port = args.port
        else:
            port = var.config.getint("server", "port")

        if args.password:
            password = args.password
        else:
            password = var.config.get("server", "password")

        if args.channel:
            self.channel = args.channel
        else:
            self.channel = var.config.get("server", "channel")

        if args.certificate:
            certificate = args.certificate
        else:
            certificate = util.solve_filepath(
                var.config.get("server", "certificate"))

        if args.tokens:
            tokens = args.tokens
        else:
            tokens = var.config.get("server", "tokens")
            tokens = tokens.split(',')

        if args.user:
            self.username = args.user
        else:
            self.username = var.config.get("bot", "username")

        self.mumble = pymumble.Mumble(host,
                                      user=self.username,
                                      port=port,
                                      password=password,
                                      tokens=tokens,
                                      debug=var.config.getboolean(
                                          'debug', 'mumbleConnection'),
                                      certfile=certificate)
        self.mumble.callbacks.set_callback(
            pymumble.constants.PYMUMBLE_CLBK_TEXTMESSAGERECEIVED,
            self.message_received)

        self.mumble.set_codec_profile("audio")
        self.mumble.start()  # start the mumble thread
        self.mumble.is_ready()  # wait for the connection

        if self.mumble.connected >= pymumble_py3.constants.PYMUMBLE_CONN_STATE_FAILED:
            exit()

        self.set_comment()
        self.mumble.users.myself.unmute()  # by sure the user is not muted
        self.join_channel()
        self.mumble.set_bandwidth(200000)

        self.is_ducking = False
        self.on_ducking = False
        self.ducking_release = time.time()
        self.last_volume_cycle_time = time.time()

        if not var.db.has_option("bot", "ducking") and var.config.getboolean("bot", "ducking", fallback=False) \
                or var.config.getboolean("bot", "ducking"):
            self.is_ducking = True
            self.ducking_volume = var.config.getfloat("bot",
                                                      "ducking_volume",
                                                      fallback=0.05)
            self.ducking_volume = var.db.getfloat("bot",
                                                  "ducking_volume",
                                                  fallback=self.ducking_volume)
            self.ducking_threshold = var.config.getfloat("bot",
                                                         "ducking_threshold",
                                                         fallback=5000)
            self.ducking_threshold = var.db.getfloat(
                "bot", "ducking_threshold", fallback=self.ducking_threshold)
            self.mumble.callbacks.set_callback(
                pymumble.constants.PYMUMBLE_CLBK_SOUNDRECEIVED,
                self.ducking_sound_received)
            self.mumble.set_receive_sound(True)

        assert var.config.get("bot", "when_nobody_in_channel") in ['pause', 'pause_resume', 'stop', 'nothing', ''], \
            "Unknown action for when_nobody_in_channel"

        if var.config.get("bot", "when_nobody_in_channel",
                          fallback='') in ['pause', 'pause_resume', 'stop']:
            self.mumble.callbacks.set_callback(
                pymumble.constants.PYMUMBLE_CLBK_USERREMOVED,
                self.users_changed)
            self.mumble.callbacks.set_callback(
                pymumble.constants.PYMUMBLE_CLBK_USERUPDATED,
                self.users_changed)

        # Debug use
        self._loop_status = 'Idle'
        self._display_rms = False
        self._max_rms = 0

        self.redirect_ffmpeg_log = var.config.getboolean('debug',
                                                         'redirect_ffmpeg_log',
                                                         fallback=True)

        if var.config.getboolean("bot", "auto_check_update"):
            th = threading.Thread(target=self.check_update,
                                  name="UpdateThread")
            th.daemon = True
            th.start()

        last_startup_version = var.db.get("bot", "version", fallback=None)
        if not last_startup_version or version.parse(
                last_startup_version) < version.parse(self.version):
            var.db.set("bot", "version", self.version)
            changelog = util.fetch_changelog().replace("\n", "<br>")
            self.send_channel_msg(
                constants.strings("update_successful",
                                  version=self.version,
                                  changelog=changelog))
Пример #5
0
    def __init__(self, args):
        self.log = logging.getLogger("bot")
        self.log.info("bot: botamusique version %s, starting..." % self.version)
        signal.signal(signal.SIGINT, self.ctrl_caught)
        self.cmd_handle = {}
        self.volume_set = var.config.getfloat('bot', 'volume')
        if var.db.has_option('bot', 'volume'):
            self.volume_set = var.db.getfloat('bot', 'volume')

        self.volume = self.volume_set

        if args.channel:
            self.channel = args.channel
        else:
            self.channel = var.config.get("server", "channel", fallback=None)

        var.user = args.user
        var.music_folder = util.solve_filepath(var.config.get('bot', 'music_folder'))
        var.tmp_folder = util.solve_filepath(var.config.get('bot', 'tmp_folder'))
        var.is_proxified = var.config.getboolean(
            "webinterface", "is_web_proxified")
        self.exit = False
        self.nb_exit = 0
        self.thread = None
        self.thread_stderr = None
        self.is_pause = False
        self.pause_at_id = ""
        self.playhead = -1
        self.song_start_at = -1
        self.last_ffmpeg_err = ""
        self.read_pcm_size = 0
        # self.download_threads = []
        self.wait_for_ready = False  # flag for the loop are waiting for download to complete in the other thread

        if var.config.getboolean("webinterface", "enabled"):
            wi_addr = var.config.get("webinterface", "listening_addr")
            wi_port = var.config.getint("webinterface", "listening_port")
            tt = threading.Thread(
                target=start_web_interface, name="WebThread", args=(wi_addr, wi_port))
            tt.daemon = True
            self.log.info('Starting web interface on {}:{}'.format(wi_addr, wi_port))
            tt.start()

        if var.config.getboolean("bot", "auto_check_update"):
            th = threading.Thread(target=self.check_update, name="UpdateThread")
            th.daemon = True
            th.start()

        if args.host:
            host = args.host
        else:
            host = var.config.get("server", "host")

        if args.port:
            port = args.port
        else:
            port = var.config.getint("server", "port")

        if args.password:
            password = args.password
        else:
            password = var.config.get("server", "password")

        if args.channel:
            self.channel = args.channel
        else:
            self.channel = var.config.get("server", "channel")

        if args.certificate:
            certificate = args.certificate
        else:
            certificate = util.solve_filepath(var.config.get("server", "certificate"))

        if args.tokens:
            tokens = args.tokens
        else:
            tokens = var.config.get("server", "tokens")
            tokens = tokens.split(',')

        if args.user:
            self.username = args.user
        else:
            self.username = var.config.get("bot", "username")

        self.mumble = pymumble.Mumble(host, user=self.username, port=port, password=password, tokens=tokens,
                                      debug=var.config.getboolean('debug', 'mumbleConnection'), certfile=certificate)
        self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_TEXTMESSAGERECEIVED, self.message_received)

        self.mumble.set_codec_profile("audio")
        self.mumble.start()  # start the mumble thread
        self.mumble.is_ready()  # wait for the connection
        self.set_comment()
        self.mumble.users.myself.unmute()  # by sure the user is not muted
        self.join_channel()
        self.mumble.set_bandwidth(200000)

        self.is_ducking = False
        self.on_ducking = False
        self.ducking_release = time.time()

        if not var.db.has_option("bot", "ducking") and var.config.getboolean("bot", "ducking", fallback=False)\
                or var.config.getboolean("bot", "ducking"):
            self.is_ducking = True
            self.ducking_volume = var.config.getfloat("bot", "ducking_volume", fallback=0.05)
            self.ducking_volume = var.db.getfloat("bot", "ducking_volume", fallback=self.ducking_volume)
            self.ducking_threshold = var.config.getfloat("bot", "ducking_threshold", fallback=5000)
            self.ducking_threshold = var.db.getfloat("bot", "ducking_threshold", fallback=self.ducking_threshold)
            self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_SOUNDRECEIVED,
                                               self.ducking_sound_received)
            self.mumble.set_receive_sound(True)

        if var.config.get("bot", "when_nobody_in_channel") not in ['pause', 'pause_resume', 'stop', 'nothing']:
            self.log.warn('Config "when_nobody_in_channel" is not on of "pause", "pause_resume", "stop" or "nothing", falling back to "nothing".')

        if var.config.get("bot", "when_nobody_in_channel", fallback='nothing') in ['pause', 'pause_resume', 'stop']:
            self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_USERREMOVED, self.users_changed)
            self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_USERUPDATED, self.users_changed)
        
        # Debug use
        self._loop_status = 'Idle'
        self._display_rms = False
        self._max_rms = 0

        self.redirect_ffmpeg_log = var.config.getboolean('debug', 'redirect_ffmpeg_log', fallback=True)
Пример #6
0
                        type=str, help="Username for the bot")
    parser.add_argument("-P", "--password", dest="password",
                        type=str, help="Server password, if required")
    parser.add_argument("-T", "--tokens", dest="tokens",
                        type=str, help="Server tokens, if required")
    parser.add_argument("-p", "--port", dest="port",
                        type=int, help="Port for the Mumble server")
    parser.add_argument("-c", "--channel", dest="channel",
                        type=str, help="Default channel for the bot")
    parser.add_argument("-C", "--cert", dest="certificate",
                        type=str, default=None, help="Certificate file")

    args = parser.parse_args()

    config = configparser.ConfigParser(interpolation=None, allow_no_value=True)
    parsed_configs = config.read([util.solve_filepath('configuration.default.ini'), util.solve_filepath(args.config)],
                                 encoding='utf-8')
    var.dbfile = args.db if args.db is not None else util.solve_filepath(
        config.get("bot", "database_path", fallback="database.db"))

    if len(parsed_configs) == 0:
        logging.error('Could not read configuration from file \"{}\"'.format(args.config))
        sys.exit()

    var.config = config
    var.db = SettingsDatabase(var.dbfile)

    # Setup logger
    bot_logger = logging.getLogger("bot")
    formatter = logging.Formatter('[%(asctime)s %(levelname)s %(threadName)s] %(message)s', "%b %d %H:%M:%S")
    bot_logger.setLevel(logging.INFO)