Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
6aefe05
coveralls test
FruitieX May 18, 2015
7471237
remember to generate coverage first
FruitieX May 18, 2015
6e625a1
travis ci: cache node_modules for faster builds
FruitieX May 18, 2015
5dc0a15
getPlaylists function calls all backends and fetches playlists
FruitieX Nov 12, 2015
970570b
WIP: playlist refactor
FruitieX Nov 12, 2015
04d45ec
more WIP
FruitieX Nov 12, 2015
84c4b4a
simplify playlist logic by only using one list
FruitieX Nov 13, 2015
36da5ad
WIP: playlist refactor
FruitieX Nov 13, 2015
9962ef7
it runs!
FruitieX Nov 13, 2015
2f4aebc
WIP
FruitieX Nov 13, 2015
cecb4ec
first song plays fine
FruitieX Nov 13, 2015
d90db79
playlist concepts
FruitieX Nov 26, 2015
d71f892
clarification
FruitieX Nov 26, 2015
3baf5e5
clarification
FruitieX Nov 26, 2015
8131a3f
clarification
FruitieX Nov 26, 2015
3b8aab7
WIP: refactor playback queue handling into queue.js
FruitieX Nov 26, 2015
dfe4dfc
Merge branch 'playlists' of github.com:FruitieX/nodeplayer into playl…
FruitieX Nov 26, 2015
43bb8ac
WIP: refactor and document, comment out tests for now
FruitieX Nov 26, 2015
f1bc0ff
s/curPlaylistPos/queue.curQueuePos
FruitieX Nov 26, 2015
b5b242e
renames
FruitieX Nov 27, 2015
9c1090c
add screenshot of weblistener
FruitieX Apr 19, 2015
4f3c976
travis gitter webhook
FruitieX May 12, 2015
6d1e44d
gitter and coverall badges
FruitieX May 18, 2015
bbaacbc
getPlaylists function calls all backends and fetches playlists
FruitieX Nov 12, 2015
4f45c4b
WIP: playlist refactor
FruitieX Nov 12, 2015
e867248
more WIP
FruitieX Nov 12, 2015
c0505cf
simplify playlist logic by only using one list
FruitieX Nov 13, 2015
3142263
WIP: playlist refactor
FruitieX Nov 13, 2015
f491ab1
it runs!
FruitieX Nov 13, 2015
b940dd0
WIP
FruitieX Nov 13, 2015
51aa30e
first song plays fine
FruitieX Nov 13, 2015
0573945
playlist concepts
FruitieX Nov 26, 2015
e752aeb
WIP: refactor playback queue handling into queue.js
FruitieX Nov 26, 2015
faf0f3d
clarification
FruitieX Nov 26, 2015
b8e05b1
clarification
FruitieX Nov 26, 2015
4831197
clarification
FruitieX Nov 26, 2015
35db869
WIP: refactor and document, comment out tests for now
FruitieX Nov 26, 2015
3c6036f
s/curPlaylistPos/queue.curQueuePos
FruitieX Nov 26, 2015
5c54ab8
renames
FruitieX Nov 27, 2015
eab91e2
Merge branch 'playlists' of github.com:FruitieX/nodeplayer into playl…
FruitieX Nov 27, 2015
7994bf2
tests are passing
FruitieX Nov 27, 2015
41ed309
move playback vars into player
FruitieX Nov 28, 2015
6e2cdc0
split backend and song objects into own modules & constructors
FruitieX Nov 29, 2015
4de1526
fix build
FruitieX Nov 29, 2015
9083c19
insertion creates new Song objects
FruitieX Dec 5, 2015
55cd94d
move plugin/backend init code into separate module
FruitieX Dec 5, 2015
656df22
only bin/nodeplayer starts a new Player() instance, be more verbose o…
FruitieX Dec 5, 2015
312c0ab
fix build
FruitieX Dec 5, 2015
69e61ff
builtin plugins & backends
FruitieX Dec 6, 2015
79a22aa
fix build
FruitieX Dec 6, 2015
a02954d
fix typo
FruitieX Dec 6, 2015
3051669
playlist field, docs
FruitieX Dec 6, 2015
68159fd
move song encoding into backend super constructor
FruitieX Dec 6, 2015
9ff7d91
comment
FruitieX Dec 6, 2015
20c60d7
s/vars/player
FruitieX Dec 6, 2015
f1747b2
WIP: get local backend running again
FruitieX Dec 7, 2015
48e478f
probe and db insert works
FruitieX Dec 13, 2015
68062ec
fix build
FruitieX Dec 13, 2015
911a7bd
util.inherits must be called immediately after constructor
FruitieX Dec 13, 2015
762df9b
fix search, s/songID/songId
FruitieX Dec 13, 2015
34fbc86
adding and listing a song works
FruitieX Dec 20, 2015
4783a01
fix pause handling
FruitieX Dec 20, 2015
b160585
small cleanup + remove dead code
FruitieX Dec 20, 2015
c0fc47f
fix build
FruitieX Dec 20, 2015
ed98e4d
Update dependencies
FruitieX Jun 9, 2016
67d86d4
Avoid duplicate loggers, log when initializing modules
FruitieX Jun 9, 2016
e7dad79
Express module: announce which port we're listening on
FruitieX Jun 9, 2016
e292f2c
WIP: refactor
FruitieX Jun 21, 2016
da447b4
Streaming local files now works
FruitieX Jul 4, 2016
a8741e7
WIP: streaming songs while preparing
FruitieX Jul 5, 2016
b0c2fcd
Clear prepare timeout after song is prepared
FruitieX Jul 5, 2016
61cc97b
Move cancelPrepare() into common backend functions
FruitieX Jul 5, 2016
2517da3
Local backend: Try to guess metadata from filename if needed
FruitieX Jul 5, 2016
f568711
WIP: playback of preparing songs
FruitieX Jul 5, 2016
2c44c78
WIP: Keep song data in memory while preparing, write to disk once done
FruitieX Jul 5, 2016
1b73ede
Keep song data in memory while preparing
FruitieX Jul 6, 2016
124f645
WIP: streaming changes
FruitieX Jul 18, 2016
0ef737b
Run dev environment with node-babel, migrate plugins to ES6
FruitieX Aug 1, 2016
972cb5f
Add simple eslint config and make codebase pass
FruitieX Sep 5, 2016
c65d663
Editorconfig
FruitieX Sep 5, 2016
5c8253c
Add google js style preset, make codebase pass, add babel build script
FruitieX Sep 5, 2016
848888b
Convert all function definitions to ES6 arrow syntax
FruitieX Sep 5, 2016
fd175a0
Refactor remaining prototypes to be ES6 classes
FruitieX Sep 5, 2016
f2f1a9c
Disallow var keyword
FruitieX Sep 5, 2016
75ae35f
Enforce const on variables that don't change
FruitieX Sep 5, 2016
6f5ae0c
More eslint rules, fix comment indentation
FruitieX Sep 5, 2016
ebbb4da
Cleanup Player constructor
FruitieX Sep 5, 2016
d626a6d
WIP: make third party modules work properly
FruitieX Sep 5, 2016
9911eb1
Return songs as array
FruitieX Oct 9, 2016
731da04
Queue.insertSongs supports either Song objects or arrays
FruitieX Oct 9, 2016
45ffe12
Implement prepare() in core
FruitieX Oct 9, 2016
caf8af2
Create initial DB migration script (#35)
FruitieX Oct 19, 2016
e5c3ceb
Support backends & plugins calling callback without 'this' argument
FruitieX Oct 19, 2016
59f0f2d
Add db config file
FruitieX Oct 19, 2016
446ef5c
Move to hapi.js instead of express
FruitieX Nov 2, 2016
0963c01
Refactor plugin superclass into plugins dir
FruitieX Nov 2, 2016
c30e922
Refactor backend superclass into backends dir
FruitieX Nov 2, 2016
1baeacb
Implement search, queue and song data fetch routes with hapi.js
FruitieX Nov 12, 2016
9014bb1
Yarn lockfile
FruitieX Nov 12, 2016
0caaa48
@#$%ing EVERYTHING WORKS
FruitieX Nov 18, 2016
85af1fe
add some terrible hax to allow storeQueue to restore uuids, comment o…
FruitieX Nov 18, 2016
fa020e4
store queue even if it didnt exist at startup
FruitieX Nov 18, 2016
e7be625
fix more stupid typos
FruitieX Nov 18, 2016
3cec10f
Add endpoint for deleting songs
FruitieX Nov 19, 2016
11fac87
For now don't auto start playback after song prepared, causes weirdness
FruitieX Nov 19, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"presets": [
"es2015-node"
]
}
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# http://editorconfig.org

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
38 changes: 38 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"env": {
"node": true,
"mocha": true
},
"extends": [
"eslint:recommended",
"google"
],
"rules": {
"comma-dangle": ["error", "always-multiline"],
"quotes": ["error", "single"],
"max-len": ["warn", 100, 2],
"indent": ["error", 2],
"linebreak-style": "error",
"no-multiple-empty-lines": ["error", { "max": 1 }],
"no-trailing-spaces": "error",
"eol-last": "error",
"new-cap": ["error", { "properties": false }],
"arrow-parens": ["error", "as-needed"],
"no-var": "error",
"prefer-const": "warn",
"space-infix-ops": "error",
"space-before-blocks": "error",
"padded-blocks": ["error", "never"],
"object-curly-spacing": ["error", "always"],
"no-multi-spaces": "error",
"block-spacing": ["error", "always"],
"key-spacing": ["error", { "align": "value" }],
"comma-spacing": "error",
"computed-property-spacing": "error",
"keyword-spacing": "error"
}
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ node_modules
songCache
cache
settings

