mongoose migration, db models and torrent details - seedlinux - Torrent indexing tool opensource torrents with share ratio's etc.
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit e9c73f44d56778f627f379c8771dec110db24b1c
 (DIR) parent 231870fba89f2a4082e2433ca3cb6cbd610db745
 (HTM) Author: Jay Scott <jay@jayscott.co.uk>
       Date:   Thu, 29 Jun 2017 20:51:15 +0100
       
       mongoose migration, db models and torrent details
       
           moving from mongodb/monk to mongoose
       
           things were getting a bit of a mess to say the least. I have now
           created controllers and models along with moving to mongoose.
       
             - I have removed all old routes
             - Add an model and controller for Torrents
             - Added in async for better handling of requests
             - Removed the DB loader and just used app.js
             - Moved the content to /torrent
             - Create a torrent details page
       
       Diffstat:
         M app.js                              |      15 +++++++++++----
         M app/db.js                           |      10 ++++++----
         M config/development.json             |       2 +-
         A controllers/torrents_controller.js  |      31 +++++++++++++++++++++++++++++++
         A models/torrent_model.js             |      27 +++++++++++++++++++++++++++
         M package-lock.json                   |     124 ++++++++++++++++++++-----------
         M package.json                        |       4 ++--
         M routes/index.js                     |      14 +++-----------
         D routes/parse.js                     |      72 -------------------------------
         A routes/torrent_route.js             |      10 ++++++++++
         A views/details.pug                   |      65 +++++++++++++++++++++++++++++++
         D views/index.pug                     |      27 ---------------------------
         M views/layout.pug                    |       2 +-
         A views/torrent.pug                   |      24 ++++++++++++++++++++++++
       
       14 files changed, 260 insertions(+), 167 deletions(-)
       ---
 (DIR) diff --git a/app.js b/app.js
       @@ -6,11 +6,18 @@ const favicon = require('serve-favicon');
        const logger = require('morgan');
        const cookieParser = require('cookie-parser');
        const bodyParser = require('body-parser');
       +const mongoose = require('mongoose');
        
       -const dbconn = require('./app/db');
       -const parse = require('./routes/parse');
       +const config = require('./app/config');
       +const torrent = require('./routes/torrent_route');
        const index = require('./routes/index');
        
       +const mongoDB = config.dbURI;
       +mongoose.connect(mongoDB);
       +
       +var db = mongoose.connection;
       +db.on('error', console.error.bind(console, 'MongoDB connection error:'));
       +
        const app = express();
        
        app.set('views', path.join(__dirname, 'views'));
       @@ -23,12 +30,12 @@ app.use(cookieParser());
        app.use(express.static(path.join(__dirname, 'public')));
        
        app.use(function(req,res,next){
       -    req.db = dbconn.db;
       +    req.db = db;
            next();
        });
        
        app.use('/', index);
       -app.use('/parse/', parse);
       +app.use('/torrent/', torrent);
        
        app.use(function(req, res, next) {
          var err = new Error('Not Found');
 (DIR) diff --git a/app/db.js b/app/db.js
       @@ -1,10 +1,12 @@
        'use strict';
        
       -const config = require('./config');
       -const mongo = require('mongodb');
       -const monk = require('monk');
       +const mongoose = require('mongoose');
        
       -const db = monk(config.dbURI);
       +const mongoDB = config.dbURI;
       +mongoose.connect(mongoDB);
       +
       +var db = mongoose.connection;
       +db.on('error', console.error.bind(console, 'MongoDB connection error:'));
        
        module.exports = { 
                db
 (DIR) diff --git a/config/development.json b/config/development.json
       @@ -1,6 +1,6 @@
        { 
          "host": "http://localhost:3000",
       -  "dbURI": "localhost:27017/seedlinux",
       +  "dbURI": "mongodb://localhost:27017/seedlinux",
          "collection" : "torrents",
          "torrent_data" : "data/torrents"
        }
        \ No newline at end of file
 (DIR) diff --git a/controllers/torrents_controller.js b/controllers/torrents_controller.js
       @@ -0,0 +1,31 @@
       +'use strict';
       +
       +let Torrent = require('../models/torrent_model');
       +const async = require('async');
       +
       +exports.index = function(req, res) {   
       +    
       +    async.parallel({
       +        torrent_count: function(callback) {
       +            Torrent.count(callback);
       +        },
       +        torrent_data: function(callback) {
       +            Torrent.find({},callback);
       +        },
       +    }, function(err, results) {
       +        res.render('torrent', { title: 'Index Page', error: err, data: results });
       +    });
       +};
       +
       +exports.torrent_detail = function(req, res) {
       +    async.parallel({
       +      torrent_count: function(callback) {
       +        Torrent.count(callback);
       +      },
       +      torrent_data: function(callback) {
       +          Torrent.find({hash: req.params.id},callback);
       +      },
       +    }, function(err, results) {
       +        res.render('details', { title: 'Torrent Details', error: err, data: results });
       +    });
       +};
 (DIR) diff --git a/models/torrent_model.js b/models/torrent_model.js
       @@ -0,0 +1,27 @@
       +'use strict';
       +
       +const mongoose = require('mongoose');
       +const Schema = mongoose.Schema;
       +
       +const TorrentSchema = Schema(
       +  {
       +    name: {type: String, required: true, max: 100},
       +    hash: {type: String, required: true, max: 20},
       +    created: {type: String},
       +    comment: {type: String, max: 100},
       +    announce: [
       +      {type: String}
       +      ],  
       +    files: [{
       +      path: String,
       +      name: String,
       +      length: Number,
       +      offset: Number
       +    }],
       +    magneturi: {type: String},
       +    leechers: {type: Number},
       +    seeders: {type: Number},
       +  }
       +);
       +
       +module.exports = mongoose.model('Torrent', TorrentSchema);
 (DIR) diff --git a/package-lock.json b/package-lock.json
       @@ -50,6 +50,11 @@
              "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.5.tgz",
              "integrity": "sha1-UidltQw1EEkOUtfc/ghe+bqWlY8="
            },
       +    "async": {
       +      "version": "2.5.0",
       +      "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
       +      "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw=="
       +    },
            "basic-auth": {
              "version": "1.1.0",
              "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz",
       @@ -72,6 +77,11 @@
              "resolved": "https://registry.npmjs.org/blob-to-buffer/-/blob-to-buffer-1.2.6.tgz",
              "integrity": "sha1-CJrCZMaGtz6tbFOaSEqAA7+7IDM="
            },
       +    "bluebird": {
       +      "version": "2.10.2",
       +      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.2.tgz",
       +      "integrity": "sha1-AkpVFylTCIV/FPkfEQb8O1VfRGs="
       +    },
            "body-parser": {
              "version": "1.17.2",
              "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz",
       @@ -268,6 +278,11 @@
              "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
              "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg="
            },
       +    "hooks-fixed": {
       +      "version": "2.0.0",
       +      "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-2.0.0.tgz",
       +      "integrity": "sha1-oB2JTVKsf2WZu7H2PfycQR33DLo="
       +    },
            "http-errors": {
              "version": "1.6.1",
              "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.1.tgz",
       @@ -323,6 +338,11 @@
              "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
              "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM="
            },
       +    "kareem": {
       +      "version": "1.4.1",
       +      "resolved": "https://registry.npmjs.org/kareem/-/kareem-1.4.1.tgz",
       +      "integrity": "sha1-7XYgAET6BB7zK02oJh4lU/EXNTE="
       +    },
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
       @@ -333,10 +353,10 @@
              "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
              "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4="
            },
       -    "lint": {
       -      "version": "1.1.2",
       -      "resolved": "https://registry.npmjs.org/lint/-/lint-1.1.2.tgz",
       -      "integrity": "sha1-Ne0GTzIlR8MxNY2JmGhmSWi6Nx8="
       +    "lodash": {
       +      "version": "4.17.4",
       +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
       +      "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
            },
            "longest": {
              "version": "1.0.1",
       @@ -379,60 +399,64 @@
              "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0="
            },
            "mongodb": {
       -      "version": "2.2.29",
       -      "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.29.tgz",
       -      "integrity": "sha512-MrQvIsN6zN80I4hdFo8w46w51cIqD2FJBGsUfApX9GmjXA1aCclEAJbOHaQWjCtabeWq57S3ECzqEKg/9bdBhA=="
       +      "version": "2.2.27",
       +      "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.27.tgz",
       +      "integrity": "sha1-NBIgNNtm2YO89qta2yaiSnD+9uY="
            },
            "mongodb-core": {
       -      "version": "2.1.13",
       -      "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.13.tgz",
       -      "integrity": "sha512-mbcvqLLZwVcpTrsfBDY3hRNk2SDNJWOvKKxFJSc0pnUBhYojymBc/L0THfQsWwKJrkb2nIXSjfFll1mG/I5OqQ=="
       -    },
       -    "monk": {
       -      "version": "6.0.1",
       -      "resolved": "https://registry.npmjs.org/monk/-/monk-6.0.1.tgz",
       -      "integrity": "sha512-R3fD134A/Y5kx2TPs3knFJxLc8b5kTs4Cqo3N3P/dsZjx5JMJpLHQtlEiy0CO2NPRHjH4lGBc+WziEqeyzjtiA=="
       -    },
       -    "monk-middleware-cast-ids": {
       -      "version": "0.2.1",
       -      "resolved": "https://registry.npmjs.org/monk-middleware-cast-ids/-/monk-middleware-cast-ids-0.2.1.tgz",
       -      "integrity": "sha1-QMQOWmyzPM7cKJIglDJ17ohhxSk="
       -    },
       -    "monk-middleware-fields": {
       -      "version": "0.2.0",
       -      "resolved": "https://registry.npmjs.org/monk-middleware-fields/-/monk-middleware-fields-0.2.0.tgz",
       -      "integrity": "sha1-/2N6819ZSIecyyvhWpE2CRG+psE="
       -    },
       -    "monk-middleware-handle-callback": {
       -      "version": "0.2.0",
       -      "resolved": "https://registry.npmjs.org/monk-middleware-handle-callback/-/monk-middleware-handle-callback-0.2.0.tgz",
       -      "integrity": "sha1-+r+TduzfAMnjbImwWuoIEri4Ohw="
       -    },
       -    "monk-middleware-options": {
       -      "version": "0.2.1",
       -      "resolved": "https://registry.npmjs.org/monk-middleware-options/-/monk-middleware-options-0.2.1.tgz",
       -      "integrity": "sha1-WNrhxRjUZjbr3/UG+t/Hc7tEKIY="
       -    },
       -    "monk-middleware-query": {
       -      "version": "0.2.0",
       -      "resolved": "https://registry.npmjs.org/monk-middleware-query/-/monk-middleware-query-0.2.0.tgz",
       -      "integrity": "sha1-qSbGd9SlYgxiFRsKVtDAwVFnWHQ="
       -    },
       -    "monk-middleware-wait-for-connection": {
       -      "version": "0.2.0",
       -      "resolved": "https://registry.npmjs.org/monk-middleware-wait-for-connection/-/monk-middleware-wait-for-connection-0.2.0.tgz",
       -      "integrity": "sha1-MSlY0w5Yi1fQl1TdfJe0hDMWg1o="
       +      "version": "2.1.11",
       +      "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.11.tgz",
       +      "integrity": "sha1-HDh3bOsXSZepnCiGDu2QKNqbPho="
       +    },
       +    "mongoose": {
       +      "version": "4.10.8",
       +      "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.10.8.tgz",
       +      "integrity": "sha1-MfRO14hHVvn9m3cI3cs/y0JQ804=",
       +      "dependencies": {
       +        "async": {
       +          "version": "2.1.4",
       +          "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz",
       +          "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ="
       +        }
       +      }
            },
            "morgan": {
              "version": "1.8.2",
              "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.8.2.tgz",
              "integrity": "sha1-eErHc05KRTqcbm6GgKkyknXItoc="
            },
       +    "mpath": {
       +      "version": "0.3.0",
       +      "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.3.0.tgz",
       +      "integrity": "sha1-elj3iem1/TyUUgY0FXlg8mvV70Q="
       +    },
       +    "mpromise": {
       +      "version": "0.5.5",
       +      "resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.5.tgz",
       +      "integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY="
       +    },
       +    "mquery": {
       +      "version": "2.3.1",
       +      "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.3.1.tgz",
       +      "integrity": "sha1-mrNnSXFIAP8LtTpoHOS8TV8HyHs=",
       +      "dependencies": {
       +        "sliced": {
       +          "version": "0.0.5",
       +          "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz",
       +          "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8="
       +        }
       +      }
       +    },
            "ms": {
              "version": "2.0.0",
              "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
              "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
            },
       +    "muri": {
       +      "version": "1.2.1",
       +      "resolved": "https://registry.npmjs.org/muri/-/muri-1.2.1.tgz",
       +      "integrity": "sha1-7H6lzmympSPrGrNbrNpfqBbJqjw="
       +    },
            "negotiator": {
              "version": "0.6.1",
              "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
       @@ -590,6 +614,11 @@
              "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz",
              "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE="
            },
       +    "regexp-clone": {
       +      "version": "0.0.1",
       +      "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz",
       +      "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk="
       +    },
            "repeat-string": {
              "version": "1.6.1",
              "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
       @@ -679,6 +708,11 @@
              "resolved": "https://registry.npmjs.org/simple-sha1/-/simple-sha1-2.1.0.tgz",
              "integrity": "sha1-lCe7lv8SY8wQqEFM7dUaGLkZ6LM="
            },
       +    "sliced": {
       +      "version": "1.0.1",
       +      "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
       +      "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
       +    },
            "source-map": {
              "version": "0.4.4",
              "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
 (DIR) diff --git a/package.json b/package.json
       @@ -8,12 +8,12 @@
          },
          "dependencies": {
            "app-root-path": "^2.0.1",
       +    "async": "^2.5.0",
            "body-parser": "~1.17.1",
            "cookie-parser": "~1.4.3",
            "debug": "~2.6.3",
            "express": "~4.15.2",
       -    "mongodb": "^2.2.29",
       -    "monk": "^6.0.1",
       +    "mongoose": "^4.10.8",
            "morgan": "~1.8.1",
            "parse-torrent": "^5.8.3",
            "pug": "~2.0.0-beta11",
 (DIR) diff --git a/routes/index.js b/routes/index.js
       @@ -1,19 +1,11 @@
        'use strict';
        
       -const config = require('../app/config');
        const express = require('express');
        const router = express.Router();
        
       -/* GET home page. */
       -router.get('/', (req, res) => {
       -  const collection = req.db.get(config.collection);
       -
       -  collection.find({}, {}, (e, docs) => {
       -      res.render('index', {
       -          'torrentlist': docs,
       -          'title': 'Index Page',
       -      });
       -  });
       +/* Redirect home page to torrents list. */
       +router.get('/', function(req, res) {
       +  res.redirect('/torrent');
        });
        
        module.exports = router;
 (DIR) diff --git a/routes/parse.js b/routes/parse.js
       @@ -1,72 +0,0 @@
       -'use strict';
       -
       -const config = require('../app/config');
       -
       -const express = require('express');
       -const parseTorrent = require('parse-torrent');
       -const appRoot = require('app-root-path');
       -const fs = require('fs');
       -const router = express.Router();
       -
       -/**
       -  TODO: 
       -    - Refactor.
       -    - Move to commandline tool instead of web route.
       -    - get seeders / leechers on first pass.
       -*/
       -router.get('/', (req, res) => {
       -
       -  const collection = req.db.get(config.collection);
       -  const torrentFolder = config.torrent_data;
       -
       -  fs.readdir(torrentFolder, (err, files) => {
       -    files.forEach(file => {
       -      let tFile = fs.readFileSync(torrentFolder + '/' + file);
       -      let tData = parseTorrent(tFile);
       -
       -      let tMagnet = parseTorrent.toMagnetURI({
       -        infoHash: tData.infoHash
       -      })
       -
       -      collection.update({
       -        name: tData.name},
       -        {
       -          "name" : tData.name,
       -          "hash" : tData.infoHash,
       -          "announce" : tData.announce,
       -          "created" : tData.created,
       -          "magneturi" : tMagnet,
       -          "files" : tData.files,
       -          "comment" : tData.comment
       -        },
       -        {upsert: true, safe: false},
       -        function (err, doc) {
       -          if (err) {
       -              res.status(500).send("There was a problem adding the torrent information to the database.");
       -          }
       -      });
       -    });
       -  });
       -
       -  res.send('Torrent folder updated \n');
       -
       -});
       -
       -
       -function getFiles() { 
       -
       -}
       -
       -function getMetadata() { 
       -
       -}
       -
       -function getMagnetLink() { 
       -
       -}
       -
       -function updateDB() { 
       -
       -}
       -
       -module.exports = router;
 (DIR) diff --git a/routes/torrent_route.js b/routes/torrent_route.js
       @@ -0,0 +1,10 @@
       +'use strict';
       +
       +const express = require('express');
       +const router = express.Router();
       +const torrent_controller = require('../controllers/torrents_controller');
       +
       +router.get('/', torrent_controller.index);
       +router.get('/details/:id', torrent_controller.torrent_detail);
       +
       +module.exports = router;
 (DIR) diff --git a/views/details.pug b/views/details.pug
       @@ -0,0 +1,64 @@
       +extends layout 
       +
       +block content
       +  h2.ui.header
       +    a(href='/')
       +      i.backward.icon
       +      .content= 'Back'
       +  each i in data.torrent_data
       +    table.ui.olive.table
       +      thead
       +        tr
       +          th(colspan='2')= 'Torrent Details'
       +        tr
       +          td
       +            i.tag.olive.icon
       +            = 'Name'
       +          td= i.name.replace(/\.[^/.]+$/, "")
       +        tr
       +          td
       +            i.magnet.olive.icon
       +            = 'Magnet URL'
       +          td
       +            a(href="" + i.magneturi)= i.magneturi
       +        tr
       +          td
       +            i.upload.olive.icon
       +            = 'Seeders'
       +          td= i.seeders
       +        tr
       +          td
       +            i.download.olive.icon
       +            = 'Leechers'
       +          td= i.leechers
       +        tr
       +          td
       +            i.hashtag.olive.icon
       +            = 'Info Hash'
       +          td= i.hash
       +        tr
       +          td
       +            i.calendar.olive.icon
       +            = 'Created'
       +          td= i.created
       +        tr
       +          td
       +            i.comment.outline.olive.icon
       +            = 'Comment'
       +          td= i.comment
       +        tr
       +          td
       +            i.feed.olive.icon
       +            = 'Announce URL'
       +          td
       +            ul
       +              each url in i.announce
       +                li= url
       +        tr
       +          td
       +            i.file.outline.olive.icon
       +            = 'Files'
       +          td
       +            ul
       +              each file in i.files
       +                li= file.name
       +\ No newline at end of file
 (DIR) diff --git a/views/index.pug b/views/index.pug
       @@ -1,27 +0,0 @@
       -extends layout 
       -
       -block content
       -  .ui.special.four.cards
       -    each i in torrentlist
       -      .card
       -        .content
       -          .header= i.name.replace(/\.[^/.]+$/, "")
       -          .meta
       -            span.category= "2 days ago"
       -          .description= i.comment
       -        .extra.content
       -          span.left.floated
       -            if i.seeders >= 10
       -              i.floated.upload.green.icon
       -            else
       -              i.floated.upload.red.icon
       -            = i.seeders
       -          span.left.floated
       -            if i.leechers >= 50
       -              i.floated.download.yellow.icon
       -            else
       -              i.floated.download.green.icon
       -            = i.leechers
       -        .ui.bottom.attached.button
       -          i.add.icon
       -          a(href="/torrent/details/" + i.hash) Details
 (DIR) diff --git a/views/layout.pug b/views/layout.pug
       @@ -24,7 +24,7 @@ html
            .ui.container
              .ui.small.three.statistics
                .olive.statistic
       -          .value= "143"
       +          .value= data.torrent_count
                  .label= "Total Torrents"
                .red.statistic
                  .value= "23"
 (DIR) diff --git a/views/torrent.pug b/views/torrent.pug
       @@ -0,0 +1,24 @@
       +extends layout 
       +
       +block content
       +  .ui.special.four.cards
       +    each i in data.torrent_data
       +      a.ui.card(href="/torrent/details/" + i.hash)
       +        .content
       +          .header= i.name.replace(/\.[^/.]+$/, "")
       +          .meta
       +            span.category= "2 days ago"
       +          .description= i.comment
       +        .extra.content
       +          span.left.floated
       +            if i.seeders >= 10
       +              i.floated.upload.green.icon
       +            else
       +              i.floated.upload.red.icon
       +            = i.seeders
       +          span.left.floated
       +            if i.leechers >= 50
       +              i.floated.download.yellow.icon
       +            else
       +              i.floated.download.green.icon
       +            = i.leechers