goappes/hoodie-plugin-socialmedia

View on GitHub
lib/socialmedia.js

Summary

Maintainability
F
6 days
Test Coverage
/**
 * Dependencies
 */

var async = require('async');
var utils = require('hoodie-utils-plugins')('socialmedia:socialmedia');
var log = utils.debug();
var ExtendedDatabaseAPI = utils.ExtendedDatabaseAPI;


module.exports = function (hoodie) {
  var SocialMedia = this;

  var _verifyAttrs = function (task, attr, cb) {
    log('_verifyAttrs', task);
    if (!attr || !task[attr]) {
      return cb('Pls, fill the param: ' + attr);
    }
    cb();
  };

  var _post = function (task, db, cb) {
    log('_post', task);
    var _db = new ExtendedDatabaseAPI(hoodie, hoodie.database(db));

    // @fix _db.add not generating id
    task.socialmedia.post.id = (Date.now()).toString(36);
    task.socialmedia.post.userId =  db.split('/').pop();

    _db.add('post', task.socialmedia.post, function (err, doc) {
      task.socialmedia.post = doc;
      cb(err, task);
    });
  };

  // @todo update only if owner
  var _updatePost = function (task, db, cb) {
    log('_updatePost', task);
    var _db = new ExtendedDatabaseAPI(hoodie, hoodie.database(db));
    _db.update('post', task.socialmedia.post.id, task.socialmedia.post, function (err, doc) {
      task.socialmedia.post = doc;
      cb(err, task);
    });
  };

  // @todo delete only if owner
  var _deletePost = function (task, db, cb) {
    log('_deletePost', task);
    var _db = new ExtendedDatabaseAPI(hoodie, hoodie.database(db));
    if (!task.socialmedia.post || !task.socialmedia.post.id) {
      _db.removeAll('post', function (err, doc) {
        task.socialmedia.post = doc;
        cb(err, task);
      });
    } else {
      _validateOwner(task, db, function (err) {
        if (err) return cb(err, task);
        _db.remove('post', task.socialmedia.post.id, function (err, doc) {
          task.socialmedia.post = doc;
          cb(err, task);
        });
      });
    }
  };

  var _feed = function (task, db, cb) {
    log('_feed', task);
    var _db = new ExtendedDatabaseAPI(hoodie, hoodie.database('user/' + task.socialmedia.userId));
    _db.findAll('post', function (err, posts) {
      task.socialmedia.feed = posts.filter(function (v) {
        return (v.userId === task.socialmedia.userId);
      });
      if (err && err.error === 'not_found') return cb(null, task);
      cb(err, task);
    });
  };

  var _validateOwner = function (task, db, cb) {
    log('_validateOwner', task);
    _findPost(task, db, function (err) {
      if ('user/' + task.socialmedia.post.userId !== db) return cb('you should not pass! <|>:-|>', task);
      cb(err, task);
    });
  };

  var _findPost = function (task, db, cb) {
    log('_findPost', task);
    var _db = new ExtendedDatabaseAPI(hoodie, hoodie.database(db));
    _db.find('post', task.socialmedia.post.id, function (err, doc) {
      if (err && err.error === 'not_found') return cb(null, task);
      task.socialmedia.post = doc;
      cb(err, task);
    });
  };

  var _comment = function (task, db, cb) {
    log('_comment', task);

    var doc = task.socialmedia.post;
    if (!doc.comments) doc.comments = [];
    task.socialmedia.comment.id = (Date.now()).toString(36);
    task.socialmedia.comment.owner = task.socialmedia.comment.owner || {};
    task.socialmedia.comment.owner.db = db;
    task.socialmedia.comment.owner.userId = db.split('/').pop();
    task.socialmedia.comment.createdAt = new Date();
    doc.comments.push(task.socialmedia.comment);
    _updatePost(task,  'user/' + task.socialmedia.post.userId, cb);

  };

  var _updateComment = function (task, db, cb) {
    log('_updateComment', task);
    var commentId = task.socialmedia.comment.id;

    _findPost(task, 'user/' + task.socialmedia.post.userId, function (err, _task) {
      var doc = _task.socialmedia.post;

      if (!doc.comments) return cb('Comment not found.', task);

      doc.comments.map(function (comment, i) {
        if (comment.id !== commentId) return;
        if (!comment.owner || comment.owner.db !== db) return cb('you should not pass! <|>:-|>');

        doc.comments[i] = task.socialmedia.comment;
        doc.comments[i].id = comment.id;

        return _updatePost(task,  'user/' + task.socialmedia.post.userId, cb);
      });
    });
  };

  var _deleteComment = function (task, db, cb) {
    log('_deleteComment', task);
    var commentId = task.socialmedia.comment.id;

    _findPost(task, 'user/' + task.socialmedia.post.userId, function (err, _task) {
      var doc = _task.socialmedia.post;

      if (!doc.comments) return cb('Comment not found.', task);

      doc.comments.map(function (comment, i) {
        if (comment.id !== commentId) return;
        if (!comment.owner || comment.owner.db !== db) return cb('you should not pass! <|>:-|>');

        doc.comments.splice(i, 1);

        return _updatePost(task,  'user/' + task.socialmedia.post.userId, cb);
      });
    });
  };

  var _count = function (task, db, cb) {
    log('_count', task);
    _findPost(task, 'user/' + task.socialmedia.post.userId, function (err, _task) {
      var doc = _task.socialmedia.post;
      if (!doc.countType) doc.countType = {};
      if (!doc.countType[task.socialmedia.countType]) doc.countType[task.socialmedia.countType] = [];
      doc.countType[task.socialmedia.countType].push(task.socialmedia.countObject);
      _updatePost(task,  'user/' + task.socialmedia.post.userId, cb);
    });
  };

  var _uncount = function (task, db, cb) {
    log('_uncount', task);
    _findPost(task, 'user/' + task.socialmedia.post.userId, function (err, _task) {
      var doc = _task.socialmedia.post;
      if (!doc.countType) return cb(null, task);
      if (!doc.countType[task.socialmedia.countType]) cb(null, task);
      doc.countType[task.socialmedia.countType].splice(doc.countType[task.socialmedia.countType].reduce(function (b, c, i) {
        if (c.id === db) return i;
      }), 1);
      _updatePost(task,  'user/' + task.socialmedia.post.userId, cb);
    });
  };

  var _sharePost = function (task, db, cb) {
    log('_sharePost', task);
    _findPost(task, 'user/' + task.socialmedia.post.userId, function (err, _task) {
      var doc = _task.socialmedia.post;
      doc.sourceId = _task.socialmedia.post.id;
      delete doc._rev;
      _post(task, db, cb);
    });
  };

//  var _getProfilesAsObject = function (task, db, cb) {
//    log('_getProfilesAsObject', task);
//    if (!task.socialmedia.feed)
//      return cb();
//    var ids =  task.socialmedia.feed.map(function (v) {
//      return v.userId;
//    });
//
//    dbPluginProfile.findSome('profile', ids, function (err, rows) {
//      if (err) return cb(err);
//      task.socialmedia.profiles = {};
//      rows.map(function (v) {
//        task.socialmedia.profiles[v.doc.userId] = v.doc;
//      });
//      cb();
//    });
//  };
//
//  var _setProfilesIntoPost = function (task, db, cb) {
//    log('_setProfilesIntoPost', task);
//    if (!task.socialmedia.profiles)
//      return cb();
//    task.socialmedia.feed.map(function (v, k, a) {
//      a[k].owner = task.socialmedia.profiles[v.userId];
//    });
//    delete task.socialmedia.profiles;
//    cb();
//  };

  SocialMedia.post = function (db, task) {
    log('post', task);

    async.series([
        async.apply(_verifyAttrs, task, 'socialmedia'),
        async.apply(_verifyAttrs, task.socialmedia, 'post'),
        async.apply(_verifyAttrs, task.socialmedia.post, 'userId'),
        async.apply(_post, task, db)
      ],
      utils.handleTask(hoodie, 'post', db, task)
    );
  };

  SocialMedia.getPost = function (db, task) {
    log('getPost', task);

    async.series([
        async.apply(_verifyAttrs, task, 'socialmedia'),
        async.apply(_verifyAttrs, task.socialmedia, 'post'),
        async.apply(_verifyAttrs, task.socialmedia.post, 'id'),
        async.apply(_findPost, task, db)
      ],
      utils.handleTask(hoodie, 'getPost', db, task)
    );
  };

  SocialMedia.updatePost = function (db, task) {
    log('updatePost', task);

    async.series([
        async.apply(_verifyAttrs, task, 'socialmedia'),
        async.apply(_verifyAttrs, task.socialmedia, 'post'),
        async.apply(_verifyAttrs, task.socialmedia.post, 'userId'),
        async.apply(_verifyAttrs, task.socialmedia.post, 'id'),
        async.apply(_validateOwner, task, db),
        async.apply(_updatePost, task, db)
      ],
      utils.handleTask(hoodie, 'updatePost', db, task)
    );
  };

  SocialMedia.deletePost = function (db, task) {
    log('deletePost', task);

    async.series([
//        async.apply(_verifyAttrs, task, 'userId'),
        async.apply(_deletePost, task, db)
      ],
      utils.handleTask(hoodie, 'deletePost', db, task)
    );
  };

  SocialMedia.feed = function (db, task) {
    log('feed', task);

    async.series([
        async.apply(_verifyAttrs, task, 'socialmedia'),
        async.apply(_verifyAttrs, task.socialmedia, 'userId'),
        async.apply(_feed, task, db),
        //async.apply(_getProfilesAsObject, task, db),
        //async.apply(_setProfilesIntoPost, task, db),
      ],
      utils.handleTask(hoodie, 'feed', db, task)
    );
  };

  SocialMedia.comment = function (db, task) {
    log('comment', task);

    async.series([
        async.apply(_verifyAttrs, task, 'socialmedia'),
        async.apply(_verifyAttrs, task.socialmedia, 'post'),
        async.apply(_verifyAttrs, task.socialmedia.post, 'id'),
        async.apply(_verifyAttrs, task.socialmedia, 'comment'),
        async.apply(_findPost, task, db),
        async.apply(_comment, task, db)
      ],
      utils.handleTask(hoodie, 'comment', db, task)
    );
  };

  SocialMedia.count = function (db, task) {
    log('count', task);

    async.series([
        async.apply(_verifyAttrs, task, 'socialmedia'),
        async.apply(_verifyAttrs, task.socialmedia, 'post'),
        async.apply(_verifyAttrs, task.socialmedia.post, 'id'),
        async.apply(_verifyAttrs, task.socialmedia, 'countType'),
        async.apply(_findPost, task, db),
        async.apply(_count, task, db)
      ],
      utils.handleTask(hoodie, 'count', db, task)
    );
  };

  SocialMedia.uncount = function (db, task) {
    log('uncount', task);

    async.series([
        async.apply(_verifyAttrs, task, 'socialmedia'),
        async.apply(_verifyAttrs, task.socialmedia, 'post'),
        async.apply(_verifyAttrs, task.socialmedia.post, 'id'),
        async.apply(_verifyAttrs, task.socialmedia, 'countType'),
        async.apply(_findPost, task, db),
        async.apply(_uncount, task, db)
      ],
      utils.handleTask(hoodie, 'uncount', db, task)
    );
  };

  SocialMedia.updateComment = function (db, task) {
    log('updateComment', task);

    async.series([
        async.apply(_verifyAttrs, task, 'socialmedia'),
        async.apply(_verifyAttrs, task.socialmedia, 'post'),
        async.apply(_verifyAttrs, task.socialmedia.post, 'id'),
        async.apply(_verifyAttrs, task.socialmedia, 'comment'),
        async.apply(_verifyAttrs, task.socialmedia.comment, 'id'),
        async.apply(_updateComment, task, db)
      ],
      utils.handleTask(hoodie, 'updateComment', db, task)
    );
  };

  SocialMedia.deleteComment = function (db, task) {
    log('deleteComment', task);

    async.series([
        async.apply(_verifyAttrs, task, 'socialmedia'),
        async.apply(_verifyAttrs, task.socialmedia, 'post'),
        async.apply(_verifyAttrs, task.socialmedia.post, 'id'),
        async.apply(_verifyAttrs, task.socialmedia, 'comment'),
        async.apply(_verifyAttrs, task.socialmedia.comment, 'id'),
        async.apply(_deleteComment, task, db)
      ],
      utils.handleTask(hoodie, 'deleteComment', db, task)
    );
  };

  SocialMedia.sharePost = function (db, task) {
    log('sharePost', task);

    async.series([
        async.apply(_verifyAttrs, task, 'socialmedia'),
        async.apply(_verifyAttrs, task.socialmedia, 'post'),
        async.apply(_verifyAttrs, task.socialmedia.post, 'id'),
        async.apply(_sharePost, task, db)
      ],
      utils.handleTask(hoodie, 'sharePost', db, task)
    );
  };

  return SocialMedia;
};