dist
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ notifications:
language: node_js
node_js:
- "node"
cache:
directories:
- node_modules
after_script:
- "npm run-script coverage"
- "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js"
10 changes: 0 additions & 10 deletions bin/nodeplayer

This file was deleted.

24 changes: 24 additions & 0 deletions db/migrations/000_initial.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*eslint-disable func-names*/
'use strict';

exports.up = function(knex) {
return knex.schema
.createTable('songs', function(table) {
table.text('songId').primary();
table.text('backendName').notNullable();
table.integer('duration').notNullable();
table.text('title').notNullable();
table.text('artist');
table.text('album');
table.text('albumArt');
table.timestamp('createdAt').defaultTo(knex.fn.now());
})

.then(function() {
});
};

exports.down = function(knex) {
return knex.schema
.dropTableIfExists('songs');
};
117 changes: 13 additions & 104 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,107 +1,16 @@
'use strict';

var _ = require('underscore');
var npm = require('npm');
var async = require('async');
var labeledLogger = require('./lib/logger');
var Player = require('./lib/player');
var nodeplayerConfig = require('./lib/config');
var config = nodeplayerConfig.getConfig();

var logger = labeledLogger('core');

function Core() {
this.player = new Player();
var config = require('./src/config');
var logger = require('./src/logger');

import Player from './src/player';
import Backend from './src/backends';
import Plugin from './src/plugins';

export {
Player,
Backend,
Plugin,
config,
logger,
}

Core.prototype.checkModule = function(module) {
try {
require.resolve(module);
return true;
} catch (e) {
return false;
}
};

Core.prototype.installModule = function(moduleName, callback) {
logger.info('installing module: ' + moduleName);
npm.load({}, function(err) {
npm.commands.install(__dirname, [moduleName], function(err) {
if (err) {
logger.error(moduleName + ' installation failed:', err);
callback();
} else {
logger.info(moduleName + ' successfully installed');
callback();
}
});
});
};

// make sure all modules are installed, installs missing ones, then calls loadCallback
Core.prototype.installModules = function(modules, moduleType, update, loadCallback) {
async.eachSeries(modules, _.bind(function(moduleShortName, callback) {
var moduleName = 'nodeplayer-' + moduleType + '-' + moduleShortName;
if (!this.checkModule(moduleName) || update) {
// perform install / update
this.installModule(moduleName, callback);
} else {
// skip already installed
callback();
}
}, this), loadCallback);
};

Core.prototype.initModule = function(moduleShortName, moduleType, callback) {
var moduleTypeCapital = moduleType.charAt(0).toUpperCase() + moduleType.slice(1);
var moduleName = 'nodeplayer-' + moduleType + '-' + moduleShortName;
var module = require(moduleName);

var moduleLogger = labeledLogger(moduleShortName);
module.init(this.player, moduleLogger, _.bind(function(err) {
if (!err) {
this[moduleType + 's'][moduleShortName] = module;
if (moduleType === 'backend') {
this.songsPreparing[moduleShortName] = {};
}

moduleLogger.info(moduleType + ' module initialized');
this.callHooks('on' + moduleTypeCapital + 'Initialized', [moduleShortName]);
} else {
moduleLogger.error('while initializing: ' + err);
this.callHooks('on' + moduleTypeCapital + 'InitError', [moduleShortName]);
}
callback(err);
}, this.player));
};

Core.prototype.initModules = function(update, callback) {
async.eachSeries(['plugin', 'backend'], _.bind(function(moduleType, installCallback) {
// first install missing modules
this.installModules(config[moduleType + 's'], moduleType, update, installCallback);
}, this), _.bind(function() {
// then initialize modules, first all plugins in series, then all backends in parallel
async.eachSeries(['plugin', 'backend'], _.bind(function(moduleType, typeCallback) {
var moduleTypeCapital = moduleType.charAt(0).toUpperCase() + moduleType.slice(1);

(moduleType === 'plugin' ? async.eachSeries : async.each)
(config[moduleType + 's'], _.bind(function(moduleName, moduleCallback) {
if (this.checkModule('nodeplayer-' + moduleType + '-' + moduleName)) {
this.initModule(moduleName, moduleType, moduleCallback);
}
}, this), _.bind(function(err) {
logger.info('all ' + moduleType + ' modules initialized');
this.callHooks('on' + moduleTypeCapital + 'sInitialized');
typeCallback();
}, this.player));
}, this), function() {
callback();
});
}, this));
};

exports.Player = Player;
exports.labeledLogger = labeledLogger;
exports.config = nodeplayerConfig;

exports.Core = Core;
28 changes: 28 additions & 0 deletions knexfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//This file is interpreted as ES5 CommonJS module.
'use strict';

const getConfig = require('./src/config').getConfig;

const ALL_ENVIRONMENTS = Object.assign(getConfig().db, {
pool: {
min: 1,
max: 1
},
migrations: {
tableName: 'nodeplayer_migrations',
directory: 'db/migrations'
}
});

// Feel free to create any number of other environments.
// The ones below are a best attempt at sensible defaults.
module.exports = {
// Developer's local machine
development: ALL_ENVIRONMENTS,
// Unit and integration test environment
test: ALL_ENVIRONMENTS,
// Shared test/qa/staging/preproduction
staging: ALL_ENVIRONMENTS,
// Production environment
production: ALL_ENVIRONMENTS
};
124 changes: 0 additions & 124 deletions lib/config.js

This file was deleted.

Loading