From 57fe592d02ccf93c7e2cfce16f1aeffbcf68968d Mon Sep 17 00:00:00 2001 From: luchenqun Date: Fri, 16 Nov 2018 14:04:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8B=E8=BD=BDfavicon,=20?= =?UTF-8?q?30=E5=88=86=E9=92=9F=E4=B8=8B=E8=BD=BD=E4=B8=80=E6=AC=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/db.js | 2400 ++++++++++++++++++------------------ routes/api.js | 3211 ++++++++++++++++++++++++------------------------ 2 files changed, 2795 insertions(+), 2816 deletions(-) diff --git a/database/db.js b/database/db.js index 4221773..ebf51d9 100644 --- a/database/db.js +++ b/database/db.js @@ -1,1200 +1,1200 @@ -var mysql = require('mysql'); -var dbConfig = { - host: '127.0.0.1', - user: 'test', // mysql的账号 - password: '123456', // mysql 的密码 - database: 'mybookmarks', - multipleStatements: true, - useConnectionPooling: true, - port: 3306 -}; - -var client = mysql.createConnection(dbConfig); - -Date.prototype.format = function(fmt) { //author: meizz - var o = { - "M+": this.getMonth() + 1, //月份 - "d+": this.getDate(), //日 - "h+": this.getHours(), //小时 - "m+": this.getMinutes(), //分 - "s+": this.getSeconds(), //秒 - "q+": Math.floor((this.getMonth() + 3) / 3), //季度 - "S": this.getMilliseconds() //毫秒 - }; - if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); - for (var k in o) - if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); - return fmt; -} - -// select 最多返回一行的话,返回对象,否则返回数组 -// insert 返回关键字 -// update delete 返回影响的行数 -var db = { - -} - -// 每隔10秒查询一下,出现问题直接挂掉nodejs,让forever将其重启! -setInterval(function() { - var sql = "SELECT * FROM `users` WHERE `id` = '1'"; - client.query(sql, (err, result) => { - if (err) { - var date = new Date().format('yyyy-MM-dd hh:mm:ss'); - console.log(date + " :数据查询出问题了,直接挂掉程序,让forever重启应用,错误信息:" + JSON.stringify(err)); - throw new Error(""); - } - }); -}, 60000); - - -db.getBookmarkbyUrl = function(user_id, url) { - var sql = "SELECT * FROM `bookmarks` WHERE `user_id` = '" + user_id + "' AND `url` = '" + url + "'" - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - if (result.length >= 1) { - resolve(result[0].id); - } else { - resolve(null); - } - } - }); - }); -}; - -db.addBookmark = function(user_id, bookmark) { - var sql = "INSERT INTO `bookmarks` (`user_id`, `title`, `description`, `url`, `public`, `click_count`) VALUES ('" + user_id + "', " + client.escape(bookmark.title) + ", " + client.escape(bookmark.description) + ", " + client.escape(bookmark.url) + ", '" + bookmark.public + "', '1')"; - console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.insertId); - } - }); - }); -}; - -db.delBookmark = function(id) { - var sql = "DELETE FROM `bookmarks` WHERE (`id`='" + id + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.updateBookmark = function(bookmark) { - var sql = "UPDATE `bookmarks` SET `title`='" + bookmark.title + "', `description`=" + client.escape(bookmark.description) + ", `url`='" + bookmark.url + "', `public`='" + bookmark.public + "' WHERE (`id`='" + bookmark.id + "')"; - console.log("sql updateBookmark = " + sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.getBookmark = function(id) { - var sql = "SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `id` = '" + id + "'"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result[0]); - } - }); - }); -} - -db.getBookmarkTags = function(bookmard_id) { - var sql = "SELECT tag_id FROM `tags_bookmarks` WHERE `bookmark_id` = '" + bookmard_id + "'"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - var tags = result.map((item) => item.tag_id); - resolve(tags); - } - }); - }); -} - -db.getBookmarkTagsNames = function(bookmard_id) { - var sql = "SELECT tags_bookmarks.tag_id as id, tags.name FROM tags_bookmarks LEFT JOIN tags ON tags.id = tags_bookmarks.tag_id WHERE bookmark_id = '" + bookmard_id + "'"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -} - -db.delBookmarkTags = function(bookmard_id) { - var sql = "DELETE FROM `tags_bookmarks` WHERE (`bookmark_id`='" + bookmard_id + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.getBookmarkIdsByTagId = function(tagId) { - var sql = "SELECT bookmark_id FROM `tags_bookmarks` WHERE `tag_id` = '" + tagId + "'"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -} - -db.delTag = function(tagId) { - var sql = "DELETE FROM `tags` WHERE (`id`='" + tagId + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.delTagBookmarks = function(tagId) { - var sql = "DELETE FROM `tags_bookmarks` WHERE (`tag_id`='" + tagId + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.delBookmarks = function(bookmarkIds) { - var sql = "DELETE FROM `bookmarks` WHERE id IN (" + (bookmarkIds.toString() || ("-1")) + ")"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.delTagsBookmarks = function(bookmarkIds) { - var sql = "DELETE FROM `tags_bookmarks` WHERE bookmark_id IN (" + (bookmarkIds.toString() || ("-1")) + ")"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.addTagsBookmarks = function(tags, bookmard_id) { - sql = "INSERT INTO `tags_bookmarks` (`tag_id`, `bookmark_id`) VALUES"; - for (var i = 0; i < tags.length; i++) { - if (i >= 1) { - sql += ',' - } - sql += "('" + tags[i] + "', '" + bookmard_id + "')"; - } - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.updateLastUseTags = function(user_id, tags) { - sql = "UPDATE tags SET last_use = NOW() WHERE user_id = '" + user_id + "' AND id in (" + tags.toString() + ")"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.clickBookmark = function(id, user_id) { - var sql = "UPDATE `bookmarks` SET `click_count`=`click_count`+1, `last_click`=now() WHERE (`id`='" + id + "') AND (`user_id`='" + user_id + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -}; - -db.updateUserLastLogin = function(id) { - console.log('updateUserLastLogin'); - var sql = "UPDATE `users` SET `last_login`=now() WHERE (`id`='" + id + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -}; - -db.resetPassword = function(userId, password) { - console.log('updateUserLastLogin'); - var sql = "UPDATE `users` SET `password` = '" + password + "' WHERE(`id` = '" + userId + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.updateShowStyle = function(userId, show_style) { - console.log('updateUserLastLogin'); - var sql = "UPDATE `users` SET `show_style` = '" + show_style + "' WHERE(`id` = '" + userId + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.updateSearchHistory = function(userId, search_history) { - var sql = "UPDATE `users` SET `search_history`=" + client.escape(search_history) + " WHERE (`id`='" + userId + "')"; - console.log('updateSearchHistory', sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -}; - -db.updateQuickUrl = function(userId, quick_url) { - var sql = "UPDATE `users` SET `quick_url`=" + client.escape(quick_url) + " WHERE (`id`='" + userId + "')"; - console.log('updateQuickUrl', sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -}; - -db.register = function(user) { - console.log('register'); - var sql = "INSERT INTO `users` (`username`, `password`, `email`) VALUES ('" + user.username + "', '" + user.password + "', '" + user.email + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - db.insertDefaultBookmarks(result.insertId); - } - }); - }); -}; - -db.insertDefaultBookmarks = function(userId) { - var tags_name = ["常用", "未分类", "收藏"]; - - db.addTags(userId, tags_name) - .then((insertId) => { - var bookmarks = [{ - title: "谷歌", - description: "要翻墙的搜索网站", - url: "https://www.google.com.hk/", - public: "0" - }, { - title: "百度", - description: "A:百度一下你会死啊?B:会!", - url: "https://www.baidu.com/", - public: "0" - }, { - title: "微博", - description: "随时随地发现新鲜事", - url: "http://weibo.com/", - public: "0" - }, { - title: "天猫", - description: "上天猫,就够了!", - url: "https://www.tmall.com/", - public: "0" - }, { - title: "优酷", - description: "视频网站", - url: "http://www.youku.com/", - public: "0" - }]; - - var tags = [insertId]; - bookmarks.forEach((bookmark) => { - db.addBookmark(userId, bookmark) - .then((insertId) => db.addTagsBookmarks(tags, insertId)) - .catch((err) => console.log('insertDefaultBookmarks err2', err)); // oops! - }) - }) - .catch((err) => console.log('insertDefaultBookmarks err1', err)); // oops! -} - -db.getUser = function(username) { - console.log('getUser'); - var sql = "SELECT * FROM `users` WHERE `username` = '" + username + "'"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result[0]); - } - }); - }); -}; - -db.getTags = function(user_id) { - var sql = "SELECT t.id, t.user_id, t.name, DATE_FORMAT(t.last_use, '%Y-%m-%d %H:%i:%s') as last_use, t.sort, tb.cnt, tg.ncnt FROM `tags` as t LEFT OUTER JOIN ( SELECT `tag_id`, COUNT(tag_id) as cnt FROM tags_bookmarks GROUP BY tag_id ) tb ON t.id = tb.tag_id LEFT OUTER JOIN ( SELECT `tag_id`, COUNT(tag_id) as ncnt FROM notes GROUP BY tag_id ) tg ON t.id = tg.tag_id "; - if (user_id) { - sql += "WHERE t.user_id = '" + user_id + "' "; - } - sql += "ORDER BY t.sort, t.last_use DESC"; - console.log('getTags sql = ', sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -}; - -db.updateTagName = function(tag) { - console.log('updateTagName'); - var sql = "UPDATE `tags` SET `name`='" + tag.name + "' WHERE (`id`='" + tag.id + "')"; - console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -}; - -db.updateTagsIndex = function(tagsIndex) { - console.log('updateTagsIndex'); - var sql = "UPDATE tags SET sort = CASE id "; - tagsIndex.forEach((tagIndex) => { - sql += "WHEN " + tagIndex.id + " THEN " + tagIndex.index + " "; - }) - var tagsId = tagsIndex.map((item) => item.id); - sql += "END WHERE id IN (" + tagsId.toString() + ")"; - - console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -}; - -db.getTagsByIds = function(tagIds) { - var sql = "SELECT * FROM `tags` WHERE id in(" + (tagIds.toString() || ("-1")) + ") GROUP BY id"; // 如果是空的,那查一个不存在的就行了。 - console.log('db getTagsByIds = ', sql); - - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -} - -db.getAdvices = function(params) { - console.log('getAdvices'); - var sql = "SELECT a.id, a.user_id, u.username, a.comment, a.category, DATE_FORMAT(a.created_at, '%Y-%m-%d %H:%i:%s') as created_at, a.state FROM `advices` as a LEFT OUTER JOIN users as u ON a.user_id = u.id ORDER BY a.created_at DESC LIMIT 0, 100"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -}; - -db.addAdvice = function(params) { - console.log('addAdvice'); - var sql = "INSERT INTO `advices` (`user_id`, `comment`, `category`) VALUES ('" + params.user_id + "', '" + params.comment + "', '" + params.category + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -}; - -db.getTagsByNames = function(user_id, tags_name) { - console.log('getTagsByNames'); - var sql = "SELECT * FROM `tags` WHERE `user_id` = '" + user_id + "' AND `name` in (" + tags_name.toString() + ")"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -}; - -db.addTags = function(user_id, tags_name) { - console.log('addTags', tags_name); - var sql = "INSERT INTO `tags` (`user_id`, `name`, `sort`) VALUES"; - tags_name.forEach((name, i) => { - if (i >= 1) { - sql += ',' - } - sql += "('" + user_id + "', '" + name + "', '88')"; // sort默认一个比较大的值,默认在后面 - }); - return new Promise(function(resolve, reject) { - if (tags_name.length == 0) { - reject("tags_name is empty"); - } else { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.insertId); - } - }); - } - }); -}; - -db.getBookmarksNavigate = function(tags) { - // console.log('getBookmarksNavigate'); - // var sql = "SELECT t.id as tag_id, t.name as tag_name, b.* FROM `tags` as t LEFT OUTER JOIN tags_bookmarks as tb ON t.id = tb.tag_id LEFT OUTER JOIN bookmarks as b ON tb.bookmark_id = b.id WHERE t.user_id='" + user_id + "' ORDER BY t.id ASC, b.click_count DESC"; - var sql = ""; - tags.forEach((tag, index) => { - var t = 't' + tag.id; - if (index >= 1) { - sql += " UNION " - } - sql += "(SELECT * FROM ((SELECT t.id AS tag_id, t.`name` as tag_name, t.sort, b.* FROM `tags` as t, `bookmarks`as b, `tags_bookmarks` as tb WHERE t.id = tb.tag_id AND b.id = tb.bookmark_id AND t.id = " + tag.id + " ORDER BY b.click_count DESC LIMIT 0, 16) UNION (SELECT t.id AS tag_id, t.`name` as tag_name, t.sort, b.* FROM `tags` as t, `bookmarks`as b, `tags_bookmarks` as tb WHERE t.id = tb.tag_id AND b.id = tb.bookmark_id AND t.id = " + tag.id + " ORDER BY b.created_at DESC LIMIT 0, 16)) as " + t + " ORDER BY " + t + ".click_count DESC, " + t + ".created_at DESC)"; - }) - // console.log('getBookmarksNavigate ', sql); - - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -}; - -db.getBookmarksCostomTag = function(user_id, perPageItems) { - console.log('getBookmarksCostomTag', user_id, perPageItems); - perPageItems = perPageItems || 50; - var sql1 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` = '" + user_id + "' ORDER BY `click_count` DESC LIMIT 0, " + perPageItems + ")"; - var sql2 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` = '" + user_id + "' ORDER BY `created_at` DESC LIMIT 0, " + perPageItems + ")"; - var sql3 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` = '" + user_id + "' ORDER BY `last_click` DESC LIMIT 0, " + perPageItems + ")"; - - var sql = sql1 + " UNION " + sql2 + " UNION " + sql3; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - var bookmarks = []; - var begin = 0; - var end = perPageItems; - - result.sort((a, b) => { - var click1 = parseInt(a.click_count); - var click2 = parseInt(b.click_count); - if (click1 > click2) { - return -1; - } else if (click1 == click2) { - return a.created_at >= b.created_at ? -1 : 1; - } else { - return 1; - } - }) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 1; - bookmarks.push(bookmark); - }) - - result.sort((a, b) => a.created_at >= b.created_at ? -1 : 1) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 2; - bookmarks.push(bookmark); - }) - - result.sort((a, b) => a.last_click >= b.last_click ? -1 : 1) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 3; - bookmarks.push(bookmark); - }) - - - var bookmarksData = { - totalItems: result.length, - bookmarks: bookmarks, - } - resolve(bookmarksData); - } - }); - }); -}; - -db.getBookmarksCostomAllUsersTag = function(user_id, perPageItems) { - console.log('getBookmarksCostomAllUsersTag', user_id, perPageItems); - perPageItems = perPageItems || 50; - var sql1 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` != '" + user_id + "' AND public != 0 AND user_id != 120 ORDER BY `click_count` DESC LIMIT 0, " + perPageItems + ")"; - var sql2 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` != '" + user_id + "' AND public != 0 AND user_id != 120 ORDER BY `created_at` DESC LIMIT 0, " + perPageItems + ")"; - var sql3 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` != '" + user_id + "' AND public != 0 AND user_id != 120 ORDER BY `last_click` DESC LIMIT 0, " + perPageItems + ")"; - - var sql = sql1 + " UNION " + sql2 + " UNION " + sql3; - // console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - var bookmarks = []; - var begin = 0; - var end = perPageItems; - - result.sort((a, b) => { - var click1 = parseInt(a.click_count); - var click2 = parseInt(b.click_count); - if (click1 > click2) { - return -1; - } else if (click1 == click2) { - return a.created_at >= b.created_at ? -1 : 1; - } else { - return 1; - } - }) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 1; - bookmarks.push(bookmark); - }) - - result.sort((a, b) => a.created_at >= b.created_at ? -1 : 1) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 2; - bookmarks.push(bookmark); - }) - - result.sort((a, b) => a.last_click >= b.last_click ? -1 : 1) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 3; - bookmarks.push(bookmark); - }) - - - var bookmarksData = { - totalItems: result.length, - bookmarks: bookmarks, - } - resolve(bookmarksData); - } - }); - }); -}; - - -db.getBookmarksTable = function(params) { - var user_id = params.userId; - params.currentPage = params.currentPage || 1; - params.perPageItems = params.perPageItems || 20; - - var sql = "SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE 1=1"; - if (user_id) { - sql += " AND `user_id` = '" + user_id + "'"; - } - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - var bookmarks = []; - var begin = (params.currentPage - 1) * params.perPageItems; - var end = params.currentPage * params.perPageItems; - - result.sort((a, b) => { - var click1 = parseInt(a.click_count); - var click2 = parseInt(b.click_count); - if (click1 > click2) { - return -1; - } else if (click1 == click2) { - return a.created_at >= b.created_at ? -1 : 1; - } else { - return 1; - } - }) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 1; - bookmarks.push(bookmark); - }) - - result.sort((a, b) => a.created_at >= b.created_at ? -1 : 1) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 2; - bookmarks.push(bookmark); - }) - - result.sort((a, b) => a.last_click >= b.last_click ? -1 : 1) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 3; - bookmarks.push(bookmark); - }) - - var bookmarksData = { - totalItems: result.length, - bookmarks: bookmarks, - } - - resolve(bookmarksData); - } - }); - }) -} - -db.getBookmarksByTag = function(params) { - var tag_id = params.tagId; - params.currentPage = params.currentPage || 1; - params.perPageItems = params.perPageItems || 20; - - var sql = "SELECT bookmarks.id, bookmarks.user_id, bookmarks.title, bookmarks.description, bookmarks.url, bookmarks.public, bookmarks.click_count, DATE_FORMAT(bookmarks.created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(bookmarks.last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `tags_bookmarks`, `bookmarks` WHERE tags_bookmarks.tag_id = '" + tag_id + "' AND tags_bookmarks.bookmark_id = bookmarks.id"; - - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - var bookmarks = []; - var begin = (params.currentPage - 1) * params.perPageItems; - var end = params.currentPage * params.perPageItems; - - result.sort((a, b) => { - var click1 = parseInt(a.click_count); - var click2 = parseInt(b.click_count); - if (click1 > click2) { - return -1; - } else if (click1 == click2) { - return a.created_at >= b.created_at ? -1 : 1; - } else { - return 1; - } - }) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 1; - bookmarks.push(bookmark); - }) - - result.sort((a, b) => a.created_at >= b.created_at ? -1 : 1) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 2; - bookmarks.push(bookmark); - }) - - result.sort((a, b) => a.last_click >= b.last_click ? -1 : 1) - .slice(begin, end) - .forEach((b) => { - var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 - bookmark.type = 3; - bookmarks.push(bookmark); - }) - - var bookmarksData = { - totalItems: result.length, - bookmarks: bookmarks, - } - - resolve(bookmarksData); - } - }); - }) -} - -db.getExportBookmarksByTag = function(tag_id) { - var sql = "SELECT tags_bookmarks.tag_id, bookmarks.title, bookmarks.url, DATE_FORMAT(bookmarks.created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(bookmarks.last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `tags_bookmarks`, `bookmarks` WHERE tags_bookmarks.tag_id = '" + tag_id + "' AND tags_bookmarks.bookmark_id = bookmarks.id ORDER BY bookmarks.click_count DESC"; - - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }) -} - -db.getBookmarksSearch = function(params) { - var sql = "SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE 1=1"; - - if (params.dateCreate) { - var d = new Date(); - d.setDate(d.getDate() - parseInt(params.dateCreate)); - sql += " AND `created_at` >= '" + d.format('yyyy-MM-dd') + "'" - } else if (params.dateCreateBegin && params.dateCreateEnd) { - sql += " AND `created_at` >= '" + params.dateCreateBegin + " 00:00:00" + "' AND `created_at` <= '" + params.dateCreateEnd + " 23:59:59" + "' " - } - if (params.dateClick) { - var d = new Date(); - d.setDate(d.getDate() - parseInt(params.dateClick)); - sql += " AND `last_click` >= '" + d.format('yyyy-MM-dd') + "'" - } else if (params.dateClickBegin && params.dateClickEnd) { - sql += " AND `last_click` >= '" + params.dateClickBegin + " 00:00:00" + "' AND `last_click` <= '" + params.dateClickEnd + " 23:59:59" + "' " - } - - if (params.searchWord) { - sql += " AND (`title` LIKE '%" + params.searchWord + "%' OR `url` LIKE '%" + params.searchWord + "%')" - } - - if (params.userRange == '1') { - if (params.userId) { - sql += " AND `user_id` = '" + params.userId + "'" - } - - if (params.tags) { - sql += " AND `id` IN (SELECT `bookmark_id` FROM `tags_bookmarks` WHERE tag_id IN (" + params.tags + "))" - } - } else if (params.userRange == '2') { - sql += " AND `user_id` != '" + params.userId + "'" - if (params.username) { - sql += " AND `user_id` IN (SELECT `id` FROM `users` WHERE `username` LIKE '%" + params.username + "%' ) AND public=1 " - } - } - - params.currentPage = params.currentPage || 1; - params.perPageItems = params.perPageItems || 20; - sql += " ORDER BY click_count DESC, created_at DESC"; - console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - // 如果是全站搜索,默认优先显示其他用户的 - if (params.userRange == '2') { - result.sort((a, b) => { - return params.userId == a.user_id ? 1 : -1; - }) - } - // 去掉重复的 - var bookmarks = []; - result.forEach((b1) => { - var find = false; - bookmarks.forEach((b2) => { - if (b1.url == b2.url) { - find = true; - } - }) - if (!find) { - bookmarks.push(b1); - } - }) - var searchData = { - totalItems: bookmarks.length, - bookmarks: bookmarks.slice((params.currentPage - 1) * params.perPageItems, params.currentPage * params.perPageItems), - } - resolve(searchData); - } - }); - }) -} - -db.getHotBookmarksSearch = function(params) { - var sql = "SELECT id, title, description, url, fav_count, created_by, created_at, last_click, snap_url, favicon_url FROM `hot_bookmarks` WHERE status=0"; - - if (params.dateCreate) { - var d = new Date(); - d.setDate(d.getDate() - parseInt(params.dateCreate)); - sql += " AND `date` >= '" + d.format("yyyyMMdd") + "'" - } else if (params.dateCreateBegin && params.dateCreateEnd) { - var dateCreateBegin = new Date(params.dateCreateBegin).format("yyyyMMdd"); - var dateCreateEnd = new Date(params.dateCreateEnd).format("yyyyMMdd"); - sql += " AND `date` >= '" + dateCreateBegin + "' AND `date` <= '" + dateCreateEnd + "' " - } - if (params.dateClick) { - var d = new Date(); - d.setDate(d.getDate() - parseInt(params.dateClick)); - sql += " AND `last_click` >= '" + d.getTime() + "'" - } else if (params.dateClickBegin && params.dateClickEnd) { - var dateClickBegin = new Date(params.dateClickBegin + "T00:00:00"); - var dateClickEnd = new Date(params.dateClickEnd + "T23:59:59"); - sql += " AND `last_click` >= '" + dateClickBegin.getTime() + "' AND `last_click` <= '" + dateClickEnd.getTime() + "' " - } - - if (params.searchWord) { - sql += " AND (`title` LIKE '%" + params.searchWord + "%')" - } - sql += " ORDER BY fav_count DESC"; - console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - params.currentPage = params.currentPage || 1; - params.perPageItems = params.perPageItems || 20; - var searchData = { - totalItems: result.length, - bookmarks: result.slice((params.currentPage - 1) * params.perPageItems, params.currentPage * params.perPageItems), - } - resolve(searchData); - } - }); - }) -} - -db.getBookmarksCard = function(user_id) { - return db.getBookmarksTable(user_id); -} - -db.getTagsBookmarks = function(bookmark_ids) { - var sql = "SELECT * FROM `tags_bookmarks` WHERE bookmark_id in(" + (bookmark_ids.toString() || ("-1")) + ")"; // 如果是空的,那查一个不存在的就行了。 - console.log('getTagsBookmarks', sql); - - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -} - -db.getActiveUsers = function() { - var sql = " (SELECT username, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_login, '%Y-%m-%d %H:%i:%s') as last_login, email FROM users ORDER BY last_login DESC LIMIT 0, 5) UNION (SELECT username, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_login, '%Y-%m-%d %H:%i:%s') as last_login, email FROM users ORDER BY created_at DESC LIMIT 0, 5)"; - console.log('getActiveUsers', sql); - - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -} -db.getBookmarks = function() { - var sql = "SELECT id, snap_state FROM `bookmarks`"; // 如果是空的,那查一个不存在的就行了。 - console.log('getBookmarks', sql); - - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -} - -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"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -} - -db.getBookmarkWaitFavicon = function(today) { - var todayNotSnap = today + 31; - var sql = "SELECT id, url, favicon_state FROM `bookmarks` WHERE `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) { - reject(err); - } else { - resolve(result); - } - }); - }); -} - -db.updateBookmarkSnapState = function(id, snapState) { - console.log("updateBookmarkSnapState id = " + id + ", snapState = " + snapState); - var sql = "UPDATE `bookmarks` SET `snap_state`='" + snapState + "' WHERE (`id`='" + id + "')"; - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -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); - } - }); - }); -} - -db.addHotBookmark = function(bookmark) { - var sql = "REPLACE INTO `hot_bookmarks` (`id`, `date`, `title`, `url`, `fav_count`, `created_by`, `created_at`, `last_click`, `snap_url`, `favicon_url`) VALUES ('" + bookmark.id + "', '" + bookmark.date + "', " + client.escape(bookmark.title) + ", " + client.escape(bookmark.url) + ", '" + bookmark.fav_count + "', " + client.escape(bookmark.created_by) + ", '" + bookmark.created_at + "', '" + bookmark.last_click + "', " + client.escape(bookmark.snap_url) + ", " + client.escape(bookmark.favicon_url) + ")"; - - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.insertId); - } - }); - }); -}; - -db.hotBookmarks = function(date) { - var sql = "SELECT * FROM `hot_bookmarks` WHERE `date` = " + date + " AND `status` = 0" - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); -}; - -db.addNote = function(note) { - var sql = "INSERT INTO `notes` (`user_id`, `content`, `tag_id`) VALUES ('" + note.user_id + "', " + client.escape(note.content) + ", '" + note.tag_id + "')"; - console.log(sql); - - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.insertId); - } - }); - }); -}; - -db.getNotes = function(params) { - var sql = "SELECT notes.id, notes.content, notes.public, notes.tag_id, DATE_FORMAT(notes.created_at, '%Y-%m-%d %H:%i:%s') as created_at, tags.name as tagName FROM `notes` LEFT JOIN tags ON tags.id = notes.tag_id WHERE notes.user_id = '" + params.user_id + "'"; - - if (params.dateCreate) { - var d = new Date(); - d.setDate(d.getDate() - parseInt(params.dateCreate)); - sql += " AND notes.created_at >= '" + d.format("yyyyMMdd") + "'" - } - - if (params.searchWord) { - sql += " AND notes.content LIKE '%" + params.searchWord + "%'"; - } - - if (params.tagId) { - sql += " AND notes.tag_id = '" + params.tagId + "'"; - } - - if (params.tagIds) { - sql += "AND notes.tag_id IN (" + params.tagIds.toString() + ")" - } - - sql += " ORDER BY `created_at` DESC" - console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - params.currentPage = params.currentPage || 1; - params.perPageItems = params.perPageItems || 20; - var searchData = { - totalItems: result.length, - notes: result.slice((params.currentPage - 1) * params.perPageItems, params.currentPage * params.perPageItems), - } - resolve(searchData); - } - }); - }) -}; - -db.delNote = function(id) { - var sql = "DELETE FROM `notes` WHERE (`id`='" + id + "')"; - console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.updateNote = function(id, content, tag_id) { - var sql = "UPDATE `notes` SET `content`=" + client.escape(content) + ", `tag_id`='" + tag_id + "' WHERE (`id`='" + id + "')"; - console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.updateNotePublic = function(id, public) { - var sql = "UPDATE `notes` SET `public`='"+ public +"' WHERE (`id`='"+ id +"')"; - console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - resolve(result.affectedRows); - } - }); - }); -} - -db.getNote = function(id) { - var sql = "SELECT * FROM `notes` WHERE `id` = '"+ id +"' LIMIT 0, 1"; - console.log(sql); - return new Promise(function(resolve, reject) { - client.query(sql, (err, result) => { - if (err) { - reject(err); - } else { - if(result.length > 0) { - result[0].public == 1 ? resolve(result[0].content) : resolve("提示:备忘处于私密状态!"); - } else { - resolve("提示:备忘已删除或不存在!"); - } - } - }); - }); -} - -module.exports = db; +var mysql = require('mysql'); +var dbConfig = { + host: '127.0.0.1', + user: 'test', // mysql的账号 + password: '123456', // mysql 的密码 + database: 'mybookmarks', + multipleStatements: true, + useConnectionPooling: true, + port: 3306 +}; + +var client = mysql.createConnection(dbConfig); + +Date.prototype.format = function(fmt) { //author: meizz + var o = { + "M+": this.getMonth() + 1, //月份 + "d+": this.getDate(), //日 + "h+": this.getHours(), //小时 + "m+": this.getMinutes(), //分 + "s+": this.getSeconds(), //秒 + "q+": Math.floor((this.getMonth() + 3) / 3), //季度 + "S": this.getMilliseconds() //毫秒 + }; + if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); + for (var k in o) + if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); + return fmt; +} + +// select 最多返回一行的话,返回对象,否则返回数组 +// insert 返回关键字 +// update delete 返回影响的行数 +var db = { + +} + +// 每隔10秒查询一下,出现问题直接挂掉nodejs,让forever将其重启! +setInterval(function() { + var sql = "SELECT * FROM `users` WHERE `id` = '1'"; + client.query(sql, (err, result) => { + if (err) { + var date = new Date().format('yyyy-MM-dd hh:mm:ss'); + console.log(date + " :数据查询出问题了,直接挂掉程序,让forever重启应用,错误信息:" + JSON.stringify(err)); + throw new Error(""); + } + }); +}, 60000); + + +db.getBookmarkbyUrl = function(user_id, url) { + var sql = "SELECT * FROM `bookmarks` WHERE `user_id` = '" + user_id + "' AND `url` = '" + url + "'" + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + if (result.length >= 1) { + resolve(result[0].id); + } else { + resolve(null); + } + } + }); + }); +}; + +db.addBookmark = function(user_id, bookmark) { + var sql = "INSERT INTO `bookmarks` (`user_id`, `title`, `description`, `url`, `public`, `click_count`) VALUES ('" + user_id + "', " + client.escape(bookmark.title) + ", " + client.escape(bookmark.description) + ", " + client.escape(bookmark.url) + ", '" + bookmark.public + "', '1')"; + console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.insertId); + } + }); + }); +}; + +db.delBookmark = function(id) { + var sql = "DELETE FROM `bookmarks` WHERE (`id`='" + id + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.updateBookmark = function(bookmark) { + var sql = "UPDATE `bookmarks` SET `title`='" + bookmark.title + "', `description`=" + client.escape(bookmark.description) + ", `url`='" + bookmark.url + "', `public`='" + bookmark.public + "' WHERE (`id`='" + bookmark.id + "')"; + console.log("sql updateBookmark = " + sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.getBookmark = function(id) { + var sql = "SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `id` = '" + id + "'"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result[0]); + } + }); + }); +} + +db.getBookmarkTags = function(bookmard_id) { + var sql = "SELECT tag_id FROM `tags_bookmarks` WHERE `bookmark_id` = '" + bookmard_id + "'"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + var tags = result.map((item) => item.tag_id); + resolve(tags); + } + }); + }); +} + +db.getBookmarkTagsNames = function(bookmard_id) { + var sql = "SELECT tags_bookmarks.tag_id as id, tags.name FROM tags_bookmarks LEFT JOIN tags ON tags.id = tags_bookmarks.tag_id WHERE bookmark_id = '" + bookmard_id + "'"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +} + +db.delBookmarkTags = function(bookmard_id) { + var sql = "DELETE FROM `tags_bookmarks` WHERE (`bookmark_id`='" + bookmard_id + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.getBookmarkIdsByTagId = function(tagId) { + var sql = "SELECT bookmark_id FROM `tags_bookmarks` WHERE `tag_id` = '" + tagId + "'"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +} + +db.delTag = function(tagId) { + var sql = "DELETE FROM `tags` WHERE (`id`='" + tagId + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.delTagBookmarks = function(tagId) { + var sql = "DELETE FROM `tags_bookmarks` WHERE (`tag_id`='" + tagId + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.delBookmarks = function(bookmarkIds) { + var sql = "DELETE FROM `bookmarks` WHERE id IN (" + (bookmarkIds.toString() || ("-1")) + ")"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.delTagsBookmarks = function(bookmarkIds) { + var sql = "DELETE FROM `tags_bookmarks` WHERE bookmark_id IN (" + (bookmarkIds.toString() || ("-1")) + ")"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.addTagsBookmarks = function(tags, bookmard_id) { + sql = "INSERT INTO `tags_bookmarks` (`tag_id`, `bookmark_id`) VALUES"; + for (var i = 0; i < tags.length; i++) { + if (i >= 1) { + sql += ',' + } + sql += "('" + tags[i] + "', '" + bookmard_id + "')"; + } + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.updateLastUseTags = function(user_id, tags) { + sql = "UPDATE tags SET last_use = NOW() WHERE user_id = '" + user_id + "' AND id in (" + tags.toString() + ")"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.clickBookmark = function(id, user_id) { + var sql = "UPDATE `bookmarks` SET `click_count`=`click_count`+1, `last_click`=now() WHERE (`id`='" + id + "') AND (`user_id`='" + user_id + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +}; + +db.updateUserLastLogin = function(id) { + console.log('updateUserLastLogin'); + var sql = "UPDATE `users` SET `last_login`=now() WHERE (`id`='" + id + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +}; + +db.resetPassword = function(userId, password) { + console.log('updateUserLastLogin'); + var sql = "UPDATE `users` SET `password` = '" + password + "' WHERE(`id` = '" + userId + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.updateShowStyle = function(userId, show_style) { + console.log('updateUserLastLogin'); + var sql = "UPDATE `users` SET `show_style` = '" + show_style + "' WHERE(`id` = '" + userId + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.updateSearchHistory = function(userId, search_history) { + var sql = "UPDATE `users` SET `search_history`=" + client.escape(search_history) + " WHERE (`id`='" + userId + "')"; + console.log('updateSearchHistory', sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +}; + +db.updateQuickUrl = function(userId, quick_url) { + var sql = "UPDATE `users` SET `quick_url`=" + client.escape(quick_url) + " WHERE (`id`='" + userId + "')"; + console.log('updateQuickUrl', sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +}; + +db.register = function(user) { + console.log('register'); + var sql = "INSERT INTO `users` (`username`, `password`, `email`) VALUES ('" + user.username + "', '" + user.password + "', '" + user.email + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + db.insertDefaultBookmarks(result.insertId); + } + }); + }); +}; + +db.insertDefaultBookmarks = function(userId) { + var tags_name = ["常用", "未分类", "收藏"]; + + db.addTags(userId, tags_name) + .then((insertId) => { + var bookmarks = [{ + title: "谷歌", + description: "要翻墙的搜索网站", + url: "https://www.google.com.hk/", + public: "0" + }, { + title: "百度", + description: "A:百度一下你会死啊?B:会!", + url: "https://www.baidu.com/", + public: "0" + }, { + title: "微博", + description: "随时随地发现新鲜事", + url: "http://weibo.com/", + public: "0" + }, { + title: "天猫", + description: "上天猫,就够了!", + url: "https://www.tmall.com/", + public: "0" + }, { + title: "优酷", + description: "视频网站", + url: "http://www.youku.com/", + public: "0" + }]; + + var tags = [insertId]; + bookmarks.forEach((bookmark) => { + db.addBookmark(userId, bookmark) + .then((insertId) => db.addTagsBookmarks(tags, insertId)) + .catch((err) => console.log('insertDefaultBookmarks err2', err)); // oops! + }) + }) + .catch((err) => console.log('insertDefaultBookmarks err1', err)); // oops! +} + +db.getUser = function(username) { + console.log('getUser'); + var sql = "SELECT * FROM `users` WHERE `username` = '" + username + "'"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result[0]); + } + }); + }); +}; + +db.getTags = function(user_id) { + var sql = "SELECT t.id, t.user_id, t.name, DATE_FORMAT(t.last_use, '%Y-%m-%d %H:%i:%s') as last_use, t.sort, tb.cnt, tg.ncnt FROM `tags` as t LEFT OUTER JOIN ( SELECT `tag_id`, COUNT(tag_id) as cnt FROM tags_bookmarks GROUP BY tag_id ) tb ON t.id = tb.tag_id LEFT OUTER JOIN ( SELECT `tag_id`, COUNT(tag_id) as ncnt FROM notes GROUP BY tag_id ) tg ON t.id = tg.tag_id "; + if (user_id) { + sql += "WHERE t.user_id = '" + user_id + "' "; + } + sql += "ORDER BY t.sort, t.last_use DESC"; + console.log('getTags sql = ', sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +}; + +db.updateTagName = function(tag) { + console.log('updateTagName'); + var sql = "UPDATE `tags` SET `name`='" + tag.name + "' WHERE (`id`='" + tag.id + "')"; + console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +}; + +db.updateTagsIndex = function(tagsIndex) { + console.log('updateTagsIndex'); + var sql = "UPDATE tags SET sort = CASE id "; + tagsIndex.forEach((tagIndex) => { + sql += "WHEN " + tagIndex.id + " THEN " + tagIndex.index + " "; + }) + var tagsId = tagsIndex.map((item) => item.id); + sql += "END WHERE id IN (" + tagsId.toString() + ")"; + + console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +}; + +db.getTagsByIds = function(tagIds) { + var sql = "SELECT * FROM `tags` WHERE id in(" + (tagIds.toString() || ("-1")) + ") GROUP BY id"; // 如果是空的,那查一个不存在的就行了。 + console.log('db getTagsByIds = ', sql); + + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +} + +db.getAdvices = function(params) { + console.log('getAdvices'); + var sql = "SELECT a.id, a.user_id, u.username, a.comment, a.category, DATE_FORMAT(a.created_at, '%Y-%m-%d %H:%i:%s') as created_at, a.state FROM `advices` as a LEFT OUTER JOIN users as u ON a.user_id = u.id ORDER BY a.created_at DESC LIMIT 0, 100"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +}; + +db.addAdvice = function(params) { + console.log('addAdvice'); + var sql = "INSERT INTO `advices` (`user_id`, `comment`, `category`) VALUES ('" + params.user_id + "', '" + params.comment + "', '" + params.category + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +}; + +db.getTagsByNames = function(user_id, tags_name) { + console.log('getTagsByNames'); + var sql = "SELECT * FROM `tags` WHERE `user_id` = '" + user_id + "' AND `name` in (" + tags_name.toString() + ")"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +}; + +db.addTags = function(user_id, tags_name) { + console.log('addTags', tags_name); + var sql = "INSERT INTO `tags` (`user_id`, `name`, `sort`) VALUES"; + tags_name.forEach((name, i) => { + if (i >= 1) { + sql += ',' + } + sql += "('" + user_id + "', '" + name + "', '88')"; // sort默认一个比较大的值,默认在后面 + }); + return new Promise(function(resolve, reject) { + if (tags_name.length == 0) { + reject("tags_name is empty"); + } else { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.insertId); + } + }); + } + }); +}; + +db.getBookmarksNavigate = function(tags) { + // console.log('getBookmarksNavigate'); + // var sql = "SELECT t.id as tag_id, t.name as tag_name, b.* FROM `tags` as t LEFT OUTER JOIN tags_bookmarks as tb ON t.id = tb.tag_id LEFT OUTER JOIN bookmarks as b ON tb.bookmark_id = b.id WHERE t.user_id='" + user_id + "' ORDER BY t.id ASC, b.click_count DESC"; + var sql = ""; + tags.forEach((tag, index) => { + var t = 't' + tag.id; + if (index >= 1) { + sql += " UNION " + } + sql += "(SELECT * FROM ((SELECT t.id AS tag_id, t.`name` as tag_name, t.sort, b.* FROM `tags` as t, `bookmarks`as b, `tags_bookmarks` as tb WHERE t.id = tb.tag_id AND b.id = tb.bookmark_id AND t.id = " + tag.id + " ORDER BY b.click_count DESC LIMIT 0, 16) UNION (SELECT t.id AS tag_id, t.`name` as tag_name, t.sort, b.* FROM `tags` as t, `bookmarks`as b, `tags_bookmarks` as tb WHERE t.id = tb.tag_id AND b.id = tb.bookmark_id AND t.id = " + tag.id + " ORDER BY b.created_at DESC LIMIT 0, 16)) as " + t + " ORDER BY " + t + ".click_count DESC, " + t + ".created_at DESC)"; + }) + // console.log('getBookmarksNavigate ', sql); + + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +}; + +db.getBookmarksCostomTag = function(user_id, perPageItems) { + console.log('getBookmarksCostomTag', user_id, perPageItems); + perPageItems = perPageItems || 50; + var sql1 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` = '" + user_id + "' ORDER BY `click_count` DESC LIMIT 0, " + perPageItems + ")"; + var sql2 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` = '" + user_id + "' ORDER BY `created_at` DESC LIMIT 0, " + perPageItems + ")"; + var sql3 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` = '" + user_id + "' ORDER BY `last_click` DESC LIMIT 0, " + perPageItems + ")"; + + var sql = sql1 + " UNION " + sql2 + " UNION " + sql3; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + var bookmarks = []; + var begin = 0; + var end = perPageItems; + + result.sort((a, b) => { + var click1 = parseInt(a.click_count); + var click2 = parseInt(b.click_count); + if (click1 > click2) { + return -1; + } else if (click1 == click2) { + return a.created_at >= b.created_at ? -1 : 1; + } else { + return 1; + } + }) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 1; + bookmarks.push(bookmark); + }) + + result.sort((a, b) => a.created_at >= b.created_at ? -1 : 1) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 2; + bookmarks.push(bookmark); + }) + + result.sort((a, b) => a.last_click >= b.last_click ? -1 : 1) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 3; + bookmarks.push(bookmark); + }) + + + var bookmarksData = { + totalItems: result.length, + bookmarks: bookmarks, + } + resolve(bookmarksData); + } + }); + }); +}; + +db.getBookmarksCostomAllUsersTag = function(user_id, perPageItems) { + console.log('getBookmarksCostomAllUsersTag', user_id, perPageItems); + perPageItems = perPageItems || 50; + var sql1 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` != '" + user_id + "' AND public != 0 AND user_id != 120 ORDER BY `click_count` DESC LIMIT 0, " + perPageItems + ")"; + var sql2 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` != '" + user_id + "' AND public != 0 AND user_id != 120 ORDER BY `created_at` DESC LIMIT 0, " + perPageItems + ")"; + var sql3 = "(SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE `user_id` != '" + user_id + "' AND public != 0 AND user_id != 120 ORDER BY `last_click` DESC LIMIT 0, " + perPageItems + ")"; + + var sql = sql1 + " UNION " + sql2 + " UNION " + sql3; + // console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + var bookmarks = []; + var begin = 0; + var end = perPageItems; + + result.sort((a, b) => { + var click1 = parseInt(a.click_count); + var click2 = parseInt(b.click_count); + if (click1 > click2) { + return -1; + } else if (click1 == click2) { + return a.created_at >= b.created_at ? -1 : 1; + } else { + return 1; + } + }) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 1; + bookmarks.push(bookmark); + }) + + result.sort((a, b) => a.created_at >= b.created_at ? -1 : 1) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 2; + bookmarks.push(bookmark); + }) + + result.sort((a, b) => a.last_click >= b.last_click ? -1 : 1) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 3; + bookmarks.push(bookmark); + }) + + + var bookmarksData = { + totalItems: result.length, + bookmarks: bookmarks, + } + resolve(bookmarksData); + } + }); + }); +}; + + +db.getBookmarksTable = function(params) { + var user_id = params.userId; + params.currentPage = params.currentPage || 1; + params.perPageItems = params.perPageItems || 20; + + var sql = "SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE 1=1"; + if (user_id) { + sql += " AND `user_id` = '" + user_id + "'"; + } + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + var bookmarks = []; + var begin = (params.currentPage - 1) * params.perPageItems; + var end = params.currentPage * params.perPageItems; + + result.sort((a, b) => { + var click1 = parseInt(a.click_count); + var click2 = parseInt(b.click_count); + if (click1 > click2) { + return -1; + } else if (click1 == click2) { + return a.created_at >= b.created_at ? -1 : 1; + } else { + return 1; + } + }) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 1; + bookmarks.push(bookmark); + }) + + result.sort((a, b) => a.created_at >= b.created_at ? -1 : 1) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 2; + bookmarks.push(bookmark); + }) + + result.sort((a, b) => a.last_click >= b.last_click ? -1 : 1) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 3; + bookmarks.push(bookmark); + }) + + var bookmarksData = { + totalItems: result.length, + bookmarks: bookmarks, + } + + resolve(bookmarksData); + } + }); + }) +} + +db.getBookmarksByTag = function(params) { + var tag_id = params.tagId; + params.currentPage = params.currentPage || 1; + params.perPageItems = params.perPageItems || 20; + + var sql = "SELECT bookmarks.id, bookmarks.user_id, bookmarks.title, bookmarks.description, bookmarks.url, bookmarks.public, bookmarks.click_count, DATE_FORMAT(bookmarks.created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(bookmarks.last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `tags_bookmarks`, `bookmarks` WHERE tags_bookmarks.tag_id = '" + tag_id + "' AND tags_bookmarks.bookmark_id = bookmarks.id"; + + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + var bookmarks = []; + var begin = (params.currentPage - 1) * params.perPageItems; + var end = params.currentPage * params.perPageItems; + + result.sort((a, b) => { + var click1 = parseInt(a.click_count); + var click2 = parseInt(b.click_count); + if (click1 > click2) { + return -1; + } else if (click1 == click2) { + return a.created_at >= b.created_at ? -1 : 1; + } else { + return 1; + } + }) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 1; + bookmarks.push(bookmark); + }) + + result.sort((a, b) => a.created_at >= b.created_at ? -1 : 1) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 2; + bookmarks.push(bookmark); + }) + + result.sort((a, b) => a.last_click >= b.last_click ? -1 : 1) + .slice(begin, end) + .forEach((b) => { + var bookmark = JSON.parse(JSON.stringify(b)); // 执行深度复制 + bookmark.type = 3; + bookmarks.push(bookmark); + }) + + var bookmarksData = { + totalItems: result.length, + bookmarks: bookmarks, + } + + resolve(bookmarksData); + } + }); + }) +} + +db.getExportBookmarksByTag = function(tag_id) { + var sql = "SELECT tags_bookmarks.tag_id, bookmarks.title, bookmarks.url, DATE_FORMAT(bookmarks.created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(bookmarks.last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `tags_bookmarks`, `bookmarks` WHERE tags_bookmarks.tag_id = '" + tag_id + "' AND tags_bookmarks.bookmark_id = bookmarks.id ORDER BY bookmarks.click_count DESC"; + + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }) +} + +db.getBookmarksSearch = function(params) { + var sql = "SELECT id, user_id, title, description, url, public, click_count, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_click, '%Y-%m-%d %H:%i:%s') as last_click FROM `bookmarks` WHERE 1=1"; + + if (params.dateCreate) { + var d = new Date(); + d.setDate(d.getDate() - parseInt(params.dateCreate)); + sql += " AND `created_at` >= '" + d.format('yyyy-MM-dd') + "'" + } else if (params.dateCreateBegin && params.dateCreateEnd) { + sql += " AND `created_at` >= '" + params.dateCreateBegin + " 00:00:00" + "' AND `created_at` <= '" + params.dateCreateEnd + " 23:59:59" + "' " + } + if (params.dateClick) { + var d = new Date(); + d.setDate(d.getDate() - parseInt(params.dateClick)); + sql += " AND `last_click` >= '" + d.format('yyyy-MM-dd') + "'" + } else if (params.dateClickBegin && params.dateClickEnd) { + sql += " AND `last_click` >= '" + params.dateClickBegin + " 00:00:00" + "' AND `last_click` <= '" + params.dateClickEnd + " 23:59:59" + "' " + } + + if (params.searchWord) { + sql += " AND (`title` LIKE '%" + params.searchWord + "%' OR `url` LIKE '%" + params.searchWord + "%')" + } + + if (params.userRange == '1') { + if (params.userId) { + sql += " AND `user_id` = '" + params.userId + "'" + } + + if (params.tags) { + sql += " AND `id` IN (SELECT `bookmark_id` FROM `tags_bookmarks` WHERE tag_id IN (" + params.tags + "))" + } + } else if (params.userRange == '2') { + sql += " AND `user_id` != '" + params.userId + "'" + if (params.username) { + sql += " AND `user_id` IN (SELECT `id` FROM `users` WHERE `username` LIKE '%" + params.username + "%' ) AND public=1 " + } + } + + params.currentPage = params.currentPage || 1; + params.perPageItems = params.perPageItems || 20; + sql += " ORDER BY click_count DESC, created_at DESC"; + console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + // 如果是全站搜索,默认优先显示其他用户的 + if (params.userRange == '2') { + result.sort((a, b) => { + return params.userId == a.user_id ? 1 : -1; + }) + } + // 去掉重复的 + var bookmarks = []; + result.forEach((b1) => { + var find = false; + bookmarks.forEach((b2) => { + if (b1.url == b2.url) { + find = true; + } + }) + if (!find) { + bookmarks.push(b1); + } + }) + var searchData = { + totalItems: bookmarks.length, + bookmarks: bookmarks.slice((params.currentPage - 1) * params.perPageItems, params.currentPage * params.perPageItems), + } + resolve(searchData); + } + }); + }) +} + +db.getHotBookmarksSearch = function(params) { + var sql = "SELECT id, title, description, url, fav_count, created_by, created_at, last_click, snap_url, favicon_url FROM `hot_bookmarks` WHERE status=0"; + + if (params.dateCreate) { + var d = new Date(); + d.setDate(d.getDate() - parseInt(params.dateCreate)); + sql += " AND `date` >= '" + d.format("yyyyMMdd") + "'" + } else if (params.dateCreateBegin && params.dateCreateEnd) { + var dateCreateBegin = new Date(params.dateCreateBegin).format("yyyyMMdd"); + var dateCreateEnd = new Date(params.dateCreateEnd).format("yyyyMMdd"); + sql += " AND `date` >= '" + dateCreateBegin + "' AND `date` <= '" + dateCreateEnd + "' " + } + if (params.dateClick) { + var d = new Date(); + d.setDate(d.getDate() - parseInt(params.dateClick)); + sql += " AND `last_click` >= '" + d.getTime() + "'" + } else if (params.dateClickBegin && params.dateClickEnd) { + var dateClickBegin = new Date(params.dateClickBegin + "T00:00:00"); + var dateClickEnd = new Date(params.dateClickEnd + "T23:59:59"); + sql += " AND `last_click` >= '" + dateClickBegin.getTime() + "' AND `last_click` <= '" + dateClickEnd.getTime() + "' " + } + + if (params.searchWord) { + sql += " AND (`title` LIKE '%" + params.searchWord + "%')" + } + sql += " ORDER BY fav_count DESC"; + console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + params.currentPage = params.currentPage || 1; + params.perPageItems = params.perPageItems || 20; + var searchData = { + totalItems: result.length, + bookmarks: result.slice((params.currentPage - 1) * params.perPageItems, params.currentPage * params.perPageItems), + } + resolve(searchData); + } + }); + }) +} + +db.getBookmarksCard = function(user_id) { + return db.getBookmarksTable(user_id); +} + +db.getTagsBookmarks = function(bookmark_ids) { + var sql = "SELECT * FROM `tags_bookmarks` WHERE bookmark_id in(" + (bookmark_ids.toString() || ("-1")) + ")"; // 如果是空的,那查一个不存在的就行了。 + console.log('getTagsBookmarks', sql); + + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +} + +db.getActiveUsers = function() { + var sql = " (SELECT username, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_login, '%Y-%m-%d %H:%i:%s') as last_login, email FROM users ORDER BY last_login DESC LIMIT 0, 5) UNION (SELECT username, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_login, '%Y-%m-%d %H:%i:%s') as last_login, email FROM users ORDER BY created_at DESC LIMIT 0, 5)"; + console.log('getActiveUsers', sql); + + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +} +db.getBookmarks = function() { + var sql = "SELECT id, snap_state FROM `bookmarks`"; // 如果是空的,那查一个不存在的就行了。 + console.log('getBookmarks', sql); + + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +} + +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"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +} + +db.getBookmarkWaitFavicon = function(today) { + var todayNotSnap = today + 31; + var sql = "SELECT id, url, favicon_state FROM `bookmarks` WHERE `favicon_state`>=0 AND `favicon_state` <= 64 AND favicon_state != " + todayNotSnap + " ORDER BY created_at DESC"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +} + +db.updateBookmarkSnapState = function(id, snapState) { + console.log("updateBookmarkSnapState id = " + id + ", snapState = " + snapState); + var sql = "UPDATE `bookmarks` SET `snap_state`='" + snapState + "' WHERE (`id`='" + id + "')"; + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +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); + } + }); + }); +} + +db.addHotBookmark = function(bookmark) { + var sql = "REPLACE INTO `hot_bookmarks` (`id`, `date`, `title`, `url`, `fav_count`, `created_by`, `created_at`, `last_click`, `snap_url`, `favicon_url`) VALUES ('" + bookmark.id + "', '" + bookmark.date + "', " + client.escape(bookmark.title) + ", " + client.escape(bookmark.url) + ", '" + bookmark.fav_count + "', " + client.escape(bookmark.created_by) + ", '" + bookmark.created_at + "', '" + bookmark.last_click + "', " + client.escape(bookmark.snap_url) + ", " + client.escape(bookmark.favicon_url) + ")"; + + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.insertId); + } + }); + }); +}; + +db.hotBookmarks = function(date) { + var sql = "SELECT * FROM `hot_bookmarks` WHERE `date` = " + date + " AND `status` = 0" + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); +}; + +db.addNote = function(note) { + var sql = "INSERT INTO `notes` (`user_id`, `content`, `tag_id`) VALUES ('" + note.user_id + "', " + client.escape(note.content) + ", '" + note.tag_id + "')"; + console.log(sql); + + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.insertId); + } + }); + }); +}; + +db.getNotes = function(params) { + var sql = "SELECT notes.id, notes.content, notes.public, notes.tag_id, DATE_FORMAT(notes.created_at, '%Y-%m-%d %H:%i:%s') as created_at, tags.name as tagName FROM `notes` LEFT JOIN tags ON tags.id = notes.tag_id WHERE notes.user_id = '" + params.user_id + "'"; + + if (params.dateCreate) { + var d = new Date(); + d.setDate(d.getDate() - parseInt(params.dateCreate)); + sql += " AND notes.created_at >= '" + d.format("yyyyMMdd") + "'" + } + + if (params.searchWord) { + sql += " AND notes.content LIKE '%" + params.searchWord + "%'"; + } + + if (params.tagId) { + sql += " AND notes.tag_id = '" + params.tagId + "'"; + } + + if (params.tagIds) { + sql += "AND notes.tag_id IN (" + params.tagIds.toString() + ")" + } + + sql += " ORDER BY `created_at` DESC" + console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + params.currentPage = params.currentPage || 1; + params.perPageItems = params.perPageItems || 20; + var searchData = { + totalItems: result.length, + notes: result.slice((params.currentPage - 1) * params.perPageItems, params.currentPage * params.perPageItems), + } + resolve(searchData); + } + }); + }) +}; + +db.delNote = function(id) { + var sql = "DELETE FROM `notes` WHERE (`id`='" + id + "')"; + console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.updateNote = function(id, content, tag_id) { + var sql = "UPDATE `notes` SET `content`=" + client.escape(content) + ", `tag_id`='" + tag_id + "' WHERE (`id`='" + id + "')"; + console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.updateNotePublic = function(id, public) { + var sql = "UPDATE `notes` SET `public`='"+ public +"' WHERE (`id`='"+ id +"')"; + console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result.affectedRows); + } + }); + }); +} + +db.getNote = function(id) { + var sql = "SELECT * FROM `notes` WHERE `id` = '"+ id +"' LIMIT 0, 1"; + console.log(sql); + return new Promise(function(resolve, reject) { + client.query(sql, (err, result) => { + if (err) { + reject(err); + } else { + if(result.length > 0) { + result[0].public == 1 ? resolve(result[0].content) : resolve("提示:备忘处于私密状态!"); + } else { + resolve("提示:备忘已删除或不存在!"); + } + } + }); + }); +} + +module.exports = db; diff --git a/routes/api.js b/routes/api.js index a70011a..841677f 100644 --- a/routes/api.js +++ b/routes/api.js @@ -1,1616 +1,1595 @@ -var api = require('express').Router(); -var mysql = require('mysql'); -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('download'); -var multer = require('multer'); -// var webshot = require('webshot'); -var fs = require('fs'); -var request = require('request'); -var cheerio = require('cheerio'); -var path = require('path'); -var beautify_html = require('js-beautify').html; - -var storage = multer.diskStorage({ - destination: function(req, file, cb) { - cb(null, 'uploads/') - }, - filename: function(req, file, cb) { - var now = new Date().format('yyyyMMddhhmmss') - if (req.session.user) { - cb(null, 'importbookmark-' + req.session.username + '-' + now + '.html') - } else { - cb(null, "UnknowUser" + '-' + now + '.html') - } - } -}) - -var upload = multer({ - storage: storage, - limits: { - fileSize: 10 * 1024 * 2014, // 最大值接受10M - }, - fileFilter: function(req, file, cb) { - cb(null, file.mimetype == "text/html"); - }, -}) - -api.post('/logout', function(req, res) { - var params = req.body.params; - console.log('logout......', params); - req.session.destroy(); - res.json({ - data: "logout success", - }); -}); - -api.post('/clickBookmark', function(req, res) { - console.log("clickBookmark username = ", req.session.username); - db.getUser(req.session.username) - .then((user) => { return user.id == req.session.userId ? db.clickBookmark(req.body.params.id, req.session.userId) : Promise.resolve(0); }) - .then((affectedRows) => res.json({})) - .catch((err) => console.log('clickBookmark error', err)); -}); - -api.post('/jumpQuickUrl', function(req, res) { - console.log("jumpQuickUrl username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - db.getBookmarkbyUrl(req.session.user.id, req.body.params.url) - .then((bookmarkId) => { - res.json({id: bookmarkId}); - if (bookmarkId) { - return db.clickBookmark(bookmarkId, req.session.user.id); - } else { - return Promise.reject(0); - } - }) - .then((affectedRows) => {}) - .catch((err) => console.log('jumpQuickUrl err', err)); // oops! -}); - -api.post('/login', function(req, res) { - var params = req.body.params; - var username = params.username; - var password = md5(params.password); - console.log(password); - db.getUser(username) - .then((user) => { - var ret = { - logined: false, - user: {}, - } - if (user && user.password === password) { - ret.logined = true; - ret.user = user; - req.session.user = user; - req.session.username = ret.user.username; - req.session.userId = ret.user.id; - } - ret.user.password = "*"; - res.json(ret); - return ret.logined ? db.updateUserLastLogin(ret.user.id) : Promise.resolve(0); - }) - .then((affectedRows) => { - console.log('updateUserLastLogin affectedRows ', affectedRows) - }) - .catch((err) => console.log('login error', err)); -}); - -api.get('/userInfo', function(req, res) { - console.log("userInfo username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var user = {}; - db.getUser(req.session.username) - .then((_user) => { - user = _user - user.password = "*"; - if (req.session.username == 'lcq' && req.session.userId == 1) { - return db.getActiveUsers(); - } else { - return Promise.resolve([]); - } - }) - .then((_activeUsers) => { - user.activeUsers = _activeUsers; - res.json(user); - }) - .catch((err) => console.log('userInfo error', err)); -}); - -api.post('/register', function(req, res) { - var params = req.body.params; - params.password = md5(params.password); // 进行密码加密 - - db.register(params) - .then((affectedRows) => { - res.json({ - retCode: 0, - msg: params.username + " 注册成功 ", - }) - console.log('register affectedRows ', affectedRows) - }) - .catch((err) => { - console.log('login error', err); - res.json({ - retCode: 1, - msg: params.username + " 注册失败: " + JSON.stringify(err), - }) - }); -}); - -api.post('/resetPassword', function(req, res) { - console.log("resetPassword username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - - var params = req.body.params; - var passwordOrigin = md5(params.passwordOrgin); // 进行密码加密 - var passwordNew = md5(params.passwordNew); // 进行密码加密 - - db.getUser(req.session.user.username) - .then((user) => { - if (user && user.password === passwordOrigin) { - return db.resetPassword(req.session.userId, passwordNew) - } else { - return Promise.resolve(0) - } - }) - .then((affectedRows) => { - res.json({ - retCode: (affectedRows == 1 ? 0 : 1), - msg: req.session.username + " 更新密码失败,可能原密码不正确!", - }) - - if (affectedRows) { - req.session.destroy(); - } - }) - .catch((err) => { - console.log('resetPassword error', err); - res.json({ - retCode: 2, - msg: req.session.username + " 更新密码失败: " + JSON.stringify(err), - }) - }); -}); - -api.post('/updateShowStyle', function(req, res) { - console.log("updateShowStyle username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - - var params = req.body.params; - db.getUser(req.session.user.username) - .then((user) => { - if (user) { - return db.updateShowStyle(req.session.userId, params.showStyle) - } else { - return Promise.resolve(0) - } - }) - .then((affectedRows) => { - res.json({ - retCode: (affectedRows == 1 ? 0 : 1), - msg: req.session.username + " 更新书签默认显示风格配置成功!", - }) - - if (affectedRows) { - req.session.user.show_style = params.showStyle; - } - }) - .catch((err) => { - console.log('resetPassword error', err); - res.json({ - retCode: 2, - msg: req.session.username + " 更新书签默认显示风格配置失败!: " + JSON.stringify(err), - }) - }); -}); - -api.post('/updateSearchHistory', function(req, res) { - console.log("updateSearchHistory username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - - var params = req.body.params; - db.getUser(req.session.user.username) - .then((user) => { - if (user) { - return db.updateSearchHistory(req.session.userId, params.searchHistory) - } else { - return Promise.resolve(0) - } - }) - .then((affectedRows) => { - res.json({ - retCode: (affectedRows == 1 ? 0 : 1), - msg: req.session.username + " 更新历史搜索成功!", - }) - }) - .catch((err) => { - console.log('resetPassword error', err); - res.json({ - retCode: 2, - msg: req.session.username + " 更新历史搜索失败!: " + JSON.stringify(err), - }) - }); -}); - -api.post('/updateQuickUrl', function(req, res) { - console.log("updateQuickUrl username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - - var params = req.body.params; - db.getUser(req.session.user.username) - .then((user) => { - if (user) { - return db.updateQuickUrl(req.session.userId, params.quickUrl) - } else { - return Promise.resolve(0) - } - }) - .then((affectedRows) => { - res.json({ - retCode: (affectedRows == 1 ? 0 : 1), - msg: req.session.username + " 更新全局快捷键成功!", - }) - }) - .catch((err) => { - console.log('resetPassword error', err); - res.json({ - retCode: 2, - msg: req.session.username + " 更新全局快捷键失败!: " + JSON.stringify(err), - }) - }); -}); - -api.get('/autoLogin', function(req, res) { - console.log("autoLogin username = ", req.session.username); - var ret = { - logined: false, - user: {}, - } - if (req.session.user) { - db.getUser(req.session.user.username) - .then((user) => { - if (user) { - user.password = "*"; - ret.logined = true; - ret.user = user; - } - res.json(ret); - return ret.logined ? db.updateUserLastLogin(ret.user.id) : Promise.resolve(0); - }) - .catch((err) => { - res.json(ret); - }) - } else { - res.json(ret); - } -}); - -api.delete('/delBookmark', function(req, res) { - console.log("delBookmark username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var bookmarkId = req.query.id; - db.delBookmarkTags(bookmarkId) - .then(() => db.delBookmark(bookmarkId)) - .then((affectedRows) => res.json({ - result: affectedRows - })) - .catch((err) => console.log('delBookmark err', err)); -}) - -api.post('/updateBookmark', function(req, res) { - console.log("updateBookmark username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - - var bookmark = req.body.params; - var userId = req.session.user.id; - var tags = bookmark.tags; - var ret = {} - console.log('hello updateBookmark', JSON.stringify(bookmark)); - db.updateBookmark(bookmark) // 更新标签信息 - .then((affectedRows) => db.delBookmarkTags(bookmark.id)) // 将之前所有的书签分类信息删掉 - .then((insertId) => db.addTagsBookmarks(tags, bookmark.id)) // 将新的分类关联起来 - .then(() => db.updateLastUseTags(userId, tags)) // 更新最近使用的分类(这个有待考虑) - .then(() => db.getBookmark(bookmark.id)) // 将新的信息返回去 - .then((bookmark) => { - ret = bookmark; - return db.getBookmarkTagsNames(bookmark.id); - }) - .then((tags) => { - ret.tags = tags; - res.json(ret); - }) // 运气不错 - .catch((err) => console.log('updateBookmark err', err)); // oops! -}) - -api.get('/bookmark', function(req, res) { - console.log("bookmark username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var bookmarkId = req.query.bookmarkId; - var userId = req.session.user.id; - var ret = { - bookmark: {}, - bookmarkTags: [], - tags: [], - }; - - db.getBookmark(bookmarkId) - .then((bookmark) => { - ret.bookmark = bookmark; - return db.getBookmarkTags(bookmarkId); - }) - .then((bookmarkTags) => { - ret.bookmarkTags = bookmarkTags; - return db.getTags(userId); - }) - .then((tags) => { - ret.tags = tags; - res.json(ret); - }) - .catch((err) => console.log('bookmark err', err)); -}) - -api.get('/bookmarks', function(req, res) { - console.log("bookmarks username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var userId = req.session.user.id; - var params = req.query; - params.showStyle = params.showStyle || req.session.user.show_style; // 如果没有指定风格,那么用系统风格 - if (params.showStyle === 'navigate') { - db.getTags(userId) - .then((tags) => db.getBookmarksNavigate(tags)) - .then((result) => { - var data = []; - var tag = { - id: result && result[0] && result[0].tag_id, - name: result && result[0] && result[0].tag_name, - sort: result && result[0] && result[0].sort, - click: 0, - bookmarks: [] - }; - result.forEach(function(bookmark) { - if (tag.id !== bookmark.tag_id) { - data.push({ - id: tag.id, - name: tag.name, - sort: tag.sort, - click: tag.click, - bookmarks: tag.bookmarks - }); - tag.id = bookmark.tag_id; - tag.name = bookmark.tag_name; - tag.sort = bookmark.sort; - tag.click = 0; - tag.bookmarks = []; - } - tag.click += bookmark.click_count; - bookmark.created_at = new Date(bookmark.created_at).format("yyyy-MM-dd hh:mm:ss"); - bookmark.last_click = new Date(bookmark.last_click).format("yyyy-MM-dd hh:mm:ss"); - tag.bookmarks.push(bookmark); - }); - if (result && result.length > 0) { - data.push(tag); - } - data.sort((a, b) => { - if (a.sort == b.sort) return b.click - a.click; - return a.sort - b.sort; - }); - var temp = data.map(item => { - return { - name: item.name, - sort: item.sort, - click: item.click, - } - }) - res.json(data); - }) - .catch((err) => console.log('bookmarks navigate err', err)); - } else if (params.showStyle === 'costomTag') { - var bookmarks = [] - db.getBookmarksCostomTag(userId) - .then((bookmarksData) => { - bookmarks = bookmarksData.bookmarks; - var bookmarkIds = bookmarks.map((bookmark) => bookmark.id) - return db.getTagsBookmarks(bookmarkIds); - }) - .then((tbs) => { - tagsBookmarks = tbs; - return db.getTags(userId); - }) - .then((tags) => { - bookmarks.forEach(function(bookmark, index) { - var bookmarkTags = []; - tagsBookmarks.forEach(function(tb) { - if (tb.bookmark_id == bookmark.id) { - tags.forEach(function(tag) { - if (tb.tag_id == tag.id) { - bookmarkTags.push(tag) - } - }) - } - }); - bookmarks[index].tags = bookmarkTags; - }) - res.json(bookmarks); - }) - .catch((err) => console.log('bookmarks costomTag err', err)) - } else { - var tagsBookmarks = []; - var sendData = { - totalItems: 0, - bookmarks: [], - } - - params.userId = userId; - db.getBookmarksTable(params) - .then((bookmarksData) => { - sendData = bookmarksData; - var bookmarkIds = sendData.bookmarks.map((bookmark) => bookmark.id) - return db.getTagsBookmarks(bookmarkIds); - }) - .then((tbs) => { - tagsBookmarks = tbs; - return db.getTags(userId); - }) - .then((tags) => { - sendData.bookmarks.forEach(function(bookmark, index) { - var bookmarkTags = []; - tagsBookmarks.forEach(function(tb) { - if (tb.bookmark_id == bookmark.id) { - tags.forEach(function(tag) { - if (tb.tag_id == tag.id) { - bookmarkTags.push(tag) - } - }) - } - }); - sendData.bookmarks[index].tags = bookmarkTags; - }) - - res.json(sendData); - }) - .catch((err) => console.log('bookmarks table or card err', err)) - } -}); - -api.get('/hotBookmarks', function(req, res) { - console.log("hotBookmarks username = ", req.session.username); - var userId = req.session.user.id; - var params = req.query; - var date = params.date || new Date().format('yyyyMMdd');; - db.hotBookmarks(date) - .then((bookmarks) => { - res.json(bookmarks); - }) - .catch((err) => console.log('hotBookmarks err', err)) -}); - -api.get('/bookmarksByTag', function(req, res) { - console.log("bookmarksByTag username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var userId = req.session.user.id; - var params = req.query; - - var bookmarks = []; - var tagsBookmarks = []; - var totalItems = 0; - var totalItems = 0; - var sendData = { - totalItems: 0, - bookmarks: [], - } - - // -1 获取自己定制的 - // -2 获取全站定制的 - var fun = (params.tagId <= -1) ? (params.tagId == -1 ? db.getBookmarksCostomTag : db.getBookmarksCostomAllUsersTag) : (db.getBookmarksByTag); - - fun((params.tagId <= -1) ? (userId) : (params), params.perPageItems) - .then((bookmarksData) => { - sendData = bookmarksData; - var bookmarkIds = sendData.bookmarks.map((bookmark) => bookmark.id) - return db.getTagsBookmarks(bookmarkIds); - }) - .then((tbs) => { - tagsBookmarks = tbs; - return db.getTags(params.tagId >= -1 ? userId : null); - }) - .then((tags) => { - // 获取每个书签的所有分类标签 - sendData.bookmarks.forEach(function(bookmark, index) { - var bookmarkTags = []; - tagsBookmarks.forEach(function(tb) { - if (tb.bookmark_id == bookmark.id) { - tags.forEach(function(tag) { - if (tb.tag_id == tag.id) { - bookmarkTags.push(tag) - } - }) - } - }); - sendData.bookmarks[index].tags = bookmarkTags; - }) - res.json(sendData); - }) - .catch((err) => console.log('getBookmarksByTag err', err)) - -}); - -api.get('/searchBookmarks', function(req, res) { - console.log("searchBookmarks username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var params = req.query; - params.userId = req.session.user.id; - var bookmarks = []; - var tagsBookmarks = []; - var userId = req.session.user.id; - var totalItems = 0; - var sendData = { - totalItems: totalItems, - bookmarks: [] - } - db.getBookmarksSearch(params) - .then((searchData) => { - totalItems = searchData.totalItems; - bookmarks = searchData.bookmarks; - if (bookmarks.length > 0) { - var bookmarkIds = bookmarks.map((bookmark) => { - bookmark.own = bookmark.user_id == userId ? true : false; - if (!bookmark.own) { - bookmark.description = "其他用户的描述信息不允许查看"; - } - return bookmark.id; - }); - return db.getTagsBookmarks(bookmarkIds); - } else { - res.json(sendData); - return Promise.reject('没有搜到到任何书签'); - } - }) - .then((tbs) => { - if (tbs.length > 0) { - var tagIds = tbs.map((tb) => tb.tag_id); - tagsBookmarks = tbs; - return db.getTagsByIds(tagIds); - } else { - res.json(sendData); - return Promise.reject('没有搜到到任何书签'); - } - }) - .then((tags) => { - var data = []; - // 获取每个书签的所有分类标签 - bookmarks.forEach(function(bookmark) { - var bookmarkTags = []; - tagsBookmarks.forEach(function(tb) { - if (tb.bookmark_id == bookmark.id) { - tags.forEach(function(tag) { - if (tb.tag_id == tag.id) { - bookmarkTags.push(tag) - } - }) - } - }); - bookmark.tags = bookmarkTags; - data.push(bookmark); - }) - sendData.totalItems = totalItems; - sendData.bookmarks = data; - res.json(sendData); - }) - .catch((err) => console.log('bookmarks table or card err', err)) -}); - -api.get('/searchHotBookmarks', function(req, res) { - console.log("searchHotBookmarks username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var params = req.query; - db.getHotBookmarksSearch(params) - .then((searchData) => { - res.json(searchData); - }) - .catch((err) => console.log('getHotBookmarksSearch err', err)) -}); - -api.get('/tags', function(req, res) { - console.log("tags username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - db.getTags(req.session.user.id) - .then((tags) => { - // 每获取一次标签,就检查一下系统默认的两个分类是不是存在 - var defaultTags = []; - var find1 = false; - var find2 = false; - tags.forEach((tag) => { - if (tag.name == "未分类") { - find1 = true; - } - if (tag.name == "收藏") { - find2 = true; - } - }) - if (!find1) { - defaultTags.push("未分类") - } - if (!find2) { - defaultTags.push("收藏") - } - if (defaultTags.length > 0) { - db.addTags(req.session.user.id, defaultTags) - } - res.json(tags); - }) - .catch((err) => console.log('tags', err)); -}); - -api.get('/advices', function(req, res) { - console.log("advices username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var params = req.query; - db.getAdvices(params) - .then((advices) => res.json(advices)) - .catch((err) => console.log('tags', err)); -}); - -api.post('/addAdvice', function(req, res) { - console.log("addAdvice username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - - var params = req.body.params; - params.user_id = req.session.user.id; - - db.addAdvice(params) - .then((affectedRows) => { - res.json({ - retCode: 0, - msg: "留言成功 ", - }) - console.log('addAdvice affectedRows ', affectedRows) - }) - .catch((err) => { - console.log('addAdvice error', err); - res.json({ - retCode: 1, - msg: "留言失败: " + JSON.stringify(err), - }) - }); -}); - -// 发现使用node启动没问题,forever启动有问题。 -api.post('/uploadBookmarkFile', upload.single('bookmark'), function(req, res) { - console.log("uploadBookmarkFile username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - - var file = req.file; - res.json(file); - parseHtml(file.path, function(data) { - var bookmarks = data.bookmarks; - var tagsName = data.tags; - - var userId = req.session.user.id; - var addTagNames = []; - - db.getTags(userId) - // 先插入分类 - .then((tags) => { - // 需要插入的书签是该用户在数据库不存在的书签 - addTagNames = tagsName.filter((name) => { - for (var i = 0; i < tags.length; i++) { - if (tags[i].name.toLowerCase() === name.toLowerCase()) { - return false; - } - } - return true; - }); - return Promise.resolve(addTagNames); - }) - .then((newTagNames) => { - if (newTagNames.length > 0) { - return db.addTags(userId, newTagNames) - } else { - return Promise.resolve(); - } - }) - .then(() => db.getTags(userId)) - .then((allTags) => { - bookmarks.forEach((item, index) => { - var count = 0; - if (/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/.test(item.url)) { - var bookmark = {}; - bookmark.title = item.name; - bookmark.description = ""; - bookmark.url = item.url; - bookmark.public = '1'; - if (item.tags.length == 0) { - item.tags.push("未分类") - } - - var tags = []; - item.tags.forEach((tag) => { - allTags.forEach((at) => { - if (at.name == tag) { - tags.push(at.id); - } - }) - }) - // 插入书签 - db.getBookmarkbyUrl(userId, bookmark.url) - .then((bookmarkId) => { - // 如果这个url的书签存在了,那么直接返回书签,否则返回插入的书签 - return bookmarkId ? Promise.resolve(bookmarkId) : db.addBookmark(userId, bookmark); - }) - .then((bookmark_id) => { - db.delBookmarkTags(bookmark_id); // 不管3721,先删掉旧的分类 - return bookmark_id; - }) // 将之前所有的书签分类信息删掉 - .then((bookmark_id) => db.addTagsBookmarks(tags, bookmark_id)) // 插入分类 - .then(() => db.updateLastUseTags(userId, tags)) // 更新最新使用的分类 - .then(() => { - count++ - }) // 运气不错 - .catch((err) => console.log('uploadBookmarkFile addBookmark err', err)); // oops! - } - - if ((index + 1) == bookmarks.length) { - // 通知前台 - } - }) - }) - .catch((err) => console.log('uploadBookmarkFile err', err)); - }) -}); - -api.post('/addBookmark', function(req, res) { - console.log("addBookmark username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var bookmark = req.body.params; - var userId = req.session.user.id; - var tags = [bookmark.tags[bookmark.tags.length - 1]]; // 只允许添加一个分类 - var bookmarkId = -1; - var ret = {}; - var update = false; - db.getBookmarkbyUrl(userId, bookmark.url) - .then((bookmarkId) => { - // 如果这个url的书签存在了,那么直接返回书签,否则返回插入的书签 - if (bookmarkId) { - bookmark.id = bookmarkId; - db.updateBookmark(bookmark); // 如果存在,更新一下。 - update = true; - return Promise.resolve(bookmarkId); - } else { - return db.addBookmark(userId, bookmark); - } - }) - .then((bookmark_id) => { - db.delBookmarkTags(bookmark_id); // 不管3721,先删掉旧的分类 - bookmarkId = bookmark_id; - return bookmark_id; - }) // 将之前所有的书签分类信息删掉 - .then((bookmark_id) => db.addTagsBookmarks(tags, bookmark_id)) // 插入分类 - .then(() => db.updateLastUseTags(userId, tags)) // 更新最新使用的分类 - .then(() => db.getBookmark(bookmarkId)) // 获取书签信息,返回去 - .then((bookmark) => { - ret = bookmark; - return db.getBookmarkTagsNames(bookmark.id); - }) - .then((bookmarkTags) => { - ret.tags = bookmarkTags; - ret.update = update; - res.json(ret) - }) - .catch((err) => console.log('addBookmark err', err)); // oops! -}); - -api.post('/favoriteBookmark', function(req, res) { - console.log("favoriteBookmark username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var bookmark = req.body.params; - var userId = req.session.user.id; - var bookmarkId = -1; - var ret = {}; - var update = false; - db.getBookmarkbyUrl(userId, bookmark.url) - .then((bookmarkId) => { - // 如果这个url的书签存在了,那么直接返回书签,否则返回插入的书签 - if (bookmarkId) { - bookmark.id = bookmarkId; - db.updateBookmark(bookmark); // 如果存在,更新一下。 - update = true; - return Promise.resolve(bookmarkId); - } else { - return db.addBookmark(userId, bookmark); - } - }) - .then((bookmark_id) => { - db.delBookmarkTags(bookmark_id); // 不管3721,先删掉旧的分类 - bookmarkId = bookmark_id; - return bookmark_id; - }) // 将之前所有的书签分类信息删掉 - .then((bookmark_id) => db.getTags(userId)) // 插入分类 - .then((tags) => { - var tagFavorite = []; - tags.forEach((tag) => { - if (tag.name == '收藏') { - tagFavorite.push(tag.id); - } - }) - if (tagFavorite.length >= 1) { - return db.addTagsBookmarks(tagFavorite, bookmarkId) - } else { - db.addTags(req.session.user.id, ['收藏']) - return Promise.reject("没有收藏的分类"); - } - }) - .then(() => db.getBookmark(bookmarkId)) // 获取书签信息,返回去 - .then((bookmark) => { - ret = bookmark; - return db.getBookmarkTags(bookmarkId); - }) - .then((bookmarkTags) => { - ret.tags = bookmarkTags; - ret.update = update; - res.json(ret) - }) - .catch((err) => console.log('addBookmark err', err)); // oops! -}); - -api.post('/addTags', function(req, res) { - console.log("addTags username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var tagsName = req.body.params; - var userId = req.session.user.id; - var addTagNames = []; - - db.getTags(userId) - .then((tags) => { - // 需要插入的书签是该用户在数据库不存在的书签 - addTagNames = tagsName.filter((name) => { - for (var i = 0; i < tags.length; i++) { - if (tags[i].name.toLowerCase() === name.toLowerCase()) { - return false; - } - } - return true; - }); - return Promise.resolve(addTagNames); - }) - .then((newTagNames) => db.addTags(userId, newTagNames)) - .then(() => db.getTags(userId)) - .then((tags) => res.json(tags)) - .catch((err) => console.log('addTags err', err)); -}); - -api.post('/updateTagName', function(req, res) { - console.log("updateTagName username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var tag = req.body.params; - var userId = req.session.user.id; - - db.getTags(userId) - .then((tags) => { - for (var i = 0; i < tags.length; i++) { - if (tags[i].id != tag.id && tags[i].name == tag.name) { - return Promise.resolve(-1); - } - } - return db.updateTagName(tag); - }) - .then((affectedRows) => { - var msg = ""; - if (affectedRows == -1) { - msg += " 您已经有这个分类了,不允许更新"; - } else if (affectedRows == 0) { - msg += " 更新失败"; - } else if (affectedRows == 1) { - msg = " 更新成功"; - } else { - msg += " 更新失败"; - } - res.json({ - retCode: (affectedRows == 1) ? 0 : 1, - msg: msg, - }) - }) - .catch((err) => { - console.log('addTags err', err); - res.json({ - retCode: 1, - msg: tag.name + " 更新失败: " + JSON.stringify(err), - }) - }); -}); - -api.post('/updateTagsIndex', function(req, res) { - console.log("updateTagsIndex username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var tagsIndex = req.body.params; - - db.updateTagsIndex(tagsIndex) - .then((affectedRows) => { - var msg = ""; - if (affectedRows == tagsIndex.length) { - msg = " 排序更新成功"; - } else { - msg += " 排序更新失败"; - } - res.json({ - retCode: (affectedRows == tagsIndex.length) ? 0 : 1, - msg: msg, - }) - }) - .catch((err) => { - console.log('updateTagsIndex err', err); - res.json({ - retCode: 1, - msg: "排序更新失败: " + JSON.stringify(err), - }) - }); -}); - -api.post('/delTag', function(req, res) { - console.log("delTag username = ", req.session.username); - if(req.session.username === "test") { - res.json({ - retCode: 100, - msg: "test用户不允许删除分类!", - }) - return; - } - if (!req.session.user) { - res.send(401); - return; - } - var tag = req.body.params; - var needDelTag = tag.del || false; - var bookmarksId = [] - db.getBookmarkIdsByTagId(tag.id) - .then((_bookmarksId) => { - bookmarksId = _bookmarksId.map((item) => item.bookmark_id); - return db.delTagBookmarks(tag.id); // 先删掉分类跟书签的映射 - }) - .then((affectedRows) => db.delBookmarks(bookmarksId)) // 再删掉该分类下面的书签 - .then((affectedRows) => db.delTagsBookmarks(bookmarksId)) // 再删掉该书签关联的其他分类 - .then((affectedRows) => { - if (needDelTag) { - return db.delTag(tag.id); - } - return Promise.resolve(1); - }) // 再删掉分类 - .then((affectedRows) => { - res.json({ - retCode: affectedRows == 1 ? 0 : 1, - }) - }) // 再删掉该分类下面的书签 - .catch((err) => { - console.log('delTag err', err); - res.json({ - retCode: 1, - msg: "删除分类失败: " + JSON.stringify(err), - }) - }); -}); - -api.post('/getArticle', function(req, res) { - console.log("getArticle username = ", req.session.username); - var params = req.body.params; - var url = params.url; - var requestId = params.requestId || 0; - read(url, function(err, article, meta) { - if (err) { - res.json({ - title: '', - content: false, - }); - } else { - if (requestId == 0) { - res.json({ - title: article.title || '', - }); - } else if (requestId == 1) { - res.json({ - content: article.content, - }); - } - article.close(); - } - }); -}) - -api.post('/getUpdateLog', function(req, res) { - console.log("getArticle username = ", req.session.username); - var params = req.body.params; - var defaultUrl = 'https://github.com/luchenqun/my-bookmark/commits/master' - var url = params.url || defaultUrl; - - request(url, function(error, response, body) { - console.log("HotBookmarks request ", error, response && response.statusCode); - if (response && response.statusCode == 200) { - const $ = cheerio.load(body); - var data = []; - $('.commit-group-title').each(function() { - var updateLogs = {}; - - var dateMap = { - 'Jan': 1, - 'Feb': 2, - 'Mar': 3, - 'Apr': 4, - 'May': 5, - 'Jun': 6, - 'Jul': 7, - 'Aug': 8, - 'Sep': 9, - 'Oct': 10, - 'Nov': 11, - 'Dec': 12, - } - var date = $(this).text().replace(/(^\s*)|(\s*$)/g, '').replace(/\s+/g, ' '); // 去除前后空格得到字符串 Commits on Jun 16, 2017; - var dateArray = date.replace(',', '').replace('Commits on ', '').split(' '); - - updateLogs.date = dateArray[2] + '-' + (dateMap[dateArray[0]] || dateArray[0]) + '-' + dateArray[1]; - updateLogs.logs = []; - - $(this).next().children('li').each(function() { - var $log = $(this).children('.table-list-cell').eq(0).children('p').children('a'); - var commit = $log.text() - var href = 'https://github.com' + $log.attr('href'); - - updateLogs.logs.push({ - commit: commit, - href: href, - }) - }) - data.push(updateLogs) - }) - - var oldUrl = $('.paginate-container .pagination a').attr('href'); - if (oldUrl) { - oldUrl = 'https://github.com' + oldUrl; - } - - res.json({ - updateLogs: data, - oldUrl: oldUrl || defaultUrl - }); - } else { - console.log("HotBookmarks request is error", error, response && response.statusCode); - } - }); -}) - -api.checkSnapFaviconState = function() { - db.getBookmarks() - .then((bookmarks) => { - bookmarks.forEach(bookmark => { - var id = bookmark.id; - var snap_state = bookmark.snap_state; - var finePath = './public/images/snap/' + id + '.png' - fs.exists(finePath, function(exists) { - if (!exists && snap_state == -1) { - db.updateBookmarkSnapState(id, 0); - } - }); - }) - }) - .catch((err) => console.log('getBookmarks err', err)); -} - -api.getSnapByTimer = function() { - console.log('getSnapByTimer...........'); - var timeout = 30000 - setInterval(function() { - var date = new Date(); - var today = date.getDate(); - var hours = date.getHours(); - if (hours >=2 && hours <= 5) { - db.getBookmarkWaitSnap(today) - .then((bookmarks) => { - if (bookmarks.length == 1) { - var id = bookmarks[0].id; - var snapState = bookmarks[0].snap_state; - var url = bookmarks[0].url; - var filePath = './public/images/snap/' + id + '.png'; - // 获取截图 - fs.exists(filePath, function(exists) { - if (exists) { - if (snapState != -1) { - db.updateBookmarkSnapState(id, -1); - } - } else { - if (!/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/.test(url)) { - db.updateBookmarkSnapState(id, today + 31); - return; - } - var webshotOptions = { - shotSize: { - width: 320, - height: 160 - }, - timeout: timeout, - }; - webshot(url, filePath, webshotOptions, function(err) { - var newSnapState = -1; - if (err) { - console.log("boomarkid = " + id + ", url = " + url + ", webshot over") - if (snapState == 0 || snapState == 1) { - newSnapState = snapState + 1; - } else if (snapState == 2) { - newSnapState = today + 31; - } - } - db.updateBookmarkSnapState(id, newSnapState); - }); - } - }); - } - }) - .catch((err) => console.log('getBookmarkWaitSnap err', err)); - } - - }, timeout + 1000); -} - -api.getFaviconByTimer = function() { - console.log('getFaviconByTimer...........'); - var timeout = 30000; - var busy = false; - setInterval(function() { - if (busy) { - console.log('getFaviconByTimer is busy') - return; - } - busy = true; - var today = new Date().getDate(); - db.getBookmarkWaitFavicon(today) - .then((bookmarks) => { - if (bookmarks.length == 1) { - var id = bookmarks[0].id; - var faviconState = bookmarks[0].favicon_state; - var url = encodeURI(bookmarks[0].url); - var faviconPath = './public/images/favicon/' + id + '.ico'; - var defaultFile = './public/images/favicon/default.ico'; - - if (!/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/.test(url)) { - copyFile(defaultFile, faviconPath); - db.updateBookmarkFaviconState(id, today + 31) - .then((affectedRows) => { - busy = false - }) - .catch((err) => { - console.log('updateBookmarkFaviconState err', err); - busy = false - }); - } else { - // http://www.cnblogs.com/zhangwei595806165/p/4984912.html 各种方法都试一遍 - var faviconUrl = "http://47.75.89.228:3000/?url=" + url; // 默认地址 - if (faviconState == 1) { - faviconUrl = "https://api.statvoo.com/favicon/?url=" + url; - } else if (faviconState == 2) { - faviconUrl = "http://www.google.com/s2/favicons?domain=" + url; - } - download(faviconUrl).then(data => { - fs.writeFileSync(faviconPath, data); - db.updateBookmarkFaviconState(id, -1) - .then((affectedRows) => { - busy = false; - }) - .catch((err) => { - console.log('updateBookmarkFaviconState err', err); - busy = false; - }); - }).catch((err) => { - var newFaviconState = -1; - console.log("boomarkid = " + id + ", url = " + url + ", download over") - if (faviconState == 0 || faviconState == 1) { - newFaviconState = faviconState + 1; - } else if (faviconState == 2) { - newFaviconState = today + 31; - copyFile(defaultFile, faviconPath); - } - db.updateBookmarkFaviconState(id, newFaviconState) - .then((affectedRows) => { - busy = false; - }) - .catch((err) => { - console.log('updateBookmarkFaviconState err', err); - busy = false; - }); - }); - } - } else { - busy = false; - } - }) - .catch((err) => { - console.log('getFaviconByTimer err', err); - busy = false; - }); - }, timeout); -} - -api.getHotBookmarksByTimer = function() { - var timeout = 1000 * 60 * 10; // 10分钟更新一遍 - var busy = false; - var dayIndex = 0; - var date = new Date(); - - console.log('getHotBookmarks...........', date.format("yyyy-MM-dd hh:mm:ss")); - - setInterval(function() { - if (busy) { - console.log('getHotBookmarks is busy') - return; - } - if (timeout < 1000 * 5) { - busy = true; // 实践证明很容易出错导致busy一直是true,所以干脆去掉此选项了。 - } - console.log('begin getHotBookmarks...'); - date.setTime(date.getTime() + dayIndex * 24 * 60 * 60 * 1000); - var requireData = { - idfa: "d4995f8a0c9b2ad9182369016e376278", - os: "ios", - osv: "9.3.5", - userId: null, - lastupdataTime: new Date().getTime(), - pageNo: 1, - pageSize: 1000, - sort: 'desc', - renderType: 0, - date: curentDate(dayIndex, "yyyy年M月d日"), - } - var url = "https://api.shouqu.me/api_service/api/v1/daily/dailyMark"; - var alterRex = "/mmbiz.qpic.cn|images.jianshu.io|zhimg.com/g"; - var defaultSnap = "./images/default.jpg"; - var defaultFavicon = "./images/favicon/default.ico"; - request.post({ - url: url, - form: requireData - }, function(error, response, body) { - console.log("HotBookmarks request ", error, response && response.statusCode); - if (response && response.statusCode == 200) { - var inserCnt = 0; - var data = JSON.parse(body).data; - var dataDate = new Date(data.date) - - console.log("getHotBookmarks success, date = ", dataDate.format("yyyy-MM-dd hh:mm:ss"), ', bookmarks length = ', data.list.length); - - if (data.list.length == 0) { - busy = false; - return; - } - var dateSql = parseInt(dataDate.format('yyyyMMdd')); - data.list.forEach((b) => { - var bookmark = {}; - bookmark.id = b.articleId; - bookmark.date = dateSql; // 因为有第二天很早的时候获取的是前一天的,所以用数据返回日期 - bookmark.title = b.title; - bookmark.url = b.url; - bookmark.fav_count = b.favCount || 0; - bookmark.created_by = b.sourceName || '泥巴'; - bookmark.created_at = b.updatetime > b.createtime ? b.createtime : b.updatetime; - bookmark.last_click = b.updatetime < b.createtime ? b.createtime : b.updatetime; - if (b.imageList.length >= 1) { - if (b.imageList[0].url) { - bookmark.snap_url = (data.pageNo == 1 ? (b.imageList[0].url.match(alterRex) != null ? defaultSnap : b.imageList[0].url) : defaultSnap); - } else { - bookmark.snap_url = defaultSnap; - for (var i = 0; i < b.images.length; i++) { - if (b.images[i]) { - bookmark.snap_url = b.images[i]; - break; - } - } - } - } else { - bookmark.snap_url = defaultSnap; - } - bookmark.favicon_url = b.sourceLogo || defaultFavicon; - - db.addHotBookmark(bookmark) - .then((id) => { - inserCnt++; - if (inserCnt == data.list.length) { - busy = false; - } - }) - .catch((err) => { - inserCnt++; - console.log('insertHotBookmarks err ', id, err); - if (inserCnt == data.list.length) { - busy = false; - } - }); - }); - } else { - console.log("HotBookmarks request is error", error, response && response.statusCode); - busy = false; - } - }); - }, timeout); -} - - - -api.post('/addNote', function(req, res) { - console.log("addNote username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - - var params = req.body.params; - params.user_id = req.session.user.id; - - db.addNote(params) - .then((insertId) => { - res.json({ - retCode: 0, - insertId: insertId, - msg: "添加备忘成功 ", - }) - console.log('addNote insertId ', insertId) - }) - .catch((err) => { - console.log('addNote error', err); - res.json({ - retCode: 1, - msg: "添加备忘失败: " + JSON.stringify(err), - }) - }); -}); - -api.get('/notes', function(req, res) { - console.log("getNotes username = ", req.session.username); - var params = req.query; - if (!params.shareNote && !req.session.user) { - res.send(401); - return; - } - if (params.shareNote) { - db.getNote(params.shareNote) - .then((data) => res.send(` - - - - - -
-
\n\n${data}\n\n
-
- `)) - .catch((err) => console.log('notes', err)); - } else { - params.user_id = req.session.user.id; - db.getNotes(params) - .then((data) => res.json(data)) - .catch((err) => console.log('notes', err)); - } -}); - -api.delete('/delNote', function(req, res) { - console.log("delBookmark username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - var noteId = req.query.id; - db.delNote(noteId) - .then((affectedRows) => res.json({ - result: affectedRows - })) - .catch((err) => { - console.log('delBookmark err', err); - res.json({ - result: -1 - }) - }); -}) - -api.post('/updateNote', function(req, res) { - console.log("updateNote username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - - var note = req.body.params; - console.log('hello updateNote', JSON.stringify(note)); - db.updateNote(note.id, note.content, note.tag_id) - .then((affectedRows) => res.json({ - result: affectedRows - })) - .catch((err) => { - console.log('updateNote err', err); - res.json({ - result: -1 - }) - }); // oops! -}) - -api.post('/updateNotePublic', function(req, res) { - console.log("updateNotePublic username = ", req.session.username); - if (!req.session.user) { - res.send(401); - return; - } - - var note = req.body.params; - console.log('hello updateNotePublic', JSON.stringify(note)); - db.updateNotePublic(note.id, note.public) - .then((affectedRows) => res.json({ - result: affectedRows - })) - .catch((err) => { - console.log('updateNote err', err); - res.json({ - result: -1 - }) - }); // oops! -}) - - -// 实现文件下载 -api.get('/download', function(req, res) { - console.log("download username = ", req.session.username); - - var userId = req.query.userId; - var type = req.query.type; - if (!req.session.user || req.session.user.id != userId) { - res.send(401); - return; - } - if (type == 'exportbookmark' && userId) { - db.getTags(userId) - .then((tags) => { - var meta = ''; - var init = 'Bookmarks

Bookmarks

'; - var $ = cheerio.load(init, { - decodeEntities: false, - xmlMode: true, - }); - - tags.forEach((tag, tagIndex) => { - $('#0').append('

' + tag.name + '

'); // 增加文件夹 - db.getExportBookmarksByTag(tag.id) - .then((bookmarks) => { - bookmarks.forEach((bookmark) => { - $('#' + bookmark.tag_id).append('
' + bookmark.title + '
'); - }); - if (tagIndex == tags.length - 1) { - console.log('export bookmarks document construct end...'); - var now = new Date().format('yyyyMMddhhmmss') - var fileName = 'exportbookmark-' + req.session.username + '-' + now + '.html'; - var filePath = path.join(path.resolve(__dirname, '..'), 'uploads', fileName); - fs.writeFile(filePath, beautify_html($.xml(), { - indent_size: 4, - }), function(err) { - if (err) { - console.log(err); - } else { - res.download(filePath, function(err) { - if (err) { - console.log(err); - } else { - console.log('download filePath[ ' + filePath + ' ]success!'); - } - }); - } - }) - } - }) - .catch((err) => { - console.log('getExportBookmarksByTag err', err); - }) - }) - }) - .catch((err) => { - console.log('exportbookmark err', err); - }); - } else { - res.send(401); - } -}); - -function md5(str) { - return crypto.createHash('md5').update(str).digest('hex'); -}; - -function copyFile(sourceFile, destFile) { - fs.exists(sourceFile, function(exists) { - if (exists) { - var readStream = fs.createReadStream(sourceFile); - var writeStream = fs.createWriteStream(destFile); - readStream.pipe(writeStream); - } - }); -} - -function curentDate(i, f) { - if (i == undefined) { - i = 0; - } - if (f == undefined) { - f = 'yyyyMMddhhmmss' - } - var now = new Date(); - now.setTime(now.getTime() + i * 24 * 60 * 60 * 1000); - var clock = now.format(f); - return (clock); -} - -module.exports = api; +var api = require('express').Router(); +var mysql = require('mysql'); +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('download'); +var multer = require('multer'); +// var webshot = require('webshot'); +var fs = require('fs'); +var request = require('request'); +var cheerio = require('cheerio'); +var path = require('path'); +var beautify_html = require('js-beautify').html; + +var storage = multer.diskStorage({ + destination: function(req, file, cb) { + cb(null, 'uploads/') + }, + filename: function(req, file, cb) { + var now = new Date().format('yyyyMMddhhmmss') + if (req.session.user) { + cb(null, 'importbookmark-' + req.session.username + '-' + now + '.html') + } else { + cb(null, "UnknowUser" + '-' + now + '.html') + } + } +}) + +var upload = multer({ + storage: storage, + limits: { + fileSize: 10 * 1024 * 2014, // 最大值接受10M + }, + fileFilter: function(req, file, cb) { + cb(null, file.mimetype == "text/html"); + }, +}) + +api.post('/logout', function(req, res) { + var params = req.body.params; + console.log('logout......', params); + req.session.destroy(); + res.json({ + data: "logout success", + }); +}); + +api.post('/clickBookmark', function(req, res) { + console.log("clickBookmark username = ", req.session.username); + db.getUser(req.session.username) + .then((user) => { return user.id == req.session.userId ? db.clickBookmark(req.body.params.id, req.session.userId) : Promise.resolve(0); }) + .then((affectedRows) => res.json({})) + .catch((err) => console.log('clickBookmark error', err)); +}); + +api.post('/jumpQuickUrl', function(req, res) { + console.log("jumpQuickUrl username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + db.getBookmarkbyUrl(req.session.user.id, req.body.params.url) + .then((bookmarkId) => { + res.json({id: bookmarkId}); + if (bookmarkId) { + return db.clickBookmark(bookmarkId, req.session.user.id); + } else { + return Promise.reject(0); + } + }) + .then((affectedRows) => {}) + .catch((err) => console.log('jumpQuickUrl err', err)); // oops! +}); + +api.post('/login', function(req, res) { + var params = req.body.params; + var username = params.username; + var password = md5(params.password); + console.log(password); + db.getUser(username) + .then((user) => { + var ret = { + logined: false, + user: {}, + } + if (user && user.password === password) { + ret.logined = true; + ret.user = user; + req.session.user = user; + req.session.username = ret.user.username; + req.session.userId = ret.user.id; + } + ret.user.password = "*"; + res.json(ret); + return ret.logined ? db.updateUserLastLogin(ret.user.id) : Promise.resolve(0); + }) + .then((affectedRows) => { + console.log('updateUserLastLogin affectedRows ', affectedRows) + }) + .catch((err) => console.log('login error', err)); +}); + +api.get('/userInfo', function(req, res) { + console.log("userInfo username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var user = {}; + db.getUser(req.session.username) + .then((_user) => { + user = _user + user.password = "*"; + if (req.session.username == 'lcq' && req.session.userId == 1) { + return db.getActiveUsers(); + } else { + return Promise.resolve([]); + } + }) + .then((_activeUsers) => { + user.activeUsers = _activeUsers; + res.json(user); + }) + .catch((err) => console.log('userInfo error', err)); +}); + +api.post('/register', function(req, res) { + var params = req.body.params; + params.password = md5(params.password); // 进行密码加密 + + db.register(params) + .then((affectedRows) => { + res.json({ + retCode: 0, + msg: params.username + " 注册成功 ", + }) + console.log('register affectedRows ', affectedRows) + }) + .catch((err) => { + console.log('login error', err); + res.json({ + retCode: 1, + msg: params.username + " 注册失败: " + JSON.stringify(err), + }) + }); +}); + +api.post('/resetPassword', function(req, res) { + console.log("resetPassword username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + + var params = req.body.params; + var passwordOrigin = md5(params.passwordOrgin); // 进行密码加密 + var passwordNew = md5(params.passwordNew); // 进行密码加密 + + db.getUser(req.session.user.username) + .then((user) => { + if (user && user.password === passwordOrigin) { + return db.resetPassword(req.session.userId, passwordNew) + } else { + return Promise.resolve(0) + } + }) + .then((affectedRows) => { + res.json({ + retCode: (affectedRows == 1 ? 0 : 1), + msg: req.session.username + " 更新密码失败,可能原密码不正确!", + }) + + if (affectedRows) { + req.session.destroy(); + } + }) + .catch((err) => { + console.log('resetPassword error', err); + res.json({ + retCode: 2, + msg: req.session.username + " 更新密码失败: " + JSON.stringify(err), + }) + }); +}); + +api.post('/updateShowStyle', function(req, res) { + console.log("updateShowStyle username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + + var params = req.body.params; + db.getUser(req.session.user.username) + .then((user) => { + if (user) { + return db.updateShowStyle(req.session.userId, params.showStyle) + } else { + return Promise.resolve(0) + } + }) + .then((affectedRows) => { + res.json({ + retCode: (affectedRows == 1 ? 0 : 1), + msg: req.session.username + " 更新书签默认显示风格配置成功!", + }) + + if (affectedRows) { + req.session.user.show_style = params.showStyle; + } + }) + .catch((err) => { + console.log('resetPassword error', err); + res.json({ + retCode: 2, + msg: req.session.username + " 更新书签默认显示风格配置失败!: " + JSON.stringify(err), + }) + }); +}); + +api.post('/updateSearchHistory', function(req, res) { + console.log("updateSearchHistory username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + + var params = req.body.params; + db.getUser(req.session.user.username) + .then((user) => { + if (user) { + return db.updateSearchHistory(req.session.userId, params.searchHistory) + } else { + return Promise.resolve(0) + } + }) + .then((affectedRows) => { + res.json({ + retCode: (affectedRows == 1 ? 0 : 1), + msg: req.session.username + " 更新历史搜索成功!", + }) + }) + .catch((err) => { + console.log('resetPassword error', err); + res.json({ + retCode: 2, + msg: req.session.username + " 更新历史搜索失败!: " + JSON.stringify(err), + }) + }); +}); + +api.post('/updateQuickUrl', function(req, res) { + console.log("updateQuickUrl username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + + var params = req.body.params; + db.getUser(req.session.user.username) + .then((user) => { + if (user) { + return db.updateQuickUrl(req.session.userId, params.quickUrl) + } else { + return Promise.resolve(0) + } + }) + .then((affectedRows) => { + res.json({ + retCode: (affectedRows == 1 ? 0 : 1), + msg: req.session.username + " 更新全局快捷键成功!", + }) + }) + .catch((err) => { + console.log('resetPassword error', err); + res.json({ + retCode: 2, + msg: req.session.username + " 更新全局快捷键失败!: " + JSON.stringify(err), + }) + }); +}); + +api.get('/autoLogin', function(req, res) { + console.log("autoLogin username = ", req.session.username); + var ret = { + logined: false, + user: {}, + } + if (req.session.user) { + db.getUser(req.session.user.username) + .then((user) => { + if (user) { + user.password = "*"; + ret.logined = true; + ret.user = user; + } + res.json(ret); + return ret.logined ? db.updateUserLastLogin(ret.user.id) : Promise.resolve(0); + }) + .catch((err) => { + res.json(ret); + }) + } else { + res.json(ret); + } +}); + +api.delete('/delBookmark', function(req, res) { + console.log("delBookmark username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var bookmarkId = req.query.id; + db.delBookmarkTags(bookmarkId) + .then(() => db.delBookmark(bookmarkId)) + .then((affectedRows) => res.json({ + result: affectedRows + })) + .catch((err) => console.log('delBookmark err', err)); +}) + +api.post('/updateBookmark', function(req, res) { + console.log("updateBookmark username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + + var bookmark = req.body.params; + var userId = req.session.user.id; + var tags = bookmark.tags; + var ret = {} + console.log('hello updateBookmark', JSON.stringify(bookmark)); + db.updateBookmark(bookmark) // 更新标签信息 + .then((affectedRows) => db.delBookmarkTags(bookmark.id)) // 将之前所有的书签分类信息删掉 + .then((insertId) => db.addTagsBookmarks(tags, bookmark.id)) // 将新的分类关联起来 + .then(() => db.updateLastUseTags(userId, tags)) // 更新最近使用的分类(这个有待考虑) + .then(() => db.getBookmark(bookmark.id)) // 将新的信息返回去 + .then((bookmark) => { + ret = bookmark; + return db.getBookmarkTagsNames(bookmark.id); + }) + .then((tags) => { + ret.tags = tags; + res.json(ret); + }) // 运气不错 + .catch((err) => console.log('updateBookmark err', err)); // oops! +}) + +api.get('/bookmark', function(req, res) { + console.log("bookmark username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var bookmarkId = req.query.bookmarkId; + var userId = req.session.user.id; + var ret = { + bookmark: {}, + bookmarkTags: [], + tags: [], + }; + + db.getBookmark(bookmarkId) + .then((bookmark) => { + ret.bookmark = bookmark; + return db.getBookmarkTags(bookmarkId); + }) + .then((bookmarkTags) => { + ret.bookmarkTags = bookmarkTags; + return db.getTags(userId); + }) + .then((tags) => { + ret.tags = tags; + res.json(ret); + }) + .catch((err) => console.log('bookmark err', err)); +}) + +api.get('/bookmarks', function(req, res) { + console.log("bookmarks username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var userId = req.session.user.id; + var params = req.query; + params.showStyle = params.showStyle || req.session.user.show_style; // 如果没有指定风格,那么用系统风格 + if (params.showStyle === 'navigate') { + db.getTags(userId) + .then((tags) => db.getBookmarksNavigate(tags)) + .then((result) => { + var data = []; + var tag = { + id: result && result[0] && result[0].tag_id, + name: result && result[0] && result[0].tag_name, + sort: result && result[0] && result[0].sort, + click: 0, + bookmarks: [] + }; + result.forEach(function(bookmark) { + if (tag.id !== bookmark.tag_id) { + data.push({ + id: tag.id, + name: tag.name, + sort: tag.sort, + click: tag.click, + bookmarks: tag.bookmarks + }); + tag.id = bookmark.tag_id; + tag.name = bookmark.tag_name; + tag.sort = bookmark.sort; + tag.click = 0; + tag.bookmarks = []; + } + tag.click += bookmark.click_count; + bookmark.created_at = new Date(bookmark.created_at).format("yyyy-MM-dd hh:mm:ss"); + bookmark.last_click = new Date(bookmark.last_click).format("yyyy-MM-dd hh:mm:ss"); + tag.bookmarks.push(bookmark); + }); + if (result && result.length > 0) { + data.push(tag); + } + data.sort((a, b) => { + if (a.sort == b.sort) return b.click - a.click; + return a.sort - b.sort; + }); + var temp = data.map(item => { + return { + name: item.name, + sort: item.sort, + click: item.click, + } + }) + res.json(data); + }) + .catch((err) => console.log('bookmarks navigate err', err)); + } else if (params.showStyle === 'costomTag') { + var bookmarks = [] + db.getBookmarksCostomTag(userId) + .then((bookmarksData) => { + bookmarks = bookmarksData.bookmarks; + var bookmarkIds = bookmarks.map((bookmark) => bookmark.id) + return db.getTagsBookmarks(bookmarkIds); + }) + .then((tbs) => { + tagsBookmarks = tbs; + return db.getTags(userId); + }) + .then((tags) => { + bookmarks.forEach(function(bookmark, index) { + var bookmarkTags = []; + tagsBookmarks.forEach(function(tb) { + if (tb.bookmark_id == bookmark.id) { + tags.forEach(function(tag) { + if (tb.tag_id == tag.id) { + bookmarkTags.push(tag) + } + }) + } + }); + bookmarks[index].tags = bookmarkTags; + }) + res.json(bookmarks); + }) + .catch((err) => console.log('bookmarks costomTag err', err)) + } else { + var tagsBookmarks = []; + var sendData = { + totalItems: 0, + bookmarks: [], + } + + params.userId = userId; + db.getBookmarksTable(params) + .then((bookmarksData) => { + sendData = bookmarksData; + var bookmarkIds = sendData.bookmarks.map((bookmark) => bookmark.id) + return db.getTagsBookmarks(bookmarkIds); + }) + .then((tbs) => { + tagsBookmarks = tbs; + return db.getTags(userId); + }) + .then((tags) => { + sendData.bookmarks.forEach(function(bookmark, index) { + var bookmarkTags = []; + tagsBookmarks.forEach(function(tb) { + if (tb.bookmark_id == bookmark.id) { + tags.forEach(function(tag) { + if (tb.tag_id == tag.id) { + bookmarkTags.push(tag) + } + }) + } + }); + sendData.bookmarks[index].tags = bookmarkTags; + }) + + res.json(sendData); + }) + .catch((err) => console.log('bookmarks table or card err', err)) + } +}); + +api.get('/hotBookmarks', function(req, res) { + console.log("hotBookmarks username = ", req.session.username); + var userId = req.session.user.id; + var params = req.query; + var date = params.date || new Date().format('yyyyMMdd');; + db.hotBookmarks(date) + .then((bookmarks) => { + res.json(bookmarks); + }) + .catch((err) => console.log('hotBookmarks err', err)) +}); + +api.get('/bookmarksByTag', function(req, res) { + console.log("bookmarksByTag username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var userId = req.session.user.id; + var params = req.query; + + var bookmarks = []; + var tagsBookmarks = []; + var totalItems = 0; + var totalItems = 0; + var sendData = { + totalItems: 0, + bookmarks: [], + } + + // -1 获取自己定制的 + // -2 获取全站定制的 + var fun = (params.tagId <= -1) ? (params.tagId == -1 ? db.getBookmarksCostomTag : db.getBookmarksCostomAllUsersTag) : (db.getBookmarksByTag); + + fun((params.tagId <= -1) ? (userId) : (params), params.perPageItems) + .then((bookmarksData) => { + sendData = bookmarksData; + var bookmarkIds = sendData.bookmarks.map((bookmark) => bookmark.id) + return db.getTagsBookmarks(bookmarkIds); + }) + .then((tbs) => { + tagsBookmarks = tbs; + return db.getTags(params.tagId >= -1 ? userId : null); + }) + .then((tags) => { + // 获取每个书签的所有分类标签 + sendData.bookmarks.forEach(function(bookmark, index) { + var bookmarkTags = []; + tagsBookmarks.forEach(function(tb) { + if (tb.bookmark_id == bookmark.id) { + tags.forEach(function(tag) { + if (tb.tag_id == tag.id) { + bookmarkTags.push(tag) + } + }) + } + }); + sendData.bookmarks[index].tags = bookmarkTags; + }) + res.json(sendData); + }) + .catch((err) => console.log('getBookmarksByTag err', err)) + +}); + +api.get('/searchBookmarks', function(req, res) { + console.log("searchBookmarks username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var params = req.query; + params.userId = req.session.user.id; + var bookmarks = []; + var tagsBookmarks = []; + var userId = req.session.user.id; + var totalItems = 0; + var sendData = { + totalItems: totalItems, + bookmarks: [] + } + db.getBookmarksSearch(params) + .then((searchData) => { + totalItems = searchData.totalItems; + bookmarks = searchData.bookmarks; + if (bookmarks.length > 0) { + var bookmarkIds = bookmarks.map((bookmark) => { + bookmark.own = bookmark.user_id == userId ? true : false; + if (!bookmark.own) { + bookmark.description = "其他用户的描述信息不允许查看"; + } + return bookmark.id; + }); + return db.getTagsBookmarks(bookmarkIds); + } else { + res.json(sendData); + return Promise.reject('没有搜到到任何书签'); + } + }) + .then((tbs) => { + if (tbs.length > 0) { + var tagIds = tbs.map((tb) => tb.tag_id); + tagsBookmarks = tbs; + return db.getTagsByIds(tagIds); + } else { + res.json(sendData); + return Promise.reject('没有搜到到任何书签'); + } + }) + .then((tags) => { + var data = []; + // 获取每个书签的所有分类标签 + bookmarks.forEach(function(bookmark) { + var bookmarkTags = []; + tagsBookmarks.forEach(function(tb) { + if (tb.bookmark_id == bookmark.id) { + tags.forEach(function(tag) { + if (tb.tag_id == tag.id) { + bookmarkTags.push(tag) + } + }) + } + }); + bookmark.tags = bookmarkTags; + data.push(bookmark); + }) + sendData.totalItems = totalItems; + sendData.bookmarks = data; + res.json(sendData); + }) + .catch((err) => console.log('bookmarks table or card err', err)) +}); + +api.get('/searchHotBookmarks', function(req, res) { + console.log("searchHotBookmarks username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var params = req.query; + db.getHotBookmarksSearch(params) + .then((searchData) => { + res.json(searchData); + }) + .catch((err) => console.log('getHotBookmarksSearch err', err)) +}); + +api.get('/tags', function(req, res) { + console.log("tags username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + db.getTags(req.session.user.id) + .then((tags) => { + // 每获取一次标签,就检查一下系统默认的两个分类是不是存在 + var defaultTags = []; + var find1 = false; + var find2 = false; + tags.forEach((tag) => { + if (tag.name == "未分类") { + find1 = true; + } + if (tag.name == "收藏") { + find2 = true; + } + }) + if (!find1) { + defaultTags.push("未分类") + } + if (!find2) { + defaultTags.push("收藏") + } + if (defaultTags.length > 0) { + db.addTags(req.session.user.id, defaultTags) + } + res.json(tags); + }) + .catch((err) => console.log('tags', err)); +}); + +api.get('/advices', function(req, res) { + console.log("advices username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var params = req.query; + db.getAdvices(params) + .then((advices) => res.json(advices)) + .catch((err) => console.log('tags', err)); +}); + +api.post('/addAdvice', function(req, res) { + console.log("addAdvice username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + + var params = req.body.params; + params.user_id = req.session.user.id; + + db.addAdvice(params) + .then((affectedRows) => { + res.json({ + retCode: 0, + msg: "留言成功 ", + }) + console.log('addAdvice affectedRows ', affectedRows) + }) + .catch((err) => { + console.log('addAdvice error', err); + res.json({ + retCode: 1, + msg: "留言失败: " + JSON.stringify(err), + }) + }); +}); + +// 发现使用node启动没问题,forever启动有问题。 +api.post('/uploadBookmarkFile', upload.single('bookmark'), function(req, res) { + console.log("uploadBookmarkFile username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + + var file = req.file; + res.json(file); + parseHtml(file.path, function(data) { + var bookmarks = data.bookmarks; + var tagsName = data.tags; + + var userId = req.session.user.id; + var addTagNames = []; + + db.getTags(userId) + // 先插入分类 + .then((tags) => { + // 需要插入的书签是该用户在数据库不存在的书签 + addTagNames = tagsName.filter((name) => { + for (var i = 0; i < tags.length; i++) { + if (tags[i].name.toLowerCase() === name.toLowerCase()) { + return false; + } + } + return true; + }); + return Promise.resolve(addTagNames); + }) + .then((newTagNames) => { + if (newTagNames.length > 0) { + return db.addTags(userId, newTagNames) + } else { + return Promise.resolve(); + } + }) + .then(() => db.getTags(userId)) + .then((allTags) => { + bookmarks.forEach((item, index) => { + var count = 0; + if (/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/.test(item.url)) { + var bookmark = {}; + bookmark.title = item.name; + bookmark.description = ""; + bookmark.url = item.url; + bookmark.public = '1'; + if (item.tags.length == 0) { + item.tags.push("未分类") + } + + var tags = []; + item.tags.forEach((tag) => { + allTags.forEach((at) => { + if (at.name == tag) { + tags.push(at.id); + } + }) + }) + // 插入书签 + db.getBookmarkbyUrl(userId, bookmark.url) + .then((bookmarkId) => { + // 如果这个url的书签存在了,那么直接返回书签,否则返回插入的书签 + return bookmarkId ? Promise.resolve(bookmarkId) : db.addBookmark(userId, bookmark); + }) + .then((bookmark_id) => { + db.delBookmarkTags(bookmark_id); // 不管3721,先删掉旧的分类 + return bookmark_id; + }) // 将之前所有的书签分类信息删掉 + .then((bookmark_id) => db.addTagsBookmarks(tags, bookmark_id)) // 插入分类 + .then(() => db.updateLastUseTags(userId, tags)) // 更新最新使用的分类 + .then(() => { + count++ + }) // 运气不错 + .catch((err) => console.log('uploadBookmarkFile addBookmark err', err)); // oops! + } + + if ((index + 1) == bookmarks.length) { + // 通知前台 + } + }) + }) + .catch((err) => console.log('uploadBookmarkFile err', err)); + }) +}); + +api.post('/addBookmark', function(req, res) { + console.log("addBookmark username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var bookmark = req.body.params; + var userId = req.session.user.id; + var tags = [bookmark.tags[bookmark.tags.length - 1]]; // 只允许添加一个分类 + var bookmarkId = -1; + var ret = {}; + var update = false; + db.getBookmarkbyUrl(userId, bookmark.url) + .then((bookmarkId) => { + // 如果这个url的书签存在了,那么直接返回书签,否则返回插入的书签 + if (bookmarkId) { + bookmark.id = bookmarkId; + db.updateBookmark(bookmark); // 如果存在,更新一下。 + update = true; + return Promise.resolve(bookmarkId); + } else { + return db.addBookmark(userId, bookmark); + } + }) + .then((bookmark_id) => { + db.delBookmarkTags(bookmark_id); // 不管3721,先删掉旧的分类 + bookmarkId = bookmark_id; + return bookmark_id; + }) // 将之前所有的书签分类信息删掉 + .then((bookmark_id) => db.addTagsBookmarks(tags, bookmark_id)) // 插入分类 + .then(() => db.updateLastUseTags(userId, tags)) // 更新最新使用的分类 + .then(() => db.getBookmark(bookmarkId)) // 获取书签信息,返回去 + .then((bookmark) => { + ret = bookmark; + return db.getBookmarkTagsNames(bookmark.id); + }) + .then((bookmarkTags) => { + ret.tags = bookmarkTags; + ret.update = update; + res.json(ret) + }) + .catch((err) => console.log('addBookmark err', err)); // oops! +}); + +api.post('/favoriteBookmark', function(req, res) { + console.log("favoriteBookmark username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var bookmark = req.body.params; + var userId = req.session.user.id; + var bookmarkId = -1; + var ret = {}; + var update = false; + db.getBookmarkbyUrl(userId, bookmark.url) + .then((bookmarkId) => { + // 如果这个url的书签存在了,那么直接返回书签,否则返回插入的书签 + if (bookmarkId) { + bookmark.id = bookmarkId; + db.updateBookmark(bookmark); // 如果存在,更新一下。 + update = true; + return Promise.resolve(bookmarkId); + } else { + return db.addBookmark(userId, bookmark); + } + }) + .then((bookmark_id) => { + db.delBookmarkTags(bookmark_id); // 不管3721,先删掉旧的分类 + bookmarkId = bookmark_id; + return bookmark_id; + }) // 将之前所有的书签分类信息删掉 + .then((bookmark_id) => db.getTags(userId)) // 插入分类 + .then((tags) => { + var tagFavorite = []; + tags.forEach((tag) => { + if (tag.name == '收藏') { + tagFavorite.push(tag.id); + } + }) + if (tagFavorite.length >= 1) { + return db.addTagsBookmarks(tagFavorite, bookmarkId) + } else { + db.addTags(req.session.user.id, ['收藏']) + return Promise.reject("没有收藏的分类"); + } + }) + .then(() => db.getBookmark(bookmarkId)) // 获取书签信息,返回去 + .then((bookmark) => { + ret = bookmark; + return db.getBookmarkTags(bookmarkId); + }) + .then((bookmarkTags) => { + ret.tags = bookmarkTags; + ret.update = update; + res.json(ret) + }) + .catch((err) => console.log('addBookmark err', err)); // oops! +}); + +api.post('/addTags', function(req, res) { + console.log("addTags username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var tagsName = req.body.params; + var userId = req.session.user.id; + var addTagNames = []; + + db.getTags(userId) + .then((tags) => { + // 需要插入的书签是该用户在数据库不存在的书签 + addTagNames = tagsName.filter((name) => { + for (var i = 0; i < tags.length; i++) { + if (tags[i].name.toLowerCase() === name.toLowerCase()) { + return false; + } + } + return true; + }); + return Promise.resolve(addTagNames); + }) + .then((newTagNames) => db.addTags(userId, newTagNames)) + .then(() => db.getTags(userId)) + .then((tags) => res.json(tags)) + .catch((err) => console.log('addTags err', err)); +}); + +api.post('/updateTagName', function(req, res) { + console.log("updateTagName username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var tag = req.body.params; + var userId = req.session.user.id; + + db.getTags(userId) + .then((tags) => { + for (var i = 0; i < tags.length; i++) { + if (tags[i].id != tag.id && tags[i].name == tag.name) { + return Promise.resolve(-1); + } + } + return db.updateTagName(tag); + }) + .then((affectedRows) => { + var msg = ""; + if (affectedRows == -1) { + msg += " 您已经有这个分类了,不允许更新"; + } else if (affectedRows == 0) { + msg += " 更新失败"; + } else if (affectedRows == 1) { + msg = " 更新成功"; + } else { + msg += " 更新失败"; + } + res.json({ + retCode: (affectedRows == 1) ? 0 : 1, + msg: msg, + }) + }) + .catch((err) => { + console.log('addTags err', err); + res.json({ + retCode: 1, + msg: tag.name + " 更新失败: " + JSON.stringify(err), + }) + }); +}); + +api.post('/updateTagsIndex', function(req, res) { + console.log("updateTagsIndex username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var tagsIndex = req.body.params; + + db.updateTagsIndex(tagsIndex) + .then((affectedRows) => { + var msg = ""; + if (affectedRows == tagsIndex.length) { + msg = " 排序更新成功"; + } else { + msg += " 排序更新失败"; + } + res.json({ + retCode: (affectedRows == tagsIndex.length) ? 0 : 1, + msg: msg, + }) + }) + .catch((err) => { + console.log('updateTagsIndex err', err); + res.json({ + retCode: 1, + msg: "排序更新失败: " + JSON.stringify(err), + }) + }); +}); + +api.post('/delTag', function(req, res) { + console.log("delTag username = ", req.session.username); + if(req.session.username === "test") { + res.json({ + retCode: 100, + msg: "test用户不允许删除分类!", + }) + return; + } + if (!req.session.user) { + res.send(401); + return; + } + var tag = req.body.params; + var needDelTag = tag.del || false; + var bookmarksId = [] + db.getBookmarkIdsByTagId(tag.id) + .then((_bookmarksId) => { + bookmarksId = _bookmarksId.map((item) => item.bookmark_id); + return db.delTagBookmarks(tag.id); // 先删掉分类跟书签的映射 + }) + .then((affectedRows) => db.delBookmarks(bookmarksId)) // 再删掉该分类下面的书签 + .then((affectedRows) => db.delTagsBookmarks(bookmarksId)) // 再删掉该书签关联的其他分类 + .then((affectedRows) => { + if (needDelTag) { + return db.delTag(tag.id); + } + return Promise.resolve(1); + }) // 再删掉分类 + .then((affectedRows) => { + res.json({ + retCode: affectedRows == 1 ? 0 : 1, + }) + }) // 再删掉该分类下面的书签 + .catch((err) => { + console.log('delTag err', err); + res.json({ + retCode: 1, + msg: "删除分类失败: " + JSON.stringify(err), + }) + }); +}); + +api.post('/getArticle', function(req, res) { + console.log("getArticle username = ", req.session.username); + var params = req.body.params; + var url = params.url; + var requestId = params.requestId || 0; + read(url, function(err, article, meta) { + if (err) { + res.json({ + title: '', + content: false, + }); + } else { + if (requestId == 0) { + res.json({ + title: article.title || '', + }); + } else if (requestId == 1) { + res.json({ + content: article.content, + }); + } + article.close(); + } + }); +}) + +api.post('/getUpdateLog', function(req, res) { + console.log("getArticle username = ", req.session.username); + var params = req.body.params; + var defaultUrl = 'https://github.com/luchenqun/my-bookmark/commits/master' + var url = params.url || defaultUrl; + + request(url, function(error, response, body) { + console.log("HotBookmarks request ", error, response && response.statusCode); + if (response && response.statusCode == 200) { + const $ = cheerio.load(body); + var data = []; + $('.commit-group-title').each(function() { + var updateLogs = {}; + + var dateMap = { + 'Jan': 1, + 'Feb': 2, + 'Mar': 3, + 'Apr': 4, + 'May': 5, + 'Jun': 6, + 'Jul': 7, + 'Aug': 8, + 'Sep': 9, + 'Oct': 10, + 'Nov': 11, + 'Dec': 12, + } + var date = $(this).text().replace(/(^\s*)|(\s*$)/g, '').replace(/\s+/g, ' '); // 去除前后空格得到字符串 Commits on Jun 16, 2017; + var dateArray = date.replace(',', '').replace('Commits on ', '').split(' '); + + updateLogs.date = dateArray[2] + '-' + (dateMap[dateArray[0]] || dateArray[0]) + '-' + dateArray[1]; + updateLogs.logs = []; + + $(this).next().children('li').each(function() { + var $log = $(this).children('.table-list-cell').eq(0).children('p').children('a'); + var commit = $log.text() + var href = 'https://github.com' + $log.attr('href'); + + updateLogs.logs.push({ + commit: commit, + href: href, + }) + }) + data.push(updateLogs) + }) + + var oldUrl = $('.paginate-container .pagination a').attr('href'); + if (oldUrl) { + oldUrl = 'https://github.com' + oldUrl; + } + + res.json({ + updateLogs: data, + oldUrl: oldUrl || defaultUrl + }); + } else { + console.log("HotBookmarks request is error", error, response && response.statusCode); + } + }); +}) + +api.checkSnapFaviconState = function() { + db.getBookmarks() + .then((bookmarks) => { + bookmarks.forEach(bookmark => { + var id = bookmark.id; + var snap_state = bookmark.snap_state; + var finePath = './public/images/snap/' + id + '.png' + fs.exists(finePath, function(exists) { + if (!exists && snap_state == -1) { + db.updateBookmarkSnapState(id, 0); + } + }); + }) + }) + .catch((err) => console.log('getBookmarks err', err)); +} + +api.getSnapByTimer = function() { + console.log('getSnapByTimer...........'); + var timeout = 30000 + setInterval(function() { + var date = new Date(); + var today = date.getDate(); + var hours = date.getHours(); + if (hours >=2 && hours <= 5) { + db.getBookmarkWaitSnap(today) + .then((bookmarks) => { + if (bookmarks.length == 1) { + var id = bookmarks[0].id; + var snapState = bookmarks[0].snap_state; + var url = bookmarks[0].url; + var filePath = './public/images/snap/' + id + '.png'; + // 获取截图 + fs.exists(filePath, function(exists) { + if (exists) { + if (snapState != -1) { + db.updateBookmarkSnapState(id, -1); + } + } else { + if (!/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/.test(url)) { + db.updateBookmarkSnapState(id, today + 31); + return; + } + var webshotOptions = { + shotSize: { + width: 320, + height: 160 + }, + timeout: timeout, + }; + webshot(url, filePath, webshotOptions, function(err) { + var newSnapState = -1; + if (err) { + console.log("boomarkid = " + id + ", url = " + url + ", webshot over") + if (snapState == 0 || snapState == 1) { + newSnapState = snapState + 1; + } else if (snapState == 2) { + newSnapState = today + 31; + } + } + db.updateBookmarkSnapState(id, newSnapState); + }); + } + }); + } + }) + .catch((err) => console.log('getBookmarkWaitSnap err', err)); + } + + }, timeout + 1000); +} + +api.getFaviconByTimer = function() { + console.log('getFaviconByTimer...........'); + let timeout = 1000 * 60 * 30; // 半小时更新一次 + let busy = false; + + let downloadFavicon = async () => { + if(busy) return; + var today = new Date().getDate(); + try { + busy = true; + let bookmarks = await db.getBookmarkWaitFavicon(today); + for (let bookmark of bookmarks) { + let id = bookmark.id; + let faviconState = bookmark.favicon_state; + let url = encodeURI(bookmark.url); + let faviconPath = './public/images/favicon/' + id + '.ico'; + let defaultFile = './public/images/favicon/default.ico'; + + if (/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/.test(url)) { + // http://www.cnblogs.com/zhangwei595806165/p/4984912.html 各种方法都试一遍 + var faviconUrl = "http://47.75.89.228:3000/?url=" + url; // 默认地址 + if (faviconState == 1) { + faviconUrl = "https://api.statvoo.com/favicon/?url=" + url; + } else if (faviconState == 2) { + faviconUrl = "http://www.google.com/s2/favicons?domain=" + url; + } + + try { + let data = await download(faviconUrl); + fs.writeFileSync(faviconPath, data); + faviconState = -1; + } catch (error) { + console.log("boomarkid = " + id + ", url = " + url + ", download error") + if (faviconState == 0 || faviconState == 1) { + faviconState = faviconState + 1; + } else if (faviconState == 2) { + faviconState = -1; + copyFile(defaultFile, faviconPath); + } + } + } else { + console.log("error http url" + url); + faviconState = -1; + copyFile(defaultFile, faviconPath); + } + await db.updateBookmarkFaviconState(id, faviconState); + } + } catch (error) { + console.log('getFaviconByTimer err', err); + } + busy = false; + } + + downloadFavicon(); // 一进来先调用一次 + setInterval(downloadFavicon, timeout); +} + +api.getHotBookmarksByTimer = function() { + var timeout = 1000 * 60 * 10; // 10分钟更新一遍 + var busy = false; + var dayIndex = 0; + var date = new Date(); + + console.log('getHotBookmarks...........', date.format("yyyy-MM-dd hh:mm:ss")); + + setInterval(function() { + if (busy) { + console.log('getHotBookmarks is busy') + return; + } + if (timeout < 1000 * 5) { + busy = true; // 实践证明很容易出错导致busy一直是true,所以干脆去掉此选项了。 + } + console.log('begin getHotBookmarks...'); + date.setTime(date.getTime() + dayIndex * 24 * 60 * 60 * 1000); + var requireData = { + idfa: "d4995f8a0c9b2ad9182369016e376278", + os: "ios", + osv: "9.3.5", + userId: null, + lastupdataTime: new Date().getTime(), + pageNo: 1, + pageSize: 1000, + sort: 'desc', + renderType: 0, + date: curentDate(dayIndex, "yyyy年M月d日"), + } + var url = "https://api.shouqu.me/api_service/api/v1/daily/dailyMark"; + var alterRex = "/mmbiz.qpic.cn|images.jianshu.io|zhimg.com/g"; + var defaultSnap = "./images/default.jpg"; + var defaultFavicon = "./images/favicon/default.ico"; + request.post({ + url: url, + form: requireData + }, function(error, response, body) { + console.log("HotBookmarks request ", error, response && response.statusCode); + if (response && response.statusCode == 200) { + var inserCnt = 0; + var data = JSON.parse(body).data; + var dataDate = new Date(data.date) + + console.log("getHotBookmarks success, date = ", dataDate.format("yyyy-MM-dd hh:mm:ss"), ', bookmarks length = ', data.list.length); + + if (data.list.length == 0) { + busy = false; + return; + } + var dateSql = parseInt(dataDate.format('yyyyMMdd')); + data.list.forEach((b) => { + var bookmark = {}; + bookmark.id = b.articleId; + bookmark.date = dateSql; // 因为有第二天很早的时候获取的是前一天的,所以用数据返回日期 + bookmark.title = b.title; + bookmark.url = b.url; + bookmark.fav_count = b.favCount || 0; + bookmark.created_by = b.sourceName || '泥巴'; + bookmark.created_at = b.updatetime > b.createtime ? b.createtime : b.updatetime; + bookmark.last_click = b.updatetime < b.createtime ? b.createtime : b.updatetime; + if (b.imageList.length >= 1) { + if (b.imageList[0].url) { + bookmark.snap_url = (data.pageNo == 1 ? (b.imageList[0].url.match(alterRex) != null ? defaultSnap : b.imageList[0].url) : defaultSnap); + } else { + bookmark.snap_url = defaultSnap; + for (var i = 0; i < b.images.length; i++) { + if (b.images[i]) { + bookmark.snap_url = b.images[i]; + break; + } + } + } + } else { + bookmark.snap_url = defaultSnap; + } + bookmark.favicon_url = b.sourceLogo || defaultFavicon; + + db.addHotBookmark(bookmark) + .then((id) => { + inserCnt++; + if (inserCnt == data.list.length) { + busy = false; + } + }) + .catch((err) => { + inserCnt++; + console.log('insertHotBookmarks err ', id, err); + if (inserCnt == data.list.length) { + busy = false; + } + }); + }); + } else { + console.log("HotBookmarks request is error", error, response && response.statusCode); + busy = false; + } + }); + }, timeout); +} + + + +api.post('/addNote', function(req, res) { + console.log("addNote username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + + var params = req.body.params; + params.user_id = req.session.user.id; + + db.addNote(params) + .then((insertId) => { + res.json({ + retCode: 0, + insertId: insertId, + msg: "添加备忘成功 ", + }) + console.log('addNote insertId ', insertId) + }) + .catch((err) => { + console.log('addNote error', err); + res.json({ + retCode: 1, + msg: "添加备忘失败: " + JSON.stringify(err), + }) + }); +}); + +api.get('/notes', function(req, res) { + console.log("getNotes username = ", req.session.username); + var params = req.query; + if (!params.shareNote && !req.session.user) { + res.send(401); + return; + } + if (params.shareNote) { + db.getNote(params.shareNote) + .then((data) => res.send(` + + + + + +
+
\n\n${data}\n\n
+
+ `)) + .catch((err) => console.log('notes', err)); + } else { + params.user_id = req.session.user.id; + db.getNotes(params) + .then((data) => res.json(data)) + .catch((err) => console.log('notes', err)); + } +}); + +api.delete('/delNote', function(req, res) { + console.log("delBookmark username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + var noteId = req.query.id; + db.delNote(noteId) + .then((affectedRows) => res.json({ + result: affectedRows + })) + .catch((err) => { + console.log('delBookmark err', err); + res.json({ + result: -1 + }) + }); +}) + +api.post('/updateNote', function(req, res) { + console.log("updateNote username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + + var note = req.body.params; + console.log('hello updateNote', JSON.stringify(note)); + db.updateNote(note.id, note.content, note.tag_id) + .then((affectedRows) => res.json({ + result: affectedRows + })) + .catch((err) => { + console.log('updateNote err', err); + res.json({ + result: -1 + }) + }); // oops! +}) + +api.post('/updateNotePublic', function(req, res) { + console.log("updateNotePublic username = ", req.session.username); + if (!req.session.user) { + res.send(401); + return; + } + + var note = req.body.params; + console.log('hello updateNotePublic', JSON.stringify(note)); + db.updateNotePublic(note.id, note.public) + .then((affectedRows) => res.json({ + result: affectedRows + })) + .catch((err) => { + console.log('updateNote err', err); + res.json({ + result: -1 + }) + }); // oops! +}) + + +// 实现文件下载 +api.get('/download', function(req, res) { + console.log("download username = ", req.session.username); + + var userId = req.query.userId; + var type = req.query.type; + if (!req.session.user || req.session.user.id != userId) { + res.send(401); + return; + } + if (type == 'exportbookmark' && userId) { + db.getTags(userId) + .then((tags) => { + var meta = ''; + var init = 'Bookmarks

Bookmarks

'; + var $ = cheerio.load(init, { + decodeEntities: false, + xmlMode: true, + }); + + tags.forEach((tag, tagIndex) => { + $('#0').append('

' + tag.name + '

'); // 增加文件夹 + db.getExportBookmarksByTag(tag.id) + .then((bookmarks) => { + bookmarks.forEach((bookmark) => { + $('#' + bookmark.tag_id).append('
' + bookmark.title + '
'); + }); + if (tagIndex == tags.length - 1) { + console.log('export bookmarks document construct end...'); + var now = new Date().format('yyyyMMddhhmmss') + var fileName = 'exportbookmark-' + req.session.username + '-' + now + '.html'; + var filePath = path.join(path.resolve(__dirname, '..'), 'uploads', fileName); + fs.writeFile(filePath, beautify_html($.xml(), { + indent_size: 4, + }), function(err) { + if (err) { + console.log(err); + } else { + res.download(filePath, function(err) { + if (err) { + console.log(err); + } else { + console.log('download filePath[ ' + filePath + ' ]success!'); + } + }); + } + }) + } + }) + .catch((err) => { + console.log('getExportBookmarksByTag err', err); + }) + }) + }) + .catch((err) => { + console.log('exportbookmark err', err); + }); + } else { + res.send(401); + } +}); + +function md5(str) { + return crypto.createHash('md5').update(str).digest('hex'); +}; + +function copyFile(sourceFile, destFile) { + fs.exists(sourceFile, function(exists) { + if (exists) { + var readStream = fs.createReadStream(sourceFile); + var writeStream = fs.createWriteStream(destFile); + readStream.pipe(writeStream); + } + }); +} + +function curentDate(i, f) { + if (i == undefined) { + i = 0; + } + if (f == undefined) { + f = 'yyyyMMddhhmmss' + } + var now = new Date(); + now.setTime(now.getTime() + i * 24 * 60 * 60 * 1000); + var clock = now.format(f); + return (clock); +} + +module.exports = api;