sync for blocks

This commit is contained in:
Matias Alejo Garcia 2014-01-07 00:19:12 -03:00
commit 4425b43f2f
24 changed files with 393 additions and 66 deletions

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

1
.gitignore vendored
View File

@ -14,6 +14,7 @@ results
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

@ -2,6 +2,13 @@ mystery
=======
## Install
- sudo npm -g i grunt-cli
- npm i
- grunt
## bitcoind configuration
There is a bitcoind configuration sample at:

View File

@ -2,5 +2,30 @@
.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')
//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')

View File

@ -1,17 +1 @@
.navbar.navbar-default.navbar-fixed-top(role='navigation')
.container
.navbar-header
button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-collapse')
span.sr-only Toggle navigation
span.icon-bar
span.icon-bar
span.icon-bar
a.navbar-brand(href='#') Mystery
.collapse.navbar-collapse
ul.nav.navbar-nav
li.active
a(href='#') Home
li
a(href='#about') About
li
a(href='#contact') Contact
.navbar.navbar-default.navbar-fixed-top(data-ng-include="'views/header.html'", role='navigation')

View File

@ -1,24 +1,25 @@
extends layouts/default
block content
.page-header
h1 Hello BitPay!
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
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

View File

@ -4,6 +4,5 @@ html(lang='en', xmlns='http://www.w3.org/1999/xhtml')
body
#wrap
include ../includes/navbar
section.container
block content
block content
include ../includes/foot

View File

@ -2,6 +2,13 @@
"name": "Mystery",
"version": "0.0.1",
"dependencies": {
"bootstrap": "3.0.3"
"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"
}
}

View File

@ -7,10 +7,12 @@
"email": "ryan@bitpay.com"
},
"repository": "git://github.com/bitpay/mystery.git",
"contributors": [{
"name": "Matias Alejo Garcia",
"email": "ematiu@gmail.com"
}],
"contributors": [
{
"name": "Matias Alejo Garcia",
"email": "ematiu@gmail.com"
}
],
"bugs": {
"url": "https://github.com/bitpay/mystery/issues"
},
@ -29,6 +31,7 @@
"node": "*"
},
"scripts": {
"start": "node node_modules/grunt-cli/bin/grunt",
"postinstall": "node node_modules/bower/bin/bower install"
},
"dependencies": {
@ -39,6 +42,23 @@
"lodash": "~2.4.1",
"bower": "~1.2.8",
"bitcore": "*",
"buffertools": "*"
"buffertools": "*",
"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"
}
}

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>

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));
})
})
})

View File

@ -11,15 +11,19 @@ var config = require('../config/config');
var mongoose = require('mongoose');
var networkName = process.argv[2] || 'testnet';
var genesisBlockHash = networks.testnet.genesisBlock.hash.reverse().toString('hex');
var network = networkName == 'testnet' ? networks.testnet : networks.livenet;
function syncBlocks(blockHash) {
function getNextBlock(blockHash,cb) {
if ( !blockHash ) {
console.log("done");
return cb();
}
rpc.getBlock(blockHash, function(err, blockInfo) {
if (err) {
console.log(err);
throw(err);
return cb(err);
}
if ( ! ( blockInfo.result.height % 1000) )
@ -27,25 +31,39 @@ function syncBlocks(blockHash) {
Block.create( blockInfo.result, function(err, inBlock) {
if (err && err.toString().match(/E11000/)) {
// console.log("\twas there. Skipping");
return syncBlocks(blockInfo.result.nextblockhash);
// E11000 => already exists
if (err && ! err.toString().match(/E11000/)) {
return cb(err);
}
if (err) throw(err);
if (inBlock.nextblockhash && ! inBlock.nextblockhash.match(/^0+$/) ) {
syncBlocks(inBlock.nextblockhash)
}
else {
mongoose.connection.close();
}
return getNextBlock(blockInfo.result.nextblockhash);
});
});
}
function syncBlocks(network, cb) {
Block.findOne({}, {}, { sort: { 'height' : -1 } }, function(err, block) {
if (err) {
return cb(err);
}
var nextHash =
block && block.hash
? block.hash
: network.genesisBlock.hash.reverse().toString('hex')
;
console.log('Starting at hash' + nextHash);
getNextBlock(nextHash, cb);
});
}
mongoose.connect(config.db);
@ -55,9 +73,12 @@ var rpc = new RpcClient(config.bitcoind);
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback () {
syncBlocks(genesisBlockHash);
syncBlocks(network, function(err) {
if (err) {
console.log(err);
}
mongoose.connection.close();
});
});