Merge remote-tracking branch 'tucuman/master'

Conflicts:
	.gitignore
This commit is contained in:
Manuel Araoz 2014-01-06 19:52:47 -03:00
commit 23a1843e30
40 changed files with 739 additions and 1 deletions

3
.bowerrc Normal file
View File

@ -0,0 +1,3 @@
{
"directory": "public/lib"
}

21
.editorconfig Normal file
View File

@ -0,0 +1,21 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 2
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

9
.gitignore vendored
View File

@ -1,5 +1,4 @@
# from https://github.com/github/gitignore/blob/master/Node.gitignore
lib-cov
*.seed
*.log
@ -8,6 +7,7 @@ lib-cov
*.out
*.pid
*.gz
*.swp
pids
logs
@ -21,3 +21,10 @@ node_modules
*~
.project
npm-debug.log
node_modules
.nodemonignore
.DS_Store
public/lib/*

40
.jshintrc Normal file
View File

@ -0,0 +1,40 @@
{
"node": true, // Enable globals available when code is running inside of the NodeJS runtime environment.
"browser": true, // Standard browser globals e.g. `window`, `document`.
"esnext": true, // Allow ES.next specific features such as `const` and `let`.
"bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.).
"camelcase": false, // Permit only camelcase for `var` and `object indexes`.
"curly": false, // Require {} for every new block or scope.
"eqeqeq": true, // Require triple equals i.e. `===`.
"immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
"latedef": true, // Prohibit variable use before definition.
"newcap": true, // Require capitalization of all constructor functions e.g. `new F()`.
"noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`.
"quotmark": "single", // Define quotes to string values.
"regexp": true, // Prohibit `.` and `[^...]` in regular expressions.
"undef": true, // Require all non-global variables be declared before they are used.
"unused": true, // Warn unused variables.
"strict": true, // Require `use strict` pragma in every file.
"trailing": true, // Prohibit trailing whitespaces.
"smarttabs": false, // Suppresses warnings about mixed tabs and spaces
"globals": { // Globals variables.
"angular": true
},
"predef": [ // Extra globals.
"define",
"require",
"exports",
"module",
"describe",
"before",
"beforeEach",
"after",
"afterEach",
"it",
"inject",
"expect"
],
"indent": 2, // Specify indentation spacing
"devel": true, // Allow development statements e.g. `console.log();`.
"noempty": true // Prohibit use of empty blocks.
}

94
Gruntfile.js Normal file
View File

@ -0,0 +1,94 @@
'use strict';
module.exports = function(grunt) {
// Project Configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
jade: {
files: ['app/views/**'],
options: {
livereload: true,
},
},
js: {
files: ['Gruntfile.js', 'server.js', 'app/**/*.js', 'public/js/**'],
tasks: ['jshint'],
options: {
livereload: true,
},
},
html: {
files: ['public/views/**'],
options: {
livereload: true,
},
},
css: {
files: ['public/css/**'],
options: {
livereload: true
}
}
},
jshint: {
all: {
src: ['Gruntfile.js', 'server.js', 'app/**/*.js', 'public/js/**'],
options: {
jshintrc: true
}
}
},
nodemon: {
dev: {
options: {
file: 'server.js',
args: [],
ignoredFiles: ['public/**'],
watchedExtensions: ['js'],
nodeArgs: ['--debug'],
delayTime: 1,
env: {
PORT: 3000
},
cwd: __dirname
}
}
},
concurrent: {
tasks: ['nodemon', 'watch'],
options: {
logConcurrentOutput: true
}
},
mochaTest: {
options: {
reporter: 'spec',
require: 'server.js'
},
src: ['test/*.js']
},
env: {
test: {
NODE_ENV: 'test'
}
}
});
//Load NPM tasks
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadNpmTasks('grunt-nodemon');
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-env');
//Making grunt default to force in order not to break the project.
grunt.option('force', true);
//Default task(s).
grunt.registerTask('default', ['jshint', 'concurrent']);
//Test task.
grunt.registerTask('test', ['env:test', 'mochaTest']);
};

View File

@ -1,2 +1,17 @@
mystery
=======
## Install
- sudo npm -g i grunt-cli
- npm i
- grunt
## bitcoind configuration
There is a bitcoind configuration sample at:
```
etc/mystery/bitcoin.conf
```

5
app/controllers/index.js Normal file
View File

@ -0,0 +1,5 @@
'use strict';
exports.render = function(req, res) {
res.render('index');
};

13
app/views/404.jade Executable file
View File

@ -0,0 +1,13 @@
extends layouts/default
block main
h1 Oops something went wrong
br
span 404
block content
#error-message-box
#error-stack-trace
pre
code!= error

12
app/views/500.jade Executable file
View File

@ -0,0 +1,12 @@
extends layouts/default
block main
h1 Oops something went wrong
br
span 500
block content
#error-message-box
#error-stack-trace
pre
code!= error

31
app/views/includes/foot.jade Executable file
View File

@ -0,0 +1,31 @@
#footer
.container
p.text-muted Place sticky footer content here.
//script(type='text/javascript', src='/lib/jquery/jquery.min.js')
//script(type='text/javascript', src='/lib/bootstrap/dist/js/bootstrap.min.js')
//AngularJS
script(type='text/javascript', src='/lib/angular/angular.js')
script(type='text/javascript', src='/lib/angular-cookies/angular-cookies.js')
script(type='text/javascript', src='/lib/angular-resource/angular-resource.js')
script(type='text/javascript', src='/lib/angular-route/angular-route.js')
//Angular UI
script(type='text/javascript', src='/lib/angular-bootstrap/ui-bootstrap.js')
script(type='text/javascript', src='/lib/angular-bootstrap/ui-bootstrap-tpls.js')
script(type='text/javascript', src='/lib/angular-ui-utils/ui-utils.js')
//Application Init
script(type='text/javascript', src='/js/app.js')
script(type='text/javascript', src='/js/config.js')
script(type='text/javascript', src='/js/directives.js')
script(type='text/javascript', src='/js/filters.js')
//Application Services
script(type='text/javascript', src='/js/services/global.js')
//Application Controllers
script(type='text/javascript', src='/js/controllers/index.js')
script(type='text/javascript', src='/js/controllers/header.js')
script(type='text/javascript', src='/js/init.js')

15
app/views/includes/head.jade Executable file
View File

@ -0,0 +1,15 @@
head
meta(charset='utf-8')
meta(http-equiv='X-UA-Compatible', content='IE=edge,chrome=1')
meta(name='viewport', content='width=device-width,initial-scale=1.0')
title Mystery
meta(http-equiv='Content-type', content='text/html;charset=UTF-8')
meta(name="keywords", content="node.js, express, mongoose, mongodb, angularjs")
meta(name="description", content="Mystery")
link(href='/img/icons/favicon.ico', rel='shortcut icon', type='image/x-icon')
link(rel='stylesheet', href='/lib/bootstrap/dist/css/bootstrap.min.css')
link(rel='stylesheet', href='/css/common.css')

View File

@ -0,0 +1 @@
.navbar.navbar-default.navbar-fixed-top(data-ng-include="'views/header.html'", role='navigation')

25
app/views/index.jade Executable file
View File

@ -0,0 +1,25 @@
extends layouts/default
block content
section.container(data-ng-view)
section.container
p ˈmɪst(ə)ri/'
| noun
audio(src="https://ssl.gstatic.com/dictionary/static/sounds/de/0/mystery.mp3",preload="auto",data-dobid="aud",id="aud")
button(onclick="document.getElementById('aud').play()") Play
ol
li
strong something that is difficult or impossible to understand or explain.
p "the mysteries of outer space"
| synonyms: puzzle, enigma, conundrum, riddle, secret, unsolved problem, problem, question, question mark, closed book; secrecy or obscurity.
p "much of her past is shrouded in mystery"
| synonyms: secrecy, darkness, obscurity, ambiguity, ambiguousness, uncertainty, impenetrability, vagueness, nebulousness; More
li
strong a person or thing whose identity or nature is puzzling or unknown.
p "He's a bit of a mystery, said Nina"
li
strong a novel, play, or film dealing with a puzzling crime, especially a murder.
p "the 1920s murder mystery, The Ghost Train"
| synonyms: thriller, detective story/novel, murder story; More

8
app/views/layouts/default.jade Executable file
View File

@ -0,0 +1,8 @@
doctype html
html(lang='en', xmlns='http://www.w3.org/1999/xhtml')
include ../includes/head
body
#wrap
include ../includes/navbar
block content
include ../includes/foot

14
bower.json Normal file
View File

@ -0,0 +1,14 @@
{
"name": "Mystery",
"version": "0.0.1",
"dependencies": {
"angular": "latest",
"angular-resource": "latest",
"angular-cookies": "latest",
"angular-mocks": "latest",
"angular-route": "latest",
"bootstrap": "3.0.3",
"angular-bootstrap": "0.9.0",
"angular-ui-utils": "0.1.0"
}
}

9
config/config.js Normal file
View File

@ -0,0 +1,9 @@
'use strict';
var _ = require('lodash');
// Load app configuration
module.exports = _.extend(
require(__dirname + '/../config/env/all.js'),
require(__dirname + '/../config/env/' + process.env.NODE_ENV + '.js') || {});

10
config/env/all.js vendored Executable file
View File

@ -0,0 +1,10 @@
'use strict';
var path = require('path'),
rootPath = path.normalize(__dirname + '/../..');
module.exports = {
root: rootPath,
port: process.env.PORT || 3000,
db: process.env.MONGOHQ_URL
}

8
config/env/development.js vendored Executable file
View File

@ -0,0 +1,8 @@
'use strict';
module.exports = {
db: "mongodb://localhost/mystery-dev",
app: {
name: "Mystery - Development"
}
}

8
config/env/production.js vendored Executable file
View File

@ -0,0 +1,8 @@
'use strict';
module.exports = {
db: "mongodb://localhost/mystery",
app: {
name: "Mystery - Production"
}
}

9
config/env/test.js vendored Executable file
View File

@ -0,0 +1,9 @@
'use strict';
module.exports = {
db: "mongodb://localhost/mystery-test",
port: 3001,
app: {
name: "Mystery - Test"
}
}

69
config/express.js Normal file
View File

@ -0,0 +1,69 @@
'use strict';
/**
* Module dependencies.
*/
var express = require('express'),
config = require('./config');
module.exports = function(app, passport, db) {
app.set('showStackError', true);
//Prettify HTML
app.locals.pretty = true;
//Should be placed before express.static
app.use(express.compress({
filter: function(req, res) {
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
},
level: 9
}));
//Set views path, template engine and default layout
app.set('views', config.root + '/app/views');
app.set('view engine', 'jade');
//Enable jsonp
app.enable("jsonp callback");
app.configure(function() {
//cookieParser should be above session
app.use(express.cookieParser());
// request body parsing middleware should be above methodOverride
app.use(express.urlencoded());
app.use(express.json());
app.use(express.methodOverride());
//routes should be at the last
app.use(app.router);
//Setting the fav icon and static folder
app.use(express.favicon());
app.use(express.static(config.root + '/public'));
//Assume "not found" in the error msgs is a 404. this is somewhat silly, but valid, you can do whatever you like, set properties, use instanceof etc.
app.use(function(err, req, res, next) {
//Treat as 404
if (~err.message.indexOf('not found')) return next();
//Log it
console.error(err.stack);
//Error page
res.status(500).render('500', {
error: err.stack
});
});
//Assume 404 since no middleware responded
app.use(function(req, res, next) {
res.status(404).render('404', {
url: req.originalUrl,
error: 'Not found'
});
});
});
};

