<commit_before>/*
 * Screenwerk main executable. Arguments:
 *
 * argv[0]          Screen's Entu ID
 *
 */

// 1. Core modules
var gui             = require('nw.gui')
var assert          = require('assert')
var util            = require('util')
var fs              = require('fs')
var https           = require('https')
var events          = require('events')
var uuid            = require('node-uuid')
var path            = require('path')


// 2. Public modules from npm
var os              = require('os-utils')


// 3. Own modules
var entulib         = require('./entulib.js')
var player          = require('./player.js')
var stringifier     = require('./stringifier.js')
var c               = require('./c.js')
var configuration   = require('./configuration.json')
var helper          = require('./helper.js')
var loader          = require('./loader.js')
var digest          = require('./digest.js')

c.__VERSION = gui.App.manifest.version
c.__APPLICATION_NAME = gui.App.manifest.name


var home_path = ''
if (process.env.HOME !== undefined) {
    home_path = process.env.HOME
} else if (process.env.HOMEPATH !== undefined) {
    home_path = process.env.HOMEDRIVE + process.env.HOMEPATH
}
home_path = path.resolve(home_path, gui.App.manifest.name)
if (!fs.existsSync(home_path)) {
    fs.mkdirSync(home_path)
}
configuration_path = path.resolve(home_path, 'configuration.json')
function exitWithMessage(message) {
    window.alert(message)
    gui.Shell.openItem(home_path)
    process.exit(1)
}
try {
    configuration = require(configuration_path)
} catch (exception) {
    fs.writeFile(configuration_path, JSON.stringify(configuration, null, 4), function(err) {
        if(err) {
            console.log(err)
        } else {
            console.log()
            exitWithMessage('Default configuration saved to \n'
                + configuration_path + '.\n'
                + 'Please put Your SCREEN_ID.uuid file in\n' + home_path)
        }
    })
}

c.__HOSTNAME = 'piletilevi.entu.ee'
c.__META_DIR = path.resolve(home_path, 'sw-meta')
if (!fs.existsSync(c.__META_DIR)) {
    fs.mkdirSync(c.__META_DIR)
}
c.__MEDIA_DIR = path.resolve(home_path, 'sw-media')
if (!fs.existsSync(c.__MEDIA_DIR)) {
    fs.mkdirSync(c.__MEDIA_DIR)
}
c.__LOG_DIR = path.resolve(home_path, 'sw-log')
if (!fs.existsSync(c.__LOG_DIR)) {
    fs.mkdirSync(c.__LOG_DIR)
}
// log_path = path.resolve(c.__LOG_DIR, 'production.log')

// TODO
// logging problem to solve.
// Switching logs off till then
//
// var consoleStream = fs.createWriteStream(log_path, {flags:'a'})
// var proxied = console.log
// console.log = function() {
//     var datestring = new Date().toISOString().replace(/T/, ' ').replace(/:/g, '-').replace(/\..+/, '')
//     var arr = [], p, i = 0
//     for (p in arguments)
//         arr[i++] = arguments[p]

//     consoleStream.write(datestring + ': ' + arr.join() + '\n')
//     return proxied.apply(this, arguments)
// }


console.log ( '= ' + c.__APPLICATION_NAME + ' v.' + c.__VERSION + ' ==================================')
console.log ( os.platform() )


c.__STRUCTURE = {"name":"screen","reference":{"name":"screen-group","reference":{"name":"configuration","child":{"name":"schedule","reference":{"name":"layout","child":{"name":"layout-playlist","reference":{"name":"playlist","child":{"name":"playlist-media","reference":{"name":"media"}}}}}}}}}
c.__HIERARCHY = {'child_of': {}, 'parent_of': {}}
function recurseHierarchy(structure, parent_name) {
    if (parent_name) {
        c.__HIERARCHY.child_of[parent_name] = structure.name
        c.__HIERARCHY.parent_of[structure.name] = parent_name
    }
    if (structure.child !== undefined)
        recurseHierarchy(structure.child, structure.name)
    else if (structure.reference !== undefined)
        recurseHierarchy(structure.reference, structure.name)
}
recurseHierarchy(c.__STRUCTURE)
c.__DEFAULT_UPDATE_INTERVAL_MINUTES = 10
c.__UPDATE_INTERVAL_SECONDS = c.__DEFAULT_UPDATE_INTERVAL_MINUTES * 60
c.__DEFAULT_DELAY_MS = 0
c.__DEBUG_MODE = configuration.debug
c.__SCREEN = configuration.run_on_screen
c.__RELAUNCH_THRESHOLD = configuration.relaunch


