完成书签的导出功能
This commit is contained in:
parent
d1ecfe57e9
commit
845fc73798
|
|
@ -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": 网页截图模块。
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
<div class="ui container" style="width:100%;height:10px"></div>
|
||||
<div class="foot" style="margin-bottom:10px;">
|
||||
<div class="ui segment container">
|
||||
Copyleft ©All Rights Reserved LCQ(假装网站有个页脚) | 联系我(QQ:530485521) | <a href="https://github.com/luchenqun/my-bookmark" target="_blank">网站源码</a> | V1.4.0 | <span>由于使用国外服务器,如果加载失败,请按F5,你懂的!(●'◡'●)</span>
|
||||
我爱佳佳与这个世界 | Copyleft ©All Rights Reserved LCQ | 联系我(QQ:530485521) | <a href="https://github.com/luchenqun/my-bookmark" target="_blank">网站源码</a> | V1.5.0 | <span>由于使用国外服务器,如果加载失败,请按F5,你懂的!(●'◡'●)</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- directive:书签编辑 -->
|
||||
|
|
|
|||
|
|
@ -205,9 +205,14 @@ app.controller('settingsCtr', ['$scope', '$stateParams', '$filter', '$state', '$
|
|||
}
|
||||
|
||||
$scope.exportBookmark = function() {
|
||||
toastr.warning('功能正在开发中,敬请期待......', '提示');
|
||||
return;
|
||||
$window.open("api/download?fileName=lcq-20170304213023.html");
|
||||
var userId = $scope.user && $scope.user.id;
|
||||
if (userId) {
|
||||
// toastr.warning('功能正在开发中,敬请期待......', '提示');
|
||||
// return;
|
||||
$window.open("api/download?userId=" + userId + "&type=exportbookmark");
|
||||
} else {
|
||||
toastr.warning('用户信息无法获取到,请尝试按刷新网页再尝试!', '提示');
|
||||
}
|
||||
}
|
||||
|
||||
function updateShowStyle(showStyle) {
|
||||
|
|
|
|||
|
|
@ -11,15 +11,15 @@
|
|||
<p>7、如果公用一台电脑,如何区分我收藏的跟别人收藏的书签?</p>
|
||||
<p>在线书签管理工具,帮助你快速记录你喜欢的网站,并可以随时随地查看这些站点,而不必拘泥于使用的浏览器。无论在什么地方,只要能接入网络,就能打开属于你自己的网络书签,看到自己收藏的页面网址。</p>
|
||||
<h3 class="ui dividing header">主要功能</h3>
|
||||
<p>1、需要注册账号用户。(初步完成)</p>
|
||||
<p>1、需要注册账号用户。(完成)</p>
|
||||
<p>2、网站展示有三种展示方式:导航,标签,列表,卡片。其中导航以分类展示,分类顺序可以在书签分类下面拖动编辑。按照点击的次数从高到低在每个分类里面提取16个书签,再按照最近添加的书签提取前面的16个书签,然后合并起来。标签是一个快捷方式。列表以表格展示,显示书签详细类容,按照点击次数优先显示,点击次数相同,则按添加顺序优先。卡片以卡片方式显示,按照最近添加优先显示。这几种展示方式,可以在设置里面默认一种你常用的方式。(完成)</p>
|
||||
<p>3、在书签分类里面,可以更新分类,删除分类,新增分类,对分类显示进行排序。分类的标签默认按照添加日期展示,但是可以点击表格的标题,按照点击次数,添加日期,最后点击从大到小进行排序。(完成)</p>
|
||||
<p>4、可以按照指定添加时间段,指定分类目录,指定网址关键字等进行查询。(完成)</p>
|
||||
<p>5、添加书签的时候,会自动获取title,供用户编辑。其中:Insert键打开添加页面,再次按Insert键保存书签,Esc取消添加。(完成)</p>
|
||||
<p>6、可以导入Chrome的书签导出文件,暂时做在设置里面。(完成)</p>
|
||||
<p>7、书签可以作为公有或者私有,公有可供所有人搜索。(完成)</p>
|
||||
<p>8、可以将搜索到其他用户的书签转存为自己的书签。(已完成)</p>
|
||||
<p>9、可以将书签导出来,然后导入到浏览器。(未完成)</p>
|
||||
<p>8、可以将搜索到其他用户的书签转存为自己的书签。(完成)</p>
|
||||
<p>9、可以将书签导出来,然后导入到浏览器。(完成)</p>
|
||||
<p>10、在热门标签里面,有在网上找的热门书签。可以转存收藏到自己书签里面。快捷键R随机查看热门书签。(完成)</p>
|
||||
<p>11、新增备忘录功能,有时候随手要做点纪录,就方便了。任意界面按快捷键A增加备忘录。双击备忘录可查看详情!(完成)</p>
|
||||
<p>12、在设置的全局链接,可设置快捷键,用来在任何页面,快速打开设置的链接。(完成)</p>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
</a>
|
||||
<a class="item" ng-class="{active:form[1]}" ng-click="changeForm(1)">我的信息
|
||||
</a>
|
||||
<a class="item" ng-class="{active:form[2]}" ng-click="changeForm(2)">上传或导出书签
|
||||
<a class="item" ng-class="{active:form[2]}" ng-click="changeForm(2)">上传导出
|
||||
</a>
|
||||
<a class="item" ng-class="{active:form[3]}" ng-click="changeForm(3)">网站说明
|
||||
</a>
|
||||
|
|
@ -123,6 +123,7 @@
|
|||
</p>
|
||||
<p>4、导入的文件不能超过10M</p>
|
||||
<p>5、如果重复导入,新的会覆盖旧的信息。</p>
|
||||
<p>6、注意:从浏览器导入进系统的书签,没有浏览器目录的树形结构,在浏览器没有目录的标签,统统转入系统未分类目录下面。</p>
|
||||
</div>
|
||||
<h2 class="ui dividing header">导出为浏览器书签</h2>
|
||||
<button class="fluid ui button" ng-click="exportBookmark()">导出书签</button>
|
||||
|
|
@ -139,15 +140,15 @@
|
|||
<p>7、如果公用一台电脑,如何区分我收藏的跟别人收藏的书签?</p>
|
||||
<p>在线书签管理工具,帮助你快速记录你喜欢的网站,并可以随时随地查看这些站点,而不必拘泥于使用的浏览器。无论在什么地方,只要能接入网络,就能打开属于你自己的网络书签,看到自己收藏的页面网址。</p>
|
||||
<h3 class="ui dividing header">主要功能</h3>
|
||||
<p>1、需要注册账号用户。(初步完成)</p>
|
||||
<p>1、需要注册账号用户。(完成)</p>
|
||||
<p>2、网站展示有三种展示方式:导航,标签,列表,卡片。其中导航以分类展示,分类顺序可以在书签分类下面拖动编辑。按照点击的次数从高到低在每个分类里面提取16个书签,再按照最近添加的书签提取前面的16个书签,然后合并起来。标签是一个快捷方式。列表以表格展示,显示书签详细类容,按照点击次数优先显示,点击次数相同,则按添加顺序优先。卡片以卡片方式显示,按照最近添加优先显示。这几种展示方式,可以在设置里面默认一种你常用的方式。(完成)</p>
|
||||
<p>3、在书签分类里面,可以更新分类,删除分类,新增分类,对分类显示进行排序。分类的标签默认按照添加日期展示,但是可以点击表格的标题,按照点击次数,添加日期,最后点击从大到小进行排序。(完成)</p>
|
||||
<p>4、可以按照指定添加时间段,指定分类目录,指定网址关键字等进行查询。(完成)</p>
|
||||
<p>5、添加书签的时候,会自动获取title,供用户编辑。其中:Insert键打开添加页面,再次按Insert键保存书签,Esc取消添加。(完成)</p>
|
||||
<p>6、可以导入Chrome的书签导出文件,暂时做在设置里面。(完成)</p>
|
||||
<p>7、书签可以作为公有或者私有,公有可供所有人搜索。(完成)</p>
|
||||
<p>8、可以将搜索到其他用户的书签转存为自己的书签。(已完成)</p>
|
||||
<p>9、可以将书签导出来,然后导入到浏览器。(未完成)</p>
|
||||
<p>8、可以将搜索到其他用户的书签转存为自己的书签。(完成)</p>
|
||||
<p>9、可以将书签导出来,然后导入到浏览器。(完成)</p>
|
||||
<p>10、在热门标签里面,有在网上找的热门书签。可以转存收藏到自己书签里面。快捷键R随机查看热门书签。(完成)</p>
|
||||
<p>11、新增备忘录功能,有时候随手要做点纪录,就方便了。任意界面按快捷键A增加备忘录。双击备忘录可查看详情!(完成)</p>
|
||||
<p>12、在设置的全局链接,可设置快捷键,用来在任何页面,快速打开设置的链接。(完成)</p>
|
||||
|
|
|
|||
|
|
@ -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,9 +1447,42 @@ api.post('/updateNote', function(req, res) {
|
|||
|
||||
// 实现文件下载
|
||||
api.get('/download', function(req, res) {
|
||||
var fileName = req.query.fileName;
|
||||
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 = '<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">';
|
||||
var init = '<TITLE>Bookmarks</TITLE><H1>Bookmarks</H1><DL id="0"></DL>';
|
||||
var $ = cheerio.load(init, {
|
||||
decodeEntities: false,
|
||||
xmlMode: true,
|
||||
});
|
||||
|
||||
tags.forEach((tag, tagIndex) => {
|
||||
$('#0').append('<DT><H3>' + tag.name + '</H3></DT><DL id="' + tag.id + '"></DL>'); // 增加文件夹
|
||||
db.getExportBookmarksByTag(tag.id)
|
||||
.then((bookmarks) => {
|
||||
bookmarks.forEach((bookmark) => {
|
||||
$('#' + bookmark.tag_id).append('<DT><A HREF="' + bookmark.url + '">' + bookmark.title + '</A></DT>');
|
||||
});
|
||||
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);
|
||||
console.log('download fileName = ', fileName, ', download filePath = ' + filePath);
|
||||
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);
|
||||
|
|
@ -1456,6 +1490,21 @@ api.get('/download', function(req, res) {
|
|||
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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue