diff --git a/README.md b/README.md index 26611ed..86f0e5d 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,11 @@ - [x] 可以导入Chrome的书签导出文件,暂时做在设置里面。 - [x] 书签可以作为公有或者私有,公有可供所有人搜索。 - [x] 可以将搜索到其他用户的书签转存为自己的书签。 -- [ ] 可以将书签导出来,然后导入到浏览器。 +- [x] 可以将书签导出来,然后导入到浏览器。 - [x] 在热门标签里面,有在网上找的热门书签。可以转存收藏到自己书签里面,快捷键R随机查看热门书签。 - [x] 新增备忘录功能,有时候随手要做点纪录,就方便了。任意界面按快捷键A增加备忘录。双击备忘录可查看详情! - [x] 在设置的全局链接,可设置快捷键,用来在任何页面,快速打开设置的链接。 -- [ ] 适配手机平板。 +- [ ] 适配手机平板(无限搁置)。 4 主要用到的模块说明 ------------------ @@ -142,18 +142,19 @@ my-bookmark/ ``` "body-parser": bodyParser用于解析客户端请求的body中的内容,内部使用JSON编码处理 "connect-mongo": 用于将session存入MongoDB -"cheerio": 用于后端的jQuery +"cheerio": 用于后端的jQuery,解析从浏览器导出来上传到服务器的书签html文件 "cookie-parser": 处理每一个请求的cookie "crypto": 加密模块,主要用来加密用户的密码 "debug": 这个好像没用到,看名字好像调试的。 "download": 主要用来下载书签的favicon文件 "express": Web 应用程序框架 "express-session": session模块 -"jsdom": 用来解析从浏览器导出来上传到服务器的书签html文件 +"js-beautify": 用来格式化导出的书签的html文件 "morgan": 一个Node.js关于http请求的日志中间件 "multer": 文件上传模块 "mysql": sql数据库操作模块 "node-readability": 获取网页title(添加书签用到)跟内容(书签详情用到)模块。 +"path": 路径处理模块。 "request": http请求模块。主要用来获取热门书签数据。 "supervisor": 文件改变监视文件,开发使用。 "webshot": 网页截图模块。 diff --git a/database/db.js b/database/db.js index 77844f2..0d6c92b 100644 --- a/database/db.js +++ b/database/db.js @@ -546,13 +546,13 @@ db.getBookmarksNavigate = function(tags) { // 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); + 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) => { @@ -568,9 +568,9 @@ db.getBookmarksNavigate = function(tags) { 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 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) { @@ -751,6 +751,20 @@ db.getBookmarksByTag = function(params) { }) } +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"; diff --git a/package.json b/package.json index 44894ca..936ff33 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "download": "^5.0.3", "express": "~4.13.4", "express-session": "^1.14.1", + "js-beautify": "^1.6.14", "morgan": "^1.8.1", "multer": "^1.3.0", "mysql": "^2.11.1", diff --git a/public/index.html b/public/index.html index 35758c1..7b4b688 100644 --- a/public/index.html +++ b/public/index.html @@ -38,7 +38,7 @@
7、如果公用一台电脑,如何区分我收藏的跟别人收藏的书签?
在线书签管理工具,帮助你快速记录你喜欢的网站,并可以随时随地查看这些站点,而不必拘泥于使用的浏览器。无论在什么地方,只要能接入网络,就能打开属于你自己的网络书签,看到自己收藏的页面网址。
1、需要注册账号用户。(初步完成)
+1、需要注册账号用户。(完成)
2、网站展示有三种展示方式:导航,标签,列表,卡片。其中导航以分类展示,分类顺序可以在书签分类下面拖动编辑。按照点击的次数从高到低在每个分类里面提取16个书签,再按照最近添加的书签提取前面的16个书签,然后合并起来。标签是一个快捷方式。列表以表格展示,显示书签详细类容,按照点击次数优先显示,点击次数相同,则按添加顺序优先。卡片以卡片方式显示,按照最近添加优先显示。这几种展示方式,可以在设置里面默认一种你常用的方式。(完成)
3、在书签分类里面,可以更新分类,删除分类,新增分类,对分类显示进行排序。分类的标签默认按照添加日期展示,但是可以点击表格的标题,按照点击次数,添加日期,最后点击从大到小进行排序。(完成)
4、可以按照指定添加时间段,指定分类目录,指定网址关键字等进行查询。(完成)
5、添加书签的时候,会自动获取title,供用户编辑。其中:Insert键打开添加页面,再次按Insert键保存书签,Esc取消添加。(完成)
6、可以导入Chrome的书签导出文件,暂时做在设置里面。(完成)
7、书签可以作为公有或者私有,公有可供所有人搜索。(完成)
-8、可以将搜索到其他用户的书签转存为自己的书签。(已完成)
-9、可以将书签导出来,然后导入到浏览器。(未完成)
+8、可以将搜索到其他用户的书签转存为自己的书签。(完成)
+9、可以将书签导出来,然后导入到浏览器。(完成)
10、在热门标签里面,有在网上找的热门书签。可以转存收藏到自己书签里面。快捷键R随机查看热门书签。(完成)
11、新增备忘录功能,有时候随手要做点纪录,就方便了。任意界面按快捷键A增加备忘录。双击备忘录可查看详情!(完成)
12、在设置的全局链接,可设置快捷键,用来在任何页面,快速打开设置的链接。(完成)
diff --git a/public/views/settings.html b/public/views/settings.html index 55d9049..6b753b6 100644 --- a/public/views/settings.html +++ b/public/views/settings.html @@ -6,7 +6,7 @@ 我的信息 - 上传或导出书签 + 上传导出 网站说明 @@ -123,6 +123,7 @@4、导入的文件不能超过10M
5、如果重复导入,新的会覆盖旧的信息。
+6、注意:从浏览器导入进系统的书签,没有浏览器目录的树形结构,在浏览器没有目录的标签,统统转入系统未分类目录下面。
7、如果公用一台电脑,如何区分我收藏的跟别人收藏的书签?
在线书签管理工具,帮助你快速记录你喜欢的网站,并可以随时随地查看这些站点,而不必拘泥于使用的浏览器。无论在什么地方,只要能接入网络,就能打开属于你自己的网络书签,看到自己收藏的页面网址。
1、需要注册账号用户。(初步完成)
+1、需要注册账号用户。(完成)
2、网站展示有三种展示方式:导航,标签,列表,卡片。其中导航以分类展示,分类顺序可以在书签分类下面拖动编辑。按照点击的次数从高到低在每个分类里面提取16个书签,再按照最近添加的书签提取前面的16个书签,然后合并起来。标签是一个快捷方式。列表以表格展示,显示书签详细类容,按照点击次数优先显示,点击次数相同,则按添加顺序优先。卡片以卡片方式显示,按照最近添加优先显示。这几种展示方式,可以在设置里面默认一种你常用的方式。(完成)
3、在书签分类里面,可以更新分类,删除分类,新增分类,对分类显示进行排序。分类的标签默认按照添加日期展示,但是可以点击表格的标题,按照点击次数,添加日期,最后点击从大到小进行排序。(完成)
4、可以按照指定添加时间段,指定分类目录,指定网址关键字等进行查询。(完成)
5、添加书签的时候,会自动获取title,供用户编辑。其中:Insert键打开添加页面,再次按Insert键保存书签,Esc取消添加。(完成)
6、可以导入Chrome的书签导出文件,暂时做在设置里面。(完成)
7、书签可以作为公有或者私有,公有可供所有人搜索。(完成)
-8、可以将搜索到其他用户的书签转存为自己的书签。(已完成)
-9、可以将书签导出来,然后导入到浏览器。(未完成)
+8、可以将搜索到其他用户的书签转存为自己的书签。(完成)
+9、可以将书签导出来,然后导入到浏览器。(完成)
10、在热门标签里面,有在网上找的热门书签。可以转存收藏到自己书签里面。快捷键R随机查看热门书签。(完成)
11、新增备忘录功能,有时候随手要做点纪录,就方便了。任意界面按快捷键A增加备忘录。双击备忘录可查看详情!(完成)
12、在设置的全局链接,可设置快捷键,用来在任何页面,快速打开设置的链接。(完成)
diff --git a/routes/api.js b/routes/api.js index ecc7efb..45a6a34 100644 --- a/routes/api.js +++ b/routes/api.js @@ -10,7 +10,8 @@ var webshot = require('webshot'); var fs = require('fs'); var request = require('request'); var cheerio = require('cheerio'); -const path = require('path'); +var path = require('path'); +var beautify_html = require('js-beautify').html; var storage = multer.diskStorage({ destination: function(req, file, cb) { @@ -19,7 +20,7 @@ var storage = multer.diskStorage({ filename: function(req, file, cb) { var now = new Date().format('yyyyMMddhhmmss') if (req.session.user) { - cb(null, req.session.username + '-' + now + '.html') + cb(null, 'importbookmark-' + req.session.username + '-' + now + '.html') } else { cb(null, "UnknowUser" + '-' + now + '.html') } @@ -1446,16 +1447,64 @@ api.post('/updateNote', function(req, res) { // 实现文件下载 api.get('/download', function(req, res) { - var fileName = req.query.fileName; - var filePath = path.join(path.resolve(__dirname, '..'), 'uploads', fileName); - console.log('download fileName = ', fileName, ', download filePath = ' + filePath); - res.download(filePath, function(err) { - if (err) { - console.log(err); - } else { - console.log('download filePath[ ' + filePath + ' ]success!'); - } - }); + 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 = '