Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • 600a457f86f63a04049ac7db7eea486682619394
  • master par défaut protégée
  • dev-deurstann-3
  • dev-deurstann-2
  • dev-kubat
  • dev-deurstann
  • dev-sting
7 résultats

lkt.js

Blame
  • lkt.js 17,25 Kio
    const logger = require.main.require('./common/logger.js'),
        net = require('net'),
        { finished } = require('stream'),
        { cli } = require('winston/lib/winston/config');
    var config = require.main.require('./common/config.js');
    
    class LktClient {
        /***************************************
         * Not static methods, do not use them *
         ***************************************/
    
        /* The constructor
         * - host: String
         * - port: String
         *
         * Private members
         * - m_socket: net.socket
         *
         * Node: You should not use that directly, prefere the use of static
         * methods */
    
        constructor() {
            this.m_online = false;
            this.m_socket = new net.Socket();
            this.m_closed = true;
            const sockopt = {
                port: config.content.lektord.port,
                host: config.content.lektord.host,
                readable: true,
                writable: true,
            };
    
            logger.debug('lkt', 'Creating the lektor client');
            this.m_socket.setTimeout(3000);
            this.m_socket.setEncoding('utf8');
            this.m_socket.on('timeout', () => {
                logger.error('lkt', `Got timeout while connecting to localhost:${config.content.lektord.port}`);
                this.m_socket.end();
            });
    
            this.m_socket.on('ready', () => {
                logger.debug('lkt', `Ready to use socket with localhost:${config.content.lektord.port}`);
                this.m_online = true;
            });
    
            this.m_socket.on('end', () => {
                logger.info('lkt', `Disconnected from server localhost:${config.content.lektord.port}`);
                this.m_online = false;
            });
    
            this.m_socket.on('error', err => {
                logger.error('lkt', `${err}`);
                if (this.m_online) {
                    this.m_socket.destroy();
                    this.m_online = false;
                }
            });
    
            this.m_socket.on('close', () => {
                logger.info('lkt', `Socket localhost:${config.content.lektord.port} closed`);
                this.m_online = false;
            });
    
            this.m_socket.connect(sockopt, () => {
                logger.info('lkt', `Socket connected to localhost:${config.content.lektord.port}`);
                this.m_online = true;
            });
    
            return this;
        }
    
        /* Close the client.
         * Note: Prefere using the static methods. */
        close() {
            if (this.m_online) {
                logger.debug('lkt', 'Requesting socket shutdown');
                this.m_socket.destroy();
            } else {
                logger.debug('lkt', 'Socket already closed');
            }
            this.m_closed = true;
        }
    
        /*****************************************
         * Static methods, to be used by clients *
         *****************************************/
    
        /* The status command */
        static commandStatus() {
            return this.__execGetResult('status');
        }
    
        /* The current command */
        static commandCurrent() {
            return this.__execGetResult('currentsong');
        }
    
        /* Arguments:
         * - command: The command to execute
         * Result:
         * - A promize with one argument: the dict of the result */
        static __execGetResult(command) {
            var client = new this();
            var once = false;
            var result = {};
            function __getResult(client) {
                return new Promise(resolv => {
                    client.m_socket.setTimeout(0);
                    client.m_socket.on('data', data => {
                        if (!once) {
                            client.m_socket.write(`${command}\n`);
                            once = true;
                            return null;
                        } else {
                            client.close();
                            result = __mpdToObject(data);
                            resolv(result);
                        }
                    });
                });
            }
            return __getResult(client);
        }
    
        /* Arguments:
         * - command: The command to execute
         * Result:
         * - Returns the status of the command */
        static __execSimple(command) {
            var client = new this();
            var once = false;
            var result = {};
            function __getResult(client) {
                return new Promise(resolv => {
                    client.m_socket.on('data', data => {
                        if (!once) {
                            client.m_socket.write(`${command}\n`);
                            once = true;
                            return null;
                        } else {
                            client.close();
                            result = __mpdStatusToBool(data);
                            resolv(result);
                        }
                    });
                });
            }
            return __getResult(client);
        }
    
        static reloadState() {
            LktClient.commandStatus().then(data => {
                LktClient.__status = data;
                LktClient.status_updated = true;
                logger.debug('lkt', `Got update in status ${JSON.stringify(data)}`);
            });
            LktClient.commandCurrent().then(data => {
                LktClient.__current = data;
                LktClient.status_updated = true;
                logger.debug('lkt', `Got update in current ${JSON.stringify(data)}`);
            });
        }
    
        static idleActualisation() {
            var client = new this();
            client.m_socket.setTimeout(0);
            function __getResult(client) {
                return new Promise((resolve, reject) => {
                    client.m_socket.on('data', data => {
                        if (String(data).includes('playlist')) {
                            LktClient.setQueueUpdated(true);
                        }
                        if (String(data).includes(' stored_playlist')) {
                            LktClient.setPlaylistsUpdated(true);
                        }
                        if (String(data).includes('player')) {
                            LktClient.reloadState();
                        }
                        if (String(data).includes('database')) {
                            LktClient.setDBUpdated(true);
                        }
                        client.m_socket.write(`idle\n`);
                        return null;
                    });
                });
            }
            return __getResult(client);
        }
    
        static statusActualisation() {
            var client = new this();
            var dataObj;
            function __getResult(client) {
                return new Promise(resolv => {
                    client.m_socket.setTimeout(0);
                    setInterval(() => client.m_socket.write(`status\n`), 100);
                    client.m_socket.on('data', data => {
                        dataObj = __mpdToObject(data);
                        if (dataObj.elapsed && dataObj.duration && dataObj.state && dataObj.song) {
                            LktClient.setSongTimeData(
                                parseInt(dataObj.elapsed, 10),
                                parseInt(dataObj.duration, 10),
                                dataObj.state,
                                parseInt(dataObj.song, 10)
                            );
                        }
                    });
                });
            }
            return __getResult(client);
        }
    
        static commandPlay() {
            return LktClient.commandStatus().then(LktClient.changePlayStatus, LktClient.errorStatus);
        }
    
        static changePlayStatus(status) {
            switch (status.state) {
                case 'play':
                    return LktClient.__execSimple('pause 1');
                    break;
                case 'pause':
                    return LktClient.__execSimple('pause 0');
                    break;
                case 'stop':
                    return LktClient.__execSimple('play');
                    break;
                default:
                    logger.info('Unknown play state' + status.state);
            }
            LktClient.setPlayState(status.state);
        }
    
        static commandPlaylistsList() {
            var client = new this();
            var once = false;
            var result = [];
            var dataObj;
            var prevcont = 0;
            function __getResult(client) {
                return new Promise(resolv => {
                    client.m_socket.setTimeout(0);
                    client.m_socket.on('data', data => {
                        if (!once) {
                            client.m_socket.write('listplaylists\n');
                            once = true;
                            return null;
                        } else {
                            dataObj = __mpdToObject(data);
                            if (dataObj.name) {
                                Array.prototype.push.apply(result, dataObj.name.split(' '));
                            }
                            if (dataObj.continue) {
                                if (prevcont == dataObj.continue) {
                                    client.close();
                                    resolv(result);
                                }
                                prevcont = dataObj.continue;
                                client.m_socket.write(`${dataObj.continue} listplaylists\n`);
                            }
                        }
                    });
                });
            }
            return __getResult(client);
        }
    
        static commandPlaylistListKaras(playlist) {
            var client = new this();
            var once = false;
            var result = [];
            var matches;
            var dataObj;
            var karaList;
            var prevcont = 0;
            const regex = /([0-9]+) (vo|va|amv|cdg|vocaloid|autres|vtuber) - (jp|fr|en|ru|sp|it|ch|latin|heb|por|pol|kor|fin|ara|swe|de|multi|undefined) \/ (.+) - (OP|ED|IS|AMV|PV|MV|LIVE)([0-9]*) - (.+) \[(.+)\]( \(U\))?/;
            var reg = new RegExp(regex);
            function __getResult(client) {
                return new Promise(resolv => {
                    client.m_socket.setTimeout(0);
                    client.m_socket.on('data', data => {
                        if (!once) {
                            client.m_socket.write(`listplaylist ${playlist}\n`);
                            once = true;
                            return null;
                        } else {
                            dataObj = __mpdToObject(data);
                            karaList = data.split('\n');
                            if (dataObj.continue) {
                                karaList.splice(-3);
                            } else {
                                karaList.splice(-1);
                            }
                            if (karaList[0] == 'OK') {
                                client.close();
                                return null;
                            }
                            karaList.forEach(kara => {
                                matches = reg.exec(kara);
                                result.push({
                                    id: matches[1],
                                    cat: matches[2],
                                    language: matches[3],
                                    source: matches[4],
                                    type: matches[5] + matches[6],
                                    title: matches[7],
                                    author: matches[8],
                                });
                                //logger.info("kara",matches[1]);
                            });
                            if (dataObj.continue && prevcont != dataObj.continue) {
                                client.m_socket.write(`${dataObj.continue} listplaylist ${playlist}\n`);
                                prevcont = dataObj.continue;
                            } else if (dataObj.continue) {
                                client.close();
                                resolv(result);
                            }
                        }
                    });
                });
            }
            return __getResult(client);
        }
    
        static commandPlayPos(position) {
            return LktClient.__execSimple(`play ${position}`);
        }
    
        static commandStop() {
            return LktClient.__execSimple('stop');
        }
    
        static commandPause() {
            return LktClient.__execSimple('pause 1');
        }
    
        static commandUnpause() {
            return LktClient.__execSimple('pause 0');
        }
    
        static commandPrev() {
            return LktClient.__execSimple('previous');
        }
    
        static commandNext() {
            return LktClient.__execSimple('next');
        }
    
        static commandShuffle() {
            return LktClient.__execSimple('shuffle');
        }
    
        static commandClear() {
            return LktClient.__execSimple('clear');
        }
    
        static commandMove(from, to) {
            return LktClient.__execSimple(`move ${from} ${to}`);
        }
    
        static commandQueueAddId(id) {
            return LktClient.__execSimple(`add id://${id}`);
        }
    
        static commandQueueInsertId(id) {
            return LktClient.__execSimple(`__insert id://${id}`);
        }
    
        static commandQueueDelPos(position) {
            return LktClient.__execSimple(`delete ${position}`);
        }
    
        static commandQueueDelId(id) {
            return LktClient.__execSimple(`deleteid ${id}`);
        }
    
        static commandPlaylistAddId(playlist, id) {
            return LktClient.__execSimple(`playlistadd ${playlist} id://${id}`);
        }
    
        static commandPlaylistRemoveId(playlist, id) {
            return LktClient.__execSimple(`playlistdelete ${playlist} ${id}`);
        }
    
        static commandPlaylistClear(playlist) {
            return LktClient.__execSimple(`playlistclear ${playlist}`);
        }
        static commandAddPlaylistToQueue(playlist) {
            return LktClient.__execSimple(`add playlist://${playlist}`);
        }
    
        static commandPlaylistCreate(playlist) {
            return LktClient.__execSimple(`playlistadd ${playlist}`);
        }
    
        static commandPlaylistDelete(playlist) {
            return LktClient.__execSimple(`playlistdelete ${playlist}`);
        }
        static commandUpdateDatabase() {
            return LktClient.__execSimple(`password hashire\nupdate`);
        }
        static commandDryUpdateDatabase() {
            return LktClient.__execSimple('password hashire\n__dry_update');
        }
        static commandDownloadId(id) {
            logger.info(`password hashire\nupdate id://${id}`);
            return LktClient.__execSimple(`password hashire\nupdate id://${id}`);
        }
    
        static commandQueueAddSearch(search) {
            //search = search.replace(/ /g,"%");
            return LktClient.__execSimple(`add query://%${search}%`);
        }
    
        static errorStatus(error) {
            logger.error('Unable to access lektor status:' + error);
        }
    
        static queue_updated = false;
    
        static setQueueUpdated(state) {
            this.queue_updated = state;
        }
    
        static isQueueUpdated() {
            return this.queue_updated;
        }
    
        static isStatusUpdated() {
            return this.status_updated;
        }
    
        static playlists_updated = true;
    
        static setPlaylistsUpdated(state) {
            this.playlists_updated = state;
        }
    
        static isPlaylistsUpdated() {
            return this.playlists_updated;
        }
        static isStatusUpdated() {
            return this.status_updated;
        }
    
        static timeData = { elapsed: 0, total: 100, state: 'stop', song: 0 };
    
        static setPlayState(state) {
            this.timeData.state = state;
        }
    
        static getCurrent() {
            return this.__current;
        }
    
        static getCurrent() {
            LktClient.status_updated = false;
            return this.__current;
        }
    
        static getStatus() {
            LktClient.status_updated = false;
            return this.__status;
        }
    
        static setSongTimeData(elapsed, total, state, song) {
            this.timeData = {
                elapsed: elapsed,
                total: total,
                state: state,
                song: song,
            };
        }
    
        static getSongTimeData() {
            return this.timeData;
        }
        static DBUpdated = false;
        static setDBUpdated(state) {
            this.DBUpdated = state;
        }
        static isDBUpdated() {
            return this.DBUpdated;
        }
    
        static ping() {
            var socket = new net.Socket();
            var result = {};
            function __getResult(socket) {
                return new Promise(resolv => {
                    const sockopt = {
                        port: config.content.lektord.port,
                        host: config.content.lektord.host,
                        readable: true,
                        writable: true,
                    };
                    logger.debug('lkt', 'Try to ping');
    
                    socket.setTimeout(3000);
                    socket.setEncoding('utf8');
    
                    socket.on('timeout', () => {
                        logger.error('lkt', `Got timeout while ping to localhost:${config.content.lektord.port}`);
                        result = false;
                        resolv(result);
                    });
    
                    socket.on('ready', () => {
                        logger.debug('lkt', `Ping success with localhost:${config.content.lektord.port}`);
                        result = true;
                        resolv(result);
                    });
    
                    socket.on('error', err => {
                        logger.error('lkt', `${err}`);
                        result = false;
                        resolv(result);
                    });
    
                    socket.connect(sockopt, () => {
                        logger.info('lkt', `Pinged localhost:${config.content.lektord.port}`);
                        socket.destroy();
                        result = true;
                        resolv(result);
                    });
                });
            }
    
            return __getResult(socket);
        }
    }
    
    function __mpdToObject(string) {
        var ret = {};
        string.split('\n').forEach(line => {
            if (line.length <= 1) return;
            var couple = line.split(/: (.+)/).slice(0, 2);
            if (!ret[couple[0]]) {
                ret[couple[0]] = couple[1];
            } else {
                ret[couple[0]] += ' ' + couple[1];
            }
        });
        return ret;
    }
    
    function __mpdStatusToBool(string) {
        string = string.split('\n');
        string = string[string.length - 1];
        return string.split(/ /) == 'OK' ? true : false;
    }
    
    module.exports = LktClient;