12
config/routes.js Normal file
View File

@ -0,0 +1,12 @@
'use strict';
module.exports = function(app) {
//Home route
var index = require('../app/controllers/index');
app.get('/', index.render);
//TX routes
//
};

13
etc/bitcoind/bitcoin.conf Normal file
View File

@ -0,0 +1,13 @@
rpcuser=mystery
rpcpassword=real_mystery
server=1
rpcport=8332
testnet=3
txindex=1
# Allow connections outsite localhost?
# rpcallowip=192.168.0.*

62
package.json Normal file
View File

@ -0,0 +1,62 @@
{
"name": "mystery",
"version": "0.0.1",
"private": true,
"author": {
"name": "Ryan X Charles",
"email": "ryan@bitpay.com"
},
"repository": "git://github.com/bitpay/mystery.git",
"contributors": [
{
"name": "Matias Alejo Garcia",
"email": "ematiu@gmail.com"
}
],
"bugs": {
"url": "https://github.com/bitpay/mystery/issues"
},
"homepage": "https://github.com/bitpay/mystery",
"license": "MIT",
"keywords": [
"mystery",
"secret",
"enigma",
"riddle",
"mystification",
"puzzle",
"conundrum"
],
"engines": {
"node": "*"
},
"scripts": {
"start": "node node_modules/grunt-cli/bin/grunt",
"postinstall": "node node_modules/bower/bin/bower install"
},
"dependencies": {
"express": "~3.4.7",
"jade": "~1.0.2",
"mongoose": "~3.8.3",
"lodash": "~2.4.1",
"bower": "~1.2.8",
"bitcore": "*",
"grunt": "~0.4.2",
"grunt-cli": "~0.1.11",
"grunt-env": "~0.4.1",
"grunt-contrib-jshint": "~0.8.0",
"grunt-contrib-watch": "~0.5.3",
"grunt-concurrent": "~0.4.2",
"grunt-nodemon": "~0.1.2",
"grunt-mocha-test": "~0.8.1",
"should": "~2.1.1"
},
"devDependencies": {
"grunt-contrib-watch": "latest",
"grunt-contrib-jshint": "latest",
"grunt-nodemon": "latest",
"grunt-concurrent": "latest",
"grunt-mocha-test": "latest",
"should": "latest"
}
}