var uuids = []
fs.readdirSync(home_path).forEach(function scanHome(filename) {
    if (filename.substr(-5) === '.uuid') {
        uuids.push(filename)
    }
})
if (uuids.length === 1) {
    c.__SCREEN_ID = uuids[0].slice(0,-5)
} else {
    // console.log(gui.App.argv)
    // assert.equal(typeof(gui.App.argv[0]), 'string'
    //             , "Screen ID should be passed as first argument.")
    // assert.ok(Number(gui.App.argv[0]) > 0
    //             , "Screen ID must be number greater than zero.")
    // c.__SCREEN_ID = Number(gui.App.argv.shift())
    try {
        c.__SCREEN_ID = Number(gui.App.argv.shift())
    } catch (exception) {
        exitWithMessage('Provide SCREEN_ID.uuid file \nor pass screen ID as first commandline argument.')
    }
}


var uuid_path = path.resolve(home_path, c.__SCREEN_ID + '.uuid')
if (fs.existsSync(uuid_path)) {
    c.__API_KEY = fs.readFileSync(uuid_path)
    console.log ( 'Read key: ' + c.__API_KEY, 'INFO')
} else {
    c.__API_KEY = uuid.v1()
    fs.writeFileSync(uuid_path, c.__API_KEY)
    exitWithMessage('Created key for screen: ' + c.__SCREEN_ID + '\n(' + uuid_path + '). \nNow register this key in Entu:\n ' + c.__API_KEY)
}


// console.log('initialize EntuLib with ' + c.__SCREEN_ID + '|' + c.__API_KEY + '|' + c.__HOSTNAME)
var EntuLib = entulib(c.__SCREEN_ID, c.__API_KEY, c.__HOSTNAME)

