From 3832b573b57208363ae1b978106c6110a3efb57a Mon Sep 17 00:00:00 2001 From: luchenqun Date: Tue, 28 Feb 2017 11:14:31 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=8E=B7=E5=8F=96favicon?= =?UTF-8?q?=E5=9B=BE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- app.js | 4 +- common/download.js | 32 +++++++ database/db.js | 16 +++- .../scripts/directives/js-init-directive.js | 12 +++ public/views/bookmarks.html | 4 +- public/views/search.html | 2 +- public/views/tags.html | 2 +- routes/api.js | 94 ++++++++++--------- schema.sql | 3 +- 10 files changed, 121 insertions(+), 51 deletions(-) create mode 100644 common/download.js diff --git a/.gitignore b/.gitignore index 13cd3c8..19e6832 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,5 @@ jspm_packages # Upload File uploads -/public/images/snap/ \ No newline at end of file +/public/images/snap/ +/public/images/favicon/ \ No newline at end of file diff --git a/app.js b/app.js index 7a1173d..d9f392c 100644 --- a/app.js +++ b/app.js @@ -75,7 +75,7 @@ app.use(function(err, req, res, next) { error: {} }); }); -// api.checkSnapState(); -api.getSnapByTimer(); +// api.checkSnapFaviconState(); +api.getSnapFaviconByTimer(); module.exports = app; diff --git a/common/download.js b/common/download.js new file mode 100644 index 0000000..0da3a32 --- /dev/null +++ b/common/download.js @@ -0,0 +1,32 @@ +var request = require('request'); +var fs = require('fs'); + +var download = function(url, dest, cb) { + var file = fs.createWriteStream(dest); + var sendReq = request.get(url); + + var error = null; + sendReq.on('response', function(response) { + if (response.statusCode !== 200) { + error = 'Response status was ' + response.statusCode; + } + }); + + sendReq.on('error', function(err) { + fs.unlink(dest); + error = err + }); + + sendReq.pipe(file); + + file.on('finish', function() { + file.close(cb(error)); + }); + + file.on('error', function(err) { + fs.unlink(dest); + error = err.message; + }); +}; + +module.exports = download; diff --git a/database/db.js b/database/db.js index 9d6b684..f2ed244 100644 --- a/database/db.js +++ b/database/db.js @@ -696,7 +696,7 @@ db.getBookmarks = function() { db.getBookmarkWaitSnap = function(today) { var todayNotSnap = today + 31; - var sql = "SELECT id, url, snap_state FROM `bookmarks` WHERE `snap_state`>=0 AND `snap_state` <= 64 AND snap_state != " + todayNotSnap + " ORDER BY created_at DESC LIMIT 0, 1"; + var sql = "SELECT id, url, snap_state, favicon_state FROM `bookmarks` WHERE (`snap_state`>=0 AND `snap_state` <= 64 AND snap_state != " + todayNotSnap + ") OR (`favicon_state`>=0 AND `favicon_state` <= 64 AND favicon_state != " + todayNotSnap + ") ORDER BY created_at DESC LIMIT 0, 1"; return new Promise(function(resolve, reject) { client.query(sql, (err, result) => { if (err) { @@ -722,4 +722,18 @@ db.updateBookmarkSnapState = function(id, snapState) { }); } +db.updateBookmarkFaviconState = function(id, faviconState) { + console.log("updateBookmarkFaviconState id = " + id + ", faviconState = " + faviconState); + var sql = "UPDATE `bookmarks` SET `favicon_state`='" + faviconState + "' WHERE (`id`='" + id + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + module.exports = db; diff --git a/public/scripts/directives/js-init-directive.js b/public/scripts/directives/js-init-directive.js index 183ecc4..d359528 100644 --- a/public/scripts/directives/js-init-directive.js +++ b/public/scripts/directives/js-init-directive.js @@ -174,3 +174,15 @@ app.directive('errSrc', function() { } } }); + +app.directive('faviconErr', function() { + return { + link: function(scope, element, attrs) { + element.bind('error', function() { + if (attrs.src != attrs.faviconErr) { + attrs.$set('src', attrs.faviconErr); + } + }); + } + } +}); diff --git a/public/views/bookmarks.html b/public/views/bookmarks.html index f252e1a..0313356 100644 --- a/public/views/bookmarks.html +++ b/public/views/bookmarks.html @@ -30,7 +30,7 @@ id="{{bookmark.id}}"> - + {{ bookmark.title}} @@ -56,7 +56,7 @@ - + {{ bookmark.title }} diff --git a/public/views/search.html b/public/views/search.html index d5f191d..a543720 100644 --- a/public/views/search.html +++ b/public/views/search.html @@ -130,7 +130,7 @@ - + {{ bookmark.title }} diff --git a/public/views/tags.html b/public/views/tags.html index 6fdd9b6..e4259c4 100644 --- a/public/views/tags.html +++ b/public/views/tags.html @@ -63,7 +63,7 @@ - + {{ bookmark.title }} diff --git a/routes/api.js b/routes/api.js index 7c64b70..73cd756 100644 --- a/routes/api.js +++ b/routes/api.js @@ -4,39 +4,12 @@ var crypto = require('crypto'); var read = require('node-readability'); var db = require('../database/db.js'); var parseHtml = require('../common/parse_html.js'); +var download = require('../common/download.js'); var multer = require('multer'); var webshot = require('webshot'); var fs = require('fs'); var favicon = require('favicon'); -var download = function(url, dest, cb) { - var file = fs.createWriteStream(dest); - var sendReq = request.get(url); - - var error = null; - sendReq.on('response', function(response) { - if (response.statusCode !== 200) { - error = 'Response status was ' + response.statusCode; - } - }); - - sendReq.on('error', function(err) { - fs.unlink(dest); - error = err - }); - - sendReq.pipe(file); - - file.on('finish', function() { - file.close(cb(error)); - }); - - file.on('error', function(err) { - fs.unlink(dest); - error = err.message; - }); -}; - var storage = multer.diskStorage({ destination: function(req, file, cb) { cb(null, 'uploads/') @@ -574,13 +547,13 @@ api.post('/uploadBookmarkFile', upload.single('bookmark'), function(req, res) { var tags = []; item.tags.forEach((tag) => { - allTags.forEach((at) => { - if (at.name == tag) { - tags.push(at.id); - } + allTags.forEach((at) => { + if (at.name == tag) { + tags.push(at.id); + } + }) }) - }) - // 插入书签 + // 插入书签 db.addBookmark(userId, bookmark) // 插入书签 .then((bookmark_id) => { db.delBookmarkTags(bookmark_id); // 不管3721,先删掉旧的分类 @@ -797,7 +770,7 @@ api.post('/getArticle', function(req, res) { }); }) -api.checkSnapState = function() { +api.checkSnapFaviconState = function() { db.getBookmarks() .then((bookmarks) => { bookmarks.forEach(bookmark => { @@ -814,8 +787,8 @@ api.checkSnapState = function() { .catch((err) => console.log('getBookmarks err', err)); } -api.getSnapByTimer = function() { - console.log('getSnapByTimer...........'); +api.getSnapFaviconByTimer = function() { + console.log('getSnapFaviconByTimer...........'); var timeout = 5000 setInterval(function() { var today = new Date().getDate(); @@ -823,13 +796,18 @@ api.getSnapByTimer = function() { .then((bookmarks) => { if (bookmarks.length == 1) { var id = bookmarks[0].id; - var snap_state = bookmarks[0].snap_state; + var snapState = bookmarks[0].snap_state; + var faviconState = bookmarks[0].snap_state; var url = bookmarks[0].url; var filePath = './public/images/snap/' + id + '.png'; + var faviconPath = './public/images/favicon/' + id + '.ico'; + // 获取截图 fs.exists(filePath, function(exists) { if (exists) { - db.updateBookmarkSnapState(id, -1); + if (snapState != -1) { + db.updateBookmarkSnapState(id, -1); + } } else { if (!/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/.test(url)) { db.updateBookmarkSnapState(id, today + 31); @@ -846,9 +824,9 @@ api.getSnapByTimer = function() { var newSnapState = -1; if (err) { console.log("boomarkid = " + id + ", webshot over", err) - if (snap_state == 0 || snap_state == 1) { - newSnapState = snap_state + 1; - } else if (snap_state == 2) { + if (snapState == 0 || snapState == 1) { + newSnapState = snapState + 1; + } else if (snapState == 2) { newSnapState = today + 31; } } @@ -856,6 +834,38 @@ api.getSnapByTimer = function() { }); } }); + + // 获取favicon + fs.exists(faviconPath, function(exists) { + if (exists) { + if (faviconState != -1) { + db.updateBookmarkFaviconState(id, -1); + } + } else { + if (!/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/.test(url)) { + db.updateBookmarkFaviconState(id, today + 31); + return; + } + favicon(url, function(err, faviconUrl) { + if (faviconUrl) { + download(faviconUrl, faviconPath, function(err) { + var newFaviconState = -1; + if (err) { + console.log("boomarkid = " + id + ", download over", err) + if (faviconState == 0 || faviconState == 1) { + newFaviconState = faviconState + 1; + } else if (faviconState == 2) { + newFaviconState = today + 31; + } + } + db.updateBookmarkFaviconState(id, newFaviconState); + }); + } else { + db.updateBookmarkFaviconState(id, today + 31); + } + }); + } + }); } }) .catch((err) => console.log('getBookmarkWaitSnap err', err)); diff --git a/schema.sql b/schema.sql index 9ae1cda..80f9571 100644 --- a/schema.sql +++ b/schema.sql @@ -24,7 +24,8 @@ CREATE TABLE `bookmarks` ( `click_count` smallint DEFAULT 1, -- 总共点击次数 `created_at` datetime DEFAULT now(), -- 创建时间 `last_click` datetime DEFAULT now(), -- 最后一次点击时间 - `snap_state` tinyint(8) DEFAULT 0, -- -1:获取截图成功。-2:获取ico成功。-3:全部获取成功。0,1,2:获取快照次数。当前天+31:今天不再获取该网页快照 + `snap_state` tinyint(8) DEFAULT 0, -- -1:获取截图成功。0~2:获取快照次数。当前天+31:今天不再获取该网页快照 + `favicon_state` tinyint(8) DEFAULT 0, -- -1:获取ico成功。0~2:获取快照次数。当前天+31:今天不再获取该网页快照 PRIMARY KEY (`id`), KEY `userIdIdx` (`user_id`) );