var fs = require('fs'),
    crypto = require('crypto');

var db = require("../models"),
    User = db.User
    Tessel = db.Tessel;

var formidable = require('formidable');

var V1Controller = {}

var cluster = require('../cluster');

V1Controller.errors = {
  notFound: {
    ok: false,
    error: {
      type: "Permission Denied",
      message: "I didn't recognize that core name or ID"
    }
  },
  noFile: {
    ok: false,
    error: {
      type: 'No File Pushed',
      message: 'A file was not pushed as part of the request'
    }
  },
  unreachable: {
    ok: false,
    error: {
      type: "Not Found",
      message: "Your Tessel is not reachable at this time."
    }
  }
}

// Lists all tessels belonging to the currently authenticated user
V1Controller.list = function(req, res) {
  User
    .find({ where: { apiKey: req.apiKey }, include: [ Tessel ] })
    .success(function(user) {
      var json = {
        ok: true,
        data: []
      };

      user.tessels.forEach(function(tessel) {
        json.data.push({
          id: tessel.device_id,
          lastPush: tessel.lastPush,
          lastPushChecksum: tessel.lastPushChecksum
        });
      });

      res.json(json);
    });
};

// Returns data on a specific tessel, if the user has access
V1Controller.details = function(req, res) {
  var self = this;

  Tessel
    .find({
      include: [ User ],
      where: { device_id: req.params.device_id, }
    })
    .success(function(tessel) {
      var users = tessel.users.filter(function(user) {
        return user.apiKey === req.apiKey;
      });

      if (users.length === 0) {
        return res.json(403, self.errors.notFound);
      }

      res.json({
        ok: true,
        data: {
          id: tessel.device_id,
          lastPush: tessel.lastPush,
          lastPushChecksum: tessel.lastPushChecksum
        }
      });
    });
};

// Pushes source to the Tessel
V1Controller.push = function(req, res) {
  var self = this;

  Tessel.find({
    include: [ User ],
    where: { device_id: req.params.device_id, }
  }).success(function(tessel) {
    if (!tessel) {
      return res.json(403, self.errors.notFound);
    }

    var users = tessel.users.filter(function(user) {
      return user.apiKey === req.apiKey;
    });

    if (users.length === 0) {
      return res.json(403, self.errors.notFound);
    }

    var form = new formidable.IncomingForm();

    form.parse(req, function(err, fields, files) {
      var file;

      for (file in files) break;
      file = files[file];

      if (!file) {
        res.json(400, self.errors.noFile)
      }

      if (cluster.isConnected(tessel.device_id)) {
        cluster.sendFile(tessel.device_id, file.path);

        var hash = crypto.createHash('md5'),
            stream = fs.createReadStream(file.path);

        stream.on('data', function (data) {
          hash.update(data, 'utf8');
        });

        stream.on('end', function () {
          tessel.lastPush = new Date();
          tessel.lastPushChecksum = hash.digest('hex');

          tessel.save();

          res.json({
            ok: true,
            data: "Your code is uploading to your Tessel now."
          })
        });
      } else {
        return res.json(404, self.errors.unreachable);
      }
    });
  });
};

module.exports = V1Controller;

@@ -227,29 +227,20 @@
 ter');%0A%0A
-V1Controller.
+var 
 errors =
@@ -1617,37 +1617,32 @@
 n res.json(403, 
-self.
 errors.notFound)
@@ -2105,37 +2105,32 @@
 n res.json(403, 
-self.
 errors.notFound)
@@ -2298,21 +2298,16 @@
 on(403, 
-self.
 errors.n
@@ -2336,178 +2336,54 @@
 ar f
-orm = new formidable.IncomingForm();%0A%0A    form.parse(req, function(err, fields, files) %7B%0A      var file;%0A%0A      for (file in files) break;%0A      file = files%5Bfile
+ile;%0A    file = req.files%5B'script_tar'
 %5D;%0A%0A    
   if
@@ -2374,26 +2374,24 @@
 tar'%5D;%0A%0A    
- 
- 
 if (!file) %7B
@@ -2387,26 +2387,24 @@
 f (!file) %7B%0A
-  
       res.js
@@ -2411,21 +2411,16 @@
 on(400, 
-self.
 errors.n
@@ -2426,31 +2426,27 @@
 noFile)%0A    
-  
 %7D%0A%0A
-  
     if (clus
@@ -2488,18 +2488,16 @@
 %7B%0A      
- 
- 
 cluster.
@@ -2538,26 +2538,24 @@
 th);%0A%0A      
-  
 var hash = c
@@ -2585,26 +2585,24 @@
 ,%0A          
- 
- 
 stream = fs.
@@ -2627,26 +2627,24 @@
 ile.path);%0A%0A
-  
       stream
@@ -2681,18 +2681,16 @@
         
-  
 hash.upd
@@ -2708,18 +2708,16 @@
 utf8');%0A
-  
       %7D)
@@ -2721,26 +2721,24 @@
  %7D);%0A%0A      
-  
 stream.on('e
@@ -2756,34 +2756,32 @@
 on () %7B%0A        
- 
- 
 tessel.lastPush 
@@ -2794,18 +2794,16 @@
 Date();%0A
-  
         
@@ -2853,26 +2853,24 @@
 );%0A%0A        
-  
 tessel.save(
@@ -2877,26 +2877,24 @@
 );%0A%0A        
- 
- 
 res.json(%7B%0A 
@@ -2898,26 +2898,24 @@
 %7B%0A          
-  
 ok: true,%0A  
@@ -2908,26 +2908,24 @@
   ok: true,%0A
-  
           da
@@ -2973,18 +2973,16 @@
 l now.%22%0A
-  
         
@@ -2986,32 +2986,28 @@
    %7D)%0A      
-  
 %7D);%0A
-  
     %7D else %7B
@@ -3007,18 +3007,16 @@
  else %7B%0A
-  
       re
@@ -3038,13 +3038,8 @@
 04, 
-self.
 erro
@@ -3063,19 +3063,10 @@
     
-  %7D%0A    %7D);
+%7D%0A
 %0A  %7D

Use multiparty to read file upload