When I try to add or delete from my database it takes a few seconds for the page to update. I use AJAX and it is still very slow. I can not figure out what the problem is. I am new at NODE JS I came from MVC NET. Thanks and here is my code.
app.js
let express = require('express');
let app = express();
let mongodb=require('./mongodb')
let bodyParser = require('body-parser');
let index=require('./index');
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public'));
app.listen(8080, function () {
console.log('Example app listening on port 8080!');
});
app.use('/',index);
app.use('/mongo',mongodb);
mongodb.js
let express = require('express');
let MongoClient = require('mongodb').MongoClient;
let url = "mongodb://localhost:27017/";
let router = express.Router();
let obj = null;
router.get('/', function (req, res) {
getDfroMongo(res);
});
function getDfroMongo(res) {
MongoClient.connect(url, function (err, db) {
if (err) throw err;
var dbo = db.db("mydb");
//Sort the result by name:
var sort = { car: 1 };
dbo.collection("customers").find().sort(sort).toArray(function (err, result) {
if (err) throw err;
obj = result;
// db.close();
res.render(__dirname + '/views/mongo', { result: obj });
});
});
}
router.post('/', function (req, response) {
switch (req.body.data) {
case "add":
let car = req.body.car;
let model = req.body.model;
let year = req.body.year;
let myimg = req.body.img;
obj = { car: car, model: model, year: year, img: myimg };
if (car != "" && model != "" && year != "" && myimg != "") {
console.log(obj);
MongoClient.connect(url, function (err, db) {
if (err) throw err;
var dbo = db.db("mydb");
var myobj = { Car: car, Model: model, Year: year, img: myimg };
dbo.collection("customers").insertOne(myobj, function (err, res) {
if (err) throw err;
console.log("1 document inserted");
// db.close();
getDfroMongo(response);
});
});
}
else
console.log('field missed');
break;
case "delete":
let carName = req.body.carName;
MongoClient.connect(url, function (err, db) {
if (err) throw err;
var dbo = db.db("mydb");
var myquery = { Car: carName };
dbo.collection("customers").deleteOne(myquery, function (err, obj) {
if (err) throw err;
console.log("1 document deleted");
// db.close();
getDfroMongo(response);
});
});
break;
case "update":
upcar = req.body.car;
upmodel = req.body.model;
upyear = req.body.year;
upimg = req.body.img;
upcarName = req.body.carName;
// obj = { car: upcar, model: upmodel, year: upyear, img: upimg, carName: upcarName };
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("mydb");
var myquery = { Car: upcarName };
var newvalues = { $set: { Car: upcar, Model: upmodel,Year:upyear,img:upimg } };
dbo.collection("customers").updateOne(myquery, newvalues, function(err, res) {
if (err) throw err;
console.log("1 document updated");
// db.close();
getDfroMongo(response);
});
});
break;
default:
break;
}
});
module.exports=router;
And This Is My View-mongo.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="/css/style.css" rel="stylesheet" type="text/css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<%include title%>
</head>
<body>
<button type="button" name="addDB" id="addDB" onclick="AddDbFunction()">insert</button>
<input type="text" name="car" id="car" placeholder="car">
<input type="text" name="model" id="model" placeholder="model">
<input type="text" name="year" id="year" placeholder="year">
<input type="text" name="img" id="img" placeholder="img"><br>
<button type="button" name="update" id="update" onclick="updateFunction()">update</button>
<button type="button" name="delete" id="delete" id="delete" onclick="deleteFunction()">delete</button>
<input type="text" name="carName" id="carName" placeholder="carName">
<script>
function updateFunction() {
let car = document.getElementById("car").value;
let model = document.getElementById("model").value;
let year = document.getElementById("year").value;
let img = document.getElementById("img").value;
let carName = document.getElementById("carName").value;
let parameters= { data: "update", car: car, model: model, year: year, img: img, carName: carName };
$.ajax({
url: '/mongo',
type: 'POST',
data: parameters,
success: function () {
location.reload();
}
});
}
function deleteFunction() {
let carName = document.getElementById("carName").value;
// $.post('/', { data: "delete", carName: carName });
let parameters = { data: "delete", carName: carName };
$.ajax({
url: '/mongo',
type: 'POST',
data: parameters,
success: function () {
location.reload();
}
});
}
function AddDbFunction() {
let car = document.getElementById("car").value;
let model = document.getElementById("model").value;
let year = document.getElementById("year").value;
let img = document.getElementById("img").value;
// $.post('/', { data: "add", car: car, model: model, year: year, img: img });
let parameters = { data: "add", car: car, model: model, year: year, img: img }
$.ajax({
url: '/mongo',
type: 'POST',
data: parameters,
success: function () {
location.reload();
}
});
}
</script>
<table>
<tr>
<th>Car</th>
<th>Model</th>
<th>Year</th>
<th>image</th>
<!-- <th>id</th> -->
</tr><br>
<% for(let i=0; i < result.length; i++) { %>
<tr>
<td><%= result[i].Car%></td>
<td><%= result[i].Model%></td>
<td><%= result[i].Year%></td>
<!-- <td><%= result[i]._id%></td> -->
<td> <img src="\images\<%= result[i].img%> " width="80" height="80"></td><br>
</tr>
<% } %>
</table>
</body>
</html>
thanks this is greate place!!
Don't connect mongo for each request, just connect once at the start of your script.
Related
I'm building a todo list using express handlebars, mongoose, mongodb, google oauth. I'm having trouble with rendering using handlebars. A todo has a mongoose attribute of done. If done true, then a class of complete is applied, which is text-decoration: line-through. The problem is that done is always rendered as true. When I click on the todo, it toggles between true/false in mongodb but doesn't show in hbs.
hbs:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="css/style.css" />
<title>To Do</title>
</head>
<body>
<div class="container">
<header class="flexContainer">
<h1 class="title main-font center">Welcome {{name}}</h1>
</header>
<form class="center" action="/todos/addTodo" method="POST">
<input type="text" placeholder="Add a To Do" name="todoItem" />
<button type="submit" class="submitButton">
<span>Add Todo</span>
</button>
</form>
<div class="to-do-list flexContainer">
<ul class="task-list center">
{{#each todo}}
<li data-id="{{_id}}">
// Problem is this block of code here.
{{done}} // Added this line just to show the done attribute is toggling between true/false. Status renders here correctly.
{{#if done}} // This if statement doesn't work. All todos are rendered with the complete class.
<span class="complete">{{todo}}</span>
{{else}}
<span class="incomplete">{{todo}}</span>
{{/if}}
<span class="fa fa-trash delete-todo"></span>
</li>
{{/each}}
</ul>
</div>
<h4 class="main-font center">Left to do: {{left}}</h4>
</div>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
controller todo.js
const Todo = require("../models/todos");
module.exports = {
getTodos: async (req, res) => {
try {
const todoItems = await Todo.find({ googleId: req.user.googleId }).lean();
const itemsLeft = await Todo.countDocuments({
googleId: req.user.googleId,
done: false,
});
res.render("todos.hbs", {
todo: todoItems,
left: itemsLeft,
name: req.user.firstName,
// done: done, <-- I'm not sure if I have to pass in a variable for done. The variable done seems to work in the hbs file anyways.
});
} catch (err) {
console.error(err);
}
},
addTodo: async (req, res) => {
console.log(req.body);
try {
await Todo.create({
todo: req.body.todoItem,
done: false,
googleId: req.user.googleId,
});
console.log("To do has been added!");
res.redirect("/");
} catch (err) {
console.error(err);
}
},
deleteTodo: async (req, res) => {
try {
await Todo.findOneAndDelete({ _id: req.body.todoId });
console.log("Deleted Todo");
res.json("Deleted Todo");
} catch (err) {
console.log(err);
}
},
markComplete: async (req, res) => {
console.log("markComplete");
try {
await Todo.findOneAndUpdate(
{ _id: req.body.todoId },
{
done: true,
}
);
console.log("complete");
res.json("Marked Complete");
} catch {
console.log(err);
}
},
markIncomplete: async (req, res) => {
try {
await Todo.findOneAndUpdate(
{ _id: req.body.todoId },
{
done: false,
}
);
console.log("Marked Incomplete");
res.json("Marked Incomplete");
} catch {
console.log(err);
}
},
};
main.js:
const deleteBtn = document.querySelectorAll(".delete-todo");
const todoIncomplete = document.querySelectorAll(".incomplete");
const todoComplete = document.querySelectorAll(".complete");
Array.from(deleteBtn).forEach((e) => {
e.addEventListener("click", deleteToDo);
});
Array.from(todoIncomplete).forEach((e) => {
e.addEventListener("click", markComplete);
});
Array.from(todoComplete).forEach((e) => {
e.addEventListener("click", markIncomplete);
});
async function deleteToDo() {
const todoId = this.parentNode.dataset.id;
try {
const response = await fetch("todos/deleteTodo", {
method: "delete",
headers: { "Content-type": "application/json" },
body: JSON.stringify({
todoId: todoId,
}),
});
const data = await response.json();
console.log(data);
location.reload();
} catch (err) {
console.log(err);
}
}
async function markComplete() {
const todoId = this.parentNode.dataset.id;
console.log(todoId);
try {
const response = await fetch("todos/markComplete", {
method: "put",
headers: { "Content-type": "application/json" },
body: JSON.stringify({
todoId: todoId,
}),
});
const data = await response.json();
console.log(data);
location.reload();
} catch (err) {
console.log(err);
}
}
async function markIncomplete() {
const todoId = this.parentNode.dataset.id;
try {
const response = await fetch("todos/markIncomplete", {
method: "put",
headers: { "Content-type": "application/json" },
body: JSON.stringify({
todoId: todoId,
}),
});
const data = await response.json();
console.log(data);
location.reload();
} catch (err) {
console.log(err);
}
}
Routes:
const express = require("express");
const router = express.Router();
const todosController = require("../controllers/todos");
const { ensureAuth, EnsureGuest } = require("../middleware/auth");
router.get("/", ensureAuth, todosController.getTodos);
router.post("/addTodo", todosController.addTodo);
router.put("/markComplete", todosController.markComplete);
router.put("/markIncomplete", todosController.markIncomplete);
router.delete("/deleteToDo", todosController.deleteTodo);
module.exports = router;
According to #76484, it is a string and not boolean. I have fixed it.
Mongoose model schema:
const toDoSchema = new mongoose.Schema({
todo: {
type: String,
required: true,
},
done: {
type: Boolean, // previously string here
required: true,
},
googleId: {
type: String,
required: true,
},
});
I am using ExpressJS with EJS template view engine. I am trying to show an HTML file on the angular component, but the form tag and its child input tag do not work on the angular side. They show only label data.
On NodeJS
agreementController.js
exports.getAgreementHtml = async (request, response, next) => {
const params = request.query
let reqPath = path.join(__dirname, '../agreements');
var agreementObj = {
user: { email: "example#gmail.com" }
}
// render domestic rent html
ejs.renderFile(reqPath + '/domestic_rent.ejs', agreementObj, {}, function (err, str) {
if (err !== null) {
responseObj.status = errorCodes.DATA_NOT_FOUND
responseObj.message = language.getMessage('NO_RECORD_FOUND')
response.send(responseObj)
return
}
responseObj.status = errorCodes.OK
responseObj.data = str
response.send(responseObj);
return;
});
}
domestic_rent.js
<form>
<div class="form-group">
<p><%= user.email %></p>
<div class="col-sm-offset-2 col-sm-10">
<input type="text" class="form-control" id="inputEmail3" placeholder="test" required name="test">
</div>
</div>
</form>
On Angular 8 Side
agreement-show.component.ts
getAgreementData() {
const params = {
id: this.agreementId
};
this.agreementService.getAgreementHtml(params).subscribe(
(result) => {
console.log('result agreement data::: ', result);
if (result.status !== 200) {
this.commonService.change.emit({ status: 'error', message: 'unknown error' });
return;
}
this.someHtml = result.data;
return;
}, (error) => {
console.log('error', error)
this.commonService.change.emit({ status: 'error', message: error.message });
}
);
}
agreement-show.component.html
<div [innerHTML]="someHtml"></div>
Output Attachment
By using ElementRef function we can add html runtime.
Please use following step:
#ViewChild('showitems') showitems: ElementRef;
const elemt: HTMLElement = this.showitems.nativeElement;
this.someHtml = result.data;
elemt.innerHTML = this.someHtml;
I'm learning nodejs and I have a project where I want users to post form data which then populates an html table located in public/index.html.
At the moment, I am writing the submitted data to a database collection using the following code:
const mongoose = require('mongoose')
const express = require('express');
const app = express();
const server = app.listen(3000);
app.use(express.json()); // for retrieving form data
app.use(express.static('public'));
mongoose.connect('mongodb://localhost/class', {useNewUrlParser: true})
.then( () => console.log('Connected to class database'))
.catch( () => console.error('Connection attempt to class database failed'))
const personSchema = new mongoose.Schema({
name: String,
date: {type: Date, default: Date.now}
})
const Person = mongoose.model('Person', personSchema)
app.post('/join_class', (req,res) => {
res.send('... joining class')
console.debug(req.body.name)
// document.getElementById('class_table').insertRow(req.body.name)
joinClass(req.body)
})
async function joinClass(data){
console.log(data)
person = new Person({
name: data.name
})
await person.save();
}
My problem is I need the same data to populate an HTML table located in my public/index.html but of course I don't have access to the document object in index.js. The index.html file is below:
<!DOCTYPE html>
<html lang="en">
<head>
<script src='https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.dev.js'></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- <script src="/client.js"></script> -->
<title>TestING</title>
</head>
<body>
<table id='class_table'>
<tr><th>Class</th></tr>
<tr><td>testing</td></tr>
</table>
</body>
</html>
So, how can I create a mongoDB event/alert such that when the post data is inserted into the database, the same data is made available to index.html where I CAN use the document object to populate the table?
Here's a example in which you can add new Person's and the list in the index.html page should update on a successful insert.
index.js
app.post('/join_class', (req, res) => {
var person = new Person({
name: req.body.name
});
person.save().then((data) => {
res.send(data);
}).catch((err) => {
res.status(500).send(err);
});
})
app.get('/class', (req, res) => {
Person.find({}).then((data) => {
res.send(data);
}).catch((err) => {
res.status(500).send(err);
});
})
index.html (body tag content)
<body>
<div>
Name:<br>
<input type="text" id="name" value="">
<br>
<button onclick="addPerson()">Add Person</button>
</div>
<br/>
<b>Person's in List: </b>
<ul id='class_table'>
</ul>
<script src="/client.js"></script>
</body>
client.js
function listPerson() {
var req = new XMLHttpRequest();
req.open("GET", '/class');
req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
req.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var aList = JSON.parse(req.responseText),
list = document.getElementById("class_table");
list.innerHTML = "";
aList.forEach(e => {
var item = document.createElement("li");
item.innerHTML = e.name;
list.appendChild(item);
});
}
};
req.send();
}
function addPerson() {
var req = new XMLHttpRequest();
req.open("POST", '/join_class');
req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
req.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) { listPerson(); } //Get list of Person on completion
};
var sName = document.getElementById("name").value;
req.send(JSON.stringify({ "name": sName }));
}
//Initially load a list of Person's
listPerson();
I new to mean stack. I want to upload video to mongodb and then I want to retrieve it.
this is app.js file
`const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const crypto = require('crypto');
const mongoose = require('mongoose');
const multer = require('multer');
const GridFsStorage = require('multer-gridfs-storage');
const Grid = require('gridfs-stream');
const methodOverride = require('method-override');
const app = express();
// Middleware
app.use(bodyParser.json());
app.use(methodOverride('_method'));
app.set('view engine', 'ejs');
// Mongo URI
const mongoURI = 'mongodb://fawad:Fawad123#ds155243.mlab.com:55243/imageupload';
// Create mongo connection
const conn = mongoose.createConnection(mongoURI);
// Init gfs
let gfs;
conn.once('open', () => {
// Init stream
gfs = Grid(conn.db, mongoose.mongo);
gfs.collection('uploads');
});
// Create storage engine
const storage = new GridFsStorage({
url: mongoURI,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: 'uploads'
};
resolve(fileInfo);
});
});
}
});
const upload = multer({ storage });
// #route GET /
// #desc Loads form
app.get('/', (req, res) => {
gfs.files.find().toArray((err, files) => {
// Check if files
if (!files || files.length === 0) {
res.render('index', { files: false });
} else {
files.map(file => {
if (
file.contentType === 'video/mp4' ||
file.contentType === 'video/webm '
) {
file.isVideo = true;
} else {
file.isVideo = false;
}
});
res.render('index', { files: files });
}
});
});
// #route POST /upload
// #desc Uploads file to DB
app.post('/upload', upload.single('file'), (req, res) => {
// res.json({ file: req.file });
res.redirect('/');
});
// #route GET /files
// #desc Display all files in JSON
app.get('/files', (req, res) => {
gfs.files.find().toArray((err, files) => {
// Check if files
if (!files || files.length === 0) {
return res.status(404).json({
err: 'No files exist'
});
}
// Files exist
return res.json(files);
});
});
// #route GET /files/:filename
// #desc Display single file object
app.get('/files/:filename', (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
// Check if file
if (!file || file.length === 0) {
return res.status(404).json({
err: 'No file exists'
});
}
// File exists
return res.json(file);
});
});
// #route GET /image/:filename
// #desc Display Image
app.get('/video/:filename', (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
// Check if file
if (!file || file.length === 0) {
return res.status(404).json({
err: 'No file exists'
});
}
// Check if image
if (file.contentType === 'video/mp4' || file.contentType === 'video/webm') {
// Read output to browser
const readstream = gfs.createReadStream(file.filename);
readstream.pipe(res);
} else {
res.status(404).json({
err: 'Not an image'
});
}
});
});
// #route DELETE /files/:id
// #desc Delete file
app.delete('/files/:id', (req, res) => {
gfs.remove({ _id: req.params.id, root: 'uploads' }, (err, gridStore) => {
if (err) {
return res.status(404).json({ err: err });
}
res.redirect('/');
});
});
const port = 9000;
app.listen(port, () => console.log(`Server started on port ${port}`));
`
index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<style>
video {
width: 100%;
}
</style>
<title>Mongo File Uploads</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 m-auto">
<h1 class="text-center display-4 my-4">Mongo File Uploads</h1>
<form action="/upload" method="POST" enctype="multipart/form-data">
<div class="custom-file mb-3">
<input type="file" name="file" id="file" class="custom-file-input">
<label for="file" class="custom-file-label">Choose File</label>
</div>
<input type="submit" value="Submit" class="btn btn-primary btn-block">
</form>
<hr>
<% if(files){ %>
<% files.forEach(function(file) { %>
<div class="card card-body mb-3">
<% if(file.isVideo) { %>
<video src="video/<%= file.filename %>" alt="">
<% } else { %>
<%= file.filename %>
<% } %>
<form method="POST" action="/files/<%= file._id %>?_method=DELETE">
<button class="btn btn-danger btn-block mt-4">Delete</button>
</form>
</div>
<% }) %>
<% } else { %>
<p>No files to show</p>
<% } %>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
</body>
</html>
this code work for image..when I used (file.contentType = image/png).
but for video it's not working.. is Image and video upload are same?
You can use Formidable. As It support multipart data. And for retrieve video you can use fs(file system)
Actually you don't save media(image or video) in DB, you store it in some storage drive(locally or cloud) like s3 bucket, and then store its location url in your DB.
and this code might be helpful.
saveImage(urlPath, folderPath, multiple) {
return new Promise((resolve, reject) => {
var timestamp = Date.now();
var filepath = urlPath;
var imageUrl;
var ext = path.extname(filepath || '').split('.');
var extension = ext[ext.length - 1];
var tmp_path = filepath;
imageUrl = folderPath + timestamp + '.' + extension;
if (multiple != '' && multiple != undefined) { imageUrl = folderPath + timestamp + multiple + '.' + extension; }
var target_path = __dirname + '/../' + imageUrl;//Change according to your location.
console.log("target_path", target_path);
mv(tmp_path, target_path, { mkdirp: true }, function (err) { })
return resolve({ status: 1, url: imageUrl });
})
}
Now, urlPath is your media path, foldarPath is path where you want to store your media and multiple is to give unique name.
you can call this method like this.
var multiple = Number(0) + Number(10);
console.log("multiple", multiple);
var saveImage = await 'YOUR_FILE_NAME'.saveImage(files.photo[0].path, 'public/Image/', multiple);
console.log(saveImage);
<video src="video/<%= file.filename %>" controls alt="">
//Try adding the controls command in the video tag. It helps the video run.
Currently,I'm able to get the download status of a file to the console.But now I'm trying to display the status in the UI.
My index.js :
#!/usr/bin/env node
var http = require('http');
var _ = require('lodash');
var express = require('express');
var fs = require('fs');
var path = require('path');
var util = require('util');
var program = require('commander');
//Downloading a file and displaying the status in the console
var request = require('request');
var progress = require('request-progress');
var DOWNLOAD_DIR = '/usr/local/';
var file_name = 'newgoogle.png'
progress(request('https://www.google.com/images/srpr/logo3w.png'), {
throttle:0,
delay: 0
})
.on('progress', function (state) {
console.log('received size in bytes', state.received);
console.log('total size in bytes', state.total);
console.log('percent', state.percent);
})
.pipe(fs.createWriteStream(DOWNLOAD_DIR + file_name))
.on('error', function (err) {
console.log("error");
})
.on('close', function (err){
console.log("Download Complete");
})
function collect(val, memo) {
if(val && val.indexOf('.') != 0) val = "." + val;
memo.push(val);
return memo;
}
program
.option('-p, --port <port>', 'Port to run the file-browser. Default value is 8088')
.option('-e, --exclude <exclude>', 'File extensions to exclude. To exclude multiple extension pass -e multiple times. e.g. ( -e .js -e .cs -e .swp) ', collect, [])
.parse(process.argv);
var app = express();
var dir = process.cwd();
app.use(express.static(dir)); //app public directory
app.use(express.static(__dirname)); //module directory
var server = http.createServer(app);
if(!program.port) program.port = 8089;
server.listen(program.port);
console.log("Please open the link in your browser http://<YOUR-IP>:" + program.port);
app.get('/files', function(req, res) {
var currentDir = dir;
var query = req.query.path || '';
if (query) currentDir = path.join(dir, query);
console.log("browsing ", currentDir);
fs.readdir(currentDir, function (err, files) {
if (err) {
throw err;
}
var data = [];
files
.filter(function (file) {
return true;
}).forEach(function (file) {
try {
//console.log("processing ", file);
var stats = fs.statSync(path.join(currentDir,file));
var time = stats["atime"];
var date = time.toString().substr(4,11);
var isDirectory = fs.statSync(path.join(currentDir,file)).isDirectory();
if (isDirectory) {
data.push({ Name : file,Date : date, IsDirectory: true, Path : path.join(query, file) });
} else {
var ext = path.extname(file);
if(program.exclude && _.contains(program.exclude, ext)) {
console.log("excluding file ", file);
return;
}
data.push({ Name : file,Date:date, Ext : ext, IsDirectory: false, Path : path.join(query, file) });
}
} catch(e) {
console.log(e);
}
});
data = _.sortBy(data, function(f) { return f.Name});
res.json(data);
});
});
app.get('/', function(req, res) {
res.redirect('lib/template.html');
});
app.get('/directory', function(req, res) {
var currentDir = dir;
var query = req.query.path || '';
if (query) currentDir = path.join(dir, query);
var data = { directory: currentDir }
res.json(data);
});
My app.js :
(function($){
var extensionsMap = {
".zip" : "fa-file-archive-o",
".gz" : "fa-file-archive-o",
".bz2" : "fa-file-archive-o",
".xz" : "fa-file-archive-o",
".rar" : "fa-file-archive-o",
".tar" : "fa-file-archive-o",
".tgz" : "fa-file-archive-o",
".tbz2" : "fa-file-archive-o",
".z" : "fa-file-archive-o",
".7z" : "fa-file-archive-o",
".mp3" : "fa-file-audio-o",
".cs" : "fa-file-code-o",
".c++" : "fa-file-code-o",
".cpp" : "fa-file-code-o",
".js" : "fa-file-code-o",
".xls" : "fa-file-excel-o",
".xlsx" : "fa-file-excel-o",
".png" : "fa-file-image-o",
".jpg" : "fa-file-image-o",
".jpeg" : "fa-file-image-o",
".gif" : "fa-file-image-o",
".mpeg" : "fa-file-movie-o",
".pdf" : "fa-file-pdf-o",
".ppt" : "fa-file-powerpoint-o",
".pptx" : "fa-file-powerpoint-o",
".txt" : "fa-file-text-o",
".log" : "fa-file-text-o",
".doc" : "fa-file-word-o",
".docx" : "fa-file-word-o",
};
function getFileIcon(ext) {
return ( ext && extensionsMap[ext.toLowerCase()]) || 'fa-file-o';
}
var currentPath = null;
var options = {
"bProcessing": true,
"bServerSide": false,
"bPaginate": false,
"bAutoWidth": false,
"sScrollY":"250px",
"fnCreatedRow" : function( nRow, aData, iDataIndex ) {
if (!aData.IsDirectory) return;
var path = aData.Path;
$(nRow).bind("click", function(e){
$.get('/files?path='+ path).then(function(data){
table.fnClearTable();
table.fnAddData(data);
currentPath = path;
});
$.get('/directory?path='+ path).then(function(data){
$("input[name='location']").val(data.directory);
//$("#showDiv").hide();
});
e.preventDefault();
});
},
"aoColumns": [{"sTitle":"File Name", "mData": null, "bSortable": false, "sClass": "head0", "sWidth": "55px",
"render": function (data, type, row, meta) {
if (data.IsDirectory) {
return "<a href='#' target='_blank'><i class='fa fa-folder'></i> " + data.Name +"</a>";
} else {
return "<a href='/" + data.Path + "' target='_balnk'><i class='fa " + getFileIcon(data.Ext) + "'></i> " + data.Name +"</a>";
}
}
},
{"sTitle":"Date",align: 'Center', "mData": null, "bSortable": false, "sClass": "head1", "sWidth": "55px",
"render": function (data, type, row, meta) {
if (data.IsDirectory) {
return data.Date;
}else{
return data.Date;
}
}
},
{"sTitle":"Status",align: 'Center', "mData": null, "bSortable": false, "sClass": "head1", "sWidth": "55px",
"render": function (data, type, row, meta) {
if (data.IsDirectory) {
return data.Date;
}else{
return data.Date;
}
}
}
]
};
var table = $(".linksholder").dataTable(options);
$.get('/files').then(function(data){
table.fnClearTable();
table.fnAddData(data);
});
$.get('/directory').then(function(data){
$("input[name='location']").val(data.directory);
$("#showDiv").hide();
});
$(".up").bind("click", function(e){
if (!currentPath) return;
var idx = currentPath.lastIndexOf("/");
var path =currentPath.substr(0, idx);
$.get('/files?path='+ path).then(function(data){
table.fnClearTable();
table.fnAddData(data);
currentPath = path;
});
$.get('/directory?path='+path).then(function(data){
$("input[name='location']").val(data.directory);
});
});
})(jQuery);
My template.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>File Browser</title>
<link rel="stylesheet" href="/lib/bootstrap.min.css">
<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="/lib/app.css">
</head>
<body>
<div id="panelDiv">
<div class="panel-heading">
<button type="button" id="butDiv" >Browse</button>
<input type="text" name="location" size="35"/>
<span class="up">
<i class="fa fa-level-up"></i> Up
</span>
</div>
<div id="showDiv" class="panel-body">
<table class="linksholder">
</table>
</div>
</div>
<script src="/lib/jquery.min.js"></script>
<script src="/lib/bootstrap.min.js"></script>
<script src="/lib/datatable/js/jquery.datatables.min.js"></script>
<script src="/lib/app.js"></script>
<script>
$(document).ready(function(){
$("#showDiv").hide();
});
$("#butDiv").click(function(){
$("#showDiv").show();
});
</script>
</body>
</html>
Current Format:
In the Current Format,in the status column I'm trying to show whether the download is complete (or) how much percent it has downloaded.Can anyone please help me out to move further ...