From 7e332a17679879e9210fae31c06bae4fe32e616b Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sat, 12 Dec 2015 16:52:33 -0700 Subject: [PATCH 1/6] Deprecated. Use nua.js --- mods/apply.js | 182 -------------------------------------------------- 1 file changed, 182 deletions(-) delete mode 100644 mods/apply.js diff --git a/mods/apply.js b/mods/apply.js deleted file mode 100644 index 1be46f64..00000000 --- a/mods/apply.js +++ /dev/null @@ -1,182 +0,0 @@ -/* jslint node: true */ -'use strict'; - -var ansi = require('../core/ansi_term.js'); -var art = require('../core/art.js'); -var user = require('../core/user.js'); -var theme = require('../core/theme.js'); -var Log = require('../core/logger.js').log; -var MenuModule = require('../core/menu_module.js').MenuModule; -var ViewController = require('../core/view_controller.js').ViewController; -var Config = require('../core/config.js').config; -var sysMenuMethod = require('../core/system_menu_method.js'); -var getDefaultMessageArea = require('../core/message_area.js').getDefaultMessageArea; - -var util = require('util'); -var async = require('async'); - -exports.submitApplication = submitApplication; - -function validateApplicationData(formData, cb) { - // :TODO: This entire section should be replaced with a generic form validation system!! - async.waterfall( - [ - function basics(callback) { - if(formData.value.username.length < Config.users.usernameMin) { - cb(new Error('Handle too short!'), [ 1 ]); - return; - } - - if(formData.value.username.length > Config.users.usernameMax) { - cb(new Error('Handle too long!'), [ 1 ]); - return; - } - - var re = new RegExp(Config.users.usernamePattern); - if(!re.test(formData.value.username)) { - cb(new Error('Handle contains invalid characters!'), [ 1 ] ); - return; - } - - var invalidNames = Config.users.newUserNames + Config.users.badUserNames; - if(invalidNames.indexOf(formData.value.username.toLowerCase()) > -1) { - cb(new Error('Handle is blacklisted!'), [ 1 ] ); - return; - } - - if(isNaN(Date.parse(formData.value.birthdate))) { - cb(new Error('Invalid birthdate!'), [ 3 ] ); - return; - } - - if(formData.value.password.length < Config.users.passwordMin) { - cb(new Error('Password too short!'), [ 9, 10 ]); - return; - } - - if(formData.value.password !== formData.value.passwordConfirm) { - cb(new Error('Passwords do not match!'), [ 9, 10 ]); - return; - } - - callback(null); - }, - function email(callback) { - user.getUserIdsWithProperty('email_address', formData.value.email, function userIdsWithEmail(err, uids) { - if(err) { - callback(new Error('Internal system error: ' + err.toString()), [ 1 ]); - } else if(uids.length > 0) { - callback(new Error('Email address not unique!'), [ 7 ] ); - } else { - callback(null); - } - }); - }, - function userName(callback) { - user.getUserIdAndName(formData.value.username, function userIdAndName(err) { - var alreadyExists = !err; - if(alreadyExists) { - callback(new Error('Username unavailable!'), [ 1 ] ); - } else { - cb(null); - } - }); - } - ], - function complete(err, viewIds) { - cb(err, viewIds); - } - ); -} - -function submitApplication(callingMenu, formData, extraArgs) { - var client = callingMenu.client; - var menuConfig = callingMenu.menuConfig; - var menuViewController = callingMenu.viewControllers.menu; - - var views = { - username : menuViewController.getView(1), - password : menuViewController.getView(9), - confirm : menuViewController.getView(10), - errorMsg : menuViewController.getView(11) - }; - - validateApplicationData(formData, function validationResult(err, viewIds) { - if(err) { - views.errorMsg.setText(err.toString().replace('Error: ', '')); - - viewIds.forEach(function formId(id) { - menuViewController.getView(id).clearText(''); - }); - - menuViewController.switchFocus(viewIds[0]); - } else { - // Seems legit! - // :TODO: All of this should be a system API, not a mod, e.g. createNewUser(...) - var newUser = new user.User(); - - newUser.username = formData.value.username; - - newUser.properties = { - real_name : formData.value.realName, - birthdate : new Date(Date.parse(formData.value.birthdate)).toISOString(), - sex : formData.value.sex, - location : formData.value.location, - affiliation : formData.value.affils, - email_address : formData.value.email, - web_address : formData.value.web, - account_created : new Date().toISOString(), - - message_area_name : getDefaultMessageArea().name, - - term_height : client.term.termHeight, - term_width : client.term.termWidth, - - // :TODO: This is set in User.create() -- proabbly don't need it here: - //account_status : Config.users.requireActivation ? user.User.AccountStatus.inactive : user.User.AccountStatus.active, - - // :TODO: Other defaults - // :TODO: should probably have a place to create defaults/etc. - }; - - if('*' === Config.defaults.theme) { - newUser.properties.theme_id = theme.getRandomTheme(); - } else { - newUser.properties.theme_id = Config.defaults.theme; - } - - // :TODO: .create() should also validate email uniqueness! - newUser.create( { password : formData.value.password }, function created(err) { - if(err) { - Log.info( { error : err, username : formData.value.username }, 'New user creation failed'); - - callingMenu.gotoMenu(extraArgs.error, function result(err) { - if(err) { - callingMenu.prevMenu(); - } - }); - } else { - Log.info( { username : formData.value.username, userId : newUser.userId }, 'New user created'); - - // Cache SysOp information now - // :TODO: Similar to bbs.js. DRY - if(newUser.isSysOp()) { - Config.general.sysOp = { - username : formData.value.username, - properties : newUser.properties, - }; - } - - if(user.User.AccountStatus.inactive === client.user.properties.account_status) { - callingMenu.gotoMenu(extraArgs.inactive); - } else { - // - // If active now, we need to call login() to authenticate - // - sysMenuMethod.login(callingMenu, formData, extraArgs); - } - } - }); - } - }); -} From b53ad03ad0833b97c3e8221a28e540319979da73 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 13 Dec 2015 16:47:28 -0700 Subject: [PATCH 2/6] Default to luciano_blocktronics for pre-login theme --- core/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/config.js b/core/config.js index d3e02122..9daa4e77 100644 --- a/core/config.js +++ b/core/config.js @@ -90,7 +90,7 @@ function getDefaultConfig() { }, // :TODO: see notes below about 'theme' section - move this! - preLoginTheme : '*', + preLoginTheme : 'luciano_blocktronics', users : { usernameMin : 2, From 2a7dce9fac0c818926632eead94c1282061cb36d Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 13 Dec 2015 17:31:16 -0700 Subject: [PATCH 3/6] Fix dateTimeFormat to use Do vs do for moment.js formatting --- mods/msg_list.js | 2 +- mods/themes/luciano_blocktronics/theme.hjson | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/msg_list.js b/mods/msg_list.js index 2404aef9..27bb9240 100644 --- a/mods/msg_list.js +++ b/mods/msg_list.js @@ -131,7 +131,7 @@ MessageListModule.prototype.mciReady = function(mciData, cb) { // :TODO: fix default format var listFormat = self.menuConfig.config.listFormat || '{msgNum} - {subj} - {to}'; var focusListFormat = self.menuConfig.config.focusListFormat || listFormat; // :TODO: default change color here - var dateTimeFormat = self.menuConfig.config.dateTimeFormat || 'ddd MMM DDD'; + var dateTimeFormat = self.menuConfig.config.dateTimeFormat || 'ddd MMM Do'; var newIndicator = self.menuConfig.config.newIndicator || '*'; var msgNum = 1; diff --git a/mods/themes/luciano_blocktronics/theme.hjson b/mods/themes/luciano_blocktronics/theme.hjson index 919c82fb..375fb479 100644 --- a/mods/themes/luciano_blocktronics/theme.hjson +++ b/mods/themes/luciano_blocktronics/theme.hjson @@ -146,7 +146,7 @@ config: { listFormat: "|00|01|37{msgNum:>4} |00|37- |36{subj:<29.29} {from:<20.20} {ts} |01|31{newIndicator}" focusListFormat: "|00|42|30{msgNum:>4} - {subj:<29.29} {from:<20.20} {ts} {newIndicator}" - dateTimeFormat: ddd MMM do + dateTimeFormat: ddd MMM Do } mci: { VM1: { From 1b68264dc2b2919a9bead56c324cced713861a96 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 13 Dec 2015 17:31:43 -0700 Subject: [PATCH 4/6] Display proper online time in whos_online.js --- mods/whos_online.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mods/whos_online.js b/mods/whos_online.js index d2a3f977..4e854efb 100644 --- a/mods/whos_online.js +++ b/mods/whos_online.js @@ -71,13 +71,18 @@ WhosOnlineModule.prototype.mciReady = function(mciData, cb) { var listFormat = self.menuConfig.config.listFormat || '{node} - {username} - {action} - {timeOn}'; + var now = moment(); + onlineListView.setItems(_.map(onlineList, function formatOnlineEntry(oe) { return listFormat.format({ node : oe.node, userId : oe.user.userId, userName : oe.user.username, realName : oe.user.properties.real_name, - timeOn : _.capitalize(moment.duration(55, 'minutes').humanize()), + timeOn : function getTimeOn() { + var diff = now.diff(moment(oe.user.properties.last_login_timestamp), 'minutes'); + return _.capitalize(moment.duration(diff, 'minutes').humanize()); + }, action : function getCurrentAction() { var cmm = oe.currentMenuModule; if(cmm) { From 0489f5b2dd32413b1ed228e8286fca98c750691b Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 13 Dec 2015 17:32:05 -0700 Subject: [PATCH 5/6] * Remove/fix up some console.log()'s --- core/config_cache.js | 2 +- core/menu_module.js | 5 ++++- core/message_area.js | 1 - core/view_controller.js | 1 - mods/last_callers.js | 2 +- mods/logoff.js | 41 ----------------------------------------- 6 files changed, 6 insertions(+), 46 deletions(-) delete mode 100644 mods/logoff.js diff --git a/core/config_cache.js b/core/config_cache.js index c8b1e00b..41bdef16 100644 --- a/core/config_cache.js +++ b/core/config_cache.js @@ -26,7 +26,7 @@ function ConfigCache() { self.cache[filePath] = hjson.parse(data); cb(null, self.cache[filePath]); } catch(e) { - console.log(e) + Log.error( { filePath : filePath, error : e.toString() }, 'Failed recaching'); cb(e); } }); diff --git a/core/menu_module.js b/core/menu_module.js index 0ea0d73a..cdacb484 100644 --- a/core/menu_module.js +++ b/core/menu_module.js @@ -231,7 +231,10 @@ MenuModule.prototype.nextMenu = function(cb) { // ...if the error is that we do not meet ACS requirements and did not get a match, then what? if(!cb) { cb = function(err) { - console.log(err) + if(err) { + // :TODO: Don't console.log() here! + console.log(err) + } } } this.client.menuStack.next(cb); diff --git a/core/message_area.js b/core/message_area.js index 7a22b5b0..b32f724a 100644 --- a/core/message_area.js +++ b/core/message_area.js @@ -94,7 +94,6 @@ function changeMessageArea(client, areaName, cb) { ], function complete(err, area) { if(!err) { - console.log(JSON.stringify(area)) client.log.info( area, 'Current message area changed'); } else { client.log.warn( { area : area, error : err.message }, 'Could not change message area'); diff --git a/core/view_controller.js b/core/view_controller.js index d4dce737..8300772c 100644 --- a/core/view_controller.js +++ b/core/view_controller.js @@ -75,7 +75,6 @@ function ViewController(options) { // :TODO: need to do validation here!!! var focusedView = self.focusedView; self.validateView(focusedView, function validated(err, newFocusedViewId) { - console.log(err) if(err) { var newFocusedView = self.getView(newFocusedViewId) || focusedView; self.setViewFocusWithEvents(newFocusedView, true); diff --git a/mods/last_callers.js b/mods/last_callers.js index 2899a69c..656794f9 100644 --- a/mods/last_callers.js +++ b/mods/last_callers.js @@ -17,7 +17,7 @@ var _ = require('lodash'); userName location affiliation - timestamp + ts */ diff --git a/mods/logoff.js b/mods/logoff.js deleted file mode 100644 index 1618ddd7..00000000 --- a/mods/logoff.js +++ /dev/null @@ -1,41 +0,0 @@ -/* jslint node: true */ -'use strict'; - -var MenuModule = require('../core/menu_module.js').MenuModule; -var ansi = require('../core/ansi_term.js'); - -exports.moduleInfo = { - name : 'LogOff', - desc : 'Log off / Goodbye Module', - author : 'NuSkooler', -}; - -exports.getModule = LogOffModule; - -function LogOffModule(menuConfig) { - MenuModule.call(this, menuConfig); -} - -require('util').inherits(LogOffModule, MenuModule); - -LogOffModule.prototype.enter = function(client) { - LogOffModule.super_.prototype.enter.call(this, client); -}; - -LogOffModule.prototype.beforeArt = function() { - LogOffModule.super_.prototype.beforeArt.call(this); - - this.client.term.write(ansi.resetScreen()); -}; - -LogOffModule.prototype.mciReady = function(mciData) { - LogOffModule.super_.prototype.mciReady.call(this, mciData); -}; - -LogOffModule.prototype.finishedLoading = function() { - LogOffModule.super_.prototype.finishedLoading.call(this); - - this.client.term.write(ansi.normal() + '\nATH0\n'); - - this.client.end(); -}; \ No newline at end of file From fce6f899a7116f8c5b7ffaac13bc9242c38e85de Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 13 Dec 2015 17:41:40 -0700 Subject: [PATCH 6/6] Some minor doc updates --- docs/doors.md | 2 ++ docs/menu_system.md | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/doors.md b/docs/doors.md index e71cf9b7..dd1c0ec4 100644 --- a/docs/doors.md +++ b/docs/doors.md @@ -131,6 +131,8 @@ qemu-system-i386 -localtime /home/enigma/dos/images/freedos_c.img -chardev socke Note the `qemu-system-i386` line. We're telling QEMU to launch and use localtime for the clock, create a character device that connects to our temporary server port on localhost and map that to a serial device. The `-hdb` entry will represent the D: drive where our drop file is generated, while `-hdc` is the path that `GO.BAT` is generated in (`E:\GO.BAT`). Finally we specify `-nographic` to run headless. +For doors that do not *require* a FOSSIL driver, it is recommended to not load or use one unless you are having issues. + #### Step 4: Create a menu entry Finally we can create a `menu.hjson` entry using the `abracadabra` module: ```hjson diff --git a/docs/menu_system.md b/docs/menu_system.md index 6b2126bb..eca73c17 100644 --- a/docs/menu_system.md +++ b/docs/menu_system.md @@ -1,5 +1,13 @@ # Menu System -ENiGMA½'s menu system is highly flexible and moddable. The possibilities are almost endless! By modifying `menu.hjson` you will be able to create a custom look and feel unique to your board. +ENiGMA½'s menu system is highly flexible and moddable. The possibilities are almost endless! By modifying your `menu.hjson` you will be able to create a custom look and feel unique to your board. + +The default `menu.hjson` file lives within the `mods` directory. To specify another file, set the `menuFile` property in your `config.hjson` file: +```hjson +general: { + /* Can also specify a full path */ + menuFile: mybbs.hjson +} +``` ## The Basics Like all configuration within ENiGMA½, menu configuration is done via a HJSON file. This file is located in the `mods` directory: `mods/menu.hjson`.