diff --git a/app.js b/app.js index 5b52d0c..d8f32d4 100644 --- a/app.js +++ b/app.js @@ -9,12 +9,18 @@ var dictionary = require('./dictionary/dictionary'); dictionary.buildDictionary(function(){ // We have a full Dictionary now to do things with :) - console.log(dictionary.missingEntryTranslations); + //console.log(dictionary.missingEntryTranslations); + //console.log(dictionary.entries); + dictionary.export(function(){ + console.log("Export Complete!!!"); + process.exit(0); + }); }); var index = require('./routes/index'); var users = require('./routes/users'); +var dictionaryV1API = require('./routes/dictionary.routes.v1'); var app = express(); @@ -32,6 +38,7 @@ app.use(express.static(path.join(__dirname, 'public'))); app.use('/', index); app.use('/users', users); +app.use('/api/v1/dictionary', dictionaryV1API); // catch 404 and forward to error handler app.use(function(req, res, next) { diff --git a/dictionary/dictionary.js b/dictionary/dictionary.js index 13e7750..d11964d 100644 --- a/dictionary/dictionary.js +++ b/dictionary/dictionary.js @@ -2,6 +2,8 @@ var format = require('string-format'); var Entry = require('./entry'); var EanaEltu = require('./eanaEltu'); +var models = require('../models'); +var Promise = require('promise'); function Dictionary () { this.debug = false; @@ -37,13 +39,85 @@ Dictionary.prototype.buildDictionary = function (callback) { buildDictionaryMetadata(self); buildDictionaryTemplates(self); buildDictionaryEntries(self); - if(this.debug){ + if(self.debug){ console.log("Complete"); } callback(); }); }; +Dictionary.prototype.export = function (callback) { + if(this.debug){ + console.log("Exporting Dictionary to new Database..."); + } + var self = this; + var sourcePromises = []; + var entryPromises = []; + + // Using force: true to drop all tables first + models.sequelize.sync({force: true}).then(function() { + + // Insert Sources + for(var source in self.sources){ + sourcePromises.push(models.Source.create({ + name: source, + description: getSourceDescription(source) + })); + } + + Promise.all(sourcePromises).then(function(){ + models.Source.findAll().then(function(sources){ + + sources.forEach(function(source){ + self.sources[source.name] = source; + }); + + // Insert Entries + for(var id in self.entries){ + var entry = self.entries[id]; + entryPromises.push(models.Entry.create({ + id: entry.id, + lemma: entry.lemma, + ipa: entry.ipa, + partOfSpeech: entry.partOfSpeech, + SourceId: self.sources[entry.source].id, + createdAt: entry.editTime * 1000 + })); + } + Promise.all(entryPromises).then(callback); + }); + }); + + + + }); +}; + +function getSourceDescription(source) { + var result = source.replace("PF", "Dr. Paul Frommer"); + if(source === "G"){ + result = result.replace("G", "The Avatar Games"); + } + if(source === "M" || source === "PF, M"){ + result = result.replace("M", "The Movie"); + } + result = result.replace("JC", "James Cameron"); + result = result.replace("LN", "LearnNavi.org"); + result = result.replace("ASG", "The Survival Guide"); + result = result.replace("PND", "Pandorapedia.com"); + result = result.replace("Prr", "Prrton"); + result = result.replace("CP", "CCH Pounder"); + result = result.replace("LA", "Laz Alonso"); + result = result.replace("RL", "Richard Littauer"); + result = result.replace("SW", "Sigourney Weaver"); + result = result.replace("ZS", "Zoƫ Saldana"); + result = result.replace("CM", "Carla Meyer"); + result = result.replace("CdS", "Cirque du Soleil"); + //result = result.replace("", ""); + + return result; +} + function buildDictionaryLanguages(self) { for(var index in self.eanaEltu.dictLanguages){ var language = self.eanaEltu.dictLanguages[index]; diff --git a/dictionary/eanaEltu.js b/dictionary/eanaEltu.js index 70c9565..97bd97a 100644 --- a/dictionary/eanaEltu.js +++ b/dictionary/eanaEltu.js @@ -2,16 +2,17 @@ var mysql = require('mysql'); // vault.js is an encrypted module that contains connection info for the db. +var env = process.env.NODE_ENV || "development"; var vault = require('../vault'); function EanaEltu() { this.debug = false; this.rawEEdata = {}; this.dbConnection = mysql.createConnection({ - host: vault.eanaEltu.host, - user: vault.eanaEltu.username, - password: vault.eanaEltu.password, // Dev Credentials - Needs to be swapped out with Prod credentials - database: vault.eanaEltu.database + host: vault[env].eanaEltu.host, + user: vault[env].eanaEltu.username, + password: vault[env].eanaEltu.password, + database: vault[env].eanaEltu.database }); } diff --git a/models/entry.js b/models/entry.js new file mode 100644 index 0000000..2590f45 --- /dev/null +++ b/models/entry.js @@ -0,0 +1,18 @@ +'use strict'; +module.exports = function (sequelize, DataTypes) { + var Entry = sequelize.define('Entry', { + lemma: { type: DataTypes.STRING, allowNull: false }, + ipa: { type: DataTypes.STRING, allowNull: false }, + partOfSpeech: { type: DataTypes.STRING, allowNull: false }, + odd: { type: DataTypes.STRING }, + audio: { type: DataTypes.STRING } + }); + + Entry.associate = function (models) { + // associations can be defined here + Entry.hasMany(models.LocalizedEntry); + Entry.belongsTo(models.Source); + }; + + return Entry; +}; diff --git a/models/index.js b/models/index.js new file mode 100644 index 0000000..3b74ff5 --- /dev/null +++ b/models/index.js @@ -0,0 +1,35 @@ +"use strict"; + +var fs = require("fs"); +var path = require("path"); +var Sequelize = require("sequelize"); +var env = process.env.NODE_ENV || "development"; +var vault = require('../vault'); + +if (process.env.DATABASE_URL) { + var sequelize = new Sequelize(process.env.DATABASE_URL,vault[env].ln_dictionary); +} else { + var sequelize = new Sequelize(vault[env].ln_dictionary.database, vault[env].ln_dictionary.username, vault[env].ln_dictionary.password, vault[env].ln_dictionary); +} +var db = {}; + +fs + .readdirSync(__dirname) + .filter(function(file) { + return (file.indexOf(".") !== 0) && (file !== "index.js"); + }) + .forEach(function(file) { + var model = sequelize.import(path.join(__dirname, file)); + db[model.name] = model; + }); + +Object.keys(db).forEach(function(modelName) { + if ("associate" in db[modelName]) { + db[modelName].associate(db); + } +}); + +db.sequelize = sequelize; +db.Sequelize = Sequelize; + +module.exports = db; diff --git a/models/localizedentry.js b/models/localizedentry.js new file mode 100644 index 0000000..4412476 --- /dev/null +++ b/models/localizedentry.js @@ -0,0 +1,16 @@ +'use strict'; +module.exports = function (sequelize, DataTypes) { + var LocalizedEntry = sequelize.define('LocalizedEntry', { + lc: { type: DataTypes.STRING, allowNull: false }, + test: DataTypes.INTEGER + }, { + classMethods: { + associate: function (models) { + // associations can be defined here + console.log("This is being called..."); + LocalizedEntry.belongsTo(models.Entry); + } + } + }); + return LocalizedEntry; +}; \ No newline at end of file diff --git a/models/source.js b/models/source.js new file mode 100644 index 0000000..ad83143 --- /dev/null +++ b/models/source.js @@ -0,0 +1,14 @@ +'use strict'; +module.exports = function (sequelize, DataTypes) { + var Source = sequelize.define('Source', { + name: { type: DataTypes.STRING, unique: true }, + description: DataTypes.STRING + }); + + Source.associate = function (models) { + // associations can be defined here + Source.hasMany(models.Entry); + }; + + return Source; +}; diff --git a/package.json b/package.json index 5060d4a..44deeb3 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "mysql2": "^1.3.5", "pug": "~2.0.0-beta11", "sequelize": "^4.2.1", - "serve-favicon": "~2.4.2" + "sequelize-cli": "^2.7.0", + "serve-favicon": "~2.4.2", + "sqlite3": "^3.1.8" } } diff --git a/dictionary/app.bak.js b/routes/dictionary.routes.v1.js similarity index 84% rename from dictionary/app.bak.js rename to routes/dictionary.routes.v1.js index d8fbf76..2c5d077 100644 --- a/dictionary/app.bak.js +++ b/routes/dictionary.routes.v1.js @@ -1,11 +1,19 @@ +var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +router.get('/', function(req, res, next) { + res.send('Mobile App Database System V1'); +}); + +module.exports = router; + //We need a function which handles requests and send response function handleRequest(request, response){ console.log(request.url); switch(request.url) { - case "/": - response.end("Mobile App Database System"); - break; + case "/dictionary/templates": var htmlText = ""; //for(var lc in dictionary.templates){ @@ -36,42 +44,42 @@ function handleRequest(request, response){ response.end(JSON.stringify(dictionary.entries), 'utf8'); break; - // Fetch dictLanguages + // Fetch dictLanguages case "/eanaEltu/dictLanguages": response.end(JSON.stringify(eanaEltu.dictLanguages)); break; - // Fetch dictLayout + // Fetch dictLayout case "/eanaEltu/dictLayout": response.end(JSON.stringify(eanaEltu.dictLayout)); break; - // Fetch dictLoc + // Fetch dictLoc case "/eanaEltu/dictLoc": response.end(JSON.stringify(eanaEltu.dictLoc)); break; - // Fetch dictMeta + // Fetch dictMeta case "/eanaEltu/dictMeta": response.end(JSON.stringify(eanaEltu.dictMeta)); break; - // Fetch dictOrder + // Fetch dictOrder case "/eanaEltu/dictOrder": response.end(JSON.stringify(eanaEltu.dictOrder)); break; - // Fetch dictWordLoc + // Fetch dictWordLoc case "/eanaEltu/dictWordLoc": response.end(JSON.stringify(eanaEltu.dictWordLoc)); break; - // Fetch dictWordMeta + // Fetch dictWordMeta case "/eanaEltu/dictWordMeta": response.end(JSON.stringify(eanaEltu.dictWordMeta)); break; - // Fetch dictWordTemplate + // Fetch dictWordTemplate case "/eanaEltu/dictWordTemplate": response.end(JSON.stringify(eanaEltu.dictWordTemplate)); break; diff --git a/vault.js b/vault.js index 8d35952..2038b80 100644 Binary files a/vault.js and b/vault.js differ