45
public/css/common.css Normal file
View File

@ -0,0 +1,45 @@
/* Sticky footer styles
-------------------------------------------------- */
html,
body {
height: 100%;
/* The html and body elements cannot have any padding or margin. */
}
/* Wrapper for page content to push down footer */
#wrap {
min-height: 100%;
height: auto;
/* Negative indent footer by its height */
margin: 0 auto -60px;
/* Pad bottom by footer height */
padding: 0 0 60px;
}
/* Set the fixed height of the footer here */
#footer {
height: 60px;
background-color: #f5f5f5;
}
/* Custom page CSS
-------------------------------------------------- */
/* Not required for template or sticky footer method. */
#wrap > .container {
padding: 60px 15px 0;
}
.container .text-muted {
margin: 20px 0;
}
#footer > .container {
padding-left: 15px;
padding-right: 15px;
}
code {
font-size: 80%;
}

0
public/img/.gitignore vendored Executable file
View File

5
public/js/app.js Executable file
View File

@ -0,0 +1,5 @@
'use strict';
angular.module('mystery', ['ngCookies', 'ngResource', 'ngRoute', 'ui.bootstrap', 'ui.route', 'mystery.system']);
angular.module('mystery.system', []);

21
public/js/config.js Executable file
View File

@ -0,0 +1,21 @@
'use strict';
//Setting up route
angular.module('mystery').config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'views/index.html'
}).
otherwise({
redirectTo: '/'
});
}
]);
//Setting HTML5 Location Mode
angular.module('mystery').config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('!');
}
]);