var player_window = gui.Window.get()
if (c.__DEBUG_MODE) {
    console.log ( 'launching in debug mode')
    player_window.moveTo(0,30)
    player_window.isFullscreen = false
    player_window.showDevTools()
} else {
    console.log ( 'launching in fullscreen mode')
    player_window.moveTo(window.screen.width * (c.__SCREEN - 1) + 1, 30)
    player_window.isFullscreen = true
}
var nativeMenuBar = new gui.Menu({ type: "menubar" })
try {
    nativeMenuBar.createMacBuiltin(gui.App.manifest.name + ' ' + c.__VERSION)<commit_msg>better feedback on misconfiguration<commit_after>/*
 * Screenwerk main executable. Arguments:
 *
 * argv[0]          Screen's Entu ID
 *
 */

// 1. Core modules
var gui             = require('nw.gui')
var assert          = require('assert')
var util            = require('util')
var fs              = require('fs')
var https           = require('https')
var events          = require('events')
var uuid            = require('node-uuid')
var path            = require('path')


// 2. Public modules from npm
var os              = require('os-utils')


// 3. Own modules
var entulib         = require('./entulib.js')
var player          = require('./player.js')
var stringifier     = require('./stringifier.js')
var c               = require('./c.js')
var configuration   = require('./configuration.json')
var helper          = require('./helper.js')
var loader          = require('./loader.js')
var digest          = require('./digest.js')

c.__VERSION = gui.App.manifest.version
c.__APPLICATION_NAME = gui.App.manifest.name


var home_path = ''
if (process.env.HOME !== undefined) {
    home_path = process.env.HOME
} else if (process.env.HOMEPATH !== undefined) {
    home_path = process.env.HOMEDRIVE + process.env.HOMEPATH
}
home_path = path.resolve(home_path, gui.App.manifest.name)
if (!fs.existsSync(home_path)) {
    fs.mkdirSync(home_path)
}
configuration_path = path.resolve(home_path, 'configuration.json')
function exitWithMessage(message) {
    window.alert(message)
    gui.Shell.openItem(home_path)
    process.exit(1)
}
try {
    configuration = require(configuration_path)
} catch (exception) {
    fs.writeFileSync(configuration_path, JSON.stringify(configuration, null, 4))
    exitWithMessage('Default configuration saved to \n'
        + configuration_path + '.\n'
        + 'Please put Your SCREEN_ID.uuid file in\n' + home_path)
}

c.__HOSTNAME = 'piletilevi.entu.ee'
c.__META_DIR = path.resolve(home_path, 'sw-meta')
if (!fs.existsSync(c.__META_DIR)) {
    fs.mkdirSync(c.__META_DIR)
}
c.__MEDIA_DIR = path.resolve(home_path, 'sw-media')
if (!fs.existsSync(c.__MEDIA_DIR)) {
    fs.mkdirSync(c.__MEDIA_DIR)
}
c.__LOG_DIR = path.resolve(home_path, 'sw-log')
if (!fs.existsSync(c.__LOG_DIR)) {
    fs.mkdirSync(c.__LOG_DIR)
}
// log_path = path.resolve(c.__LOG_DIR, 'production.log')

// TODO
// logging problem to solve.
// Switching logs off till then
//
// var consoleStream = fs.createWriteStream(log_path, {flags:'a'})
// var proxied = console.log
// console.log = function() {
//     var datestring = new Date().toISOString().replace(/T/, ' ').replace(/:/g, '-').replace(/\..+/, '')
//     var arr = [], p, i = 0
//     for (p in arguments)
//         arr[i++] = arguments[p]

//     consoleStream.write(datestring + ': ' + arr.join() + '\n')
//     return proxied.apply(this, arguments)
// }


console.log ( '= ' + c.__APPLICATION_NAME + ' v.' + c.__VERSION + ' ==================================')
console.log ( os.platform() )


c.__STRUCTURE = {"name":"screen","reference":{"name":"screen-group","reference":{"name":"configuration","child":{"name":"schedule","reference":{"name":"layout","child":{"name":"layout-playlist","reference":{"name":"playlist","child":{"name":"playlist-media","reference":{"name":"media"}}}}}}}}}
c.__HIERARCHY = {'child_of': {}, 'parent_of': {}}
function recurseHierarchy(structure, parent_name) {
    if (parent_name) {
        c.__HIERARCHY.child_of[parent_name] = structure.name
        c.__HIERARCHY.parent_of[structure.name] = parent_name
    }
    if (structure.child !== undefined)
        recurseHierarchy(structure.child, structure.name)
    else if (structure.reference !== undefined)
        recurseHierarchy(structure.reference, structure.name)
}
recurseHierarchy(c.__STRUCTURE)
c.__DEFAULT_UPDATE_INTERVAL_MINUTES = 10
c.__UPDATE_INTERVAL_SECONDS = c.__DEFAULT_UPDATE_INTERVAL_MINUTES * 60
c.__DEFAULT_DELAY_MS = 0
c.__DEBUG_MODE = configuration.debug
c.__SCREEN = configuration.run_on_screen
c.__RELAUNCH_THRESHOLD = configuration.relaunch


var uuids = []
fs.readdirSync(home_path).forEach(function scanHome(filename) {
    if (filename.substr(-5) === '.uuid') {
        uuids.push(filename)
    }
})
if (uuids.length === 1) {
    c.__SCREEN_ID = uuids[0].slice(0,-5)
} else {
    // console.log(gui.App.argv)
    // assert.equal(typeof(gui.App.argv[0]), 'string'
    //             , "Screen ID should be passed as first argument.")
    // assert.ok(Number(gui.App.argv[0]) > 0
    //             , "Screen ID must be number greater than zero.")
    // c.__SCREEN_ID = Number(gui.App.argv.shift())
    if (Number(gui.App.argv[0]) > 0) {
        c.__SCREEN_ID = Number(gui.App.argv.shift())
    } else {
        exitWithMessage('Provide SCREEN_ID.uuid file \nor pass screen ID as first commandline argument.')
    }
}

if (!c.__SCREEN_ID) {
    exitWithMessage('Missing screen ID, blame programmer.\nExiting.')
}

var uuid_path = path.resolve(home_path, c.__SCREEN_ID + '.uuid')
if (fs.existsSync(uuid_path)) {
    c.__API_KEY = fs.readFileSync(uuid_path)
    console.log ( 'Read key: ' + c.__API_KEY, 'INFO')
} else {
    c.__API_KEY = uuid.v1()
    fs.writeFileSync(uuid_path, c.__API_KEY)
    exitWithMessage('Created key for screen: ' + c.__SCREEN_ID + '\n(' + uuid_path + '). \nNow register this key in Entu:\n ' + c.__API_KEY)
}


// console.log('initialize EntuLib with ' + c.__SCREEN_ID + '|' + c.__API_KEY + '|' + c.__HOSTNAME)
var EntuLib = entulib(c.__SCREEN_ID, c.__API_KEY, c.__HOSTNAME)

var player_window = gui.Window.get()
if (c.__DEBUG_MODE) {
    console.log ( 'launching in debug mode')
    player_window.moveTo(0,30)
    player_window.isFullscreen = false
    player_window.showDevTools()
} else {
    console.log ( 'launching in fullscreen mode')
    player_window.moveTo(window.screen.width * (c.__SCREEN - 1) + 1, 30)
    player_window.isFullscreen = true
}
var nativeMenuBar = new gui.Menu({ type: "menubar" })
try {
    nativeMenuBar.createMacBuiltin(gui.App.manifest.name + ' ' + c.__VERSION)
{'fraction_non_alphanumeric': 0.16626365379804886, 'fraction_numerical': 0.004836154423413658, 'mean_word_length': 3.2989247311827956, 'pattern_counts': {'":': 34, '<': 3, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3562211', 'n_tokens_mistral': 4074, 'n_tokens_neox': 3997, 'n_words': 753}