15
public/js/controllers/header.js Executable file
View File

@ -0,0 +1,15 @@
'use strict';
angular.module('mystery.system').controller('HeaderController', ['$scope', 'Global', function ($scope, Global) {
$scope.global = Global;
$scope.menu = [{
'title': 'Articles',
'link': 'articles'
}, {
'title': 'Create New Article',
'link': 'articles/create'
}];
$scope.isCollapsed = false;
}]);

5
public/js/controllers/index.js Executable file
View File

@ -0,0 +1,5 @@
'use strict';
angular.module('mystery.system').controller('IndexController', ['$scope', 'Global', function ($scope, Global) {
$scope.global = Global;
}]);

1
public/js/directives.js Executable file
View File

@ -0,0 +1 @@
'use strict';

1
public/js/filters.js Executable file
View File

@ -0,0 +1 @@
'use strict';

9
public/js/init.js Executable file
View File

@ -0,0 +1,9 @@
'use strict';
angular.element(document).ready(function() {
//Fixing facebook bug with redirect
if (window.location.hash === '#_=_') window.location.hash = '#!';
//Then init the app
angular.bootstrap(document, ['mystery']);
});

14
public/js/services/global.js Executable file
View File

@ -0,0 +1,14 @@
'use strict';
//Global service for global variables
angular.module('mystery.system').factory('Global', [
function() {
var _this = this;
_this._data = {
user: window.user,
authenticated: !! window.user
};
return _this._data;
}
]);

18
public/views/header.html Executable file
View File

@ -0,0 +1,18 @@
<div class="container" data-ng-controller="HeaderController">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Mystery</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</div>
</div>

5
public/views/index.html Normal file
View File

@ -0,0 +1,5 @@
<section data-ng-controller="IndexController">
<div class="page-header">
<h1>Hello BitPay!</h1>
</div>
</section>

55
server.js Normal file
View File

@ -0,0 +1,55 @@
'use strict';
/**
* Module dependencies.
*/
var express = require('express'),
fs = require('fs');
/**
* Main application entry file.
*/
//Load configurations
//Set the node enviornment variable if not set before
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
//Initializing system variables
var config = require('./config/config'),
mongoose = require('mongoose');
//Bootstrap db connection
var db = mongoose.connect(config.db);
//Bootstrap models
var models_path = __dirname + '/app/models';
var walk = function(path) {
fs.readdirSync(path).forEach(function(file) {
var newPath = path + '/' + file;
var stat = fs.statSync(newPath);
if (stat.isFile()) {
if (/(.*)\.(js$|coffee$)/.test(file)) {
require(newPath);
}
} else if (stat.isDirectory()) {
walk(newPath);
}
});
};
walk(models_path);
var app = express();
//express settings
require('./config/express')(app, db);
//Bootstrap routes
require('./config/routes')(app);
//Start the app by listening on <port>
var port = process.env.PORT || config.port;
app.listen(port);
console.log('Express app started on port ' + port);
//expose app
exports = module.exports = app;

4
test/mocha.opts Normal file
View File

@ -0,0 +1,4 @@
--require should
-R spec
--ui bdd

9
test/test.js Normal file
View File

@ -0,0 +1,9 @@
var assert = require("assert")
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
})
})
})

27
util/get_block.js Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env node
var RpcClient = require('../node_modules/bitcore/RpcClient').class();
var block_hash = process.argv[2] || '0000000000b6288775bbd326bedf324ca8717a15191da58391535408205aada4';
var rpc = new RpcClient({
user: 'mystery',
pass: 'real_mystery',
protocol: 'http',
});
var block = rpc.getBlock(block_hash, function(err, block) {
console.log("Err:");
console.log(err);
console.log("Block info:");
console.log(block);
});