Compare commits

..
121 Commits
Author SHA1 Message Date
lealife 290772b437 init index 2016-05-30 11:51:41 +08:00
lealife 6ebedf94f0 app.conf 2016-05-25 17:33:38 +08:00
lealife a07bb25128 remove unused codes and add site'url configuration on admin 2016-05-25 16:05:47 +08:00
lealife a007b89ebb v2.0 2016-05-25 14:46:40 +08:00
lealife cc4b003503 markdown vim cursor fixed 2016-05-25 09:51:53 +08:00
lealife 091922175a box leanote logo 2016-05-22 16:12:51 +08:00
lealife 371c93912d build 2016-05-22 10:36:36 +08:00
lealife 27221acda7 new logo 2016-05-22 10:34:40 +08:00
lealife 5db724e80b new logo 2016-05-21 23:05:50 +08:00
lealife 5c9e95ed60 build 2016-04-16 14:53:30 +08:00
lealife 2fc97ed42d markdown editor prettify add linenums 2016-04-16 14:51:54 +08:00
lealife 45cca30cec lea++ -> Explore 2016-04-16 12:09:48 +08:00
lealife 31167b6aaf recount tags 2016-04-16 11:58:39 +08:00
lealife 139906b9d6 recount tags when public note 2016-04-16 11:31:27 +08:00
lealife a9d49369e2 upgrade markdown mathjax 2016-04-12 22:02:36 +08:00
life 303e0da5c0 Update README.md 2016-04-09 10:12:46 +08:00
life ff5523bfaa Merge pull request #340 from eric2100/patch-15
Update blog.conf
2016-04-08 17:07:20 +08:00
Tsunghan,Tsai 063dd0140d Update blog.conf
部分口語修改
2016-04-08 12:31:41 +08:00
life c52d388d5d Merge pull request #337 from eric2100/patch-14
Update msg.conf
2016-04-07 17:31:04 +08:00
eric2100 18bcdb48af Update msg.conf 2016-04-07 12:29:03 +08:00
life db8f132507 Merge pull request #333 from eric2100/patch-9
Update blog.conf
2016-04-05 10:14:31 +08:00
life 439d5212b0 Merge pull request #334 from eric2100/patch-10
Update markdown.conf
2016-04-05 10:13:40 +08:00
life 88e2320027 Merge pull request #335 from eric2100/patch-11
Update member.conf
2016-04-05 10:13:09 +08:00
life 659a4e590a Merge pull request #336 from eric2100/patch-12
Update tinymce_editor.conf
2016-04-05 10:12:19 +08:00
eric2100 ab7f2386e0 Update tinymce_editor.conf 2016-04-05 00:24:21 +08:00
eric2100 ec82ff18f2 Update member.conf 2016-04-05 00:16:00 +08:00
eric2100 f3f00626e6 Update markdown.conf 2016-04-05 00:03:27 +08:00
eric2100 80fbb56426 Update blog.conf 2016-04-05 00:01:46 +08:00
life a5c952882f Merge pull request #332 from eric2100/patch-8
Update album.conf
2016-04-03 21:30:30 +08:00
eric2100 973b452a7e Update album.conf 2016-04-02 21:12:30 +08:00
lealife 25bcd21ea9 overwrite revel.Message 2016-03-19 23:00:41 +08:00
lealife 09de5e1e83 Gulp js i18n generator 2016-03-19 15:46:41 +08:00
lealife 15b0ef21ff restructure messages 2016-03-19 15:37:36 +08:00
lealife 9cf9ded855 remove config langs. Gulp will get all langs by messages/ 2016-03-19 15:17:15 +08:00
lealife 7af433ebaf build 2016-03-19 14:36:47 +08:00
lealife 67b608b324 set langs to config and modify gulp build to support langs 2016-03-19 14:30:07 +08:00
lealife 2aa3f5a654 support 中文繁体 2016-03-19 14:05:09 +08:00
lealife f5538218bd remove baidu statistics Code
https://github.com/leanote/leanote/issues/318
2016-03-04 22:23:53 +08:00
lealife 0e3bdd177c md resize when toggle 2016-02-27 15:30:01 +08:00
lealife 12520cc09d mathjax 2.6.1 2016-02-27 14:20:31 +08:00
life cb67892124 Merge pull request #309 from alexsourcerer/patch-8
Update msg.fr
2016-02-18 14:55:17 +08:00
alexsourcerer 45c09c9a26 Update msg.fr
I updated the msg.fr file (note that the website isn't it french at all anymore for french users)
2016-02-03 23:10:50 +01:00
lealife 20951ea2dd build release 2015-12-25 23:59:57 +08:00
lealife 530f2368da v1.4.2 released 2015-12-25 23:45:38 +08:00
lealife e685a99628 member css for multi lang 2015-12-25 23:45:19 +08:00
lealife bfc5acc3ee 1.4.2 released 2015-12-25 11:50:34 +08:00
lealife 551e3d965e markdown todo-list style 2015-12-25 11:50:34 +08:00
lealife 7c479b5595 fix ace editor hide the last line part section text 2015-12-25 11:50:34 +08:00
lealife b135f9717f fix gen desc 2015-12-25 11:50:34 +08:00
lealife 08ae37cae0 markdown add todo-list feature 2015-12-25 11:50:34 +08:00
Yingbo CUI 315a7bbe62 Update README.md 2015-12-24 16:47:31 +08:00
life e173b18ddc Merge pull request #285 from eurafa/master
Portuguese (Brazil) language added
2015-12-17 10:29:10 +08:00
Rafael Andrade de Oliveira dcc25df679 Chinese translations 2015-12-13 09:09:02 -02:00
Rafael Andrade de Oliveira c561dec14c Portuguese (Brazil) language added 2015-12-13 09:03:50 -02:00
lealife 43e8f2e701 markdown editor inited 2015-12-06 15:48:05 +08:00
lealife dd9952c453 fix export pdf error 2015-12-04 17:50:14 +08:00
lealife 19517dd634 fix export pdf error 2015-12-04 17:37:57 +08:00
lealife a5b006aae7 添加全局 toggle modify with readonly; 发布1.4.1 2015-12-02 20:56:03 +08:00
lealife 90bd07cdcc * markdown v2, 修复笔记内容覆盖 2015-12-02 20:55:34 +08:00
lealife 92576e9239 arm run script 2015-11-29 13:05:26 +08:00
lealife c58e6874c2 paste image 名称是untitled 2015-11-28 21:47:50 +08:00
lealife cfebf00cf1 i18n js 2015-11-28 21:32:21 +08:00
lealife 19be0990da 注销后不再保存笔记 2015-11-28 21:31:56 +08:00
lealife 3f27e4b0d4 Failed to generate name for field. Make sure the field name is valid #201 2015-11-28 21:26:29 +08:00
lealife 4710fb6686 i18n 2015-11-28 18:57:58 +08:00
lealife 28324c0178 release v1.4 2015-11-28 18:00:45 +08:00
lealife f270ade8d7 1.4 2015-11-28 17:58:42 +08:00
lealife 3b3e665a9f paste image 2015-11-28 17:58:38 +08:00
lealife bfa85e2d34 Merge branch 'feature-v1.4' 2015-11-28 16:45:59 +08:00
lealife fcf270a521 reinit undo when toggle file 2015-11-28 16:44:59 +08:00
lealife eba113c73c dev tinymce 2015-11-28 16:40:50 +08:00
lealife 41f63156ea tinymce 不打包 2015-11-28 16:32:29 +08:00
lealife f54fe397c3 member view 2015-11-28 16:12:27 +08:00
lealife 6f157289d3 update member css 2015-11-28 16:09:33 +08:00
lealife 65792d020c move tinymce theme to /public/css/tinymce 2015-11-28 16:07:17 +08:00
lealife 926882dce6 build js 2015-11-28 15:56:25 +08:00
lealife f834f469fc update gulp build for i18n 2015-11-28 15:55:58 +08:00
lealife 06d42c36f0 i18n 2015-11-28 15:46:56 +08:00
lealife 17d513a9de fix note-dev 2015-11-28 15:42:39 +08:00
lealife 8cc00c1f66 format date config; for update note's date 2015-11-28 15:38:43 +08:00
lealife cb433d9392 theme; split by files 2015-11-28 15:36:12 +08:00
lealife 86ca1efd11 tinymce theme 2015-11-28 15:35:26 +08:00
lealife 263f978c54 import theme 2015-11-28 15:33:49 +08:00
lealife c8af7eda5d hide note and editor when search 2015-11-28 15:33:42 +08:00
lealife 3724811802 set md column width 2015-11-28 15:33:30 +08:00
lealife 10ff48267f clear undo 2015-11-28 15:33:13 +08:00
lealife cd0913aec0 paste for markdown v2 2015-11-28 15:33:06 +08:00
lealife f8d4c2ef20 markdown editor v2 2015-11-28 15:32:56 +08:00
lealife f16b5e816e Leanote upperCase 2015-11-28 15:23:33 +08:00
lealife 9a9968760a note i18n 2015-11-28 15:19:50 +08:00
lealife b1f36dfbf1 member i18n 2015-11-28 15:17:36 +08:00
lealife bc0e09f222 file upload path 统一化 GetRandomFilePath 2015-11-28 14:44:07 +08:00
lealife 0dab71e72b delete unused 2015-11-28 14:35:46 +08:00
lealife 10f23c19ab group i18n, pwd 重置密码优化 2015-11-28 14:28:51 +08:00
lealife bba57ea302 configservice 2015-11-28 14:25:45 +08:00
lealife f052117989 删除笔记时删除历史 2015-11-28 14:22:10 +08:00
lealife df4ec53647 api fixContent优化; exportPDF优化 2015-11-28 14:21:23 +08:00
lealife a7eaf6114a urlTitle 优化, 减少生成次数, 避免使用id作为urlTitle 2015-11-28 14:16:10 +08:00
lealife b25bf0e16c util 时间判断 2015-11-28 13:49:00 +08:00
lealife d13447e6d0 controller 支持传递时间 2015-11-28 13:47:59 +08:00
lealife 6a1e84da0c noteService支持传时间添加/更新笔记 2015-11-28 13:43:37 +08:00
lealife 51aeb7d46e build support linux-arm 2015-11-23 10:39:01 +08:00
lealife 2dbd025768 album js build 2015-11-22 23:26:59 +08:00
lealife d52d80d529 plugins compress 2015-11-22 23:18:07 +08:00
lealife 2000bc585b markdown editor v2 paste images 2015-11-22 23:01:30 +08:00
lealife 8301a1e515 js 优化
* 标题按tab切换到内容
* 左侧最小化用css控制
* resize markdown editor v2
* Ace剪切导致行数减少
* 删除不要的代码
2015-11-22 22:58:38 +08:00
lealife bee65eb36d markdown editor v2 editor mode i18n 2015-11-22 22:46:27 +08:00
lealife 78199583b0 mv dist -> md 2015-11-22 22:46:00 +08:00
lealife 28d5678349 remove unused files 2015-11-22 22:41:07 +08:00
lealife e97c468f6e gulp markdown v2 builder 2015-11-22 22:39:16 +08:00
lealife 5d18554542 tinymce build 2015-11-22 22:39:04 +08:00
lealife 3ff0a9e09c markdown editor v2 libs 2015-11-22 22:36:53 +08:00
lealife 6a753682b7 markdown editor v2 2015-11-22 22:33:07 +08:00
lealife ce491e62c3 insert image i18n 2015-11-22 22:28:51 +08:00
lealife e4b847b731 undo md 2015-11-22 22:21:59 +08:00
lealife a12b285a35 tinymce leanote code plugin i18n 2015-11-22 22:21:38 +08:00
lealife 7f0ada8016 update readme 2015-11-18 23:45:20 +08:00
lealife bac5ab4d79 update readme 2015-11-18 23:43:19 +08:00
life b362406819 Merge pull request #261 from alexsourcerer/patch-7
Update msg.fr
2015-11-18 13:13:54 +08:00
alexsourcerer 9e2edbb987 Update msg.fr 2015-11-16 21:56:12 +01:00
lealife 7809d00787 fmt all go file 2015-11-13 17:58:41 +08:00
1159 changed files with 34412 additions and 31584 deletions

No files matched your search

+152 -88
View File
@@ -15,13 +15,15 @@ var base = leanoteBase + '/public'; // public base
var noteDev = leanoteBase + '/app/views/note/note-dev.html'; var noteDev = leanoteBase + '/app/views/note/note-dev.html';
var noteProBase = leanoteBase + '/app/views/note'; var noteProBase = leanoteBase + '/app/views/note';
var messagesPath = leanoteBase + 'messages';
// 合并Js, 这些js都是不怎么修改, 且是依赖 // 合并Js, 这些js都是不怎么修改, 且是依赖
// 840kb, 非常耗时!! // 840kb, 非常耗时!!
gulp.task('concatDepJs', function() { gulp.task('concatDepJs', function() {
var jss = [ var jss = [
'js/jquery-1.9.0.min.js', 'js/jquery-1.9.0.min.js',
'js/jquery.ztree.all-3.5-min.js', 'js/jquery.ztree.all-3.5-min.js',
'tinymce/tinymce.full.min.js', // 使用打成的包, 加载速度快 // 'tinymce/tinymce.full.min.js', // 使用打成的包, 加载速度快
// 'libs/ace/ace.js', // 'libs/ace/ace.js',
'js/jQuery-slimScroll-1.3.0/jquery.slimscroll-min.js', 'js/jQuery-slimScroll-1.3.0/jquery.slimscroll-min.js',
'js/contextmenu/jquery.contextmenu-min.js', 'js/contextmenu/jquery.contextmenu-min.js',
@@ -62,11 +64,39 @@ gulp.task('concatAppJs', function() {
.pipe(gulp.dest(base + '/js')); .pipe(gulp.dest(base + '/js'));
}); });
// plugins压缩
gulp.task('plugins', function() {
// gulp.src(base + '/js/plugins/libs/*.js')
// .pipe(uglify()) // 压缩
// // .pipe(concat('main.min.js'))
// .pipe(gulp.dest(base + '/js/plugins/libs-min'));
// 所有js合并成一个
var jss = [
'note_info',
'tips',
'history',
'attachment_upload',
'editor_drop_paste',
'main'
];
for(var i in jss) {
jss[i] = base + '/js/plugins/' + jss[i] + '.js';
}
jss.push(base + '/js/plugins/libs-min/fileupload.js');
return gulp.src(jss)
.pipe(uglify()) // 压缩
.pipe(concat('main.min.js'))
.pipe(gulp.dest(base + '/js/plugins'));
});
// 合并requirejs和markdown为一个文件 // 合并requirejs和markdown为一个文件
gulp.task('concatMarkdownJs', function() { gulp.task('concatMarkdownJs', function() {
var jss = [ var jss = [
'js/require.js', 'js/require.js',
'dist/main.min.js', 'md/main.min.js',
]; ];
for(var i in jss) { for(var i in jss) {
@@ -80,6 +110,24 @@ gulp.task('concatMarkdownJs', function() {
.pipe(gulp.dest(base + '/js')); .pipe(gulp.dest(base + '/js'));
}); });
// / 合并requirejs和markdown为一个文件
gulp.task('concatMarkdownJsV2', function() {
var jss = [
'js/require.js',
'md/main-v2.min.js',
];
for(var i in jss) {
jss[i] = base + '/' + jss[i];
}
return gulp
.src(jss)
.pipe(uglify()) // 压缩
.pipe(concat('markdown-v2.min.js'))
.pipe(gulp.dest(base + '/js'));
});
// note-dev.html -> note.html, 替换css, js // note-dev.html -> note.html, 替换css, js
// TODO 加?t=2323232, 强制浏览器更新, 一般只需要把app.min.js上加 // TODO 加?t=2323232, 强制浏览器更新, 一般只需要把app.min.js上加
gulp.task('devToProHtml', function() { gulp.task('devToProHtml', function() {
@@ -88,28 +136,40 @@ gulp.task('devToProHtml', function() {
.pipe(replace(/<!-- dev -->[.\s\S]+?<!-- \/dev -->/g, '')) // 把dev 去掉 .pipe(replace(/<!-- dev -->[.\s\S]+?<!-- \/dev -->/g, '')) // 把dev 去掉
.pipe(replace(/<!-- pro_dep_js -->/, '<script src="/js/dep.min.js"></script>')) // 替换 .pipe(replace(/<!-- pro_dep_js -->/, '<script src="/js/dep.min.js"></script>')) // 替换
.pipe(replace(/<!-- pro_app_js -->/, '<script src="/js/app.min.js"></script>')) // 替换 .pipe(replace(/<!-- pro_app_js -->/, '<script src="/js/app.min.js"></script>')) // 替换
.pipe(replace(/<!-- pro_markdown_js -->/, '<script src="/js/markdown.min.js"></script>')) // 替换 // .pipe(replace(/<!-- pro_markdown_js -->/, '<script src="/js/markdown.min.js"></script>')) // 替换
.pipe(replace(/<!-- pro_markdown_js -->/, '<script src="/js/markdown-v2.min.js"></script>')) // 替换
.pipe(replace('/tinymce/tinymce.js', '/tinymce/tinymce.full.min.js')) // 替换
.pipe(replace(/<!-- pro_tinymce_init_js -->/, "var tinyMCEPreInit = {base: '/public/tinymce', suffix: '.min'};")) // 替换 .pipe(replace(/<!-- pro_tinymce_init_js -->/, "var tinyMCEPreInit = {base: '/public/tinymce', suffix: '.min'};")) // 替换
.pipe(replace(/plugins\/main.js/, "plugins/main.min.js")) // 替换 .pipe(replace(/plugins\/main.js/, "plugins/main.min.js")) // 替换
// 连续两个空行换成一个空行, 没用 // 连续两个空行换成一个空行
.pipe(replace(/\n\n/g, '\n')) .pipe(replace(/\r\n\r\n/g, '\r\n'))
.pipe(replace(/\n\n/g, '\n')) .pipe(replace(/\r\n\r\n/g, '\r\n'))
.pipe(replace(/\r\n\r\n/g, '\r\n'))
.pipe(replace(/\r\n\r\n/g, '\r\n'))
.pipe(replace(/\r\n\r\n/g, '\r\n'))
.pipe(replace(/\r\n\r\n/g, '\r\n'))
.pipe(replace('console.log(o);', '')) .pipe(replace('console.log(o);', ''))
.pipe(replace('console.trace(o);', ''))
// .pipe(minifyHtml()) // 不行, 压缩后golang报错 // .pipe(minifyHtml()) // 不行, 压缩后golang报错
.pipe(rename('note.html')) .pipe(rename('note.html'))
.pipe(gulp.dest(noteProBase)); .pipe(gulp.dest(noteProBase));
}); });
// Get used keys
// 只获取需要js i18n的key // 只获取需要js i18n的key
var path = require('path'); var path = require('path');
gulp.task('i18n', function() { gulp.task('i18n', function() {
var keys = {}; var keys = {};
var reg = /getMsg\(["']+(.+?)["']+/g; var reg = /getMsg\(["']+(.+?)["']+/g;
// {rule: "required", msg: "inputNewPassword"},
var reg2 = /msg: ?"?([0-9a-zA-Z]*)"?/g;
function getKey(data) { function getKey(data) {
while(ret = reg.exec(data)) { while(ret = reg.exec(data)) {
keys[ret[1]] = 1; keys[ret[1]] = 1;
} }
while(ret2 = reg2.exec(data)) {
keys[ret2[1]] = 1;
}
} }
// 先获取需要的key // 先获取需要的key
function ls(ff) { function ls(ff) {
@@ -137,14 +197,17 @@ gulp.task('i18n', function() {
ls(base + '/admin'); ls(base + '/admin');
ls(base + '/blog'); ls(base + '/blog');
ls(base + '/dist'); ls(base + '/md');
ls(base + '/js'); ls(base + '/js');
ls(base + '/album'); ls(base + '/album');
ls(base + '/libs'); ls(base + '/libs');
ls(base + '/member'); ls(base + '/member');
ls(base + '/tinymce'); ls(base + '/tinymce');
ls(leanoteBase + '/app/views');
console.log('parsed'); console.log('parsed');
var langs = {}; // zh-cn: 1
// msg.zh // msg.zh
function getAllMsgs(fname) { function getAllMsgs(fname) {
@@ -169,10 +232,30 @@ gulp.task('i18n', function() {
return msg; return msg;
} }
// 得到所有的语言的后缀
// 返回{en-us: 1, }
function getAllLangs() {
var langs = {};
var files = fs.readdirSync(messagesPath);
for(fn in files) {
var fname = files[fn];
if (fname.indexOf('-') > 0) {
langs[fname] = 1;
}
}
return langs;
}
// msg.zh, msg.js // msg.zh, msg.js
function genI18nJsFile(fromFilename, keys) { function genI18nJsFile(targetFilename, lang, fromFilenames, keys) {
var msgs = getAllMsgs(leanoteBase + '/messages/' + fromFilename); var msgs = {};
var toFilename = fromFilename + '.js'; fromFilenames.forEach(function (name) {
var tmpMsgs = getAllMsgs(leanoteBase + '/messages/' + lang + '/' + name + '.conf');
for (var i in tmpMsgs) {
msgs[i] = tmpMsgs[i];
}
});
var toMsgs = {}; var toMsgs = {};
for (var i in msgs) { for (var i in msgs) {
// 只要需要的 // 只要需要的
@@ -190,18 +273,27 @@ gulp.task('i18n', function() {
'}' + '}' +
'return key;' + 'return key;' +
'}'; '}';
// 写入到文件中 // 写入到文件中
var toFilename = targetFilename + '.' + lang + '.js';
fs.writeFile(base + '/js/i18n/' + toFilename, str); fs.writeFile(base + '/js/i18n/' + toFilename, str);
} }
genI18nJsFile('msg.zh', keys); function genTinymceLang(lang) {
genI18nJsFile('msg.en', keys); var msgs = getAllMsgs(leanoteBase + 'messages/' + lang + '/tinymce_editor.conf');
genI18nJsFile('msg.fr', keys); var str = 'tinymce.addI18n("' + lang + '",' + JSON.stringify(msgs) + ');';
genI18nJsFile('blog.zh', keys); fs.writeFile(base + '/tinymce/langs/' + lang + '.js', str);
genI18nJsFile('blog.en', keys); }
genI18nJsFile('blog.fr', keys);
});
var langs = getAllLangs();
for (var lang in langs) {
genI18nJsFile('blog', lang, ['blog'], keys);
genI18nJsFile('msg', lang, ['msg', 'member', 'markdown', 'album'], keys);
genTinymceLang(lang);
}
});
// 合并album需要的js // 合并album需要的js
gulp.task('concatAlbumJs', function() { gulp.task('concatAlbumJs', function() {
@@ -236,75 +328,6 @@ gulp.task('concatAlbumJs', function() {
.pipe(gulp.dest(base + '/album/js')); .pipe(gulp.dest(base + '/album/js'));
}); });
// plugins压缩
gulp.task('plugins', function() {
gulp.src(base + '/js/plugins/libs/*.js')
.pipe(uglify()) // 压缩
// .pipe(concat('main.min.js'))
.pipe(gulp.dest(base + '/js/plugins/libs-min'));
// 所有js合并成一个
var jss = [
'note_info',
'tips',
'history',
'attachment_upload',
'editor_drop_paste',
'main'
];
for(var i in jss) {
jss[i] = base + '/js/plugins/' + jss[i] + '.js';
}
gulp.src(jss)
.pipe(uglify()) // 压缩
.pipe(concat('main.min.js'))
.pipe(gulp.dest(base + '/js/plugins'));
});
// mincss
var minifycss = require('gulp-minify-css');
gulp.task('minifycss', function() {
gulp.src(base + '/css/bootstrap.css')
.pipe(rename({suffix: '-min'}))
.pipe(minifycss())
.pipe(gulp.dest(base + '/css'));
gulp.src(base + '/css/font-awesome-4.2.0/css/font-awesome.css')
.pipe(rename({suffix: '-min'}))
.pipe(minifycss())
.pipe(gulp.dest(base + '/css/font-awesome-4.2.0/css'));
gulp.src(base + '/css/zTreeStyle/zTreeStyle.css')
.pipe(rename({suffix: '-min'}))
.pipe(minifycss())
.pipe(gulp.dest(base + '/css/zTreeStyle'));
gulp.src(base + '/dist/themes/default.css')
.pipe(rename({suffix: '-min'}))
.pipe(minifycss())
.pipe(gulp.dest(base + '/dist/themes'));
gulp.src(base + '/js/contextmenu/css/contextmenu.css')
.pipe(rename({suffix: '-min'}))
.pipe(minifycss())
.pipe(gulp.dest(base + '/js/contextmenu/css'));
// theme
// 用codekit
var as = ['default', 'simple', 'writting', /*'writting-overwrite', */ 'mobile'];
/*
for(var i = 0; i < as.length; ++i) {
gulp.src(base + '/css/theme/' + as[i] + '.css')
.pipe(minifycss())
.pipe(gulp.dest(base + '/css/theme'));
}
*/
});
// tinymce // tinymce
// please set the right path on your own env // please set the right path on your own env
var tinymceBase = '/Users/life/leanote/leanote-tools/tinymce_4.1.9_leanote_public'; var tinymceBase = '/Users/life/leanote/leanote-tools/tinymce_4.1.9_leanote_public';
@@ -340,6 +363,47 @@ gulp.task('concatCss', function() {
.pipe(gulp.dest(markdownMin)); .pipe(gulp.dest(markdownMin));
}); });
gulp.task('concat', ['concatDepJs', 'concatAppJs', 'concatMarkdownJs']); // mincss
var minifycss = require('gulp-minify-css');
gulp.task('minifycss', function() {
gulp.src(base + '/css/bootstrap.css')
.pipe(rename({suffix: '-min'}))
.pipe(minifycss())
.pipe(gulp.dest(base + '/css'));
gulp.src(base + '/css/font-awesome-4.2.0/css/font-awesome.css')
.pipe(rename({suffix: '-min'}))
.pipe(minifycss())
.pipe(gulp.dest(base + '/css/font-awesome-4.2.0/css'));
gulp.src(base + '/css/zTreeStyle/zTreeStyle.css')
.pipe(rename({suffix: '-min'}))
.pipe(minifycss())
.pipe(gulp.dest(base + '/css/zTreeStyle'));
gulp.src(base + '/md/themes/default.css')
.pipe(rename({suffix: '-min'}))
.pipe(minifycss())
.pipe(gulp.dest(base + '/md/themes'));
gulp.src(base + '/js/contextmenu/css/contextmenu.css')
.pipe(rename({suffix: '-min'}))
.pipe(minifycss())
.pipe(gulp.dest(base + '/js/contextmenu/css'));
// theme
// 用codekit
var as = ['default', 'simple', 'writting', /*'writting-overwrite', */ 'mobile'];
/*
for(var i = 0; i < as.length; ++i) {
gulp.src(base + '/css/theme/' + as[i] + '.css')
.pipe(minifycss())
.pipe(gulp.dest(base + '/css/theme'));
}
*/
});
gulp.task('concat', ['concatDepJs', 'concatAppJs', /* 'concatMarkdownJs', */'concatMarkdownJsV2']);
gulp.task('html', ['devToProHtml']); gulp.task('html', ['devToProHtml']);
gulp.task('default', ['concat', 'plugins', 'minifycss', 'i18n', 'concatAlbumJs', 'html']); gulp.task('default', ['concat', 'plugins', 'minifycss', 'i18n', 'concatAlbumJs', 'html']);
+9 -11
View File
@@ -1,7 +1,7 @@
# Leanote # Leanote
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/leanote/leanote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Build Status](https://travis-ci.org/leanote/leanote.svg)](https://travis-ci.org/leanote/leanote) [![Build Status](https://travis-ci.org/leanote/leanote.svg)](https://travis-ci.org/leanote/leanote)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/leanote/leanote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
## 1. Introduction ## 1. Introduction
@@ -40,18 +40,16 @@ Welcome to sign up on https://leanote.com, Leanote team provide a stable and rel
More information about how to install Leanote please see: More information about how to install Leanote please see:
* [Leanote binary distribution installation tutorial](https://github.com/leanote/leanote/wiki/leanote-binary-distribution-installation-tutorial) * [Leanote binary installation tutorial](https://github.com/leanote/leanote/wiki/leanote-binary-distribution-installation-tutorial)
* [Leanote develop distribution installation tutorial](https://github.com/leanote/leanote/wiki/leanote-develop-distribution-installation-tutorial) * [Leanote source installation tutorial](https://github.com/leanote/leanote/wiki/leanote-source-installation-tutorial)
## 4. How to develop Leanote ## 4. How to develop Leanote
Please see [How-to-develop-leanote](https://github.com/leanote/leanote/wiki/How-to-develop-leanote-%E5%A6%82%E4%BD%95%E5%BC%80%E5%8F%91leanote) Please see [How-to-develop-leanote](https://github.com/leanote/leanote/wiki/How-to-develop-leanote-%E5%A6%82%E4%BD%95%E5%BC%80%E5%8F%91leanote)
## 5. Docs ## 5. Docs
* [Leanote binary distribution installation tutorial](https://github.com/leanote/leanote/wiki/leanote-binary-distribution-installation-tutorial)
* [Leanote develop distribution installation tutorial](https://github.com/leanote/leanote/wiki/leanote-develop-distribution-installation-tutorial)
More docs please see [wiki](https://github.com/leanote/leanote/wiki). Please see [wiki](https://github.com/leanote/leanote/wiki).
## 6. Contributors ## 6. Contributors
Thank you to all the [contributors](https://github.com/leanote/leanote/graphs/contributors) on Thank you to all the [contributors](https://github.com/leanote/leanote/graphs/contributors) on
@@ -74,14 +72,14 @@ Support us, [donate us](http://leanote.org/#donate). And thanks [donators](http:
* [Leanote iOS](https://github.com/leanote/leanote-ios), [Download From App Store](https://itunes.apple.com/en/app/leanote/id1022302858?mt=8) * [Leanote iOS](https://github.com/leanote/leanote-ios), [Download From App Store](https://itunes.apple.com/en/app/leanote/id1022302858?mt=8)
* [Leanote Android](https://github.com/leanote/leanote-android), development phase * [Leanote Android](https://github.com/leanote/leanote-android), development phase
Yare are welcome to join us. You are welcome to join us.
## 9. Support & Join us ## 9. Support & Join us
* Email: leanote@leanote.com * Email: leanote@leanote.com
* [Leanote BBS](http://bbs.leanote.com) * [Leanote BBS](http://bbs.leanote.com)
* [Leanote Google Group](https://groups.google.com/forum/#!forum/leanote) * [Leanote Google Group](https://groups.google.com/forum/#!forum/leanote)
* QQ Group: 256076853, 158716820 * QQ Group: 326073529, 256076853, 158716820
----------------------------------------------------------------------- -----------------------------------------------------------------------
@@ -122,7 +120,7 @@ Leanote云笔记产品包括: Leanote Web & Server(即本仓库), 桌面客户
这里详细整理了Leanote二进版和Leanote开发版的安装教程, 请移步至: 这里详细整理了Leanote二进版和Leanote开发版的安装教程, 请移步至:
* [Leanote二进制详细安装教程](https://github.com/leanote/leanote/wiki/leanote%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%89%88%E8%AF%A6%E7%BB%86%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B) * [Leanote二进制详细安装教程](https://github.com/leanote/leanote/wiki/leanote%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%89%88%E8%AF%A6%E7%BB%86%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B)
* [Leanote开发版详细安装教程](https://github.com/leanote/leanote/wiki/leanote%E5%BC%80%E5%8F%91%E7%89%88%E8%AF%A6%E7%BB%86%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B) * [Leanote源码详细安装教程](https://github.com/leanote/leanote/wiki/leanote%E5%BC%80%E5%8F%91%E7%89%88%E8%AF%A6%E7%BB%86%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B)
## 4. 如何对Leanote进行二次开发 ## 4. 如何对Leanote进行二次开发
@@ -130,7 +128,7 @@ Leanote云笔记产品包括: Leanote Web & Server(即本仓库), 桌面客户
## 5 相关文档 ## 5 相关文档
* [Leanote二进制版详细安装教程](https://github.com/leanote/leanote/wiki/leanote%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%89%88%E8%AF%A6%E7%BB%86%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B) * [Leanote二进制版详细安装教程](https://github.com/leanote/leanote/wiki/leanote%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%89%88%E8%AF%A6%E7%BB%86%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B)
* [Leanote开发版详细安装教程](https://github.com/leanote/leanote/wiki/leanote%E5%BC%80%E5%8F%91%E7%89%88%E8%AF%A6%E7%BB%86%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B) * [Leanote源码详细安装教程](https://github.com/leanote/leanote/wiki/leanote%E5%BC%80%E5%8F%91%E7%89%88%E8%AF%A6%E7%BB%86%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B)
* [Leanote source Leanote源码导读](https://github.com/leanote/leanote/wiki/Leanote-source-leanote源码导读) * [Leanote source Leanote源码导读](https://github.com/leanote/leanote/wiki/Leanote-source-leanote源码导读)
* [Leanote blog theme api(中文版)](https://github.com/leanote/leanote/wiki/leanote-blog-theme-api) * [Leanote blog theme api(中文版)](https://github.com/leanote/leanote/wiki/leanote-blog-theme-api)
* [How to develop leanote 如何开发Leanote](https://github.com/leanote/leanote/wiki/How-to-develop-leanote-如何开发leanote) * [How to develop leanote 如何开发Leanote](https://github.com/leanote/leanote/wiki/How-to-develop-leanote-如何开发leanote)
@@ -162,6 +160,6 @@ Leanote还有很多问题, 如果你喜欢它, 欢迎加入我们一起完善Lea
## 联系&加入我们 ## 联系&加入我们
* Email: leanote@leanote.com * Email: leanote@leanote.com
* [Leanote 社区](http://bbs.leanote.com) * [Leanote 社区](http://bbs.leanote.com)
* QQ群: 256076853, 158716820(已满) * QQ群: 326073529, 256076853, 158716820
* [Leanote Google Group](https://groups.google.com/forum/#!forum/leanote) * [Leanote Google Group](https://groups.google.com/forum/#!forum/leanote)
+2 -2
View File
@@ -1,9 +1,9 @@
package main package main
import ( import (
"github.com/revel/revel"
"github.com/revel/cmd/harness"
"fmt" "fmt"
"github.com/revel/cmd/harness"
"github.com/revel/revel"
) )
func main() { func main() {
+1 -1
View File
@@ -16,7 +16,7 @@ type Album struct {
// 图片管理, iframe // 图片管理, iframe
func (c Album) Index() revel.Result { func (c Album) Index() revel.Result {
c.SetLocale(); c.SetLocale()
return c.RenderTemplate("album/index.html") return c.RenderTemplate("album/index.html")
} }
+24 -16
View File
@@ -3,17 +3,17 @@ package controllers
import ( import (
"github.com/revel/revel" "github.com/revel/revel"
// "encoding/json" // "encoding/json"
"gopkg.in/mgo.v2/bson" "archive/tar"
. "github.com/leanote/leanote/app/lea" "compress/gzip"
"fmt"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"strings" "strings"
"time" "time"
"io"
"fmt"
"archive/tar"
"compress/gzip"
) )
// 附件 // 附件
@@ -57,17 +57,19 @@ func (c Attach) uploadAttach(noteId string) (re info.Re) {
return re return re
} }
// > 5M? // > 5M?
maxFileSize := configService.GetUploadSize("uploadAttachSize"); maxFileSize := configService.GetUploadSize("uploadAttachSize")
if maxFileSize <= 0 { if maxFileSize <= 0 {
maxFileSize = 1000 maxFileSize = 1000
} }
if(float64(len(data)) > maxFileSize * float64(1024*1024)) { if float64(len(data)) > maxFileSize*float64(1024*1024) {
resultMsg = fmt.Sprintf("The file's size is bigger than %vM", maxFileSize) resultMsg = fmt.Sprintf("The file's size is bigger than %vM", maxFileSize)
return re return re
} }
// 生成上传路径 // 生成上传路径
filePath := "files/" + c.GetUserId() + "/attachs" // filePath := "files/" + c.GetUserId() + "/attachs"
newGuid := NewGuid()
filePath := "files/" + GetRandomFilePath(c.GetUserId(), newGuid) + "/attachs"
dir := revel.BasePath + "/" + filePath dir := revel.BasePath + "/" + filePath
err = os.MkdirAll(dir, 0755) err = os.MkdirAll(dir, 0755)
if err != nil { if err != nil {
@@ -76,8 +78,8 @@ func (c Attach) uploadAttach(noteId string) (re info.Re) {
// 生成新的文件名 // 生成新的文件名
filename := handel.Filename filename := handel.Filename
_, ext := SplitFilename(filename) // .doc _, ext := SplitFilename(filename) // .doc
filename = NewGuid() + ext filename = newGuid + ext
toPath := dir + "/" + filename; toPath := dir + "/" + filename
err = ioutil.WriteFile(toPath, data, 0777) err = ioutil.WriteFile(toPath, data, 0777)
if err != nil { if err != nil {
return re return re
@@ -97,7 +99,7 @@ func (c Attach) uploadAttach(noteId string) (re info.Re) {
Type: fileType, Type: fileType,
Size: filesize} Size: filesize}
id := bson.NewObjectId(); id := bson.NewObjectId()
fileInfo.AttachId = id fileInfo.AttachId = id
fileId = id.Hex() fileId = id.Hex()
Ok, resultMsg = attachService.AddAttach(fileInfo, false) Ok, resultMsg = attachService.AddAttach(fileInfo, false)
@@ -105,7 +107,7 @@ func (c Attach) uploadAttach(noteId string) (re info.Re) {
resultMsg = c.Message(resultMsg) resultMsg = c.Message(resultMsg)
} }
fileInfo.Path = ""; // 不要返回 fileInfo.Path = "" // 不要返回
if Ok { if Ok {
resultMsg = "success" resultMsg = "success"
} }
@@ -130,7 +132,7 @@ func (c Attach) GetAttachs(noteId string) revel.Result {
// 下载附件 // 下载附件
// 权限判断 // 权限判断
func (c Attach) Download(attachId string) revel.Result { func (c Attach) Download(attachId string) revel.Result {
attach := attachService.GetAttach(attachId, c.GetUserId()); // 得到路径 attach := attachService.GetAttach(attachId, c.GetUserId()) // 得到路径
path := attach.Path path := attach.Path
if path == "" { if path == "" {
return c.RenderText("") return c.RenderText("")
@@ -165,10 +167,16 @@ func (c Attach) DownloadAll(noteId string) revel.Result {
filename = "all.tar.gz" filename = "all.tar.gz"
} }
dir := revel.BasePath + "/files/attach_all"
if !MkdirAll(dir) {
return c.RenderText("error")
}
// file write // file write
fw, err := os.Create(revel.BasePath + "/files/" + filename) fw, err := os.Create(dir + "/" + filename)
if err != nil { if err != nil {
return c.RenderText("") return c.RenderText("error")
} }
// defer fw.Close() // 不需要关闭, 还要读取给用户下载 // defer fw.Close() // 不需要关闭, 还要读取给用户下载
+15 -7
View File
@@ -1,9 +1,10 @@
package controllers package controllers
import ( import (
"github.com/revel/revel"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"github.com/revel/revel"
"strings"
// "strconv" // "strconv"
) )
@@ -75,6 +76,7 @@ func (c Auth) DoLogin(email, pwd string, captcha string) revel.Result {
return c.RenderJson(info.Re{Ok: false, Item: sessionService.LoginTimesIsOver(sessionId), Msg: c.Message(msg)}) return c.RenderJson(info.Re{Ok: false, Item: sessionService.LoginTimesIsOver(sessionId), Msg: c.Message(msg)})
} }
// 注销 // 注销
func (c Auth) Logout() revel.Result { func (c Auth) Logout() revel.Result {
sessionId := c.Session.Id() sessionId := c.Session.Id()
@@ -117,15 +119,17 @@ func (c Auth) DoRegister(email, pwd, iu string) revel.Result {
return c.Redirect("/index") return c.Redirect("/index")
} }
re := info.NewRe(); re := info.NewRe()
if re.Ok, re.Msg = Vd("email", email); !re.Ok { if re.Ok, re.Msg = Vd("email", email); !re.Ok {
return c.RenderRe(re); return c.RenderRe(re)
} }
if re.Ok, re.Msg = Vd("password", pwd); !re.Ok { if re.Ok, re.Msg = Vd("password", pwd); !re.Ok {
return c.RenderRe(re); return c.RenderRe(re)
} }
email = strings.ToLower(email)
// 注册 // 注册
re.Ok, re.Msg = authService.Register(email, pwd, iu) re.Ok, re.Msg = authService.Register(email, pwd, iu)
@@ -140,6 +144,7 @@ func (c Auth) DoRegister(email, pwd, iu string) revel.Result {
//-------- //--------
// 找回密码 // 找回密码
func (c Auth) FindPassword() revel.Result { func (c Auth) FindPassword() revel.Result {
c.SetLocale()
c.RenderArgs["title"] = c.Message("findPassword") c.RenderArgs["title"] = c.Message("findPassword")
c.RenderArgs["subTitle"] = c.Message("findPassword") c.RenderArgs["subTitle"] = c.Message("findPassword")
return c.RenderTemplate("home/find_password.html") return c.RenderTemplate("home/find_password.html")
@@ -150,14 +155,16 @@ func (c Auth) DoFindPassword(email string) revel.Result {
re.Ok = true re.Ok = true
return c.RenderJson(re) return c.RenderJson(re)
} }
// 点击链接后, 先验证之 // 点击链接后, 先验证之
func (c Auth) FindPassword2(token string) revel.Result { func (c Auth) FindPassword2(token string) revel.Result {
c.SetLocale()
c.RenderArgs["title"] = c.Message("findPassword") c.RenderArgs["title"] = c.Message("findPassword")
c.RenderArgs["subTitle"] = c.Message("findPassword") c.RenderArgs["subTitle"] = c.Message("findPassword")
if token == "" { if token == "" {
return c.RenderTemplate("find_password2_timeout.html") return c.RenderTemplate("find_password2_timeout.html")
} }
ok, _, findPwd := tokenService.VerifyToken(token, info.TokenPwd); ok, _, findPwd := tokenService.VerifyToken(token, info.TokenPwd)
if !ok { if !ok {
return c.RenderTemplate("home/find_password2_timeout.html") return c.RenderTemplate("home/find_password2_timeout.html")
} }
@@ -168,12 +175,13 @@ func (c Auth) FindPassword2(token string) revel.Result {
return c.RenderTemplate("home/find_password2.html") return c.RenderTemplate("home/find_password2.html")
} }
// 找回密码修改密码 // 找回密码修改密码
func (c Auth) FindPasswordUpdate(token, pwd string) revel.Result { func (c Auth) FindPasswordUpdate(token, pwd string) revel.Result {
re := info.NewRe(); re := info.NewRe()
if re.Ok, re.Msg = Vd("password", pwd); !re.Ok { if re.Ok, re.Msg = Vd("password", pwd); !re.Ok {
return c.RenderRe(re); return c.RenderRe(re)
} }
// 修改之 // 修改之
+29 -19
View File
@@ -1,17 +1,18 @@
package controllers package controllers
import ( import (
"github.com/revel/revel"
"gopkg.in/mgo.v2/bson"
"encoding/json" "encoding/json"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/lea/i18n"
"github.com/revel/revel"
"gopkg.in/mgo.v2/bson"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
// "io/ioutil" // "io/ioutil"
// "fmt" // "fmt"
"bytes"
"math" "math"
"strconv" "strconv"
"strings" "strings"
"bytes"
) )
// 公用Controller, 其它Controller继承它 // 公用Controller, 其它Controller继承它
@@ -19,6 +20,11 @@ type BaseController struct {
*revel.Controller *revel.Controller
} }
// 覆盖revel.Message
func (c *BaseController) Message(message string, args ...interface{}) (value string) {
return i18n.Message(c.Request.Locale, message, args...)
}
func (c BaseController) GetUserId() string { func (c BaseController) GetUserId() string {
if userId, ok := c.Session["UserId"]; ok { if userId, ok := c.Session["UserId"]; ok {
return userId return userId
@@ -56,7 +62,7 @@ func (c BaseController) GetUsername() string {
// 得到用户信息 // 得到用户信息
func (c BaseController) GetUserInfo() info.User { func (c BaseController) GetUserInfo() info.User {
if userId, ok := c.Session["UserId"]; ok && userId != "" { if userId, ok := c.Session["UserId"]; ok && userId != "" {
return userService.GetUserInfo(userId); return userService.GetUserInfo(userId)
/* /*
notebookWidth, _ := strconv.Atoi(c.Session["NotebookWidth"]) notebookWidth, _ := strconv.Atoi(c.Session["NotebookWidth"])
noteListWidth, _ := strconv.Atoi(c.Session["NoteListWidth"]) noteListWidth, _ := strconv.Atoi(c.Session["NoteListWidth"])
@@ -86,7 +92,7 @@ func (c BaseController) GetUserInfo() info.User {
func (c BaseController) GetUserAndBlogUrl() info.UserAndBlogUrl { func (c BaseController) GetUserAndBlogUrl() info.UserAndBlogUrl {
if userId, ok := c.Session["UserId"]; ok && userId != "" { if userId, ok := c.Session["UserId"]; ok && userId != "" {
return userService.GetUserAndBlogUrl(userId); return userService.GetUserAndBlogUrl(userId)
} }
return info.UserAndBlogUrl{} return info.UserAndBlogUrl{}
} }
@@ -157,9 +163,9 @@ func (c BaseController) GetPage() int {
// 判断是否含有某参数 // 判断是否含有某参数
func (c BaseController) Has(key string) bool { func (c BaseController) Has(key string) bool {
if _, ok := c.Params.Values[key]; ok { if _, ok := c.Params.Values[key]; ok {
return true; return true
} }
return false; return false
} }
/* /*
@@ -174,23 +180,27 @@ func (c BaseController) GetTotalPage(page, count int) int {
//------------- //-------------
func (c BaseController) E404() revel.Result { func (c BaseController) E404() revel.Result {
c.RenderArgs["title"] = "404"; c.RenderArgs["title"] = "404"
return c.NotFound("", nil) return c.NotFound("", nil)
} }
// 设置本地 // 设置本地
func (c BaseController) SetLocale() string { func (c BaseController) SetLocale() string {
locale := string(c.Request.Locale) // zh-CN locale := string(c.Request.Locale) // zh-CN
// lang := locale
// if strings.Contains(locale, "-") {
// pos := strings.Index(locale, "-")
// lang = locale[0:pos]
// }
// if lang != "zh" && lang != "en" {
// lang = "en"
// }
lang := locale lang := locale
if strings.Contains(locale, "-") { if !i18n.HasLang(locale) {
pos := strings.Index(locale, "-") lang = i18n.GetDefaultLang()
lang = locale[0:pos]
} }
if lang != "zh" && lang != "en" { c.RenderArgs["locale"] = lang
lang = "en"; c.RenderArgs["siteUrl"] = configService.GetSiteUrl()
}
c.RenderArgs["locale"] = lang;
c.RenderArgs["siteUrl"] = configService.GetSiteUrl();
c.RenderArgs["blogUrl"] = configService.GetBlogUrl() c.RenderArgs["blogUrl"] = configService.GetBlogUrl()
c.RenderArgs["leaUrl"] = configService.GetLeaUrl() c.RenderArgs["leaUrl"] = configService.GetLeaUrl()
@@ -203,7 +213,7 @@ func (c BaseController) SetLocale() string {
func (c BaseController) SetUserInfo() info.User { func (c BaseController) SetUserInfo() info.User {
userInfo := c.GetUserInfo() userInfo := c.GetUserInfo()
c.RenderArgs["userInfo"] = userInfo c.RenderArgs["userInfo"] = userInfo
if(userInfo.Username == configService.GetAdminUsername()) { if userInfo.Username == configService.GetAdminUsername() {
c.RenderArgs["isAdmin"] = true c.RenderArgs["isAdmin"] = true
} }
return userInfo return userInfo
@@ -225,7 +235,7 @@ func (c BaseController) RenderTemplateStr(templatePath string) string {
var buffer bytes.Buffer var buffer bytes.Buffer
tpl.Template.Render(&buffer, c.RenderArgs) tpl.Template.Render(&buffer, c.RenderArgs)
return buffer.String(); return buffer.String()
} }
// json, result // json, result
@@ -234,7 +244,7 @@ func (c BaseController) RenderTemplateStr(templatePath string) string {
func (c BaseController) RenderRe(re info.Re) revel.Result { func (c BaseController) RenderRe(re info.Re) revel.Result {
oldMsg := re.Msg oldMsg := re.Msg
if re.Msg != "" { if re.Msg != "" {
if(strings.Contains(re.Msg, "-")) { if strings.Contains(re.Msg, "-") {
msgAndValues := strings.Split(re.Msg, "-") msgAndValues := strings.Split(re.Msg, "-")
if len(msgAndValues) == 2 { if len(msgAndValues) == 2 {
re.Msg = c.Message(msgAndValues[0], msgAndValues[1]) re.Msg = c.Message(msgAndValues[0], msgAndValues[1])
+15 -14
View File
@@ -59,7 +59,7 @@ func (c Blog) render(templateName string, themePath string) revel.Result {
c.setPreviewUrl() c.setPreviewUrl()
// 因为common的themeInfo是从UserBlog.ThemeId来取的, 所以这里要fugai下 // 因为common的themeInfo是从UserBlog.ThemeId来取的, 所以这里要fugai下
c.RenderArgs["themeInfo"] = c.RenderArgs["themeInfoPreview"]; c.RenderArgs["themeInfo"] = c.RenderArgs["themeInfoPreview"]
} }
return blog.RenderTemplate(templateName, c.RenderArgs, revel.BasePath+"/"+themePath, isPreview) return blog.RenderTemplate(templateName, c.RenderArgs, revel.BasePath+"/"+themePath, isPreview)
} }
@@ -113,8 +113,8 @@ func (c Blog) setPreviewUrl() {
themeId := c.Session["themeId"] themeId := c.Session["themeId"]
theme := themeService.GetTheme(userId, themeId) theme := themeService.GetTheme(userId, themeId)
siteUrl := configService.GetSiteUrl() // siteUrl := configService.GetSiteUrl()
blogUrl := siteUrl + "/preview" // blog.leanote.com blogUrl := "/preview" // blog.leanote.com
indexUrl = blogUrl + "/" + userIdOrEmail indexUrl = blogUrl + "/" + userIdOrEmail
cateUrl = blogUrl + "/cate/" + userIdOrEmail // /notebookId cateUrl = blogUrl + "/cate/" + userIdOrEmail // /notebookId
@@ -143,8 +143,8 @@ func (c Blog) setPreviewUrl() {
// 各种地址设置 // 各种地址设置
func (c Blog) setUrl(userBlog info.UserBlog, userInfo info.User) { func (c Blog) setUrl(userBlog info.UserBlog, userInfo info.User) {
// 主页 http://leanote.com/blog/life or http://blog.leanote.com/life or http:// xxxx.leanote.com or aa.com // 主页 http://leanote.com/blog/life or http://blog.leanote.com/life or http:// xxxx.leanote.com or aa.com
host := c.Request.Request.Host // host := c.Request.Request.Host
var staticUrl = configService.GetUserUrl(strings.Split(host, ":")[0]) // var staticUrl = configService.GetUserUrl(strings.Split(host, ":")[0])
// staticUrl == host, 为保证同源!!! 只有host, http://leanote.com, http://blog/leanote.com // staticUrl == host, 为保证同源!!! 只有host, http://leanote.com, http://blog/leanote.com
// life.leanote.com, lealife.com // life.leanote.com, lealife.com
siteUrl := configService.GetSiteUrl() siteUrl := configService.GetSiteUrl()
@@ -168,20 +168,20 @@ func (c Blog) setUrl(userBlog info.UserBlog, userInfo info.User) {
c.RenderArgs["themeBaseUrl"] = "/" + userBlog.ThemePath c.RenderArgs["themeBaseUrl"] = "/" + userBlog.ThemePath
// 其它static js // 其它static js
c.RenderArgs["jQueryUrl"] = siteUrl + "/js/jquery-1.9.0.min.js" c.RenderArgs["jQueryUrl"] = "/js/jquery-1.9.0.min.js"
c.RenderArgs["prettifyJsUrl"] = siteUrl + "/js/google-code-prettify/prettify.js" c.RenderArgs["prettifyJsUrl"] = "/js/google-code-prettify/prettify.js"
c.RenderArgs["prettifyCssUrl"] = siteUrl + "/js/google-code-prettify/prettify.css" c.RenderArgs["prettifyCssUrl"] = "/js/google-code-prettify/prettify.css"
c.RenderArgs["blogCommonJsUrl"] = siteUrl + "/public/blog/js/common.js" c.RenderArgs["blogCommonJsUrl"] = "/public/blog/js/common.js"
c.RenderArgs["shareCommentCssUrl"] = siteUrl + "/public/blog/css/share_comment.css" c.RenderArgs["shareCommentCssUrl"] = "/public/blog/css/share_comment.css"
c.RenderArgs["shareCommentJsUrl"] = siteUrl + "/public/blog/js/share_comment.js" c.RenderArgs["shareCommentJsUrl"] = "/public/blog/js/share_comment.js"
c.RenderArgs["fontAwesomeUrl"] = staticUrl + "/css/font-awesome-4.2.0/css/font-awesome.css" c.RenderArgs["fontAwesomeUrl"] = "/css/font-awesome-4.2.0/css/font-awesome.css"
c.RenderArgs["bootstrapCssUrl"] = siteUrl + "/css/bootstrap.css" c.RenderArgs["bootstrapCssUrl"] = "/css/bootstrap.css"
c.RenderArgs["bootstrapJsUrl"] = siteUrl + "/js/bootstrap-min.js" c.RenderArgs["bootstrapJsUrl"] = "/js/bootstrap-min.js"
} }
// 笔记本分类 // 笔记本分类
@@ -507,6 +507,7 @@ func (c Blog) Archives(userIdOrEmail string, cateId string, year, month int) (re
// 进入某个用户的博客 // 进入某个用户的博客
var blogPageSize = 5 var blogPageSize = 5
var searchBlogPageSize = 30 var searchBlogPageSize = 30
// 分类 /cate/xxxxxxxx?notebookId=1212 // 分类 /cate/xxxxxxxx?notebookId=1212
func (c Blog) Cate(userIdOrEmail string, notebookId string) (re revel.Result) { func (c Blog) Cate(userIdOrEmail string, notebookId string) (re revel.Result) {
// 自定义域名 // 自定义域名
+1
View File
@@ -22,6 +22,7 @@ type Captcha struct {
} }
type Ca string type Ca string
func (r Ca) Apply(req *revel.Request, resp *revel.Response) { func (r Ca) Apply(req *revel.Request, resp *revel.Response) {
resp.WriteHeader(http.StatusOK, "image/png") resp.WriteHeader(http.StatusOK, "image/png")
} }
+17 -12
View File
@@ -3,13 +3,13 @@ package controllers
import ( import (
"github.com/revel/revel" "github.com/revel/revel"
// "encoding/json" // "encoding/json"
"gopkg.in/mgo.v2/bson" "fmt"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/lea/netutil" "github.com/leanote/leanote/app/lea/netutil"
"github.com/leanote/leanote/app/info" "gopkg.in/mgo.v2/bson"
"io/ioutil" "io/ioutil"
"os" "os"
"fmt"
// "strconv" // "strconv"
"strings" "strings"
) )
@@ -22,7 +22,7 @@ type File struct {
// 上传的是博客logo // 上传的是博客logo
// TODO logo不要设置权限, 另外的目录 // TODO logo不要设置权限, 另外的目录
func (c File) UploadBlogLogo() revel.Result { func (c File) UploadBlogLogo() revel.Result {
re := c.uploadImage("blogLogo", ""); re := c.uploadImage("blogLogo", "")
c.RenderArgs["fileUrlPath"] = re.Id c.RenderArgs["fileUrlPath"] = re.Id
c.RenderArgs["resultCode"] = re.Code c.RenderArgs["resultCode"] = re.Code
@@ -34,8 +34,9 @@ func (c File) UploadBlogLogo() revel.Result {
// 拖拉上传, pasteImage // 拖拉上传, pasteImage
// noteId 是为了判断是否是协作的note, 如果是则需要复制一份到note owner中 // noteId 是为了判断是否是协作的note, 如果是则需要复制一份到note owner中
func (c File) PasteImage(noteId string) revel.Result { func (c File) PasteImage(noteId string) revel.Result {
re := c.uploadImage("pasteImage", ""); re := c.uploadImage("pasteImage", "")
if noteId != "" {
userId := c.GetUserId() userId := c.GetUserId()
note := noteService.GetNoteById(noteId) note := noteService.GetNoteById(noteId)
if note.UserId != "" { if note.UserId != "" {
@@ -51,13 +52,14 @@ func (c File) PasteImage(noteId string) revel.Result {
} }
} }
} }
}
return c.RenderJson(re) return c.RenderJson(re)
} }
// 头像设置 // 头像设置
func (c File) UploadAvatar() revel.Result { func (c File) UploadAvatar() revel.Result {
re := c.uploadImage("logo", ""); re := c.uploadImage("logo", "")
c.RenderArgs["fileUrlPath"] = re.Id c.RenderArgs["fileUrlPath"] = re.Id
c.RenderArgs["resultCode"] = re.Code c.RenderArgs["resultCode"] = re.Code
@@ -66,7 +68,7 @@ func (c File) UploadAvatar() revel.Result {
if re.Ok { if re.Ok {
re.Ok = userService.UpdateAvatar(c.GetUserId(), re.Id) re.Ok = userService.UpdateAvatar(c.GetUserId(), re.Id)
if re.Ok { if re.Ok {
c.UpdateSession("Logo", re.Id); c.UpdateSession("Logo", re.Id)
} }
} }
@@ -106,10 +108,11 @@ func (c File) uploadImage(from, albumId string) (re info.Re) {
userId := c.GetUserId() userId := c.GetUserId()
if(from == "logo" || from == "blogLogo") { if from == "logo" || from == "blogLogo" {
fileUrlPath = "public/upload/" + Digest3(userId) + "/" + userId + "/images/logo" fileUrlPath = "public/upload/" + Digest3(userId) + "/" + userId + "/images/logo"
} else { } else {
fileUrlPath = "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/images" // fileUrlPath = "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/images"
fileUrlPath = "files/" + GetRandomFilePath(userId, newGuid) + "/images"
} }
dir := revel.BasePath + "/" + fileUrlPath dir := revel.BasePath + "/" + fileUrlPath
@@ -122,6 +125,7 @@ func (c File) uploadImage(from, albumId string) (re info.Re) {
var ext string var ext string
if from == "pasteImage" { if from == "pasteImage" {
handel.Filename = c.Message("unTitled")
ext = ".png" // TODO 可能不是png类型 ext = ".png" // TODO 可能不是png类型
} else { } else {
_, ext = SplitFilename(filename) _, ext = SplitFilename(filename)
@@ -181,7 +185,7 @@ func (c File) uploadImage(from, albumId string) (re info.Re) {
fileInfo.FileId = id fileInfo.FileId = id
fileId = id.Hex() fileId = id.Hex()
if(from == "logo" || from == "blogLogo") { if from == "logo" || from == "blogLogo" {
fileId = fileUrlPath fileId = fileUrlPath
} }
@@ -217,7 +221,7 @@ func (c File) DeleteImage(fileId string) revel.Result {
// 输出image // 输出image
// 权限判断 // 权限判断
func (c File) OutputImage(noteId, fileId string) revel.Result { func (c File) OutputImage(noteId, fileId string) revel.Result {
path := fileService.GetFile(c.GetUserId(), fileId); // 得到路径 path := fileService.GetFile(c.GetUserId(), fileId) // 得到路径
if path == "" { if path == "" {
return c.RenderText("") return c.RenderText("")
} }
@@ -242,7 +246,8 @@ func (c File) CopyHttpImage(src string) revel.Result {
// 生成上传路径 // 生成上传路径
newGuid := NewGuid() newGuid := NewGuid()
userId := c.GetUserId() userId := c.GetUserId()
fileUrlPath := "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/images" // fileUrlPath := "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/images"
fileUrlPath := "files/" + GetRandomFilePath(userId, newGuid) + "/images"
dir := revel.BasePath + "/" + fileUrlPath dir := revel.BasePath + "/" + fileUrlPath
err := os.MkdirAll(dir, 0755) err := os.MkdirAll(dir, 0755)
if err != nil { if err != nil {
+5 -4
View File
@@ -1,8 +1,8 @@
package controllers package controllers
import ( import (
"github.com/revel/revel"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"github.com/revel/revel"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
) )
@@ -15,10 +15,11 @@ type Index struct {
func (c Index) Default() revel.Result { func (c Index) Default() revel.Result {
if configService.HomePageIsAdminsBlog() { if configService.HomePageIsAdminsBlog() {
blog := Blog{c.BaseController} blog := Blog{c.BaseController}
return blog.Index(configService.GetAdminUsername()); return blog.Index(configService.GetAdminUsername())
} }
return c.Index() return c.Index()
} }
// leanote展示页, 没有登录的, 或已登录明确要进该页的 // leanote展示页, 没有登录的, 或已登录明确要进该页的
func (c Index) Index() revel.Result { func (c Index) Index() revel.Result {
c.SetUserInfo() c.SetUserInfo()
@@ -26,7 +27,7 @@ func (c Index) Index() revel.Result {
c.RenderArgs["openRegister"] = configService.GlobalStringConfigs["openRegister"] c.RenderArgs["openRegister"] = configService.GlobalStringConfigs["openRegister"]
c.SetLocale() c.SetLocale()
return c.RenderTemplate("home/index.html"); return c.RenderTemplate("home/index.html")
} }
// 建议 // 建议
@@ -37,7 +38,7 @@ func (c Index) Suggestion(addr, suggestion string) revel.Result {
// 发给我 // 发给我
go func() { go func() {
emailService.SendEmail("leanote@leanote.com", "建议", "UserId: "+c.GetUserId()+" <br /> Suggestions: "+suggestion) emailService.SendEmail("leanote@leanote.com", "建议", "UserId: "+c.GetUserId()+" <br /> Suggestions: "+suggestion)
}(); }()
return c.RenderJson(re) return c.RenderJson(re)
} }
+22 -39
View File
@@ -11,9 +11,9 @@ import (
"regexp" "regexp"
"strings" "strings"
"time" "time"
"fmt"
// "github.com/leanote/leanote/app/types" // "github.com/leanote/leanote/app/types"
// "io/ioutil" // "io/ioutil"
"fmt"
// "bytes" // "bytes"
// "os" // "os"
) )
@@ -67,13 +67,13 @@ func (c Note) Index(noteId, online string) revel.Result {
// 不要获取notebook下的笔记 // 不要获取notebook下的笔记
// 在前端下发请求 // 在前端下发请求
c.RenderArgs["curSharedNoteNotebookId"] = note.NotebookId.Hex() c.RenderArgs["curSharedNoteNotebookId"] = note.NotebookId.Hex()
c.RenderArgs["curSharedUserId"] = noteOwner; c.RenderArgs["curSharedUserId"] = noteOwner
// 没有读写权限 // 没有读写权限
} else { } else {
hasRightNoteId = false hasRightNoteId = false
} }
} else { } else {
_, notes = noteService.ListNotes(c.GetUserId(), note.NotebookId.Hex(), false, c.GetPage(), 50, defaultSortField, false, false); _, notes = noteService.ListNotes(c.GetUserId(), note.NotebookId.Hex(), false, c.GetPage(), 50, defaultSortField, false, false)
// 如果指定了某笔记, 则该笔记放在首位 // 如果指定了某笔记, 则该笔记放在首位
lenNotes := len(notes) lenNotes := len(notes)
@@ -84,7 +84,7 @@ func (c Note) Index(noteId, online string) revel.Result {
for _, note := range notes { for _, note := range notes {
if note.NoteId.Hex() != noteId { if note.NoteId.Hex() != noteId {
if i == lenNotes { // 防止越界 if i == lenNotes { // 防止越界
break; break
} }
notes2[i] = note notes2[i] = note
i++ i++
@@ -96,14 +96,14 @@ func (c Note) Index(noteId, online string) revel.Result {
} }
// 得到最近的笔记 // 得到最近的笔记
_, latestNotes := noteService.ListNotes(c.GetUserId(), "", false, c.GetPage(), 50, defaultSortField, false, false); _, latestNotes := noteService.ListNotes(c.GetUserId(), "", false, c.GetPage(), 50, defaultSortField, false, false)
c.RenderArgs["latestNotes"] = latestNotes c.RenderArgs["latestNotes"] = latestNotes
} }
// 没有传入笔记 // 没有传入笔记
// 那么得到最新笔记 // 那么得到最新笔记
if !hasRightNoteId { if !hasRightNoteId {
_, notes = noteService.ListNotes(c.GetUserId(), "", false, c.GetPage(), 50, defaultSortField, false, false); _, notes = noteService.ListNotes(c.GetUserId(), "", false, c.GetPage(), 50, defaultSortField, false, false)
if len(notes) > 0 { if len(notes) > 0 {
noteContent = noteService.GetNoteContent(notes[0].NoteId.Hex(), userId) noteContent = noteService.GetNoteContent(notes[0].NoteId.Hex(), userId)
c.RenderArgs["curNoteId"] = notes[0].NoteId.Hex() c.RenderArgs["curNoteId"] = notes[0].NoteId.Hex()
@@ -162,29 +162,11 @@ func (c Note) GetNoteContent(noteId string) revel.Result {
return c.RenderJson(noteContent) return c.RenderJson(noteContent)
} }
// 更新note或content
// 肯定会传userId(谁的), NoteId
// 会传Title, Content, Tags, 一种或几种
type NoteOrContent struct {
NotebookId string
NoteId string
UserId string
Title string
Desc string
ImgSrc string
Tags string
Content string
Abstract string
IsNew bool
IsMarkdown bool
FromUserId string // 为共享而新建
IsBlog bool // 是否是blog, 更新note不需要修改, 添加note时才有可能用到, 此时需要判断notebook是否设为Blog
}
// 这里不能用json, 要用post // 这里不能用json, 要用post
func (c Note) UpdateNoteOrContent(noteOrContent NoteOrContent) revel.Result { func (c Note) UpdateNoteOrContent(noteOrContent info.NoteOrContent) revel.Result {
// 新添加note // 新添加note
if noteOrContent.IsNew { if noteOrContent.IsNew {
userId := c.GetObjectUserId(); userId := c.GetObjectUserId()
// myUserId := userId // myUserId := userId
// 为共享新建? // 为共享新建?
if noteOrContent.FromUserId != "" { if noteOrContent.FromUserId != "" {
@@ -200,12 +182,12 @@ func (c Note) UpdateNoteOrContent(noteOrContent NoteOrContent) revel.Result {
ImgSrc: noteOrContent.ImgSrc, ImgSrc: noteOrContent.ImgSrc,
IsBlog: noteOrContent.IsBlog, IsBlog: noteOrContent.IsBlog,
IsMarkdown: noteOrContent.IsMarkdown, IsMarkdown: noteOrContent.IsMarkdown,
}; }
noteContent := info.NoteContent{NoteId: note.NoteId, noteContent := info.NoteContent{NoteId: note.NoteId,
UserId: userId, UserId: userId,
IsBlog: note.IsBlog, IsBlog: note.IsBlog,
Content: noteOrContent.Content, Content: noteOrContent.Content,
Abstract: noteOrContent.Abstract}; Abstract: noteOrContent.Abstract}
note = noteService.AddNoteAndContentForController(note, noteContent, c.GetUserId()) note = noteService.AddNoteAndContentForController(note, noteContent, c.GetUserId())
return c.RenderJson(note) return c.RenderJson(note)
@@ -217,20 +199,20 @@ func (c Note) UpdateNoteOrContent(noteOrContent NoteOrContent) revel.Result {
// Desc前台传来 // Desc前台传来
if c.Has("Desc") { if c.Has("Desc") {
needUpdateNote = true needUpdateNote = true
noteUpdate["Desc"] = noteOrContent.Desc; noteUpdate["Desc"] = noteOrContent.Desc
} }
if c.Has("ImgSrc") { if c.Has("ImgSrc") {
needUpdateNote = true needUpdateNote = true
noteUpdate["ImgSrc"] = noteOrContent.ImgSrc; noteUpdate["ImgSrc"] = noteOrContent.ImgSrc
} }
if c.Has("Title") { if c.Has("Title") {
needUpdateNote = true needUpdateNote = true
noteUpdate["Title"] = noteOrContent.Title; noteUpdate["Title"] = noteOrContent.Title
} }
if c.Has("Tags") { if c.Has("Tags") {
needUpdateNote = true needUpdateNote = true
noteUpdate["Tags"] = strings.Split(noteOrContent.Tags, ","); noteUpdate["Tags"] = strings.Split(noteOrContent.Tags, ",")
} }
// web端不控制 // web端不控制
@@ -247,7 +229,8 @@ func (c Note) UpdateNoteOrContent(noteOrContent NoteOrContent) revel.Result {
// noteService.UpdateNoteContent(noteOrContent.UserId, c.GetUserId(), // noteService.UpdateNoteContent(noteOrContent.UserId, c.GetUserId(),
// noteOrContent.NoteId, noteOrContent.Content, noteOrContent.Abstract) // noteOrContent.NoteId, noteOrContent.Content, noteOrContent.Abstract)
contentOk, contentMsg, afterContentUsn = noteService.UpdateNoteContent(c.GetUserId(), contentOk, contentMsg, afterContentUsn = noteService.UpdateNoteContent(c.GetUserId(),
noteOrContent.NoteId, noteOrContent.Content, noteOrContent.Abstract, needUpdateNote, -1) noteOrContent.NoteId, noteOrContent.Content, noteOrContent.Abstract,
needUpdateNote, -1, time.Now())
} }
Log(afterContentUsn) Log(afterContentUsn)
@@ -333,11 +316,11 @@ func (c Note) ToPdf(noteId, appKey string) revel.Result {
// 虽然传了cookie但是这里还是不能得到userId, 所以还是通过appKey来验证之 // 虽然传了cookie但是这里还是不能得到userId, 所以还是通过appKey来验证之
appKeyTrue, _ := revel.Config.String("app.secret") appKeyTrue, _ := revel.Config.String("app.secret")
if appKeyTrue != appKey { if appKeyTrue != appKey {
return c.RenderText("error") return c.RenderText("auth error")
} }
note := noteService.GetNoteById(noteId) note := noteService.GetNoteById(noteId)
if note.NoteId == "" { if note.NoteId == "" {
return c.RenderText("error") return c.RenderText("no note")
} }
noteUserId := note.UserId.Hex() noteUserId := note.UserId.Hex()
@@ -426,13 +409,13 @@ func (c Note) ExportPdf(noteId string) revel.Result {
// 是否是有权限协作的 // 是否是有权限协作的
if !note.IsBlog && !shareService.HasReadPerm(noteUserId, userId, noteId) { if !note.IsBlog && !shareService.HasReadPerm(noteUserId, userId, noteId) {
re.Msg = "No Perm" re.Msg = "No Perm"
return c.RenderText("error") return c.RenderText("No Perm")
} }
} }
// path 判断是否需要重新生成之 // path 判断是否需要重新生成之
guid := NewGuid() guid := NewGuid()
fileUrlPath := "files/" + Digest3(noteUserId) + "/" + noteUserId + "/" + Digest2(guid) + "/images/pdf" fileUrlPath := "files/export_pdf"
dir := revel.BasePath + "/" + fileUrlPath dir := revel.BasePath + "/" + fileUrlPath
if !MkdirAll(dir) { if !MkdirAll(dir) {
return c.RenderText("error, no dir") return c.RenderText("error, no dir")
@@ -461,9 +444,9 @@ func (c Note) ExportPdf(noteId string) revel.Result {
// wkhtmltopdf参数大全 // wkhtmltopdf参数大全
var cc string var cc string
if note.IsMarkdown { if note.IsMarkdown {
cc = binPath + " --window-status done \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\"" cc = binPath + " --lowquality --window-status done \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\""
} else { } else {
cc = binPath + " \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\"" cc = binPath + " --lowquality \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\""
} }
cmd := exec.Command("/bin/sh", "-c", cc) cmd := exec.Command("/bin/sh", "-c", cc)
+8 -6
View File
@@ -1,9 +1,9 @@
package controllers package controllers
import ( import (
"github.com/revel/revel"
"encoding/json" "encoding/json"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"github.com/revel/revel"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
// "io/ioutil" // "io/ioutil"
@@ -34,18 +34,19 @@ func (c Notebook) AddNotebook(notebookId, title, parentNotebookId string) revel.
Title: title, Title: title,
Seq: -1, Seq: -1,
UserId: c.GetObjectUserId()} UserId: c.GetObjectUserId()}
if(parentNotebookId != "") { if parentNotebookId != "" {
notebook.ParentNotebookId = bson.ObjectIdHex(parentNotebookId) notebook.ParentNotebookId = bson.ObjectIdHex(parentNotebookId)
} }
re, notebook := notebookService.AddNotebook(notebook) re, notebook := notebookService.AddNotebook(notebook)
if(re) { if re {
return c.RenderJson(notebook) return c.RenderJson(notebook)
} else { } else {
return c.RenderJson(false) return c.RenderJson(false)
} }
} }
// 修改标题 // 修改标题
func (c Notebook) UpdateNotebookTitle(notebookId, title string) revel.Result { func (c Notebook) UpdateNotebookTitle(notebookId, title string) revel.Result {
return c.RenderJson(notebookService.UpdateNotebookTitle(notebookId, c.GetUserId(), title)) return c.RenderJson(notebookService.UpdateNotebookTitle(notebookId, c.GetUserId(), title))
@@ -53,9 +54,9 @@ func (c Notebook) UpdateNotebookTitle(notebookId, title string) revel.Result {
// 排序 // 排序
// 无用 // 无用
func (c Notebook) SortNotebooks(notebookId2Seqs map[string]int) revel.Result { // func (c Notebook) SortNotebooks(notebookId2Seqs map[string]int) revel.Result {
return c.RenderJson(notebookService.SortNotebooks(c.GetUserId(), notebookId2Seqs)) // return c.RenderJson(notebookService.SortNotebooks(c.GetUserId(), notebookId2Seqs))
} // }
// 调整notebooks, 可能是排序, 可能是移动到其它笔记本下 // 调整notebooks, 可能是排序, 可能是移动到其它笔记本下
type DragNotebooksInfo struct { type DragNotebooksInfo struct {
@@ -63,6 +64,7 @@ type DragNotebooksInfo struct {
ParentNotebookId string ParentNotebookId string
Siblings []string Siblings []string
} }
// 传过来的data是JSON.stringfy数据 // 传过来的data是JSON.stringfy数据
func (c Notebook) DragNotebooks(data string) revel.Result { func (c Notebook) DragNotebooks(data string) revel.Result {
info := DragNotebooksInfo{} info := DragNotebooksInfo{}
+1 -1
View File
@@ -23,7 +23,7 @@ type Preview struct {
// 得到要预览的主题绝对路径 // 得到要预览的主题绝对路径
func (c Preview) getPreviewThemeAbsolutePath(themeId string) bool { func (c Preview) getPreviewThemeAbsolutePath(themeId string) bool {
if themeId != "" { if themeId != "" {
c.Session["themeId"] = themeId // 存到session中, 下次的url就不能带了 c.Session["themeId"] = themeId // 存到session中, 下次的url就不能带了, 待优化, 有时会取不到
} else { } else {
themeId = c.Session["themeId"] // 直接从session中获取 themeId = c.Session["themeId"] // 直接从session中获取
} }
+34 -30
View File
@@ -4,8 +4,8 @@ import (
"github.com/revel/revel" "github.com/revel/revel"
// "encoding/json" // "encoding/json"
// "gopkg.in/mgo.v2/bson" // "gopkg.in/mgo.v2/bson"
. "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea"
// "github.com/leanote/leanote/app/types" // "github.com/leanote/leanote/app/types"
// "io/ioutil" // "io/ioutil"
// "fmt" // "fmt"
@@ -19,13 +19,13 @@ type Share struct {
func (c Share) AddShareNote(noteId string, emails []string, perm int) revel.Result { func (c Share) AddShareNote(noteId string, emails []string, perm int) revel.Result {
status := make(map[string]info.Re, len(emails)) status := make(map[string]info.Re, len(emails))
// 自己不能给自己添加共享 // 自己不能给自己添加共享
myEmail := c.GetEmail(); myEmail := c.GetEmail()
for _, email := range emails { for _, email := range emails {
if email == "" { if email == "" {
continue; continue
} }
if(myEmail != email) { if myEmail != email {
ok, msg, userId := shareService.AddShareNote(noteId, perm, c.GetUserId(), email); ok, msg, userId := shareService.AddShareNote(noteId, perm, c.GetUserId(), email)
status[email] = info.Re{Ok: ok, Msg: msg, Id: userId} status[email] = info.Re{Ok: ok, Msg: msg, Id: userId}
} else { } else {
@@ -40,13 +40,13 @@ func (c Share) AddShareNote(noteId string, emails []string, perm int) revel.Resu
func (c Share) AddShareNotebook(notebookId string, emails []string, perm int) revel.Result { func (c Share) AddShareNotebook(notebookId string, emails []string, perm int) revel.Result {
status := make(map[string]info.Re, len(emails)) status := make(map[string]info.Re, len(emails))
// 自己不能给自己添加共享 // 自己不能给自己添加共享
myEmail := c.GetEmail(); myEmail := c.GetEmail()
for _, email := range emails { for _, email := range emails {
if email == "" { if email == "" {
continue; continue
} }
if(myEmail != email) { if myEmail != email {
ok, msg, userId := shareService.AddShareNotebook(notebookId, perm, c.GetUserId(), email); ok, msg, userId := shareService.AddShareNotebook(notebookId, perm, c.GetUserId(), email)
status[email] = info.Re{Ok: ok, Msg: msg, Id: userId} status[email] = info.Re{Ok: ok, Msg: msg, Id: userId}
} else { } else {
status[email] = info.Re{Ok: false, Msg: "不能分享给自己"} status[email] = info.Re{Ok: false, Msg: "不能分享给自己"}
@@ -62,11 +62,11 @@ func (c Share) ListShareNotes(notebookId, userId string) revel.Result {
// 表示是默认笔记本, 不是某个特定notebook的共享 // 表示是默认笔记本, 不是某个特定notebook的共享
var notes []info.ShareNoteWithPerm var notes []info.ShareNoteWithPerm
if notebookId == "" { if notebookId == "" {
notes = shareService.ListShareNotes(c.GetUserId(), userId, c.GetPage(), pageSize, defaultSortField, false); notes = shareService.ListShareNotes(c.GetUserId(), userId, c.GetPage(), pageSize, defaultSortField, false)
return c.RenderJson(notes) return c.RenderJson(notes)
} else { } else {
// 有notebookId的 // 有notebookId的
return c.RenderJson(shareService.ListShareNotesByNotebookId(notebookId, c.GetUserId(), userId, c.GetPage(), pageSize, defaultSortField, false)); return c.RenderJson(shareService.ListShareNotesByNotebookId(notebookId, c.GetUserId(), userId, c.GetPage(), pageSize, defaultSortField, false))
} }
} }
@@ -90,7 +90,7 @@ func (c Share) ListNoteShareUserInfo(noteId string) revel.Result {
c.RenderArgs["noteOrNotebookShareGroupInfos"] = shareService.GetNoteShareGroups(noteId, c.GetUserId()) c.RenderArgs["noteOrNotebookShareGroupInfos"] = shareService.GetNoteShareGroups(noteId, c.GetUserId())
c.RenderArgs["isNote"] = true c.RenderArgs["isNote"] = true
c.RenderArgs["noteOrNotebookId"] = note.NoteId.Hex(); c.RenderArgs["noteOrNotebookId"] = note.NoteId.Hex()
c.RenderArgs["title"] = note.Title c.RenderArgs["title"] = note.Title
return c.RenderTemplate("share/note_notebook_share_user_infos.html") return c.RenderTemplate("share/note_notebook_share_user_infos.html")
@@ -105,7 +105,7 @@ func (c Share) ListNotebookShareUserInfo(notebookId string) revel.Result {
LogJ(c.RenderArgs["noteOrNotebookShareGroupInfos"]) LogJ(c.RenderArgs["noteOrNotebookShareGroupInfos"])
c.RenderArgs["isNote"] = false c.RenderArgs["isNote"] = false
c.RenderArgs["noteOrNotebookId"] = notebook.NotebookId.Hex(); c.RenderArgs["noteOrNotebookId"] = notebook.NotebookId.Hex()
c.RenderArgs["title"] = notebook.Title c.RenderArgs["title"] = notebook.Title
return c.RenderTemplate("share/note_notebook_share_user_infos.html") return c.RenderTemplate("share/note_notebook_share_user_infos.html")
@@ -114,74 +114,78 @@ func (c Share) ListNotebookShareUserInfo(notebookId string) revel.Result {
//------------ //------------
// 改变share note 权限 // 改变share note 权限
func (c Share) UpdateShareNotePerm(noteId string, perm int, toUserId string) revel.Result { func (c Share) UpdateShareNotePerm(noteId string, perm int, toUserId string) revel.Result {
return c.RenderJson(shareService.UpdateShareNotePerm(noteId, perm, c.GetUserId(), toUserId)); return c.RenderJson(shareService.UpdateShareNotePerm(noteId, perm, c.GetUserId(), toUserId))
} }
// 改变share notebook 权限 // 改变share notebook 权限
func (c Share) UpdateShareNotebookPerm(notebookId string, perm int, toUserId string) revel.Result { func (c Share) UpdateShareNotebookPerm(notebookId string, perm int, toUserId string) revel.Result {
return c.RenderJson(shareService.UpdateShareNotebookPerm(notebookId, perm, c.GetUserId(), toUserId)); return c.RenderJson(shareService.UpdateShareNotebookPerm(notebookId, perm, c.GetUserId(), toUserId))
} }
//--------------- //---------------
// 删除share note // 删除share note
func (c Share) DeleteShareNote(noteId string, toUserId string) revel.Result { func (c Share) DeleteShareNote(noteId string, toUserId string) revel.Result {
return c.RenderJson(shareService.DeleteShareNote(noteId, c.GetUserId(), toUserId)); return c.RenderJson(shareService.DeleteShareNote(noteId, c.GetUserId(), toUserId))
} }
// 删除share notebook // 删除share notebook
func (c Share) DeleteShareNotebook(notebookId string, toUserId string) revel.Result { func (c Share) DeleteShareNotebook(notebookId string, toUserId string) revel.Result {
return c.RenderJson(shareService.DeleteShareNotebook(notebookId, c.GetUserId(), toUserId)); return c.RenderJson(shareService.DeleteShareNotebook(notebookId, c.GetUserId(), toUserId))
} }
// 删除share note, 被共享方删除 // 删除share note, 被共享方删除
func (c Share) DeleteShareNoteBySharedUser(noteId string, fromUserId string) revel.Result { func (c Share) DeleteShareNoteBySharedUser(noteId string, fromUserId string) revel.Result {
return c.RenderJson(shareService.DeleteShareNote(noteId, fromUserId, c.GetUserId())); return c.RenderJson(shareService.DeleteShareNote(noteId, fromUserId, c.GetUserId()))
} }
// 删除share notebook, 被共享方删除 // 删除share notebook, 被共享方删除
func (c Share) DeleteShareNotebookBySharedUser(notebookId string, fromUserId string) revel.Result { func (c Share) DeleteShareNotebookBySharedUser(notebookId string, fromUserId string) revel.Result {
return c.RenderJson(shareService.DeleteShareNotebook(notebookId, fromUserId, c.GetUserId())); return c.RenderJson(shareService.DeleteShareNotebook(notebookId, fromUserId, c.GetUserId()))
} }
// 删除fromUserId分享给我的所有note, notebook // 删除fromUserId分享给我的所有note, notebook
func (c Share) DeleteUserShareNoteAndNotebook(fromUserId string) revel.Result { func (c Share) DeleteUserShareNoteAndNotebook(fromUserId string) revel.Result {
return c.RenderJson(shareService.DeleteUserShareNoteAndNotebook(fromUserId, c.GetUserId())); return c.RenderJson(shareService.DeleteUserShareNoteAndNotebook(fromUserId, c.GetUserId()))
} }
//------------- //-------------
// 用户组 // 用户组
// 将笔记分享给分组 // 将笔记分享给分组
func (c Share) AddShareNoteGroup(noteId, groupId string, perm int) revel.Result { func (c Share) AddShareNoteGroup(noteId, groupId string, perm int) revel.Result {
re := info.NewRe() re := info.NewRe()
re.Ok = shareService.AddShareNoteGroup(c.GetUserId(), noteId, groupId, perm); re.Ok = shareService.AddShareNoteGroup(c.GetUserId(), noteId, groupId, perm)
return c.RenderJson(re); return c.RenderJson(re)
} }
// 删除 // 删除
func (c Share) DeleteShareNoteGroup(noteId, groupId string) revel.Result { func (c Share) DeleteShareNoteGroup(noteId, groupId string) revel.Result {
re := info.NewRe() re := info.NewRe()
re.Ok = shareService.DeleteShareNoteGroup(c.GetUserId(), noteId, groupId); re.Ok = shareService.DeleteShareNoteGroup(c.GetUserId(), noteId, groupId)
return c.RenderJson(re); return c.RenderJson(re)
} }
// 更新, 也是一样, 先删后加 // 更新, 也是一样, 先删后加
func (c Share) UpdateShareNoteGroupPerm(noteId, groupId string, perm int) revel.Result { func (c Share) UpdateShareNoteGroupPerm(noteId, groupId string, perm int) revel.Result {
return c.AddShareNoteGroup(noteId, groupId, perm) return c.AddShareNoteGroup(noteId, groupId, perm)
} }
//------ //------
// 将笔记分享给分组 // 将笔记分享给分组
func (c Share) AddShareNotebookGroup(notebookId, groupId string, perm int) revel.Result { func (c Share) AddShareNotebookGroup(notebookId, groupId string, perm int) revel.Result {
re := info.NewRe() re := info.NewRe()
re.Ok = shareService.AddShareNotebookGroup(c.GetUserId(), notebookId, groupId, perm); re.Ok = shareService.AddShareNotebookGroup(c.GetUserId(), notebookId, groupId, perm)
return c.RenderJson(re); return c.RenderJson(re)
} }
// 删除 // 删除
func (c Share) DeleteShareNotebookGroup(notebookId, groupId string) revel.Result { func (c Share) DeleteShareNotebookGroup(notebookId, groupId string) revel.Result {
re := info.NewRe() re := info.NewRe()
re.Ok = shareService.DeleteShareNotebookGroup(c.GetUserId(), notebookId, groupId); re.Ok = shareService.DeleteShareNotebookGroup(c.GetUserId(), notebookId, groupId)
return c.RenderJson(re); return c.RenderJson(re)
} }
// 更新, 也是一样, 先删后加 // 更新, 也是一样, 先删后加
func (c Share) UpdateShareNotebookGroupPerm(notebookId, groupId string, perm int) revel.Result { func (c Share) UpdateShareNotebookGroupPerm(notebookId, groupId string, perm int) revel.Result {
return c.AddShareNotebookGroup(notebookId, groupId, perm) return c.AddShareNotebookGroup(notebookId, groupId, perm)
+21 -57
View File
@@ -4,8 +4,8 @@ import (
"github.com/revel/revel" "github.com/revel/revel"
// "encoding/json" // "encoding/json"
// "gopkg.in/mgo.v2/bson" // "gopkg.in/mgo.v2/bson"
. "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea"
// "github.com/leanote/leanote/app/types" // "github.com/leanote/leanote/app/types"
// "io/ioutil" // "io/ioutil"
// "fmt" // "fmt"
@@ -32,18 +32,18 @@ func (c User) UpdateUsername(username string) revel.Result {
re := info.NewRe() re := info.NewRe()
if c.GetUserId() == configService.GetGlobalStringConfig("demoUserId") { if c.GetUserId() == configService.GetGlobalStringConfig("demoUserId") {
re.Msg = "cannotUpdateDemo" re.Msg = "cannotUpdateDemo"
return c.RenderRe(re); return c.RenderRe(re)
} }
if re.Ok, re.Msg = Vd("username", username); !re.Ok { if re.Ok, re.Msg = Vd("username", username); !re.Ok {
return c.RenderRe(re); return c.RenderRe(re)
} }
re.Ok, re.Msg = userService.UpdateUsername(c.GetUserId(), username) re.Ok, re.Msg = userService.UpdateUsername(c.GetUserId(), username)
if(re.Ok) { if re.Ok {
c.UpdateSession("Username", username) c.UpdateSession("Username", username)
} }
return c.RenderRe(re); return c.RenderRe(re)
} }
// 修改密码 // 修改密码
@@ -51,37 +51,37 @@ func (c User) UpdatePwd(oldPwd, pwd string) revel.Result {
re := info.NewRe() re := info.NewRe()
if c.GetUserId() == configService.GetGlobalStringConfig("demoUserId") { if c.GetUserId() == configService.GetGlobalStringConfig("demoUserId") {
re.Msg = "cannotUpdateDemo" re.Msg = "cannotUpdateDemo"
return c.RenderRe(re); return c.RenderRe(re)
} }
if re.Ok, re.Msg = Vd("password", oldPwd); !re.Ok { if re.Ok, re.Msg = Vd("password", oldPwd); !re.Ok {
return c.RenderRe(re); return c.RenderRe(re)
} }
if re.Ok, re.Msg = Vd("password", pwd); !re.Ok { if re.Ok, re.Msg = Vd("password", pwd); !re.Ok {
return c.RenderRe(re); return c.RenderRe(re)
} }
re.Ok, re.Msg = userService.UpdatePwd(c.GetUserId(), oldPwd, pwd) re.Ok, re.Msg = userService.UpdatePwd(c.GetUserId(), oldPwd, pwd)
return c.RenderRe(re); return c.RenderRe(re)
} }
// 更新主题 // 更新主题
func (c User) UpdateTheme(theme string) revel.Result { func (c User) UpdateTheme(theme string) revel.Result {
re := info.NewRe(); re := info.NewRe()
re.Ok = userService.UpdateTheme(c.GetUserId(), theme) re.Ok = userService.UpdateTheme(c.GetUserId(), theme)
if re.Ok { if re.Ok {
c.UpdateSession("Theme", theme) c.UpdateSession("Theme", theme)
} }
return c.RenderJson(re); return c.RenderJson(re)
} }
// 发送邀请链接 // 发送邀请链接
func (c User) SendRegisterEmail(content, toEmail string) revel.Result { func (c User) SendRegisterEmail(content, toEmail string) revel.Result {
re := info.NewRe() re := info.NewRe()
if content == "" || !IsEmail(toEmail) { if content == "" || !IsEmail(toEmail) {
return c.RenderJson(re); return c.RenderJson(re)
} }
re.Ok = emailService.SendInviteEmail(c.GetUserInfo(), toEmail, content) re.Ok = emailService.SendInviteEmail(c.GetUserInfo(), toEmail, content)
return c.RenderJson(re); return c.RenderJson(re)
} }
//--------------------------- //---------------------------
@@ -93,25 +93,10 @@ func (c User) ReSendActiveEmail() revel.Result {
return c.RenderJson(re) return c.RenderJson(re)
} }
// 修改Email发送激活邮箱
func (c User) updateEmailSendActiveEmail(email, pwd string) revel.Result {
re := info.NewRe()
if c.GetUserId() == configService.GetGlobalStringConfig("demoUserId") {
re.Msg = "cannotUpdateDemo"
return c.RenderJson(re);
}
if re.Ok, re.Msg = Vd("email", email); !re.Ok {
return c.RenderRe(re);
}
re.Ok, re.Msg = emailService.UpdateEmailSendActiveEmail(c.GetUserInfo(), email)
return c.RenderRe(re)
}
// 通过点击链接 // 通过点击链接
// 修改邮箱 // 修改邮箱
func (c User) UpdateEmail(token string) revel.Result { func (c User) UpdateEmail(token string) revel.Result {
c.SetUserInfo(); c.SetUserInfo()
ok, msg, email := userService.UpdateEmail(token) ok, msg, email := userService.UpdateEmail(token)
@@ -130,13 +115,13 @@ func (c User) UpdateEmail(token string) revel.Result {
// 注册后激活邮箱 // 注册后激活邮箱
func (c User) ActiveEmail(token string) revel.Result { func (c User) ActiveEmail(token string) revel.Result {
c.SetUserInfo(); c.SetUserInfo()
ok, msg, email := userService.ActiveEmail(token) ok, msg, email := userService.ActiveEmail(token)
// 需要修改session // 需要修改session
if ok { if ok {
c.UpdateSession("Verified", "1"); c.UpdateSession("Verified", "1")
} }
c.RenderArgs["title"] = "验证邮箱" c.RenderArgs["title"] = "验证邮箱"
@@ -147,36 +132,15 @@ func (c User) ActiveEmail(token string) revel.Result {
return c.RenderTemplate("user/active_email.html") return c.RenderTemplate("user/active_email.html")
} }
//------------
// 第三方账号添加leanote账号
func (c User) AddAccount(email, pwd string) revel.Result {
re := info.NewRe()
if re.Ok, re.Msg = Vd("email", email); !re.Ok {
return c.RenderRe(re);
}
if re.Ok, re.Msg = Vd("password", pwd); !re.Ok {
return c.RenderRe(re);
}
re.Ok, re.Msg = userService.ThirdAddUser(c.GetUserId(), email, pwd)
if re.Ok {
c.UpdateSession("Email", email);
}
return c.RenderRe(re)
}
//----------------- //-----------------
// 用户偏爱 // 用户偏爱
func (c User) UpdateColumnWidth(notebookWidth, noteListWidth, mdEditorWidth int) revel.Result { func (c User) UpdateColumnWidth(notebookWidth, noteListWidth, mdEditorWidth int) revel.Result {
re := info.NewRe() re := info.NewRe()
re.Ok = userService.UpdateColumnWidth(c.GetUserId(), notebookWidth, noteListWidth, mdEditorWidth) re.Ok = userService.UpdateColumnWidth(c.GetUserId(), notebookWidth, noteListWidth, mdEditorWidth)
if re.Ok { if re.Ok {
c.UpdateSession("NotebookWidth", strconv.Itoa(notebookWidth)); c.UpdateSession("NotebookWidth", strconv.Itoa(notebookWidth))
c.UpdateSession("NoteListWidth", strconv.Itoa(noteListWidth)); c.UpdateSession("NoteListWidth", strconv.Itoa(noteListWidth))
c.UpdateSession("MdEditorWidth", strconv.Itoa(mdEditorWidth)); c.UpdateSession("MdEditorWidth", strconv.Itoa(mdEditorWidth))
LogJ(c.Session) LogJ(c.Session)
} }
@@ -187,9 +151,9 @@ func (c User) UpdateLeftIsMin(leftIsMin bool) revel.Result {
re.Ok = userService.UpdateLeftIsMin(c.GetUserId(), leftIsMin) re.Ok = userService.UpdateLeftIsMin(c.GetUserId(), leftIsMin)
if re.Ok { if re.Ok {
if leftIsMin { if leftIsMin {
c.UpdateSession("LeftIsMin", "1"); c.UpdateSession("LeftIsMin", "1")
} else { } else {
c.UpdateSession("LeftIsMin", "0"); c.UpdateSession("LeftIsMin", "0")
} }
} }
return c.RenderJson(re) return c.RenderJson(re)
+5 -5
View File
@@ -4,8 +4,8 @@ import (
// "github.com/revel/revel" // "github.com/revel/revel"
// "gopkg.in/mgo.v2/bson" // "gopkg.in/mgo.v2/bson"
// "encoding/json" // "encoding/json"
. "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/controllers" "github.com/leanote/leanote/app/controllers"
. "github.com/leanote/leanote/app/lea"
// "io/ioutil" // "io/ioutil"
// "fmt" // "fmt"
// "math" // "math"
@@ -24,19 +24,19 @@ func (c AdminBaseController) getSorter(sorterField string, isAsc bool, okSorter
sorter := "" sorter := ""
c.Params.Bind(&sorter, "sorter") c.Params.Bind(&sorter, "sorter")
if sorter == "" { if sorter == "" {
return sorterField, isAsc; return sorterField, isAsc
} }
// sorter形式 email-up, email-down // sorter形式 email-up, email-down
s2 := strings.Split(sorter, "-") s2 := strings.Split(sorter, "-")
if len(s2) != 2 { if len(s2) != 2 {
return sorterField, isAsc; return sorterField, isAsc
} }
// 必须是可用的sorter // 必须是可用的sorter
if okSorter != nil && len(okSorter) > 0 { if okSorter != nil && len(okSorter) > 0 {
if !InArray(okSorter, s2[0]) { if !InArray(okSorter, s2[0]) {
return sorterField, isAsc; return sorterField, isAsc
} }
} }
@@ -47,7 +47,7 @@ func (c AdminBaseController) getSorter(sorterField string, isAsc bool, okSorter
isAsc = false isAsc = false
} }
c.RenderArgs["sorter"] = sorter c.RenderArgs["sorter"] = sorter
return sorterField, isAsc; return sorterField, isAsc
} }
func (c AdminBaseController) updateConfig(keys []string) { func (c AdminBaseController) updateConfig(keys []string) {
+4 -4
View File
@@ -15,16 +15,16 @@ type AdminBlog struct {
// admin 主页 // admin 主页
func (c AdminBlog) Index(sorter, keywords string) revel.Result { func (c AdminBlog) Index(sorter, keywords string) revel.Result {
pageNumber := c.GetPage() pageNumber := c.GetPage()
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "userId", "isRecommed", "createdTime"}); sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "userId", "isRecommed", "createdTime"})
pageInfo, blogs := blogService.ListAllBlogs("", "", keywords, false, pageNumber, userPageSize, sorterField, isAsc); pageInfo, blogs := blogService.ListAllBlogs("", "", keywords, false, pageNumber, userPageSize, sorterField, isAsc)
c.RenderArgs["pageInfo"] = pageInfo c.RenderArgs["pageInfo"] = pageInfo
c.RenderArgs["blogs"] = blogs c.RenderArgs["blogs"] = blogs
c.RenderArgs["keywords"] = keywords c.RenderArgs["keywords"] = keywords
return c.RenderTemplate("admin/blog/list.html"); return c.RenderTemplate("admin/blog/list.html")
} }
func (c AdminBlog) SetRecommend(noteId string, recommend bool) revel.Result { func (c AdminBlog) SetRecommend(noteId string, recommend bool) revel.Result {
re := info.NewRe() re := info.NewRe()
re.Ok = blogService.SetRecommend(noteId, recommend); re.Ok = blogService.SetRecommend(noteId, recommend)
return c.RenderJson(re) return c.RenderJson(re)
} }
+2 -2
View File
@@ -21,7 +21,7 @@ func (c Admin) Index() revel.Result {
c.RenderArgs["countNote"] = noteService.CountNote("") c.RenderArgs["countNote"] = noteService.CountNote("")
c.RenderArgs["countBlog"] = noteService.CountBlog("") c.RenderArgs["countBlog"] = noteService.CountBlog("")
return c.RenderTemplate("admin/index.html"); return c.RenderTemplate("admin/index.html")
} }
// 模板 // 模板
@@ -35,5 +35,5 @@ func (c Admin) T(t string) revel.Result {
} }
func (c Admin) GetView(view string) revel.Result { func (c Admin) GetView(view string) revel.Result {
return c.RenderTemplate("admin/" + view); return c.RenderTemplate("admin/" + view)
} }
+5 -5
View File
@@ -1,13 +1,13 @@
package admin package admin
import ( import (
"github.com/revel/revel"
. "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/info"
"archive/tar" "archive/tar"
"compress/gzip" "compress/gzip"
"os" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea"
"github.com/revel/revel"
"io" "io"
"os"
"time" "time"
) )
@@ -27,7 +27,7 @@ func (c AdminData) Index() revel.Result {
j++ j++
} }
c.RenderArgs["backups"] = backups2 c.RenderArgs["backups"] = backups2
return c.RenderTemplate("admin/data/index.html"); return c.RenderTemplate("admin/data/index.html")
} }
func (c AdminData) Backup() revel.Result { func (c AdminData) Backup() revel.Result {
+19 -20
View File
@@ -1,11 +1,11 @@
package admin package admin
import ( import (
"github.com/revel/revel"
. "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"strings" . "github.com/leanote/leanote/app/lea"
"github.com/revel/revel"
"strconv" "strconv"
"strings"
) )
// admin 首页 // admin 首页
@@ -25,7 +25,7 @@ func (c AdminEmail) Blog() revel.Result {
newTags := configService.GetGlobalArrayConfig("newTags") newTags := configService.GetGlobalArrayConfig("newTags")
c.RenderArgs["recommendTags"] = strings.Join(recommendTags, ",") c.RenderArgs["recommendTags"] = strings.Join(recommendTags, ",")
c.RenderArgs["newTags"] = strings.Join(newTags, ",") c.RenderArgs["newTags"] = strings.Join(newTags, ",")
return c.RenderTemplate("admin/setting/blog.html"); return c.RenderTemplate("admin/setting/blog.html")
} }
func (c AdminEmail) DoBlogTag(recommendTags, newTags string) revel.Result { func (c AdminEmail) DoBlogTag(recommendTags, newTags string) revel.Result {
re := info.NewRe() re := info.NewRe()
@@ -41,7 +41,7 @@ func (c AdminEmail) DoBlogTag(recommendTags, newTags string) revel.Result {
func (c AdminEmail) Demo() revel.Result { func (c AdminEmail) Demo() revel.Result {
c.RenderArgs["demoUsername"] = configService.GetGlobalStringConfig("demoUsername") c.RenderArgs["demoUsername"] = configService.GetGlobalStringConfig("demoUsername")
c.RenderArgs["demoPassword"] = configService.GetGlobalStringConfig("demoPassword") c.RenderArgs["demoPassword"] = configService.GetGlobalStringConfig("demoPassword")
return c.RenderTemplate("admin/setting/demo.html"); return c.RenderTemplate("admin/setting/demo.html")
} }
func (c AdminEmail) DoDemo(demoUsername, demoPassword string) revel.Result { func (c AdminEmail) DoDemo(demoUsername, demoPassword string) revel.Result {
re := info.NewRe() re := info.NewRe()
@@ -51,7 +51,7 @@ func (c AdminEmail) DoDemo(demoUsername, demoPassword string) revel.Result {
return c.RenderJson(info.Re{Ok: false}) return c.RenderJson(info.Re{Ok: false})
} }
if userInfo.UserId == "" { if userInfo.UserId == "" {
re.Msg = "The User is Not Exists"; re.Msg = "The User is Not Exists"
return c.RenderJson(re) return c.RenderJson(re)
} }
@@ -66,7 +66,7 @@ func (c AdminEmail) DoDemo(demoUsername, demoPassword string) revel.Result {
// 长微博的bin路径phantomJs // 长微博的bin路径phantomJs
func (c AdminEmail) ToImage() revel.Result { func (c AdminEmail) ToImage() revel.Result {
c.RenderArgs["toImageBinPath"] = configService.GetGlobalStringConfig("toImageBinPath") c.RenderArgs["toImageBinPath"] = configService.GetGlobalStringConfig("toImageBinPath")
return c.RenderTemplate("admin/setting/toImage.html"); return c.RenderTemplate("admin/setting/toImage.html")
} }
func (c AdminEmail) DoToImage(toImageBinPath string) revel.Result { func (c AdminEmail) DoToImage(toImageBinPath string) revel.Result {
re := info.NewRe() re := info.NewRe()
@@ -132,13 +132,13 @@ func (c AdminEmail) SendEmailToEmails(sendEmails, latestEmailSubject, latestEmai
if saveAsOldEmail { if saveAsOldEmail {
oldEmails := configService.GetGlobalMapConfig("oldEmails") oldEmails := configService.GetGlobalMapConfig("oldEmails")
oldEmails[latestEmailSubject] = latestEmailBody oldEmails[latestEmailSubject] = latestEmailBody
configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails); configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails)
} }
sendEmails = strings.Replace(sendEmails, "\r", "", -1) sendEmails = strings.Replace(sendEmails, "\r", "", -1)
emails := strings.Split(sendEmails, "\n") emails := strings.Split(sendEmails, "\n")
re.Ok, re.Msg = emailService.SendEmailToEmails(emails, latestEmailSubject, latestEmailBody); re.Ok, re.Msg = emailService.SendEmailToEmails(emails, latestEmailSubject, latestEmailBody)
return c.RenderJson(re) return c.RenderJson(re)
} }
@@ -156,7 +156,7 @@ func (c AdminEmail) SendToUsers2(emails, latestEmailSubject, latestEmailBody str
if saveAsOldEmail { if saveAsOldEmail {
oldEmails := configService.GetGlobalMapConfig("oldEmails") oldEmails := configService.GetGlobalMapConfig("oldEmails")
oldEmails[latestEmailSubject] = latestEmailBody oldEmails[latestEmailSubject] = latestEmailBody
configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails); configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails)
} }
emails = strings.Replace(emails, "\r", "", -1) emails = strings.Replace(emails, "\r", "", -1)
@@ -165,8 +165,7 @@ func (c AdminEmail) SendToUsers2(emails, latestEmailSubject, latestEmailBody str
users := userService.ListUserInfosByEmails(emailsArr) users := userService.ListUserInfosByEmails(emailsArr)
LogJ(emailsArr) LogJ(emailsArr)
re.Ok, re.Msg = emailService.SendEmailToUsers(users, latestEmailSubject, latestEmailBody)
re.Ok, re.Msg = emailService.SendEmailToUsers(users, latestEmailSubject, latestEmailBody);
return c.RenderJson(re) return c.RenderJson(re)
} }
@@ -180,7 +179,7 @@ func (c AdminEmail) SendEmailDialog(emails string) revel.Result{
c.RenderArgs["str"] = configService.GlobalStringConfigs c.RenderArgs["str"] = configService.GlobalStringConfigs
c.RenderArgs["map"] = configService.GlobalMapConfigs c.RenderArgs["map"] = configService.GlobalMapConfigs
return c.RenderTemplate("admin/email/emailDialog.html"); return c.RenderTemplate("admin/email/emailDialog.html")
} }
func (c AdminEmail) SendToUsers(userFilterEmail, userFilterWhiteList, userFilterBlackList, latestEmailSubject, latestEmailBody string, verified, saveAsOldEmail bool) revel.Result { func (c AdminEmail) SendToUsers(userFilterEmail, userFilterWhiteList, userFilterBlackList, latestEmailSubject, latestEmailBody string, verified, saveAsOldEmail bool) revel.Result {
@@ -196,19 +195,19 @@ func (c AdminEmail) SendToUsers(userFilterEmail, userFilterWhiteList, userFilter
if saveAsOldEmail { if saveAsOldEmail {
oldEmails := configService.GetGlobalMapConfig("oldEmails") oldEmails := configService.GetGlobalMapConfig("oldEmails")
oldEmails[latestEmailSubject] = latestEmailBody oldEmails[latestEmailSubject] = latestEmailBody
configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails); configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails)
} }
users := userService.GetAllUserByFilter(userFilterEmail, userFilterWhiteList, userFilterBlackList, verified) users := userService.GetAllUserByFilter(userFilterEmail, userFilterWhiteList, userFilterBlackList, verified)
if(users == nil || len(users) == 0) { if users == nil || len(users) == 0 {
re.Ok = false re.Ok = false
re.Msg = "no users" re.Msg = "no users"
return c.RenderJson(re) return c.RenderJson(re)
} }
re.Ok, re.Msg = emailService.SendEmailToUsers(users, latestEmailSubject, latestEmailBody); re.Ok, re.Msg = emailService.SendEmailToUsers(users, latestEmailSubject, latestEmailBody)
if(!re.Ok) { if !re.Ok {
return c.RenderJson(re) return c.RenderJson(re)
} }
@@ -227,10 +226,10 @@ func (c AdminEmail) DeleteEmails(ids string) revel.Result {
func (c AdminEmail) List(sorter, keywords string) revel.Result { func (c AdminEmail) List(sorter, keywords string) revel.Result {
pageNumber := c.GetPage() pageNumber := c.GetPage()
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"email", "ok", "subject", "createdTime"}); sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"email", "ok", "subject", "createdTime"})
pageInfo, emails := emailService.ListEmailLogs(pageNumber, userPageSize, sorterField, isAsc, keywords); pageInfo, emails := emailService.ListEmailLogs(pageNumber, userPageSize, sorterField, isAsc, keywords)
c.RenderArgs["pageInfo"] = pageInfo c.RenderArgs["pageInfo"] = pageInfo
c.RenderArgs["emails"] = emails c.RenderArgs["emails"] = emails
c.RenderArgs["keywords"] = keywords c.RenderArgs["keywords"] = keywords
return c.RenderTemplate("admin/email/list.html"); return c.RenderTemplate("admin/email/list.html")
} }
@@ -3,9 +3,9 @@ package admin
import ( import (
"github.com/revel/revel" "github.com/revel/revel"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
"fmt"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"strings" "strings"
"fmt"
) )
// admin 首页 // admin 首页
@@ -25,7 +25,7 @@ func (c AdminSetting) Blog() revel.Result {
newTags := configService.GetGlobalArrayConfig("newTags") newTags := configService.GetGlobalArrayConfig("newTags")
c.RenderArgs["recommendTags"] = strings.Join(recommendTags, ",") c.RenderArgs["recommendTags"] = strings.Join(recommendTags, ",")
c.RenderArgs["newTags"] = strings.Join(newTags, ",") c.RenderArgs["newTags"] = strings.Join(newTags, ",")
return c.RenderTemplate("admin/setting/blog.html"); return c.RenderTemplate("admin/setting/blog.html")
} }
func (c AdminSetting) DoBlogTag(recommendTags, newTags string) revel.Result { func (c AdminSetting) DoBlogTag(recommendTags, newTags string) revel.Result {
re := info.NewRe() re := info.NewRe()
@@ -42,7 +42,7 @@ func (c AdminSetting) ShareNote(registerSharedUserId string,
registerSharedNotebookIds, registerSharedNoteIds, registerCopyNoteIds []string) revel.Result { registerSharedNotebookIds, registerSharedNoteIds, registerCopyNoteIds []string) revel.Result {
re := info.NewRe() re := info.NewRe()
re.Ok, re.Msg = configService.UpdateShareNoteConfig(registerSharedUserId, registerSharedNotebookPerms, registerSharedNotePerms, registerSharedNotebookIds, registerSharedNoteIds, registerCopyNoteIds); re.Ok, re.Msg = configService.UpdateShareNoteConfig(registerSharedUserId, registerSharedNotebookPerms, registerSharedNotePerms, registerSharedNotebookIds, registerSharedNoteIds, registerCopyNoteIds)
return c.RenderJson(re) return c.RenderJson(re)
} }
@@ -51,7 +51,7 @@ func (c AdminSetting) ShareNote(registerSharedUserId string,
func (c AdminSetting) Demo() revel.Result { func (c AdminSetting) Demo() revel.Result {
c.RenderArgs["demoUsername"] = configService.GetGlobalStringConfig("demoUsername") c.RenderArgs["demoUsername"] = configService.GetGlobalStringConfig("demoUsername")
c.RenderArgs["demoPassword"] = configService.GetGlobalStringConfig("demoPassword") c.RenderArgs["demoPassword"] = configService.GetGlobalStringConfig("demoPassword")
return c.RenderTemplate("admin/setting/demo.html"); return c.RenderTemplate("admin/setting/demo.html")
} }
func (c AdminSetting) DoDemo(demoUsername, demoPassword string) revel.Result { func (c AdminSetting) DoDemo(demoUsername, demoPassword string) revel.Result {
re := info.NewRe() re := info.NewRe()
@@ -62,7 +62,7 @@ func (c AdminSetting) DoDemo(demoUsername, demoPassword string) revel.Result {
return c.RenderJson(info.Re{Ok: false}) return c.RenderJson(info.Re{Ok: false})
} }
if userInfo.UserId == "" { if userInfo.UserId == "" {
re.Msg = "The User is Not Exists"; re.Msg = "The User is Not Exists"
return c.RenderJson(re) return c.RenderJson(re)
} }
@@ -79,6 +79,12 @@ func (c AdminSetting) ExportPdf(path string) revel.Result {
return c.RenderJson(re) return c.RenderJson(re)
} }
func (c AdminSetting) DoSiteUrl(siteUrl string) revel.Result {
re := info.NewRe()
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "siteUrl", siteUrl)
return c.RenderJson(re)
}
// SubDomain // SubDomain
func (c AdminSetting) SubDomain() revel.Result { func (c AdminSetting) SubDomain() revel.Result {
c.RenderArgs["str"] = configService.GlobalStringConfigs c.RenderArgs["str"] = configService.GlobalStringConfigs
@@ -88,7 +94,7 @@ func (c AdminSetting) SubDomain() revel.Result {
c.RenderArgs["blogSubDomain"] = configService.GetGlobalStringConfig("blogSubDomain") c.RenderArgs["blogSubDomain"] = configService.GetGlobalStringConfig("blogSubDomain")
c.RenderArgs["leaSubDomain"] = configService.GetGlobalStringConfig("leaSubDomain") c.RenderArgs["leaSubDomain"] = configService.GetGlobalStringConfig("leaSubDomain")
return c.RenderTemplate("admin/setting/subDomain.html"); return c.RenderTemplate("admin/setting/subDomain.html")
} }
func (c AdminSetting) DoSubDomain(noteSubDomain, blogSubDomain, leaSubDomain, blackSubDomains, allowCustomDomain, blackCustomDomains string) revel.Result { func (c AdminSetting) DoSubDomain(noteSubDomain, blogSubDomain, leaSubDomain, blackSubDomains, allowCustomDomain, blackCustomDomains string) revel.Result {
re := info.NewRe() re := info.NewRe()
@@ -14,7 +14,7 @@ type AdminUpgrade struct {
func (c AdminUpgrade) UpgradeBlog() revel.Result { func (c AdminUpgrade) UpgradeBlog() revel.Result {
upgradeService.UpgradeBlog() upgradeService.UpgradeBlog()
return nil; return nil
} }
func (c AdminUpgrade) UpgradeBetaToBeta2() revel.Result { func (c AdminUpgrade) UpgradeBetaToBeta2() revel.Result {
+12 -11
View File
@@ -1,8 +1,8 @@
package admin package admin
import ( import (
"github.com/revel/revel"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"github.com/revel/revel"
// "time" // "time"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
) )
@@ -15,32 +15,33 @@ type AdminUser struct {
// admin 主页 // admin 主页
var userPageSize = 10 var userPageSize = 10
func (c AdminUser) Index(sorter, keywords string, pageSize int) revel.Result { func (c AdminUser) Index(sorter, keywords string, pageSize int) revel.Result {
pageNumber := c.GetPage() pageNumber := c.GetPage()
if userPageSize == 0 { if userPageSize == 0 {
pageSize = userPageSize pageSize = userPageSize
} }
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"email", "username", "verified", "createdTime", "accountType"}); sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"email", "username", "verified", "createdTime", "accountType"})
pageInfo, users := userService.ListUsers(pageNumber, pageSize, sorterField, isAsc, keywords); pageInfo, users := userService.ListUsers(pageNumber, pageSize, sorterField, isAsc, keywords)
c.RenderArgs["pageInfo"] = pageInfo c.RenderArgs["pageInfo"] = pageInfo
c.RenderArgs["users"] = users c.RenderArgs["users"] = users
c.RenderArgs["keywords"] = keywords c.RenderArgs["keywords"] = keywords
return c.RenderTemplate("admin/user/list.html"); return c.RenderTemplate("admin/user/list.html")
} }
func (c AdminUser) Add() revel.Result { func (c AdminUser) Add() revel.Result {
return c.RenderTemplate("admin/user/add.html"); return c.RenderTemplate("admin/user/add.html")
} }
// 添加 // 添加
func (c AdminUser) Register(email, pwd string) revel.Result { func (c AdminUser) Register(email, pwd string) revel.Result {
re := info.NewRe(); re := info.NewRe()
if re.Ok, re.Msg = Vd("email", email); !re.Ok { if re.Ok, re.Msg = Vd("email", email); !re.Ok {
return c.RenderRe(re); return c.RenderRe(re)
} }
if re.Ok, re.Msg = Vd("password", pwd); !re.Ok { if re.Ok, re.Msg = Vd("password", pwd); !re.Ok {
return c.RenderRe(re); return c.RenderRe(re)
} }
// 注册 // 注册
@@ -53,13 +54,13 @@ func (c AdminUser) Register(email, pwd string) revel.Result {
func (c AdminUser) ResetPwd(userId string) revel.Result { func (c AdminUser) ResetPwd(userId string) revel.Result {
userInfo := userService.GetUserInfo(userId) userInfo := userService.GetUserInfo(userId)
c.RenderArgs["userInfo"] = userInfo c.RenderArgs["userInfo"] = userInfo
return c.RenderTemplate("admin/user/reset_pwd.html"); return c.RenderTemplate("admin/user/reset_pwd.html")
} }
func (c AdminUser) DoResetPwd(userId, pwd string) revel.Result { func (c AdminUser) DoResetPwd(userId, pwd string) revel.Result {
re := info.NewRe(); re := info.NewRe()
if re.Ok, re.Msg = Vd("password", pwd); !re.Ok { if re.Ok, re.Msg = Vd("password", pwd); !re.Ok {
return c.RenderRe(re); return c.RenderRe(re)
} }
re.Ok, re.Msg = userService.ResetPwd(c.GetUserId(), userId, pwd) re.Ok, re.Msg = userService.ResetPwd(c.GetUserId(), userId, pwd)
return c.RenderRe(re) return c.RenderRe(re)
+3 -2
View File
@@ -1,8 +1,8 @@
package admin package admin
import ( import (
"github.com/leanote/leanote/app/service"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/service"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
"github.com/revel/revel" "github.com/revel/revel"
// "strings" // "strings"
@@ -56,6 +56,7 @@ var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": tru
"File": map[string]bool{"OutputImage": true, "OutputFile": true}, "File": map[string]bool{"OutputImage": true, "OutputFile": true},
"Attach": map[string]bool{"Download": true, "DownloadAll": true}, "Attach": map[string]bool{"Download": true, "DownloadAll": true},
} }
func needValidate(controller, method string) bool { func needValidate(controller, method string) bool {
// 在里面 // 在里面
if v, ok := commonUrl[controller]; ok { if v, ok := commonUrl[controller]; ok {
@@ -66,7 +67,7 @@ func needValidate(controller, method string) bool {
return true return true
} else { } else {
// controller不在这里的, 肯定要验证 // controller不在这里的, 肯定要验证
return true; return true
} }
} }
func AuthInterceptor(c *revel.Controller) revel.Result { func AuthInterceptor(c *revel.Controller) revel.Result {
+13 -11
View File
@@ -4,9 +4,9 @@ import (
"github.com/revel/revel" "github.com/revel/revel"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
// "encoding/json" // "encoding/json"
. "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/controllers" "github.com/leanote/leanote/app/controllers"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea"
"os" "os"
// "fmt" // "fmt"
"io/ioutil" "io/ioutil"
@@ -43,7 +43,7 @@ func (c ApiBaseContrller) getUserInfo() info.User {
// 上传附件 // 上传附件
func (c ApiBaseContrller) uploadAttach(name string, noteId string) (ok bool, msg string, id string) { func (c ApiBaseContrller) uploadAttach(name string, noteId string) (ok bool, msg string, id string) {
userId := c.getUserId(); userId := c.getUserId()
// 判断是否有权限为笔记添加附件 // 判断是否有权限为笔记添加附件
// 如果笔记还没有添加是不是会有问题 // 如果笔记还没有添加是不是会有问题
@@ -64,18 +64,19 @@ func (c ApiBaseContrller) uploadAttach(name string, noteId string) (ok bool, msg
return return
} }
// > 5M? // > 5M?
maxFileSize := configService.GetUploadSize("uploadAttachSize"); maxFileSize := configService.GetUploadSize("uploadAttachSize")
if maxFileSize <= 0 { if maxFileSize <= 0 {
maxFileSize = 1000 maxFileSize = 1000
} }
if(float64(len(data)) > maxFileSize * float64(1024*1024)) { if float64(len(data)) > maxFileSize*float64(1024*1024) {
msg = "fileIsTooLarge" msg = "fileIsTooLarge"
return return
} }
// 生成上传路径 // 生成上传路径
newGuid := NewGuid() newGuid := NewGuid()
filePath := "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/attachs" // filePath := "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/attachs"
filePath := "files/" + GetRandomFilePath(userId, newGuid) + "/attachs"
dir := revel.BasePath + "/" + filePath dir := revel.BasePath + "/" + filePath
err = os.MkdirAll(dir, 0755) err = os.MkdirAll(dir, 0755)
@@ -86,7 +87,7 @@ func (c ApiBaseContrller) uploadAttach(name string, noteId string) (ok bool, msg
filename := handel.Filename filename := handel.Filename
_, ext := SplitFilename(filename) // .doc _, ext := SplitFilename(filename) // .doc
filename = newGuid + ext filename = newGuid + ext
toPath := dir + "/" + filename; toPath := dir + "/" + filename
err = ioutil.WriteFile(toPath, data, 0777) err = ioutil.WriteFile(toPath, data, 0777)
if err != nil { if err != nil {
return return
@@ -130,7 +131,8 @@ func (c ApiBaseContrller) upload(name string, noteId string, isAttach bool) (ok
newGuid := NewGuid() newGuid := NewGuid()
// 生成上传路径 // 生成上传路径
userId := c.getUserId() userId := c.getUserId()
fileUrlPath := "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/images" // fileUrlPath := "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/images"
fileUrlPath := "files/" + GetRandomFilePath(userId, newGuid) + "/images"
dir := revel.BasePath + "/" + fileUrlPath dir := revel.BasePath + "/" + fileUrlPath
err = os.MkdirAll(dir, 0755) err = os.MkdirAll(dir, 0755)
@@ -140,7 +142,7 @@ func (c ApiBaseContrller) upload(name string, noteId string, isAttach bool) (ok
// 生成新的文件名 // 生成新的文件名
filename := handel.Filename filename := handel.Filename
_, ext := SplitFilename(filename) _, ext := SplitFilename(filename)
if(ext != ".gif" && ext != ".jpg" && ext != ".png" && ext != ".bmp" && ext != ".jpeg") { if ext != ".gif" && ext != ".jpg" && ext != ".png" && ext != ".bmp" && ext != ".jpeg" {
msg = "notImage" msg = "notImage"
return return
} }
@@ -151,18 +153,18 @@ func (c ApiBaseContrller) upload(name string, noteId string, isAttach bool) (ok
return return
} }
maxFileSize := configService.GetUploadSize("uploadImageSize"); maxFileSize := configService.GetUploadSize("uploadImageSize")
if maxFileSize <= 0 { if maxFileSize <= 0 {
maxFileSize = 1000 maxFileSize = 1000
} }
// > 2M? // > 2M?
if(float64(len(data)) > maxFileSize * float64(1024*1024)) { if float64(len(data)) > maxFileSize*float64(1024*1024) {
msg = "fileIsTooLarge" msg = "fileIsTooLarge"
return return
} }
toPath := dir + "/" + filename; toPath := dir + "/" + filename
err = ioutil.WriteFile(toPath, data, 0777) err = ioutil.WriteFile(toPath, data, 0777)
if err != nil { if err != nil {
return return
+4 -5
View File
@@ -10,11 +10,11 @@ import (
// "io/ioutil" // "io/ioutil"
"os" "os"
// "strconv" // "strconv"
"io"
"time"
"strings"
"archive/tar" "archive/tar"
"compress/gzip" "compress/gzip"
"io"
"strings"
"time"
) )
// 文件操作, 图片, 头像上传, 输出 // 文件操作, 图片, 头像上传, 输出
@@ -73,7 +73,7 @@ func (c ApiFile) GetImage(fileId string) revel.Result {
// 下载附件 // 下载附件
// [OK] // [OK]
func (c ApiFile) GetAttach(fileId string) revel.Result { func (c ApiFile) GetAttach(fileId string) revel.Result {
attach := attachService.GetAttach(fileId, c.getUserId()); // 得到路径 attach := attachService.GetAttach(fileId, c.getUserId()) // 得到路径
path := attach.Path path := attach.Path
if path == "" { if path == "" {
return c.RenderText("No Such File") return c.RenderText("No Such File")
@@ -161,4 +161,3 @@ func (c ApiFile) GetAllAttachs(noteId string) revel.Result {
// fw.Seek(0, 0) // fw.Seek(0, 0)
return c.RenderBinary(fw, filename, revel.Attachment, time.Now()) // revel.Attachment return c.RenderBinary(fw, filename, revel.Attachment, time.Now()) // revel.Attachment
} }
+33 -79
View File
@@ -6,11 +6,10 @@ import (
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"regexp" "os"
"os/exec"
"strings" "strings"
"time" "time"
"os/exec"
"os"
// "github.com/leanote/leanote/app/types" // "github.com/leanote/leanote/app/types"
// "io/ioutil" // "io/ioutil"
// "fmt" // "fmt"
@@ -85,7 +84,6 @@ func (c ApiNote) GetTrashNotes() revel.Result {
"Title": "asdfadsf--=", "Title": "asdfadsf--=",
"Desc": "", "Desc": "",
"Tags": [ "Tags": [
""
], ],
"Abstract": "", "Abstract": "",
"Content": "", "Content": "",
@@ -95,7 +93,7 @@ func (c ApiNote) GetTrashNotes() revel.Result {
"Usn": 8, "Usn": 8,
"Files": [ "Files": [
{ {
"FileId": "551975d599c37b970f000002", "FileId": "551975d599c37b970f000000",
"LocalFileId": "", "LocalFileId": "",
"Type": "", "Type": "",
"Title": "", "Title": "",
@@ -103,18 +101,18 @@ func (c ApiNote) GetTrashNotes() revel.Result {
"IsAttach": false "IsAttach": false
}, },
{ {
"FileId": "551975de99c37b970f000003", "FileId": "551975de99c37b970f000001",
"LocalFileId": "", "LocalFileId": "",
"Type": "doc", "Type": "doc",
"Title": "李铁-简历-ali-print-en.doc", "Title": "李铁-print-en.doc",
"HasBody": false, "HasBody": false,
"IsAttach": true "IsAttach": true
}, },
{ {
"FileId": "551975de99c37b970f000004", "FileId": "551975de99c37b970f000002",
"LocalFileId": "", "LocalFileId": "",
"Type": "doc", "Type": "doc",
"Title": "李铁-简历-ali-print.doc", "Title": "李铁-print.doc",
"HasBody": false, "HasBody": false,
"IsAttach": true "IsAttach": true
} }
@@ -148,68 +146,10 @@ func (c ApiNote) GetNoteAndContent(noteId string) revel.Result {
apiNotes := noteService.ToApiNotes([]info.Note{noteAndContent.Note}) apiNotes := noteService.ToApiNotes([]info.Note{noteAndContent.Note})
apiNote := apiNotes[0] apiNote := apiNotes[0]
apiNote.Content = noteAndContent.Content apiNote.Content = noteService.FixContent(noteAndContent.Content, noteAndContent.IsMarkdown)
return c.RenderJson(apiNote) return c.RenderJson(apiNote)
} }
// 处理笔记内容数据 http://leanote.com/file/outputImage -> https://leanote.com/api/file/getImage
// 图片, 附件都替换
func (c ApiNote) fixContent(content string) string {
// TODO, 这个url需要从config中取
// baseUrl := "http://leanote.com"
baseUrl := configService.GetSiteUrl()
// baseUrl := "http://localhost:9000"
patterns := []map[string]string{
map[string]string{"src": "src", "middle": "/file/outputImage", "param": "fileId", "to": "getImage?fileId="},
map[string]string{"src": "href", "middle": "/attach/download", "param": "attachId", "to": "getAttach?fileId="},
map[string]string{"src": "href", "middle": "/attach/downloadAll", "param": "noteId", "to": "getAllAttachs?noteId="},
}
for _, eachPattern := range patterns {
// src="http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1"
// href="http://leanote.com/attach/download?attachId=5504243a38f4111dcb00017d"
// href="http://leanote.com/attach/downloadAll?noteId=55041b6a38f4111dcb000159"
regImage, _ := regexp.Compile(eachPattern["src"] + `=('|")`+ baseUrl + eachPattern["middle"] + `\?` + eachPattern["param"] + `=([a-z0-9A-Z]{24})("|')`)
findsImage := regImage.FindAllStringSubmatch(content, -1) // 查找所有的
// [[src='http://leanote.com/file/outputImage?fileId=54672e8d38f411286b000069" ' 54672e8d38f411286b000069 "] [src="http://leanote.com/file/outputImage?fileId=54672e8d38f411286b000069" " 54672e8d38f411286b000069 "] [src="http://leanote.com/file/outputImage?fileId=54672e8d38f411286b000069" " 54672e8d38f411286b000069 "] [src="http://leanote.com/file/outputImage?fileId=54672e8d38f411286b000069" " 54672e8d38f411286b000069 "]]
for _, eachFind := range findsImage {
// [src='http://leanote.com/file/outputImage?fileId=54672e8d38f411286b000069" ' 54672e8d38f411286b000069 "]
if len(eachFind) == 4 {
content = strings.Replace(content,
eachFind[0],
eachPattern["src"] + "=\"" + baseUrl + "/api/file/" + eachPattern["to"] + eachFind[2] + "\"",
1);
}
}
// markdown处理
// ![](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1)
// [selection 2.html](http://leanote.com/attach/download?attachId=5504262638f4111dcb00017f)
// [all.tar.gz](http://leanote.com/attach/downloadAll?noteId=5503b57d59f81b4eb4000000)
pre := "!" // 默认图片
if eachPattern["src"] == "href" { // 是attach
pre = ""
}
regImageMarkdown, _ := regexp.Compile(pre + `\[(.*?)\]\(`+ baseUrl + eachPattern["middle"] + `\?` + eachPattern["param"] + `=([a-z0-9A-Z]{24})\)`)
findsImageMarkdown := regImageMarkdown.FindAllStringSubmatch(content, -1) // 查找所有的
// [[![](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1) 5503537b38f4111dcb0000d1] [![你好啊, 我很好, 为什么?](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1) 5503537b38f4111dcb0000d1]]
for _, eachFind := range findsImageMarkdown {
// [![你好啊, 我很好, 为什么?](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1) 你好啊, 我很好, 为什么? 5503537b38f4111dcb0000d1]
if len(eachFind) == 3 {
content = strings.Replace(content, eachFind[0], pre + "[" + eachFind[1] + "](" + baseUrl + "/api/file/" + eachPattern["to"] + eachFind[2] + ")", 1);
}
}
}
return content
}
// content里的image, attach链接是 // content里的image, attach链接是
// https://leanote.com/api/file/getImage?fileId=xx // https://leanote.com/api/file/getImage?fileId=xx
// https://leanote.com/api/file/getAttach?fileId=xx // https://leanote.com/api/file/getAttach?fileId=xx
@@ -229,12 +169,13 @@ func (c ApiNote) fixPostNotecontent(noteOrContent *info.ApiNote) {
} }
// 得到内容 // 得到内容
// [OK]
func (c ApiNote) GetNoteContent(noteId string) revel.Result { func (c ApiNote) GetNoteContent(noteId string) revel.Result {
userId := c.getUserId()
note := noteService.GetNote(noteId, userId)
// re := info.NewRe() // re := info.NewRe()
noteContent := noteService.GetNoteContent(noteId, c.getUserId()) noteContent := noteService.GetNoteContent(noteId, userId)
if noteContent.Content != "" { if noteContent.Content != "" {
noteContent.Content = c.fixContent(noteContent.Content) noteContent.Content = noteService.FixContent(noteContent.Content, note.IsMarkdown)
} }
apiNoteContent := info.ApiNoteContent{ apiNoteContent := info.ApiNoteContent{
@@ -243,7 +184,6 @@ func (c ApiNote) GetNoteContent(noteId string) revel.Result {
Content: noteContent.Content, Content: noteContent.Content,
} }
// re.Item = noteContent
return c.RenderJson(apiNoteContent) return c.RenderJson(apiNoteContent)
} }
@@ -261,6 +201,7 @@ func (c ApiNote) AddNote(noteOrContent info.ApiNote) revel.Result {
*/ */
// Log(noteOrContent.Title) // Log(noteOrContent.Title)
// LogJ(noteOrContent) // LogJ(noteOrContent)
/* /*
LogJ(c.Params) LogJ(c.Params)
for name, _ := range c.Params.Files { for name, _ := range c.Params.Files {
@@ -330,12 +271,17 @@ func (c ApiNote) AddNote(noteOrContent info.ApiNote) revel.Result {
IsBlog: noteOrContent.IsBlog, IsBlog: noteOrContent.IsBlog,
IsMarkdown: noteOrContent.IsMarkdown, IsMarkdown: noteOrContent.IsMarkdown,
AttachNum: attachNum, AttachNum: attachNum,
CreatedTime: noteOrContent.CreatedTime,
UpdatedTime: noteOrContent.UpdatedTime,
} }
noteContent := info.NoteContent{NoteId: note.NoteId, noteContent := info.NoteContent{NoteId: note.NoteId,
UserId: userId, UserId: userId,
IsBlog: note.IsBlog, IsBlog: note.IsBlog,
Content: noteOrContent.Content, Content: noteOrContent.Content,
Abstract: noteOrContent.Abstract} Abstract: noteOrContent.Abstract,
CreatedTime: noteOrContent.CreatedTime,
UpdatedTime: noteOrContent.UpdatedTime,
}
// 通过内容得到Desc, abstract // 通过内容得到Desc, abstract
if noteOrContent.Abstract == "" { if noteOrContent.Abstract == "" {
@@ -447,6 +393,7 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
// Log("after upload") // Log("after upload")
// LogJ(noteOrContent.Files) // LogJ(noteOrContent.Files)
} }
// 移到外面来, 删除最后一个file时也要处理, 不然总删不掉 // 移到外面来, 删除最后一个file时也要处理, 不然总删不掉
@@ -509,6 +456,8 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
} }
} }
noteUpdate["UpdatedTime"] = noteOrContent.UpdatedTime
afterNoteUsn := 0 afterNoteUsn := 0
noteOk := false noteOk := false
noteMsg := "" noteMsg := ""
@@ -532,10 +481,16 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
if noteOrContent.Abstract == "" { if noteOrContent.Abstract == "" {
noteOrContent.Abstract = SubStringHTML(noteOrContent.Content, 200, "") noteOrContent.Abstract = SubStringHTML(noteOrContent.Content, 200, "")
} }
// Log("--------> afte fixed") // Log("--------> afte fixed")
// Log(noteOrContent.Content) // Log(noteOrContent.Content)
contentOk, contentMsg, afterContentUsn = noteService.UpdateNoteContent(c.getUserId(), contentOk, contentMsg, afterContentUsn = noteService.UpdateNoteContent(c.getUserId(),
noteOrContent.NoteId, noteOrContent.Content, noteOrContent.Abstract, needUpdateNote, noteOrContent.Usn) noteOrContent.NoteId,
noteOrContent.Content,
noteOrContent.Abstract,
needUpdateNote,
noteOrContent.Usn,
noteOrContent.UpdatedTime)
} }
if needUpdateNote { if needUpdateNote {
@@ -585,7 +540,6 @@ func (c ApiNote) GetHistories(noteId string) revel.Result {
// 0.2 新增 // 0.2 新增
// 导出成PDF // 导出成PDF
// test localhost:9000/api/note/exportPdf?noteId=554f07bf05fcd15fa9000000&token=562211dc99c37ba6a7000001
func (c ApiNote) ExportPdf(noteId string) revel.Result { func (c ApiNote) ExportPdf(noteId string) revel.Result {
re := info.NewApiRe() re := info.NewApiRe()
userId := c.getUserId() userId := c.getUserId()
@@ -612,7 +566,7 @@ func (c ApiNote) ExportPdf(noteId string) revel.Result {
// path 判断是否需要重新生成之 // path 判断是否需要重新生成之
guid := NewGuid() guid := NewGuid()
fileUrlPath := "files/" + Digest3(noteUserId) + "/" + noteUserId + "/" + Digest2(guid) + "/images/pdf" fileUrlPath := "files/export_pdf"
dir := revel.BasePath + "/" + fileUrlPath dir := revel.BasePath + "/" + fileUrlPath
if !MkdirAll(dir) { if !MkdirAll(dir) {
re.Msg = "noDir" re.Msg = "noDir"
@@ -635,10 +589,10 @@ func (c ApiNote) ExportPdf(noteId string) revel.Result {
url := configService.GetSiteUrl() + "/note/toPdf?noteId=" + noteId + "&appKey=" + appKey url := configService.GetSiteUrl() + "/note/toPdf?noteId=" + noteId + "&appKey=" + appKey
var cc string var cc string
if(note.IsMarkdown) { if note.IsMarkdown {
cc = binPath + " --window-status done \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\"" cc = binPath + " --lowquality --window-status done \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\""
} else { } else {
cc = binPath + " \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\"" cc = binPath + " --lowquality \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\""
} }
cmd := exec.Command("/bin/sh", "-c", cc) cmd := exec.Command("/bin/sh", "-c", cc)
+1 -1
View File
@@ -2,9 +2,9 @@ package api
import ( import (
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea"
"github.com/revel/revel" "github.com/revel/revel"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
. "github.com/leanote/leanote/app/lea"
// "io/ioutil" // "io/ioutil"
) )
+1 -2
View File
@@ -3,9 +3,9 @@ package api
import ( import (
"github.com/revel/revel" "github.com/revel/revel"
// "encoding/json" // "encoding/json"
"gopkg.in/mgo.v2/bson"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson"
"time" "time"
// "github.com/leanote/leanote/app/types" // "github.com/leanote/leanote/app/types"
"io/ioutil" "io/ioutil"
@@ -82,7 +82,6 @@ func (c ApiUser) GetSyncState() revel.Result {
return c.RenderJson(ret) return c.RenderJson(ret)
} }
// 头像设置 // 头像设置
// 参数file=文件 // 参数file=文件
// 成功返回{Logo: url} 头像新url // 成功返回{Logo: url} 头像新url
+1 -1
View File
@@ -90,7 +90,7 @@ func AuthInterceptor(c *revel.Controller) revel.Result {
if noToken && userId == "" { if noToken && userId == "" {
// 从session中获取, api/file/getImage, api/file/getAttach, api/file/getAllAttach // 从session中获取, api/file/getImage, api/file/getAttach, api/file/getAllAttach
// 客户端 // 客户端
userId, _ = c.Session["UserId"]; userId, _ = c.Session["UserId"]
} }
c.Session["_userId"] = userId c.Session["_userId"] = userId
+1 -1
View File
@@ -1,9 +1,9 @@
package controllers package controllers
import ( import (
"github.com/leanote/leanote/app/service"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/lea/blog" "github.com/leanote/leanote/app/lea/blog"
"github.com/leanote/leanote/app/service"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
"github.com/revel/revel" "github.com/revel/revel"
"strings" "strings"
@@ -4,8 +4,8 @@ import (
// "github.com/revel/revel" // "github.com/revel/revel"
// "gopkg.in/mgo.v2/bson" // "gopkg.in/mgo.v2/bson"
// "encoding/json" // "encoding/json"
. "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/controllers" "github.com/leanote/leanote/app/controllers"
. "github.com/leanote/leanote/app/lea"
// "io/ioutil" // "io/ioutil"
// "fmt" // "fmt"
// "math" // "math"
@@ -24,19 +24,19 @@ func (c MemberBaseController) getSorter(sorterField string, isAsc bool, okSorter
sorter := "" sorter := ""
c.Params.Bind(&sorter, "sorter") c.Params.Bind(&sorter, "sorter")
if sorter == "" { if sorter == "" {
return sorterField, isAsc; return sorterField, isAsc
} }
// sorter形式 email-up, email-down // sorter形式 email-up, email-down
s2 := strings.Split(sorter, "-") s2 := strings.Split(sorter, "-")
if len(s2) != 2 { if len(s2) != 2 {
return sorterField, isAsc; return sorterField, isAsc
} }
// 必须是可用的sorter // 必须是可用的sorter
if okSorter != nil && len(okSorter) > 0 { if okSorter != nil && len(okSorter) > 0 {
if !InArray(okSorter, s2[0]) { if !InArray(okSorter, s2[0]) {
return sorterField, isAsc; return sorterField, isAsc
} }
} }
@@ -47,7 +47,7 @@ func (c MemberBaseController) getSorter(sorterField string, isAsc bool, okSorter
isAsc = false isAsc = false
} }
c.RenderArgs["sorter"] = sorter c.RenderArgs["sorter"] = sorter
return sorterField, isAsc; return sorterField, isAsc
} }
func (c MemberBaseController) updateConfig(keys []string) { func (c MemberBaseController) updateConfig(keys []string) {
+15 -13
View File
@@ -74,7 +74,7 @@ func (c MemberBlog) Index(sorter, keywords string) revel.Result {
userInfo := userService.GetUserInfo(userId) userInfo := userService.GetUserInfo(userId)
c.RenderArgs["userInfo"] = userInfo c.RenderArgs["userInfo"] = userInfo
c.RenderArgs["title"] = "Posts" c.RenderArgs["title"] = c.Message("Posts")
pageNumber := c.GetPage() pageNumber := c.GetPage()
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "urlTitle", "updatedTime", "publicTime", "createdTime"}) sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "urlTitle", "updatedTime", "publicTime", "createdTime"})
pageInfo, blogs := blogService.ListAllBlogs(c.GetUserId(), "", keywords, false, pageNumber, userPageSize, sorterField, isAsc) pageInfo, blogs := blogService.ListAllBlogs(c.GetUserId(), "", keywords, false, pageNumber, userPageSize, sorterField, isAsc)
@@ -85,6 +85,8 @@ func (c MemberBlog) Index(sorter, keywords string) revel.Result {
userAndBlog := userService.GetUserAndBlog(c.GetUserId()) userAndBlog := userService.GetUserAndBlog(c.GetUserId())
c.RenderArgs["userAndBlog"] = userAndBlog c.RenderArgs["userAndBlog"] = userAndBlog
c.common()
return c.RenderTemplate("member/blog/list.html") return c.RenderTemplate("member/blog/list.html")
} }
@@ -97,7 +99,8 @@ func (c MemberBlog) UpdateBlogUrlTitle(noteId, urlTitle string) revel.Result {
// 修改笔记的urlTitle // 修改笔记的urlTitle
func (c MemberBlog) UpdateBlogAbstract(noteId string) revel.Result { func (c MemberBlog) UpdateBlogAbstract(noteId string) revel.Result {
c.RenderArgs["title"] = "Update Post Abstract" c.common()
c.RenderArgs["title"] = c.Message("Update Post Abstract")
note := noteService.GetNoteAndContent(noteId, c.GetUserId()) note := noteService.GetNoteAndContent(noteId, c.GetUserId())
if !note.Note.IsBlog { if !note.Note.IsBlog {
return c.E404() return c.E404()
@@ -107,7 +110,6 @@ func (c MemberBlog) UpdateBlogAbstract(noteId string) revel.Result {
return c.RenderTemplate("member/blog/update_abstract.html") return c.RenderTemplate("member/blog/update_abstract.html")
} }
func (c MemberBlog) DoUpdateBlogAbstract(noteId, imgSrc, desc, abstract string) revel.Result { func (c MemberBlog) DoUpdateBlogAbstract(noteId, imgSrc, desc, abstract string) revel.Result {
re := info.NewRe() re := info.NewRe()
re.Ok = blogService.UpateBlogAbstract(c.GetUserId(), noteId, imgSrc, desc, abstract) re.Ok = blogService.UpateBlogAbstract(c.GetUserId(), noteId, imgSrc, desc, abstract)
return c.RenderJson(re) return c.RenderJson(re)
@@ -116,24 +118,24 @@ func (c MemberBlog) DoUpdateBlogAbstract(noteId, imgSrc, desc, abstract string)
// 基本信息设置 // 基本信息设置
func (c MemberBlog) Base() revel.Result { func (c MemberBlog) Base() revel.Result {
c.common() c.common()
c.RenderArgs["title"] = "Blog Base Info" c.RenderArgs["title"] = c.Message("Blog Base Info")
return c.RenderTemplate("member/blog/base.html") return c.RenderTemplate("member/blog/base.html")
} }
func (c MemberBlog) Comment() revel.Result { func (c MemberBlog) Comment() revel.Result {
c.common() c.common()
c.RenderArgs["title"] = "Comment" c.RenderArgs["title"] = c.Message("Comment")
return c.RenderTemplate("member/blog/comment.html") return c.RenderTemplate("member/blog/comment.html")
} }
func (c MemberBlog) Paging() revel.Result { func (c MemberBlog) Paging() revel.Result {
c.common() c.common()
c.RenderArgs["title"] = "Paging" c.RenderArgs["title"] = c.Message("Paging")
return c.RenderTemplate("member/blog/paging.html") return c.RenderTemplate("member/blog/paging.html")
} }
func (c MemberBlog) Cate() revel.Result { func (c MemberBlog) Cate() revel.Result {
userBlog := c.common() userBlog := c.common()
c.RenderArgs["title"] = "Cate" c.RenderArgs["title"] = c.Message("Category")
notebooks := blogService.ListBlogNotebooks(c.GetUserId()) notebooks := blogService.ListBlogNotebooks(c.GetUserId())
notebooksMap := map[string]info.Notebook{} notebooksMap := map[string]info.Notebook{}
@@ -190,10 +192,10 @@ func (c MemberBlog) DoAddOrUpdateSingle(singleId, title, content string) revel.R
} }
func (c MemberBlog) AddOrUpdateSingle(singleId string) revel.Result { func (c MemberBlog) AddOrUpdateSingle(singleId string) revel.Result {
c.common() c.common()
c.RenderArgs["title"] = "Add Single" c.RenderArgs["title"] = c.Message("Add Single")
c.RenderArgs["singleId"] = singleId c.RenderArgs["singleId"] = singleId
if singleId != "" { if singleId != "" {
c.RenderArgs["title"] = "Update Single" c.RenderArgs["title"] = c.Message("Update Single")
c.RenderArgs["single"] = blogService.GetSingle(singleId) c.RenderArgs["single"] = blogService.GetSingle(singleId)
} }
return c.RenderTemplate("member/blog/add_single.html") return c.RenderTemplate("member/blog/add_single.html")
@@ -219,7 +221,7 @@ func (c MemberBlog) UpdateSingleUrlTitle(singleId, urlTitle string) revel.Result
func (c MemberBlog) Single() revel.Result { func (c MemberBlog) Single() revel.Result {
c.common() c.common()
c.RenderArgs["title"] = "Cate" c.RenderArgs["title"] = c.Message("Single")
c.RenderArgs["singles"] = blogService.GetSingles(c.GetUserId()) c.RenderArgs["singles"] = blogService.GetSingles(c.GetUserId())
return c.RenderTemplate("member/blog/single.html") return c.RenderTemplate("member/blog/single.html")
@@ -234,7 +236,7 @@ func (c MemberBlog) Theme() revel.Result {
c.RenderArgs["optionThemes"] = themeService.GetDefaultThemes() c.RenderArgs["optionThemes"] = themeService.GetDefaultThemes()
c.RenderArgs["title"] = "Theme" c.RenderArgs["title"] = c.Message("Theme")
return c.RenderTemplate("member/blog/theme.html") return c.RenderTemplate("member/blog/theme.html")
} }
@@ -251,7 +253,7 @@ func (c MemberBlog) UpdateTheme(themeId string, isNew int) revel.Result {
} }
c.common() c.common()
c.RenderArgs["title"] = "Upate Theme" c.RenderArgs["title"] = c.Message("Update Theme")
c.RenderArgs["isNew"] = isNew c.RenderArgs["isNew"] = isNew
// 先复制之 // 先复制之
@@ -443,8 +445,8 @@ func (c MemberBlog) ImportTheme() revel.Result {
if err != nil { if err != nil {
re.Msg = fmt.Sprintf("%v", err) re.Msg = fmt.Sprintf("%v", err)
return c.RenderJson(re) return c.RenderJson(re)
} }
defer file.Close() defer file.Close()
// 生成上传路径 // 生成上传路径
userId := c.GetUserId() userId := c.GetUserId()
@@ -1,8 +1,8 @@
package member package member
import ( import (
"github.com/revel/revel"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"github.com/revel/revel"
) )
// 分组管理 // 分组管理
@@ -14,9 +14,9 @@ type MemberGroup struct {
func (c MemberGroup) Index() revel.Result { func (c MemberGroup) Index() revel.Result {
c.SetUserInfo() c.SetUserInfo()
c.SetLocale() c.SetLocale()
c.RenderArgs["title"] = "My Group" c.RenderArgs["title"] = c.Message("My Group")
c.RenderArgs["groups"] = groupService.GetGroupsAndUsers(c.GetUserId()) c.RenderArgs["groups"] = groupService.GetGroupsAndUsers(c.GetUserId())
return c.RenderTemplate("member/group/index.html"); return c.RenderTemplate("member/group/index.html")
} }
// 添加分组 // 添加分组
@@ -13,14 +13,14 @@ type MemberIndex struct {
// admin 主页 // admin 主页
func (c MemberIndex) Index() revel.Result { func (c MemberIndex) Index() revel.Result {
c.SetUserInfo() c.SetUserInfo()
c.RenderArgs["title"] = "Leanote Member Center" c.RenderArgs["title"] = c.Message("Leanote Member Center")
c.RenderArgs["countNote"] = noteService.CountNote(c.GetUserId()) c.RenderArgs["countNote"] = noteService.CountNote(c.GetUserId())
c.RenderArgs["countBlog"] = noteService.CountBlog(c.GetUserId()) c.RenderArgs["countBlog"] = noteService.CountBlog(c.GetUserId())
c.SetLocale() c.SetLocale()
return c.RenderTemplate("member/index.html"); return c.RenderTemplate("member/index.html")
} }
// 模板 // 模板
@@ -33,5 +33,5 @@ func (c MemberIndex) T(t string) revel.Result {
} }
func (c MemberIndex) GetView(view string) revel.Result { func (c MemberIndex) GetView(view string) revel.Result {
return c.RenderTemplate("admin/" + view); return c.RenderTemplate("admin/" + view)
} }
+8 -14
View File
@@ -13,34 +13,28 @@ type MemberUser struct {
func (c MemberUser) Username() revel.Result { func (c MemberUser) Username() revel.Result {
c.SetUserInfo() c.SetUserInfo()
c.SetLocale() c.SetLocale()
c.RenderArgs["title"] = "Username" c.RenderArgs["title"] = c.Message("Username")
return c.RenderTemplate("member/user/username.html"); return c.RenderTemplate("member/user/username.html")
} }
func (c MemberUser) Email() revel.Result { func (c MemberUser) Email() revel.Result {
c.SetUserInfo() c.SetUserInfo()
c.SetLocale() c.SetLocale()
c.RenderArgs["title"] = "Email" c.RenderArgs["title"] = c.Message("Email")
return c.RenderTemplate("member/user/email.html"); return c.RenderTemplate("member/user/email.html")
} }
func (c MemberUser) Password() revel.Result { func (c MemberUser) Password() revel.Result {
c.SetUserInfo() c.SetUserInfo()
c.SetLocale() c.SetLocale()
c.RenderArgs["title"] = "Password" c.RenderArgs["title"] = c.Message("Password")
return c.RenderTemplate("member/user/password.html"); return c.RenderTemplate("member/user/password.html")
} }
func (c MemberUser) Avatar() revel.Result { func (c MemberUser) Avatar() revel.Result {
c.SetUserInfo() c.SetUserInfo()
c.SetLocale() c.SetLocale()
c.RenderArgs["title"] = "Avatar" c.RenderArgs["title"] = c.Message("Avatar")
c.RenderArgs["globalConfigs"] = configService.GetGlobalConfigForUser() c.RenderArgs["globalConfigs"] = configService.GetGlobalConfigForUser()
return c.RenderTemplate("member/user/avatar.html"); return c.RenderTemplate("member/user/avatar.html")
}
func (c MemberUser) AddAccount() revel.Result {
c.SetUserInfo()
c.SetLocale()
c.RenderArgs["title"] = "Add Account"
return c.RenderTemplate("member/user/add_account.html");
} }
+3 -2
View File
@@ -1,8 +1,8 @@
package member package member
import ( import (
"github.com/leanote/leanote/app/service"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/service"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
"github.com/revel/revel" "github.com/revel/revel"
// "strings" // "strings"
@@ -58,6 +58,7 @@ var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": tru
"File": map[string]bool{"OutputImage": true, "OutputFile": true}, "File": map[string]bool{"OutputImage": true, "OutputFile": true},
"Attach": map[string]bool{"Download": true, "DownloadAll": true}, "Attach": map[string]bool{"Download": true, "DownloadAll": true},
} }
func needValidate(controller, method string) bool { func needValidate(controller, method string) bool {
// 在里面 // 在里面
if v, ok := commonUrl[controller]; ok { if v, ok := commonUrl[controller]; ok {
@@ -68,7 +69,7 @@ func needValidate(controller, method string) bool {
return true return true
} else { } else {
// controller不在这里的, 肯定要验证 // controller不在这里的, 肯定要验证
return true; return true
} }
} }
func AuthInterceptor(c *revel.Controller) revel.Result { func AuthInterceptor(c *revel.Controller) revel.Result {
-2
View File
@@ -1,2 +0,0 @@
包括基本信息设置
博客设置
+211 -1
View File
@@ -2,8 +2,8 @@ package db
import ( import (
"fmt" "fmt"
"github.com/revel/revel"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"github.com/revel/revel"
"gopkg.in/mgo.v2" "gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"strings" "strings"
@@ -166,6 +166,216 @@ func Init(url, dbname string) {
// session // session
Sessions = Session.DB(dbname).C("sessions") Sessions = Session.DB(dbname).C("sessions")
collectionNames, err := Session.DB(dbname).CollectionNames()
// 如果没有表, 则表示是第一次安装
if (err != nil || len(collectionNames) == 0) {
Log("init db index")
initIndex(dbname)
}
}
func initIndex(dbname string) {
// 索引
indexes := map[string][]mgo.Index{
"notebooks": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"notes": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
mgo.Index{
Key: []string{"IsTrash"},
Background: true,
},
mgo.Index{
Key: []string{"UrlTitle"},
Background: true,
},
mgo.Index{
Key: []string{"IsBlog"},
Background: true,
},
mgo.Index{
Key: []string{"CreatedTime"},
Background: true,
},
mgo.Index{
Key: []string{"UpdatedTime"},
Background: true,
},
mgo.Index{
Key: []string{"PublicTime"},
Background: true,
},
mgo.Index{
Key: []string{"RecommendTime"},
Background: true,
},
mgo.Index{
Key: []string{"NotebookId"},
Background: true,
},
mgo.Index{
Key: []string{"UserId", "IsBlog"},
Background: true,
},
},
"note_contents": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"note_content_histories": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"share_notes": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
mgo.Index{
Key: []string{"ToUserId"},
Background: true,
},
},
"share_notebooks": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
mgo.Index{
Key: []string{"ToUserId"},
Background: true,
},
},
"has_share_notes": []mgo.Index{
mgo.Index{
Key: []string{"UserId", "ToUserId"},
Background: true,
Unique: true,
},
},
"users": []mgo.Index{
mgo.Index{
Key: []string{"Email"},
Background: true,
},
mgo.Index{
Key: []string{"Username"},
Background: true,
},
},
"groups": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"group_users": []mgo.Index{
mgo.Index{
Key: []string{"GroupId"},
Background: true,
},
},
"tags": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"note_tags": []mgo.Index{
mgo.Index{
Key: []string{"UserId", "TagId"},
Background: true,
},
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"tag_count": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"blog_singles": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"blog_likes": []mgo.Index{
mgo.Index{
Key: []string{"NoteId"},
Background: true,
},
},
"blog_comments": []mgo.Index{
mgo.Index{
Key: []string{"NoteId"},
Background: true,
},
},
"themes": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"note_images": []mgo.Index{
mgo.Index{
Key: []string{"ImageId"},
Background: true,
},
mgo.Index{
Key: []string{"NoteId"},
Background: true,
},
},
"albums": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"files": []mgo.Index{
mgo.Index{
Key: []string{"UserId"},
Background: true,
},
},
"attachs": []mgo.Index{
mgo.Index{
Key: []string{"NoteId"},
Background: true,
},
},
"sessions": []mgo.Index{
mgo.Index{
Key: []string{"SessionId"},
Background: true,
},
},
}
for collection, ins := range indexes {
col := Session.DB(dbname).C(collection)
for _, in := range ins {
col.EnsureIndex(in)
}
}
} }
func close() { func close() {
-91
View File
@@ -1,91 +0,0 @@
package main
import (
"fmt"
"os"
"bufio"
"strings"
"encoding/json"
)
// convert revel msg to js msg
var msgBasePath = "/Users/life/Documents/Go/package2/src/github.com/leanote/leanote/messages/"
var targetBasePath = "/Users/life/Documents/Go/package2/src/github.com/leanote/leanote/public/js/i18n/"
func parse(filename string) {
file, err := os.Open(msgBasePath + filename)
reader := bufio.NewReader(file)
msg := map[string]string{}
if err != nil {
fmt.Println(err)
return
}
for true {
line, _, err := reader.ReadLine()
if err != nil {
break
}
if len(line) == 0 {
continue
}
// 对每一行进行处理
if line[0] == '#' || line[1] == '#' {
continue;
}
lineStr := string(line)
// 找到第一个=位置
pos := strings.Index(lineStr, "=")
if pos < 0 {
continue;
}
key := string(line[0:pos])
value := string(line[pos+1:])
// fmt.Println(lineStr)
// fmt.Println(value)
msg[key] = value
}
// JSON
b, _ := json.Marshal(msg)
str := string(b)
fmt.Println(str);
targetName := targetBasePath + filename + ".js"
file2, err2 := os.OpenFile(targetName, os.O_RDWR|os.O_CREATE, 0644)
if err2 != nil {
file2, err2 = os.Create(targetName)
}
file2.WriteString("var MSG = " + str + ";" + `
function getMsg(key, data) {
var msg = MSG[key]
if(msg) {
if(data) {
if(!isArray(data)) {
data = [data];
}
for(var i = 0; i < data.length; ++i) {
msg = msg.replace("%s", data[i]);
}
}
return msg;
}
return key;
}`)
}
// 生成js的i18n文件
func main() {
parse("msg.en")
parse("msg.zh")
parse("msg.fr")
parse("blog.zh")
parse("blog.en")
parse("blog.fr")
}
+2 -2
View File
@@ -1,8 +1,8 @@
package info package info
import ( import (
"time"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"time"
) )
//--------- //---------
@@ -38,7 +38,6 @@ type ApiNote struct {
PublicTime time.Time PublicTime time.Time
} }
// 内容 // 内容
type ApiNoteContent struct { type ApiNoteContent struct {
NoteId bson.ObjectId `bson:"_id,omitempty"` NoteId bson.ObjectId `bson:"_id,omitempty"`
@@ -114,6 +113,7 @@ type ReUpdate struct {
Msg string Msg string
Usn int Usn int
} }
func NewReUpdate() ReUpdate { func NewReUpdate() ReUpdate {
return ReUpdate{Ok: false} return ReUpdate{Ok: false}
} }
+1
View File
@@ -37,6 +37,7 @@ type Post struct {
LikeNum int LikeNum int
IsMarkdown bool IsMarkdown bool
} }
// 归档 // 归档
type ArchiveMonth struct { type ArchiveMonth struct {
Month int Month int
+21
View File
@@ -80,3 +80,24 @@ type NoteContentHistory struct {
UserId bson.ObjectId `bson:"UserId"` // 所属者 UserId bson.ObjectId `bson:"UserId"` // 所属者
Histories []EachHistory `Histories` Histories []EachHistory `Histories`
} }
// 为了NoteController接收参数
// 更新note或content
// 肯定会传userId(谁的), NoteId
// 会传Title, Content, Tags, 一种或几种
type NoteOrContent struct {
NotebookId string
NoteId string
UserId string
Title string
Desc string
ImgSrc string
Tags string
Content string
Abstract string
IsNew bool
IsMarkdown bool
FromUserId string // 为共享而新建
IsBlog bool // 是否是blog, 更新note不需要修改, 添加note时才有可能用到, 此时需要判断notebook是否设为Blog
}
+1 -2
View File
@@ -1,7 +1,6 @@
package info package info
import ( import ()
)
// controller ajax返回 // controller ajax返回
type Re struct { type Re struct {
-1
View File
@@ -4,7 +4,6 @@ import (
"math" "math"
) )
// 分页数据 // 分页数据
type Page struct { type Page struct {
CurPage int // 当前页码 CurPage int // 当前页码
+45 -35
View File
@@ -1,25 +1,26 @@
package app package app
import ( import (
"github.com/revel/revel" "encoding/json"
. "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/service"
"github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/controllers"
"github.com/leanote/leanote/app/controllers/api"
"github.com/leanote/leanote/app/controllers/admin"
"github.com/leanote/leanote/app/controllers/member"
_ "github.com/leanote/leanote/app/lea/binder"
"github.com/leanote/leanote/app/lea/route"
"reflect"
"fmt" "fmt"
"github.com/leanote/leanote/app/controllers"
"github.com/leanote/leanote/app/controllers/admin"
"github.com/leanote/leanote/app/controllers/api"
"github.com/leanote/leanote/app/controllers/member"
"github.com/leanote/leanote/app/db"
. "github.com/leanote/leanote/app/lea"
_ "github.com/leanote/leanote/app/lea/binder"
"github.com/leanote/leanote/app/lea/i18n"
"github.com/leanote/leanote/app/lea/route"
"github.com/leanote/leanote/app/service"
"github.com/revel/revel"
"html/template" "html/template"
"math" "math"
"strings"
"strconv"
"time"
"encoding/json"
"net/url" "net/url"
"reflect"
"strconv"
"strings"
"time"
) )
func init() { func init() {
@@ -40,7 +41,8 @@ func init() {
revel.FlashFilter, // Restore and write the flash cookie. revel.FlashFilter, // Restore and write the flash cookie.
revel.ValidationFilter, // Restore kept validation errors and save new ones from cookie. revel.ValidationFilter, // Restore kept validation errors and save new ones from cookie.
revel.I18nFilter, // Resolve the requested language // revel.I18nFilter, // Resolve the requested language
i18n.I18nFilter, // Resolve the requested language by leanote
revel.InterceptorFilter, // Run interceptors around the action. revel.InterceptorFilter, // Run interceptors around the action.
revel.CompressFilter, // Compress the result. revel.CompressFilter, // Compress the result.
revel.ActionInvoker, // Invoke the action. revel.ActionInvoker, // Invoke the action.
@@ -62,16 +64,16 @@ func init() {
return str return str
} }
revel.TemplateFuncs["add"] = func(i int) string { revel.TemplateFuncs["add"] = func(i int) string {
i = i + 1; i = i + 1
return fmt.Sprintf("%v", i) return fmt.Sprintf("%v", i)
} }
revel.TemplateFuncs["sub"] = func(i int) int { revel.TemplateFuncs["sub"] = func(i int) int {
i = i - 1; i = i - 1
return i return i
} }
// 增加或减少 // 增加或减少
revel.TemplateFuncs["incr"] = func(n, i int) int { revel.TemplateFuncs["incr"] = func(n, i int) int {
n = n + i; n = n + i
return n return n
} }
revel.TemplateFuncs["join"] = func(arr []string) template.HTML { revel.TemplateFuncs["join"] = func(arr []string) template.HTML {
@@ -147,7 +149,7 @@ func init() {
classes += " label-post" classes += " label-post"
var url = tagPostUrl + "/" + url.QueryEscape(tag) var url = tagPostUrl + "/" + url.QueryEscape(tag)
tagStr += "<a class=\"" + classes + "\" href=\"" + url + "\">" + str + "</a>"; tagStr += "<a class=\"" + classes + "\" href=\"" + url + "\">" + str + "</a>"
if i != lenTags-1 { if i != lenTags-1 {
tagStr += " " tagStr += " "
} }
@@ -172,7 +174,7 @@ func init() {
} }
classes += " label-post" classes += " label-post"
tagStr += "<span class=\"" + classes + "\" >" + str + "</span>"; tagStr += "<span class=\"" + classes + "\" >" + str + "</span>"
if i != lenTags-1 { if i != lenTags-1 {
tagStr += " " tagStr += " "
} }
@@ -180,14 +182,22 @@ func init() {
return template.HTML(tagStr) return template.HTML(tagStr)
} }
revel.TemplateFuncs["msg"] = func(renderArgs map[string]interface{}, message string, args ...interface{}) template.HTML {
str, ok := renderArgs[revel.CurrentLocaleRenderArg].(string)
if !ok {
return ""
}
return template.HTML(i18n.Message(str, message, args...))
}
// 不用revel的msg // 不用revel的msg
revel.TemplateFuncs["leaMsg"] = func(renderArgs map[string]interface{}, key string) template.HTML { revel.TemplateFuncs["leaMsg"] = func(renderArgs map[string]interface{}, key string) template.HTML {
locale, _ := renderArgs[revel.CurrentLocaleRenderArg].(string) locale, _ := renderArgs[revel.CurrentLocaleRenderArg].(string)
str := revel.Message(locale, key) str := i18n.Message(locale, key)
if strings.HasPrefix(str, "???") { if strings.HasPrefix(str, "???") {
str = key str = key
} }
return template.HTML(str); return template.HTML(str)
} }
// lea++ // lea++
@@ -201,11 +211,11 @@ func init() {
tagPostUrl := "http://lea.leanote.com/" tagPostUrl := "http://lea.leanote.com/"
if typeStr == "recommend" { if typeStr == "recommend" {
tagPostUrl += "?tag="; tagPostUrl += "?tag="
} else if typeStr == "latest" { } else if typeStr == "latest" {
tagPostUrl += "latest?tag="; tagPostUrl += "latest?tag="
} else { } else {
tagPostUrl += "subscription?tag="; tagPostUrl += "subscription?tag="
} }
for i, tag := range tags { for i, tag := range tags {
@@ -221,7 +231,7 @@ func init() {
} }
classes += " label-post" classes += " label-post"
var url = tagPostUrl + url.QueryEscape(tag) var url = tagPostUrl + url.QueryEscape(tag)
tagStr += "<a class=\"" + classes + "\" href=\"" + url + "\">" + str + "</a>"; tagStr += "<a class=\"" + classes + "\" href=\"" + url + "\">" + str + "</a>"
if i != lenTags-1 { if i != lenTags-1 {
tagStr += " " tagStr += " "
} }
@@ -260,7 +270,7 @@ func init() {
for i := 0; i < len(v); i = i + 2 { for i := 0; i < len(v); i = i + 2 {
item := v[i] item := v[i]
if i+1 == len(v) { if i+1 == len(v) {
break; break
} }
value := v[i+1] value := v[i+1]
if item != nil && value != nil { if item != nil && value != nil {
@@ -317,21 +327,21 @@ func init() {
if sorterI != nil { if sorterI != nil {
sorter, _ = sorterI.(string) sorter, _ = sorterI.(string)
} }
html := "data-url=\"" + url + "\" data-sorter=\"" + sorterField + "\""; html := "data-url=\"" + url + "\" data-sorter=\"" + sorterField + "\""
html += " class=\"th-sortable "; html += " class=\"th-sortable "
if sorter == sorterField+"-up" { if sorter == sorterField+"-up" {
html += "th-sort-up\""; html += "th-sort-up\""
} else if(sorter == sorterField + "-down") { } else if sorter == sorterField+"-down" {
html += "th-sort-down"; html += "th-sort-down"
} }
html += "\""; html += "\""
return template.HTMLAttr(html) return template.HTMLAttr(html)
} }
// pagination // pagination
revel.TemplateFuncs["page"] = func(urlBase string, page, pageSize, count int) template.HTML { revel.TemplateFuncs["page"] = func(urlBase string, page, pageSize, count int) template.HTML {
if count == 0 { if count == 0 {
return ""; return ""
} }
totalPage := int(math.Ceil(float64(count) / float64(pageSize))) totalPage := int(math.Ceil(float64(count) / float64(pageSize)))
+1 -1
View File
@@ -2,8 +2,8 @@ package lea
import ( import (
"encoding/json" "encoding/json"
"github.com/revel/revel"
"fmt" "fmt"
"github.com/revel/revel"
) )
func Log(i interface{}) { func Log(i interface{}) {
+5 -3
View File
@@ -1,10 +1,11 @@
package lea package lea
import ( import (
"github.com/revel/revel"
"net/smtp" "net/smtp"
"strings" "strings"
"github.com/revel/revel"
) )
// 发送邮件 // 发送邮件
var host = "smtp.ym.163.com" var host = "smtp.ym.163.com"
var port = "25" var port = "25"
@@ -12,7 +13,7 @@ var username = "noreply@leanote.com"
var password = "---" var password = "---"
func InitEmail() { func InitEmail() {
config := revel.Config; config := revel.Config
host, _ = config.String("email.host") host, _ = config.String("email.host")
port, _ = config.String("email.port") port, _ = config.String("email.port")
username, _ = config.String("email.username") username, _ = config.String("email.username")
@@ -56,6 +57,7 @@ var bodyTpl = `
</body> </body>
</html> </html>
` `
func SendEmailOld(to, subject, body string) bool { func SendEmailOld(to, subject, body string) bool {
hp := strings.Split(host, ":") hp := strings.Split(host, ":")
auth := smtp.PlainAuth("", username, password, hp[0]) auth := smtp.PlainAuth("", username, password, hp[0])
@@ -85,5 +87,5 @@ func SendEmailOld(to, subject, body string) bool {
func SendToLeanoteOld(subject, title, body string) { func SendToLeanoteOld(subject, title, body string) {
to := "leanote@leanote.com" to := "leanote@leanote.com"
SendEmailOld(to, subject, body); SendEmailOld(to, subject, body)
} }
+50 -13
View File
@@ -1,19 +1,19 @@
package lea package lea
import ( import (
"fmt" "bytes"
"regexp"
"crypto/md5" "crypto/md5"
"crypto/rand" "crypto/rand"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"io" "fmt"
"gopkg.in/mgo.v2/bson"
"time"
"strings"
"github.com/PuerkitoBio/goquery" "github.com/PuerkitoBio/goquery"
"bytes" "gopkg.in/mgo.v2/bson"
"io"
math_rand "math/rand" math_rand "math/rand"
"regexp"
"strings"
"time"
) )
// 字符串 // 字符串
@@ -161,7 +161,7 @@ func SubStringHTMLToRaw(param string, length int) string {
continue continue
} else if temp == '>' { } else if temp == '>' {
isCode = false isCode = false
resultRune[n] = ' '; resultRune[n] = ' '
n++ n++
if n >= length { if n >= length {
@@ -170,7 +170,7 @@ func SubStringHTMLToRaw(param string, length int) string {
continue continue
} }
if !isCode { if !isCode {
resultRune[n] = temp; resultRune[n] = temp
// s += string(temp) // s += string(temp)
n++ n++
if n >= length { if n >= length {
@@ -244,7 +244,7 @@ func SubStringHTML(param string, length int, end string) string {
var temp rune // 中文问题, 用rune来解决 var temp rune // 中文问题, 用rune来解决
isCode := false //是不是HTML代码 isCode := false //是不是HTML代码
isHTML := false //是不是HTML特殊字符,如&nbsp; isHTML := false //是不是HTML特殊字符,如&nbsp;
var i = 0; var i = 0
for ; i < lenStr; i++ { for ; i < lenStr; i++ {
temp = rStr[i] temp = rStr[i]
if temp == '<' { if temp == '<' {
@@ -305,7 +305,7 @@ func IsGoodPwd(pwd string) (bool, string) {
// 是否是email // 是否是email
func IsEmail(email string) bool { func IsEmail(email string) bool {
if email == "" { if email == "" {
return false; return false
} }
ok, _ := regexp.MatchString(`^([a-zA-Z0-9]+[_|\_|\.|\-]?)*[_a-z\-A-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.|\-]?)*[a-zA-Z0-9\-]+\.[0-9a-zA-Z]{2,6}$`, email) ok, _ := regexp.MatchString(`^([a-zA-Z0-9]+[_|\_|\.|\-]?)*[_a-z\-A-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.|\-]?)*[a-zA-Z0-9\-]+\.[0-9a-zA-Z]{2,6}$`, email)
return ok return ok
@@ -314,7 +314,7 @@ func IsEmail(email string) bool {
// 是否只包含数字, 字母 -, _ // 是否只包含数字, 字母 -, _
func IsUsername(username string) bool { func IsUsername(username string) bool {
if username == "" { if username == "" {
return false; return false
} }
ok, _ := regexp.MatchString(`[^0-9a-zA-Z_\-]`, username) ok, _ := regexp.MatchString(`[^0-9a-zA-Z_\-]`, username)
return !ok return !ok
@@ -351,7 +351,7 @@ func RandomPwd(num int) string {
chars[j] = byte(i) chars[j] = byte(i)
j++ j++
} }
j--; j--
str := "" str := ""
math_rand.Seed(time.Now().UnixNano()) math_rand.Seed(time.Now().UnixNano())
@@ -394,3 +394,40 @@ func FixFilename(filename string) string {
} }
return filename return filename
} }
// 是否是合法的时间
// 不是, 0001-01-01T00:00:00Z, 且比今天小
func IsValidTime(t time.Time) bool {
if t.Year() > 20 {
now := time.Now()
Log("------")
Log(t)
Log(now)
if t.Before(now) {
return true
}
}
return false
}
// url传过来的时间没有时区信息, 转到本地时间
func ToLocalTime(t time.Time) time.Time {
return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), 0, time.Local)
}
// 修复传过来的时间, 如果比今天大, 则设为现在
func FixUrlTime(t time.Time) time.Time {
localTime := ToLocalTime(t)
if IsValidTime(localTime) {
return localTime
}
return time.Now()
}
// 得到用户的随机文件路径 3位/userId/2位
func GetRandomFilePath(userId, uuid string) string {
if uuid == "" {
uuid = NewGuid()
}
return Digest3(userId) + "/" + userId + "/" + Digest2(uuid)
}
+1 -1
View File
@@ -2,8 +2,8 @@ package lea
import ( import (
"encoding/json" "encoding/json"
"strconv"
"regexp" "regexp"
"strconv"
) )
// 验证 // 验证
+4 -4
View File
@@ -3,10 +3,10 @@ package archive
import ( import (
"archive/zip" "archive/zip"
"fmt" "fmt"
"strings"
"io" "io"
"os" "os"
"path" "path"
"strings"
) )
// main functions shows how to TarGz a directory/file and // main functions shows how to TarGz a directory/file and
@@ -138,14 +138,14 @@ func Unzip(srcFilePath string, destDirPath string) (ok bool, msg string) {
}() }()
os.Mkdir(destDirPath, os.ModePerm) os.Mkdir(destDirPath, os.ModePerm)
r, err := zip.OpenReader(srcFilePath); r, err := zip.OpenReader(srcFilePath)
if err != nil { if err != nil {
panic(err) panic(err)
} }
defer r.Close(); defer r.Close()
for _, f := range r.File { for _, f := range r.File {
// fmt.Println("FileName : ", f.Name); // j/aaa.zip // fmt.Println("FileName : ", f.Name); // j/aaa.zip
rc, err := f.Open(); rc, err := f.Open()
if err != nil { if err != nil {
panic(err) panic(err)
} }
+4 -4
View File
@@ -1,9 +1,8 @@
package binder package binder
import ( import (
"github.com/revel/revel"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/controllers" "github.com/revel/revel"
// "github.com/leanote/leanote/app/controllers/api" // "github.com/leanote/leanote/app/controllers/api"
"fmt" "fmt"
"reflect" "reflect"
@@ -54,6 +53,7 @@ func nextKey(key string) string {
} }
return key[:fieldLen] return key[:fieldLen]
} }
var leanoteStructBinder = revel.Binder{ var leanoteStructBinder = revel.Binder{
// name == "noteOrContent" // name == "noteOrContent"
Bind: func(params *revel.Params, name string, typ reflect.Type) reflect.Value { Bind: func(params *revel.Params, name string, typ reflect.Type) reflect.Value {
@@ -111,7 +111,7 @@ files[0][HasBody]:[true]]
} }
var boundVal reflect.Value var boundVal reflect.Value
// 没有name前缀 // 没有name前缀
if(noPrefix) { if noPrefix {
// life // life
// fmt.Println("<<") // fmt.Println("<<")
// fmt.Println(strings.Title(key[:fieldLen])); // fmt.Println(strings.Title(key[:fieldLen]));
@@ -150,7 +150,7 @@ func init() {
revel.TypeBinders[reflect.TypeOf(info.UserBlogStyle{})] = leanoteStructBinder revel.TypeBinders[reflect.TypeOf(info.UserBlogStyle{})] = leanoteStructBinder
revel.TypeBinders[reflect.TypeOf(info.Notebook{})] = leanoteStructBinder revel.TypeBinders[reflect.TypeOf(info.Notebook{})] = leanoteStructBinder
revel.TypeBinders[reflect.TypeOf(info.UserAccount{})] = leanoteStructBinder revel.TypeBinders[reflect.TypeOf(info.UserAccount{})] = leanoteStructBinder
revel.TypeBinders[reflect.TypeOf(controllers.NoteOrContent{})] = leanoteStructBinder revel.TypeBinders[reflect.TypeOf(info.NoteOrContent{})] = leanoteStructBinder
revel.TypeBinders[reflect.TypeOf(info.ApiNote{})] = leanoteStructBinder revel.TypeBinders[reflect.TypeOf(info.ApiNote{})] = leanoteStructBinder
revel.TypeBinders[reflect.TypeOf(info.NoteFile{})] = leanoteStructBinder revel.TypeBinders[reflect.TypeOf(info.NoteFile{})] = leanoteStructBinder
} }
+2 -4
View File
@@ -6,8 +6,8 @@ import (
"html/template" "html/template"
"io/ioutil" "io/ioutil"
// "os" // "os"
"fmt"
"bytes" "bytes"
"fmt"
"io" "io"
"net/http" "net/http"
"regexp" "regexp"
@@ -181,7 +181,7 @@ func RenderTemplate(name string, args map[string]interface{}, basePath string, i
files := ListDir(basePath) files := ListDir(basePath)
for _, t := range files { for _, t := range files {
if !strings.Contains(t, ".html") { if !strings.Contains(t, ".html") {
continue; continue
} }
fileBytes, err := ioutil.ReadFile(basePath + "/" + t) fileBytes, err := ioutil.ReadFile(basePath + "/" + t)
if err != nil { if err != nil {
@@ -211,11 +211,9 @@ func RenderTemplate(name string, args map[string]interface{}, basePath string, i
return r return r
} }
//////////////////// ////////////////////
// //
type ErrorResult struct { type ErrorResult struct {
RenderArgs map[string]interface{} RenderArgs map[string]interface{}
Error error Error error
+4 -2
View File
@@ -1,15 +1,16 @@
package captcha package captcha
import ( import (
crand "crypto/rand"
"image" "image"
"image/color" "image/color"
"image/png" "image/png"
"io" "io"
"math/rand" "math/rand"
crand "crypto/rand"
"time"
"strconv" "strconv"
"time"
) )
const ( const (
stdWidth = 100 stdWidth = 100
stdHeight = 40 stdHeight = 40
@@ -132,6 +133,7 @@ type Image struct {
height int //a digit height height int //a digit height
dotsize int dotsize int
} }
func init() { func init() {
rand.Seed(int64(time.Second)) rand.Seed(int64(time.Second))
} }
-1
View File
@@ -7,4 +7,3 @@ import (
func Html2Image(userInfo info.User, note info.Note, content, toPath string) bool { func Html2Image(userInfo info.User, note info.Note, content, toPath string) bool {
return true return true
} }
+223
View File
@@ -0,0 +1,223 @@
package i18n
import (
"fmt"
"github.com/revel/revel"
"github.com/robfig/config"
"os"
"path/filepath"
"regexp"
"strings"
)
const (
CurrentLocaleRenderArg = "currentLocale" // The key for the current locale render arg value
messageFilesDirectory = "messages"
messageFilePattern = `^\w+\.conf$`
unknownValueFormat = "??? %s ???"
defaultLanguageOption = "i18n.default_language"
localeCookieConfigKey = "i18n.cookie"
)
var (
// All currently loaded message configs.
// en-us, zh-cn, zh-hk ->
messages map[string]*config.Config
)
func GetAllLangMessages() map[string]*config.Config {
return messages
}
func HasLang(lang string) bool {
_, ok := messages[lang]
return ok
}
func GetDefaultLang() string {
lang, _ := revel.Config.String(defaultLanguageOption)
return lang
}
// Return all currently loaded message languages.
func MessageLanguages() []string {
languages := make([]string, len(messages))
i := 0
for language, _ := range messages {
languages[i] = language
i++
}
return languages
}
// Perform a message look-up for the given locale and message using the given arguments.
//
// When either an unknown locale or message is detected, a specially formatted string is returned.
func Message(locale, message string, args ...interface{}) string {
language, region := parseLocale(locale)
langAndRegion := language + "-" + region
// revel.TRACE.Println(langAndRegion + " 怎么回事")
messageConfig, knownLanguage := messages[langAndRegion]
if !knownLanguage {
// revel.TRACE.Printf("Unsupported language for locale '%s' and message '%s', trying default language", locale, message)
if defaultLanguage, found := revel.Config.String(defaultLanguageOption); found {
// revel.TRACE.Printf("Using default language '%s'", defaultLanguage)
messageConfig, knownLanguage = messages[defaultLanguage]
if !knownLanguage {
// WARN.Printf("Unsupported default language for locale '%s' and message '%s'", defaultLanguage, message)
return fmt.Sprintf(unknownValueFormat, message)
}
} else {
// WARN.Printf("Unable to find default language option (%s); messages for unsupported locales will never be translated", defaultLanguageOption)
return fmt.Sprintf(unknownValueFormat, message)
}
}
// This works because unlike the goconfig documentation suggests it will actually
// try to resolve message in DEFAULT if it did not find it in the given section.
value, error := messageConfig.String(region, message)
if error != nil {
// WARN.Printf("Unknown message '%s' for locale '%s'", message, locale)
return fmt.Sprintf(unknownValueFormat, message)
}
if len(args) > 0 {
// revel.TRACE.Printf("Arguments detected, formatting '%s' with %v", value, args)
value = fmt.Sprintf(value, args...)
}
return value
}
func parseLocale(locale string) (language, region string) {
if strings.Contains(locale, "-") {
languageAndRegion := strings.Split(locale, "-")
return languageAndRegion[0], languageAndRegion[1]
}
return locale, ""
}
// Recursively read and cache all available messages from all message files on the given path.
func loadMessages(path string) {
messages = make(map[string]*config.Config)
if error := filepath.Walk(path, loadEachMessageLang); error != nil && !os.IsNotExist(error) {
// ERROR.Println("Error reading messages files:", error)
}
}
// 加载每一个文件夹
func loadEachMessageLang(parentPath string, parentInfo os.FileInfo, osError error) (err error) {
if !parentInfo.IsDir() {
return nil
}
if err := filepath.Walk(parentPath, func(path string, info os.FileInfo, osError error) error {
return loadMessageFile(parentInfo.Name(), path, info, osError)
}); err != nil && !os.IsNotExist(err) {
// ERROR.Println("Error reading messages files:", error)
}
return err
}
// Load a single message file
func loadMessageFile(locale string, path string, info os.FileInfo, osError error) error {
if osError != nil {
return osError
}
if info.IsDir() {
return nil
}
if matched, _ := regexp.MatchString(messageFilePattern, info.Name()); matched {
if config, error := parseMessagesFile(path); error != nil {
return error
} else {
// locale := parseLocaleFromFileName(info.Name())
// revel.TRACE.Print(locale + "----locale")
// If we have already parsed a message file for this locale, merge both
if _, exists := messages[locale]; exists {
messages[locale].Merge(config)
revel.TRACE.Printf("Successfully merged messages for locale '%s'", locale)
} else {
messages[locale] = config
}
revel.TRACE.Println("Successfully loaded messages from file", info.Name())
}
} else {
revel.TRACE.Printf("Ignoring file %s because it did not have a valid extension", info.Name())
}
return nil
}
func parseMessagesFile(path string) (messageConfig *config.Config, error error) {
messageConfig, error = config.ReadDefault(path)
return
}
func parseLocaleFromFileName(file string) string {
extension := filepath.Ext(file)[1:]
return strings.ToLower(extension)
}
func init() {
revel.OnAppStart(func() {
loadMessages(filepath.Join(revel.BasePath, messageFilesDirectory))
})
}
func I18nFilter(c *revel.Controller, fc []revel.Filter) {
if foundCookie, cookieValue := hasLocaleCookie(c.Request); foundCookie {
revel.TRACE.Printf("Found locale cookie value: %s", cookieValue)
setCurrentLocaleControllerArguments(c, cookieValue)
} else if foundHeader, headerValue := hasAcceptLanguageHeader(c.Request); foundHeader {
revel.TRACE.Printf("Found Accept-Language header value: %s", headerValue)
setCurrentLocaleControllerArguments(c, headerValue)
} else {
revel.TRACE.Println("Unable to find locale in cookie or header, using empty string")
setCurrentLocaleControllerArguments(c, "")
}
fc[0](c, fc[1:])
}
// Set the current locale controller argument (CurrentLocaleControllerArg) with the given locale.
func setCurrentLocaleControllerArguments(c *revel.Controller, locale string) {
c.Request.Locale = locale
c.RenderArgs[CurrentLocaleRenderArg] = locale
}
// Determine whether the given request has valid Accept-Language value.
//
// Assumes that the accept languages stored in the request are sorted according to quality, with top
// quality first in the slice.
func hasAcceptLanguageHeader(request *revel.Request) (bool, string) {
if request.AcceptLanguages != nil && len(request.AcceptLanguages) > 0 {
return true, request.AcceptLanguages[0].Language
}
return false, ""
}
// Determine whether the given request has a valid language cookie value.
func hasLocaleCookie(request *revel.Request) (bool, string) {
if request != nil && request.Cookies() != nil {
name := revel.Config.StringDefault(localeCookieConfigKey, revel.CookiePrefix+"_LANG")
if cookie, error := request.Cookie(name); error == nil {
return true, cookie.Value
} else {
revel.TRACE.Printf("Unable to read locale cookie with name '%s': %s", name, error.Error())
}
}
return false, ""
}
+16 -15
View File
@@ -1,12 +1,13 @@
package netutil package netutil
import ( import (
"strings"
"os" "os"
"strings"
// "path/filepath" // "path/filepath"
. "github.com/leanote/leanote/app/lea"
"io/ioutil"
"net" "net"
"net/http" "net/http"
"io/ioutil"
. "github.com/leanote/leanote/app/lea"
) )
// net的util // net的util
@@ -16,11 +17,11 @@ import (
// 返回文件的完整目录 // 返回文件的完整目录
func WriteUrl(url string, toPath string) (length int64, newFilename, path string, ok bool) { func WriteUrl(url string, toPath string) (length int64, newFilename, path string, ok bool) {
if url == "" { if url == "" {
return; return
} }
content, err := GetContent(url) content, err := GetContent(url)
if err != nil { if err != nil {
return; return
} }
length = int64(len(content)) length = int64(len(content))
@@ -53,7 +54,7 @@ func GetContent(url string) (content []byte, err error) {
var resp *http.Response var resp *http.Response
resp, err = http.Get(url) resp, err = http.Get(url)
Log(err) Log(err)
if(resp != nil && resp.Body != nil) { if resp != nil && resp.Body != nil {
defer resp.Body.Close() defer resp.Body.Close()
} else { } else {
} }
@@ -63,33 +64,33 @@ func GetContent(url string) (content []byte, err error) {
var buf []byte var buf []byte
buf, err = ioutil.ReadAll(resp.Body) buf, err = ioutil.ReadAll(resp.Body)
if(err != nil) { if err != nil {
Log(err) Log(err)
return return
} }
content = buf; content = buf
err = nil err = nil
return return
} }
// 将url ?, #后面的字符串去掉 // 将url ?, #后面的字符串去掉
func trimQueryParams(url string) string { func trimQueryParams(url string) string {
pos := strings.Index(url, "?"); pos := strings.Index(url, "?")
if pos != -1 { if pos != -1 {
url = Substr(url, 0, pos); url = Substr(url, 0, pos)
} }
pos = strings.Index(url, "#"); pos = strings.Index(url, "#")
if pos != -1 { if pos != -1 {
url = Substr(url, 0, pos); url = Substr(url, 0, pos)
} }
pos = strings.Index(url, "!"); pos = strings.Index(url, "!")
if pos != -1 { if pos != -1 {
url = Substr(url, 0, pos); url = Substr(url, 0, pos)
} }
return url; return url
} }
// 通过domain得到ip // 通过domain得到ip
+2 -2
View File
@@ -1,8 +1,8 @@
package route package route
import ( import (
"github.com/revel/revel"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/revel/revel"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
"net/url" "net/url"
"strings" "strings"
@@ -11,6 +11,7 @@ import (
// overwite revel RouterFilter // overwite revel RouterFilter
// /api/user/Info => ApiUser.Info() // /api/user/Info => ApiUser.Info()
var staticPrefix = []string{"/public", "/favicon.ico", "/css", "/js", "/images", "/tinymce", "/upload", "/fonts"} var staticPrefix = []string{"/public", "/favicon.ico", "/css", "/js", "/images", "/tinymce", "/upload", "/fonts"}
func RouterFilter(c *revel.Controller, fc []revel.Filter) { func RouterFilter(c *revel.Controller, fc []revel.Filter) {
// 补全controller部分 // 补全controller部分
path := c.Request.Request.URL.Path path := c.Request.Request.URL.Path
@@ -84,4 +85,3 @@ func RouterFilter(c *revel.Controller, fc []revel.Filter) {
fc[0](c, fc[1:]) fc[0](c, fc[1:])
} }
+5 -5
View File
@@ -2,9 +2,9 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"os/exec" "os/exec"
"io/ioutil"
"strings" "strings"
// "time" // "time"
) )
@@ -54,7 +54,7 @@ func compressJs(filename string) {
to := base + filename + "-min.js" to := base + filename + "-min.js"
cmd := exec.Command(cmdPath, source, "-o", to) cmd := exec.Command(cmdPath, source, "-o", to)
_, err := cmd.CombinedOutput() _, err := cmd.CombinedOutput()
fmt.Println(source); fmt.Println(source)
cmdError(err) cmdError(err)
} }
@@ -121,10 +121,10 @@ func dev() {
func tinymce() { func tinymce() {
// cmdStr := "node_modules/jake/bin/cli.js minify bundle[themes:modern,plugins:table,paste,advlist,autolink,link,image,lists,charmap,hr,searchreplace,visualblocks,visualchars,code,nav,tabfocus,contextmenu,directionality,codemirror,codesyntax,textcolor,fullpage]" // cmdStr := "node_modules/jake/bin/cli.js minify bundle[themes:modern,plugins:table,paste,advlist,autolink,link,image,lists,charmap,hr,searchreplace,visualblocks,visualchars,code,nav,tabfocus,contextmenu,directionality,codemirror,codesyntax,textcolor,fullpage]"
// cmd := exec.Command("/Users/life/Documents/eclipse-workspace/go/leanote_release/tinymce-master/node_modules/jake/bin/cli.js", "minify", "bundle[themes:modern,plugins:table,paste,advlist,autolink,link,image,lists,charmap,hr,searchreplace,visualblocks,visualchars,code,nav,tabfocus,contextmenu,directionality,codemirror,codesyntax,textcolor,fullpage]") // cmd := exec.Command("/Users/life/Documents/eclipse-workspace/go/leanote_release/tinymce-master/node_modules/jake/bin/cli.js", "minify", "bundle[themes:modern,plugins:table,paste,advlist,autolink,link,image,lists,charmap,hr,searchreplace,visualblocks,visualchars,code,nav,tabfocus,contextmenu,directionality,codemirror,codesyntax,textcolor,fullpage]")
cmd := exec.Command("/bin/sh", "-c", "grunt minify"); cmd := exec.Command("/bin/sh", "-c", "grunt minify")
cmd.Dir = base + "/tinymce_4.1.9" cmd.Dir = base + "/tinymce_4.1.9"
fmt.Println("正在build tinymce"); fmt.Println("正在build tinymce")
// 必须要先删除 // 必须要先删除
cmd2 := exec.Command("/bin/sh", "-c", "rm "+cmd.Dir+"/js/tinymce/tinymce.dev.js") cmd2 := exec.Command("/bin/sh", "-c", "rm "+cmd.Dir+"/js/tinymce/tinymce.dev.js")
@@ -141,7 +141,7 @@ func main() {
// 压缩tinymce // 压缩tinymce
// tinymce() // tinymce()
dev(); dev()
// 其它零散的需要压缩的js // 其它零散的需要压缩的js
otherJss := []string{"js/main", "js/app/page", "js/contextmenu/jquery.contextmenu", otherJss := []string{"js/main", "js/app/page", "js/contextmenu/jquery.contextmenu",
+1 -1
View File
@@ -123,7 +123,7 @@ func (this *AttachService) DeleteAttach(attachId, userId string) (bool, string)
attach := info.Attach{} attach := info.Attach{}
db.Get(db.Attachs, attachId, &attach) db.Get(db.Attachs, attachId, &attach)
if(attach.AttachId != "") { if attach.AttachId != "" {
// 判断是否有权限为笔记添加附件 // 判断是否有权限为笔记添加附件
if !shareService.HasUpdateNotePerm(attach.NoteId.Hex(), userId) { if !shareService.HasUpdateNotePerm(attach.NoteId.Hex(), userId) {
return false, "No Perm" return false, "No Perm"
+11 -6
View File
@@ -518,7 +518,7 @@ func (this *BlogService) fixUserBlog(userBlog *info.UserBlog) {
// Logo路径问题, 有些有http: 有些没有 // Logo路径问题, 有些有http: 有些没有
if userBlog.Logo != "" && !strings.HasPrefix(userBlog.Logo, "http") { if userBlog.Logo != "" && !strings.HasPrefix(userBlog.Logo, "http") {
userBlog.Logo = strings.Trim(userBlog.Logo, "/") userBlog.Logo = strings.Trim(userBlog.Logo, "/")
userBlog.Logo = configService.GetSiteUrl() + "/" + userBlog.Logo userBlog.Logo = "/" + userBlog.Logo
} }
if userBlog.SortField == "" { if userBlog.SortField == "" {
@@ -919,7 +919,7 @@ func (this *BlogService) UpateCateUrlTitle(userId string, cateId, urlTitle strin
"UrlTitle": "", "UrlTitle": "",
}) })
*/ */
url = GetUrTitle(userId, urlTitle, "notebook") url = GetUrTitle(userId, urlTitle, "notebook", cateId)
ok = db.UpdateByIdAndUserIdMap(db.Notebooks, cateId, userId, bson.M{ ok = db.UpdateByIdAndUserIdMap(db.Notebooks, cateId, userId, bson.M{
"UrlTitle": url, "UrlTitle": url,
}) })
@@ -935,7 +935,7 @@ func (this *BlogService) UpateBlogUrlTitle(userId string, noteId, urlTitle strin
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, bson.M{ ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, bson.M{
"UrlTitle": "", "UrlTitle": "",
}) })
url = GetUrTitle(userId, urlTitle, "note") url = GetUrTitle(userId, urlTitle, "note", noteId)
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, bson.M{ ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, bson.M{
"UrlTitle": url, "UrlTitle": url,
}) })
@@ -1036,7 +1036,7 @@ func (this *BlogService) UpdateSingleUrlTitle(userId, singleId, urlTitle string)
"UrlTitle": "", "UrlTitle": "",
}) })
*/ */
url = GetUrTitle(userId, urlTitle, "single") url = GetUrTitle(userId, urlTitle, "single", singleId)
ok = db.UpdateByIdAndUserIdMap(db.BlogSingles, singleId, userId, bson.M{ ok = db.UpdateByIdAndUserIdMap(db.BlogSingles, singleId, userId, bson.M{
"UrlTitle": url, "UrlTitle": url,
}) })
@@ -1070,7 +1070,7 @@ func (this *BlogService) AddOrUpdateSingle(userId, singleId, title, content stri
UserId: bson.ObjectIdHex(userId), UserId: bson.ObjectIdHex(userId),
Title: title, Title: title,
Content: content, Content: content,
UrlTitle: GetUrTitle(userId, title, "single"), UrlTitle: GetUrTitle(userId, title, "single", singleId),
CreatedTime: time.Now(), CreatedTime: time.Now(),
} }
page.UpdatedTime = page.CreatedTime page.UpdatedTime = page.CreatedTime
@@ -1108,6 +1108,7 @@ func (this *BlogService) SortSingles(userId string, singleIds []string) (ok bool
// 得到用户的博客url // 得到用户的博客url
func (this *BlogService) GetUserBlogUrl(userBlog *info.UserBlog, username string) string { func (this *BlogService) GetUserBlogUrl(userBlog *info.UserBlog, username string) string {
/*
if userBlog != nil { if userBlog != nil {
if userBlog.Domain != "" && configService.AllowCustomDomain() { if userBlog.Domain != "" && configService.AllowCustomDomain() {
return configService.GetUserUrl(userBlog.Domain) return configService.GetUserUrl(userBlog.Domain)
@@ -1118,12 +1119,15 @@ func (this *BlogService) GetUserBlogUrl(userBlog *info.UserBlog, username string
username = userBlog.UserId.Hex() username = userBlog.UserId.Hex()
} }
} }
*/
return configService.GetBlogUrl() + "/" + username return configService.GetBlogUrl() + "/" + username
} }
// 得到所有url // 得到所有url
func (this *BlogService) GetBlogUrls(userBlog *info.UserBlog, userInfo *info.User) info.BlogUrls { func (this *BlogService) GetBlogUrls(userBlog *info.UserBlog, userInfo *info.User) info.BlogUrls {
var indexUrl, postUrl, searchUrl, cateUrl, singleUrl, tagsUrl, archiveUrl, tagPostsUrl string var indexUrl, postUrl, searchUrl, cateUrl, singleUrl, tagsUrl, archiveUrl, tagPostsUrl string
/*
if userBlog.Domain != "" && configService.AllowCustomDomain() { // http://demo.com if userBlog.Domain != "" && configService.AllowCustomDomain() { // http://demo.com
// ok // ok
indexUrl = configService.GetUserUrl(userBlog.Domain) indexUrl = configService.GetUserUrl(userBlog.Domain)
@@ -1144,6 +1148,7 @@ func (this *BlogService) GetBlogUrls(userBlog *info.UserBlog, userInfo *info.Use
tagsUrl = indexUrl + "/tags" tagsUrl = indexUrl + "/tags"
tagPostsUrl = indexUrl + "/tag" tagPostsUrl = indexUrl + "/tag"
} else { } else {
*/
// ok // ok
blogUrl := configService.GetBlogUrl() // blog.leanote.com blogUrl := configService.GetBlogUrl() // blog.leanote.com
userIdOrEmail := "" userIdOrEmail := ""
@@ -1162,7 +1167,7 @@ func (this *BlogService) GetBlogUrls(userBlog *info.UserBlog, userInfo *info.Use
archiveUrl = blogUrl + "/archives/" + userIdOrEmail // blog.leanote.com/archive/username archiveUrl = blogUrl + "/archives/" + userIdOrEmail // blog.leanote.com/archive/username
tagsUrl = blogUrl + "/tags/" + userIdOrEmail tagsUrl = blogUrl + "/tags/" + userIdOrEmail
tagPostsUrl = blogUrl + "/tag/" + userIdOrEmail // blog.leanote.com/archive/username tagPostsUrl = blogUrl + "/tag/" + userIdOrEmail // blog.leanote.com/archive/username
} // }
return info.BlogUrls{ return info.BlogUrls{
IndexUrl: indexUrl, IndexUrl: indexUrl,
+56 -46
View File
@@ -1,17 +1,17 @@
package service package service
import ( import (
"fmt"
"github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/db"
"gopkg.in/mgo.v2/bson"
"github.com/revel/revel" "github.com/revel/revel"
"time" "gopkg.in/mgo.v2/bson"
"os" "os"
"os/exec" "os/exec"
"fmt"
"strings"
"strconv" "strconv"
"strings"
"time"
) )
// 配置服务 // 配置服务
@@ -27,6 +27,7 @@ type ConfigService struct {
GlobalMapConfigs map[string]map[string]string GlobalMapConfigs map[string]map[string]string
GlobalArrMapConfigs map[string][]map[string]string GlobalArrMapConfigs map[string][]map[string]string
} }
// appStart时 将全局的配置从数据库中得到作为全局 // appStart时 将全局的配置从数据库中得到作为全局
func (this *ConfigService) InitGlobalConfigs() bool { func (this *ConfigService) InitGlobalConfigs() bool {
this.GlobalAllConfigs = map[string]interface{}{} this.GlobalAllConfigs = map[string]interface{}{}
@@ -66,11 +67,21 @@ func (this *ConfigService) InitGlobalConfigs() bool {
} }
} }
// site URL
if s, ok := this.GlobalStringConfigs["siteUrl"]; !ok || s != "" {
this.GlobalStringConfigs["siteUrl"] = this.siteUrl
}
return true return true
} }
func (this *ConfigService) GetSiteUrl() string { func (this *ConfigService) GetSiteUrl() string {
return this.siteUrl; s := this.GetGlobalStringConfig("siteUrl")
if s != "" {
return s
}
return this.siteUrl
} }
func (this *ConfigService) GetAdminUsername() string { func (this *ConfigService) GetAdminUsername() string {
return this.adminUsername return this.adminUsername
@@ -92,7 +103,7 @@ func (this *ConfigService) updateGlobalConfig(userId, key string, value interfac
IsArrMap: isArrMap, IsArrMap: isArrMap,
UpdatedTime: time.Now(), UpdatedTime: time.Now(),
} }
if(isArr) { if isArr {
v, _ := value.([]string) v, _ := value.([]string)
config.ValueArr = v config.ValueArr = v
this.GlobalArrayConfigs[key] = v this.GlobalArrayConfigs[key] = v
@@ -113,7 +124,7 @@ func (this *ConfigService) updateGlobalConfig(userId, key string, value interfac
} else { } else {
i := bson.M{"UpdatedTime": time.Now()} i := bson.M{"UpdatedTime": time.Now()}
this.GlobalAllConfigs[key] = value this.GlobalAllConfigs[key] = value
if(isArr) { if isArr {
v, _ := value.([]string) v, _ := value.([]string)
i["ValueArr"] = v i["ValueArr"] = v
this.GlobalArrayConfigs[key] = v this.GlobalArrayConfigs[key] = v
@@ -177,6 +188,7 @@ func (this *ConfigService) GetGlobalArrMapConfig(key string) []map[string]string
func (this *ConfigService) IsOpenRegister() bool { func (this *ConfigService) IsOpenRegister() bool {
return this.GetGlobalStringConfig("openRegister") != "" return this.GetGlobalStringConfig("openRegister") != ""
} }
//------- //-------
// 修改共享笔记的配置 // 修改共享笔记的配置
func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string, func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
@@ -188,7 +200,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
ok = false ok = false
msg = fmt.Sprint(err) msg = fmt.Sprint(err)
} }
}(); }()
// 用户是否存在? // 用户是否存在?
if registerSharedUserId == "" { if registerSharedUserId == "" {
@@ -222,7 +234,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
msg = "The user has no such notebook: " + notebookId msg = "The user has no such notebook: " + notebookId
return return
} else { } else {
perm := "0"; perm := "0"
if registerSharedNotebookPerms[i] == 1 { if registerSharedNotebookPerms[i] == 1 {
perm = "1" perm = "1"
} }
@@ -247,7 +259,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
msg = "The user has no such note: " + noteId msg = "The user has no such note: " + noteId
return return
} else { } else {
perm := "0"; perm := "0"
if registerSharedNotePerms[i] == 1 { if registerSharedNotePerms[i] == 1 {
perm = "1" perm = "1"
} }
@@ -298,7 +310,7 @@ func (this *ConfigService) getBackupDirname() string {
} }
func (this *ConfigService) Backup(remark string) (ok bool, msg string) { func (this *ConfigService) Backup(remark string) (ok bool, msg string) {
binPath := configService.GetGlobalStringConfig("mongodumpPath") binPath := configService.GetGlobalStringConfig("mongodumpPath")
config := revel.Config; config := revel.Config
dbname, _ := config.String("db.dbname") dbname, _ := config.String("db.dbname")
host, _ := revel.Config.String("db.host") host, _ := revel.Config.String("db.host")
port, _ := revel.Config.String("db.port") port, _ := revel.Config.String("db.port")
@@ -320,7 +332,7 @@ func (this *ConfigService) Backup(remark string) (ok bool, msg string) {
} }
cmd := exec.Command("/bin/sh", "-c", binPath) cmd := exec.Command("/bin/sh", "-c", binPath)
Log(binPath); Log(binPath)
b, err := cmd.Output() b, err := cmd.Output()
if err != nil { if err != nil {
msg = fmt.Sprintf("%v", err) msg = fmt.Sprintf("%v", err)
@@ -332,6 +344,7 @@ func (this *ConfigService) Backup(remark string) (ok bool, msg string) {
ok = configService.AddBackup(dir, remark) ok = configService.AddBackup(dir, remark)
return ok, msg return ok, msg
} }
// 还原 // 还原
func (this *ConfigService) Restore(createdTime string) (ok bool, msg string) { func (this *ConfigService) Restore(createdTime string) (ok bool, msg string) {
backups := this.GetGlobalArrMapConfig("backups") // [{}, {}] backups := this.GetGlobalArrMapConfig("backups") // [{}, {}]
@@ -339,7 +352,7 @@ func (this *ConfigService) Restore(createdTime string) (ok bool, msg string) {
var backup map[string]string var backup map[string]string
for i, backup = range backups { for i, backup = range backups {
if backup["createdTime"] == createdTime { if backup["createdTime"] == createdTime {
break; break
} }
} }
if i == len(backups) { if i == len(backups) {
@@ -354,7 +367,7 @@ func (this *ConfigService) Restore(createdTime string) (ok bool, msg string) {
// mongorestore -h localhost -d leanote --directoryperdb /home/user1/gopackage/src/github.com/leanote/leanote/mongodb_backup/leanote_install_data/ // mongorestore -h localhost -d leanote --directoryperdb /home/user1/gopackage/src/github.com/leanote/leanote/mongodb_backup/leanote_install_data/
binPath := configService.GetGlobalStringConfig("mongorestorePath") binPath := configService.GetGlobalStringConfig("mongorestorePath")
config := revel.Config; config := revel.Config
dbname, _ := config.String("db.dbname") dbname, _ := config.String("db.dbname")
host, _ := revel.Config.String("db.host") host, _ := revel.Config.String("db.host")
port, _ := revel.Config.String("db.port") port, _ := revel.Config.String("db.port")
@@ -375,7 +388,7 @@ func (this *ConfigService) Restore(createdTime string) (ok bool, msg string) {
binPath += " " + path binPath += " " + path
cmd := exec.Command("/bin/sh", "-c", binPath) cmd := exec.Command("/bin/sh", "-c", binPath)
Log(binPath); Log(binPath)
b, err := cmd.Output() b, err := cmd.Output()
if err != nil { if err != nil {
msg = fmt.Sprintf("%v", err) msg = fmt.Sprintf("%v", err)
@@ -393,7 +406,7 @@ func (this *ConfigService) DeleteBackup(createdTime string) (bool, string) {
var backup map[string]string var backup map[string]string
for i, backup = range backups { for i, backup = range backups {
if backup["createdTime"] == createdTime { if backup["createdTime"] == createdTime {
break; break
} }
} }
if i == len(backups) { if i == len(backups) {
@@ -419,13 +432,13 @@ func (this *ConfigService) UpdateBackupRemark(createdTime, remark string) (bool,
var backup map[string]string var backup map[string]string
for i, backup = range backups { for i, backup = range backups {
if backup["createdTime"] == createdTime { if backup["createdTime"] == createdTime {
break; break
} }
} }
if i == len(backups) { if i == len(backups) {
return false, "Backup Not Found" return false, "Backup Not Found"
} }
backup["remark"] = remark; backup["remark"] = remark
ok := this.UpdateGlobalArrMapConfig(this.adminUserId, "backups", backups) ok := this.UpdateGlobalArrMapConfig(this.adminUserId, "backups", backups)
return ok, "" return ok, ""
@@ -438,7 +451,7 @@ func (this *ConfigService) GetBackup(createdTime string) (map[string]string, boo
var backup map[string]string var backup map[string]string
for i, backup = range backups { for i, backup = range backups {
if backup["createdTime"] == createdTime { if backup["createdTime"] == createdTime {
break; break
} }
} }
if i == len(backups) { if i == len(backups) {
@@ -487,49 +500,36 @@ func init() {
} }
func (this *ConfigService) GetSchema() string { func (this *ConfigService) GetSchema() string {
return schema; return schema
} }
// 默认 // 默认
func (this *ConfigService) GetDefaultDomain() string { func (this *ConfigService) GetDefaultDomain() string {
return defaultDomain return defaultDomain
} }
// 包含http://
func (this *ConfigService) GetDefaultUrl() string {
return schema + defaultDomain
}
// note // note
func (this *ConfigService) GetNoteDomain() string { func (this *ConfigService) GetNoteDomain() string {
subDomain := this.GetGlobalStringConfig("noteSubDomain"); return "/note"
if subDomain != "" {
return subDomain + port
}
return this.GetDefaultDomain() + "/note"
} }
func (this *ConfigService) GetNoteUrl() string { func (this *ConfigService) GetNoteUrl() string {
return schema + this.GetNoteDomain(); return this.GetNoteDomain()
} }
// blog // blog
func (this *ConfigService) GetBlogDomain() string { func (this *ConfigService) GetBlogDomain() string {
subDomain := this.GetGlobalStringConfig("blogSubDomain"); return "/blog"
if subDomain != "" {
return subDomain + port
}
return this.GetDefaultDomain() + "/blog"
} }
func (this *ConfigService) GetBlogUrl() string { func (this *ConfigService) GetBlogUrl() string {
return schema + this.GetBlogDomain(); return this.GetBlogDomain()
} }
// lea // lea
func (this *ConfigService) GetLeaDomain() string { func (this *ConfigService) GetLeaDomain() string {
subDomain := this.GetGlobalStringConfig("leaSubDomain"); return "/lea"
if subDomain != "" {
return subDomain + port
}
return this.GetDefaultDomain() + "/lea"
} }
func (this *ConfigService) GetLeaUrl() string { func (this *ConfigService) GetLeaUrl() string {
return schema + this.GetLeaDomain(); return schema + this.GetLeaDomain()
} }
func (this *ConfigService) GetUserUrl(domain string) string { func (this *ConfigService) GetUserUrl(domain string) string {
@@ -543,6 +543,7 @@ func (this *ConfigService) GetUserSubUrl(subDomain string) string {
func (this *ConfigService) AllowCustomDomain() bool { func (this *ConfigService) AllowCustomDomain() bool {
return configService.GetGlobalStringConfig("allowCustomDomain") != "" return configService.GetGlobalStringConfig("allowCustomDomain") != ""
} }
// 是否是好的自定义域名 // 是否是好的自定义域名
func (this *ConfigService) IsGoodCustomDomain(domain string) bool { func (this *ConfigService) IsGoodCustomDomain(domain string) bool {
blacks := this.GetGlobalArrayConfig("blackCustomDomains") blacks := this.GetGlobalArrayConfig("blackCustomDomains")
@@ -567,7 +568,15 @@ func (this *ConfigService) IsGoodSubDomain(domain string) bool {
// 上传大小 // 上传大小
func (this *ConfigService) GetUploadSize(key string) float64 { func (this *ConfigService) GetUploadSize(key string) float64 {
f, _ := strconv.ParseFloat(this.GetGlobalStringConfig(key), 64) f, _ := strconv.ParseFloat(this.GetGlobalStringConfig(key), 64)
return f; return f
}
func (this *ConfigService) GetInt64(key string) int64 {
f, _ := strconv.ParseInt(this.GetGlobalStringConfig(key), 10, 64)
return f
}
func (this *ConfigService) GetInt32(key string) int32 {
f, _ := strconv.ParseInt(this.GetGlobalStringConfig(key), 10, 32)
return int32(f)
} }
func (this *ConfigService) GetUploadSizeLimit() map[string]float64 { func (this *ConfigService) GetUploadSizeLimit() map[string]float64 {
return map[string]float64{ return map[string]float64{
@@ -577,10 +586,11 @@ func (this *ConfigService) GetUploadSizeLimit() map[string]float64 {
"uploadAvatarSize": this.GetUploadSize("uploadAvatarSize"), "uploadAvatarSize": this.GetUploadSize("uploadAvatarSize"),
} }
} }
// 为用户得到全局的配置 // 为用户得到全局的配置
// NoteController调用 // NoteController调用
func (this *ConfigService) GetGlobalConfigForUser() map[string]interface{} { func (this *ConfigService) GetGlobalConfigForUser() map[string]interface{} {
uploadSizeConfigs := this.GetUploadSizeLimit(); uploadSizeConfigs := this.GetUploadSizeLimit()
config := map[string]interface{}{} config := map[string]interface{}{}
for k, v := range uploadSizeConfigs { for k, v := range uploadSizeConfigs {
config[k] = v config[k] = v
@@ -594,5 +604,5 @@ func (this *ConfigService) HomePageIsAdminsBlog() bool {
} }
func (this *ConfigService) GetVersion() string { func (this *ConfigService) GetVersion() string {
return "1.3.1" return "2.0"
} }
+39 -39
View File
@@ -1,17 +1,17 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/info" "bytes"
"fmt"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"time" "html/template"
"strings"
"net/smtp" "net/smtp"
"strconv" "strconv"
"fmt" "strings"
"html/template" "time"
"bytes"
) )
// 发送邮件 // 发送邮件
@@ -20,7 +20,7 @@ type EmailService struct {
tpls map[string]*template.Template tpls map[string]*template.Template
} }
func NewEmailService() (*EmailService) { func NewEmailService() *EmailService {
return &EmailService{tpls: map[string]*template.Template{}} return &EmailService{tpls: map[string]*template.Template{}}
} }
@@ -75,10 +75,10 @@ func (this *EmailService) RegisterSendActiveEmail(userInfo info.User, email stri
return false return false
} }
subject := configService.GetGlobalStringConfig("emailTemplateRegisterSubject"); subject := configService.GetGlobalStringConfig("emailTemplateRegisterSubject")
tpl := configService.GetGlobalStringConfig("emailTemplateRegister"); tpl := configService.GetGlobalStringConfig("emailTemplateRegister")
if(tpl == "") { if tpl == "" {
return false return false
} }
@@ -118,8 +118,8 @@ func (this *EmailService) UpdateEmailSendActiveEmail(userInfo info.User, email s
return return
} }
subject := configService.GetGlobalStringConfig("emailTemplateUpdateEmailSubject"); subject := configService.GetGlobalStringConfig("emailTemplateUpdateEmailSubject")
tpl := configService.GetGlobalStringConfig("emailTemplateUpdateEmail"); tpl := configService.GetGlobalStringConfig("emailTemplateUpdateEmail")
// 发送邮件 // 发送邮件
tokenUrl := configService.GetSiteUrl() + "/user/updateEmail?token=" + token tokenUrl := configService.GetSiteUrl() + "/user/updateEmail?token=" + token
@@ -144,8 +144,8 @@ func (this *EmailService) UpdateEmailSendActiveEmail(userInfo info.User, email s
} }
func (this *EmailService) FindPwdSendEmail(token, email string) (ok bool, msg string) { func (this *EmailService) FindPwdSendEmail(token, email string) (ok bool, msg string) {
subject := configService.GetGlobalStringConfig("emailTemplateFindPasswordSubject"); subject := configService.GetGlobalStringConfig("emailTemplateFindPasswordSubject")
tpl := configService.GetGlobalStringConfig("emailTemplateFindPassword"); tpl := configService.GetGlobalStringConfig("emailTemplateFindPassword")
// 发送邮件 // 发送邮件
tokenUrl := configService.GetSiteUrl() + "/findPassword/" + token tokenUrl := configService.GetSiteUrl() + "/findPassword/" + token
@@ -164,8 +164,8 @@ func (this *EmailService) FindPwdSendEmail(token, email string) (ok bool, msg st
// 发送邀请链接 // 发送邀请链接
func (this *EmailService) SendInviteEmail(userInfo info.User, email, content string) bool { func (this *EmailService) SendInviteEmail(userInfo info.User, email, content string) bool {
subject := configService.GetGlobalStringConfig("emailTemplateInviteSubject"); subject := configService.GetGlobalStringConfig("emailTemplateInviteSubject")
tpl := configService.GetGlobalStringConfig("emailTemplateInvite"); tpl := configService.GetGlobalStringConfig("emailTemplateInvite")
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(),
"registerUrl": configService.GetSiteUrl() + "/register?from=" + userInfo.Username, "registerUrl": configService.GetSiteUrl() + "/register?from=" + userInfo.Username,
@@ -187,8 +187,8 @@ func (this *EmailService) SendInviteEmail(userInfo info.User, email, content str
// 发送评论 // 发送评论
func (this *EmailService) SendCommentEmail(note info.Note, comment info.BlogComment, userId, content string) bool { func (this *EmailService) SendCommentEmail(note info.Note, comment info.BlogComment, userId, content string) bool {
subject := configService.GetGlobalStringConfig("emailTemplateCommentSubject"); subject := configService.GetGlobalStringConfig("emailTemplateCommentSubject")
tpl := configService.GetGlobalStringConfig("emailTemplateComment"); tpl := configService.GetGlobalStringConfig("emailTemplateComment")
// title := "评论提醒" // title := "评论提醒"
@@ -257,7 +257,6 @@ func (this *EmailService) SendCommentEmail(note info.Note, comment info.BlogComm
return ok return ok
} }
// 验证模板是否正确 // 验证模板是否正确
func (this *EmailService) ValidTpl(str string) (ok bool, msg string) { func (this *EmailService) ValidTpl(str string) (ok bool, msg string) {
defer func() { defer func() {
@@ -265,9 +264,9 @@ func (this *EmailService) ValidTpl(str string) (ok bool, msg string){
ok = false ok = false
msg = fmt.Sprint(err) msg = fmt.Sprint(err)
} }
}(); }()
header := configService.GetGlobalStringConfig("emailTemplateHeader"); header := configService.GetGlobalStringConfig("emailTemplateHeader")
footer := configService.GetGlobalStringConfig("emailTemplateFooter"); footer := configService.GetGlobalStringConfig("emailTemplateFooter")
str = strings.Replace(str, "{{header}}", header, -1) str = strings.Replace(str, "{{header}}", header, -1)
str = strings.Replace(str, "{{footer}}", footer, -1) str = strings.Replace(str, "{{footer}}", footer, -1)
_, err := template.New("tpl name").Parse(str) _, err := template.New("tpl name").Parse(str)
@@ -286,7 +285,7 @@ func (this *EmailService) getTpl(str string) (ok bool, msg string, tpl *template
ok = false ok = false
msg = fmt.Sprint(err) msg = fmt.Sprint(err)
} }
}(); }()
var err error var err error
var has bool var has bool
@@ -312,16 +311,16 @@ func (this *EmailService) renderEmail(subject, body string, values map[string]in
ok = false ok = false
msg = fmt.Sprint(err) // 这里的err其实就是panic传入的内容, msg = fmt.Sprint(err) // 这里的err其实就是panic传入的内容,
} }
}(); }()
var tpl *template.Template var tpl *template.Template
values["siteUrl"] = configService.GetSiteUrl(); values["siteUrl"] = configService.GetSiteUrl()
// subject // subject
if subject != "" { if subject != "" {
ok, msg, tpl = this.getTpl(subject) ok, msg, tpl = this.getTpl(subject)
if(!ok) { if !ok {
return return
} }
var buffer bytes.Buffer var buffer bytes.Buffer
@@ -336,13 +335,13 @@ func (this *EmailService) renderEmail(subject, body string, values map[string]in
} }
// content // content
header := configService.GetGlobalStringConfig("emailTemplateHeader"); header := configService.GetGlobalStringConfig("emailTemplateHeader")
footer := configService.GetGlobalStringConfig("emailTemplateFooter"); footer := configService.GetGlobalStringConfig("emailTemplateFooter")
body = strings.Replace(body, "{{header}}", header, -1) body = strings.Replace(body, "{{header}}", header, -1)
body = strings.Replace(body, "{{footer}}", footer, -1) body = strings.Replace(body, "{{footer}}", footer, -1)
values["subject"] = o values["subject"] = o
ok, msg, tpl = this.getTpl(body) ok, msg, tpl = this.getTpl(body)
if(!ok) { if !ok {
return return
} }
var buffer2 bytes.Buffer var buffer2 bytes.Buffer
@@ -359,14 +358,14 @@ func (this *EmailService) renderEmail(subject, body string, values map[string]in
// 发送email给用户 // 发送email给用户
// 需要记录 // 需要记录
func (this *EmailService) SendEmailToUsers(users []info.User, subject, body string) (ok bool, msg string) { func (this *EmailService) SendEmailToUsers(users []info.User, subject, body string) (ok bool, msg string) {
if(users == nil || len(users) == 0) { if users == nil || len(users) == 0 {
msg = "no users" msg = "no users"
return return
} }
// 尝试renderHtml // 尝试renderHtml
ok, msg, _, _ = this.renderEmail(subject, body, map[string]interface{}{}) ok, msg, _, _ = this.renderEmail(subject, body, map[string]interface{}{})
if(!ok) { if !ok {
Log(msg) Log(msg)
return return
} }
@@ -381,8 +380,8 @@ func (this *EmailService) SendEmailToUsers(users []info.User, subject, body stri
ok2, msg2, subject2, body2 := this.renderEmail(subject, body, m) ok2, msg2, subject2, body2 := this.renderEmail(subject, body, m)
ok = ok2 ok = ok2
msg = msg2 msg = msg2
if(ok2) { if ok2 {
sendOk, msg := this.SendEmail(user.Email, subject2, body2); sendOk, msg := this.SendEmail(user.Email, subject2, body2)
this.AddEmailLog(user.Email, subject, body, sendOk, msg) // 把模板记录下 this.AddEmailLog(user.Email, subject, body, sendOk, msg) // 把模板记录下
// 记录到Email Log // 记录到Email Log
if sendOk { if sendOk {
@@ -400,14 +399,14 @@ func (this *EmailService) SendEmailToUsers(users []info.User, subject, body stri
} }
func (this *EmailService) SendEmailToEmails(emails []string, subject, body string) (ok bool, msg string) { func (this *EmailService) SendEmailToEmails(emails []string, subject, body string) (ok bool, msg string) {
if(emails == nil || len(emails) == 0) { if emails == nil || len(emails) == 0 {
msg = "no emails" msg = "no emails"
return return
} }
// 尝试renderHtml // 尝试renderHtml
ok, msg, _, _ = this.renderEmail(subject, body, map[string]interface{}{}) ok, msg, _, _ = this.renderEmail(subject, body, map[string]interface{}{})
if(!ok) { if !ok {
Log(msg) Log(msg)
return return
} }
@@ -420,8 +419,8 @@ func (this *EmailService) SendEmailToEmails(emails []string, subject, body strin
m := map[string]interface{}{} m := map[string]interface{}{}
m["email"] = email m["email"] = email
ok, msg, subject, body = this.renderEmail(subject, body, m) ok, msg, subject, body = this.renderEmail(subject, body, m)
if(ok) { if ok {
sendOk, msg := this.SendEmail(email, subject, body); sendOk, msg := this.SendEmail(email, subject, body)
this.AddEmailLog(email, subject, body, sendOk, msg) this.AddEmailLog(email, subject, body, sendOk, msg)
// 记录到Email Log // 记录到Email Log
if sendOk { if sendOk {
@@ -430,7 +429,7 @@ func (this *EmailService) SendEmailToEmails(emails []string, subject, body strin
Log("no " + email) Log("no " + email)
} }
} else { } else {
Log(msg); Log(msg)
} }
} }
// }() // }()
@@ -443,6 +442,7 @@ func (this *EmailService) AddEmailLog(email, subject, body string, ok bool, msg
log := info.EmailLog{LogId: bson.NewObjectId(), Email: email, Subject: subject, Body: body, Ok: ok, Msg: msg, CreatedTime: time.Now()} log := info.EmailLog{LogId: bson.NewObjectId(), Email: email, Subject: subject, Body: body, Ok: ok, Msg: msg, CreatedTime: time.Now()}
db.Insert(db.EmailLogs, log) db.Insert(db.EmailLogs, log)
} }
// 展示邮件日志 // 展示邮件日志
func (this *EmailService) DeleteEmails(ids []string) bool { func (this *EmailService) DeleteEmails(ids []string) bool {
@@ -461,7 +461,7 @@ func (this *EmailService) ListEmailLogs(pageNumber, pageSize int, sortField stri
if email != "" { if email != "" {
query["Email"] = bson.M{"$regex": bson.RegEx{".*?" + email + ".*", "i"}} query["Email"] = bson.M{"$regex": bson.RegEx{".*?" + email + ".*", "i"}}
} }
q := db.EmailLogs.Find(query); q := db.EmailLogs.Find(query)
// 总记录数 // 总记录数
count, _ := q.Count() count, _ := q.Count()
// 列表 // 列表
+14 -12
View File
@@ -43,7 +43,7 @@ func (this *FileService) ListImagesWithPage(userId, albumId, key string, pageNum
q := bson.M{"UserId": bson.ObjectIdHex(userId), "Type": ""} // life q := bson.M{"UserId": bson.ObjectIdHex(userId), "Type": ""} // life
if albumId != "" { if albumId != "" {
q["AlbumId"] = bson.ObjectIdHex(albumId); q["AlbumId"] = bson.ObjectIdHex(albumId)
} else { } else {
q["IsDefaultAlbum"] = true q["IsDefaultAlbum"] = true
} }
@@ -53,7 +53,7 @@ func (this *FileService) ListImagesWithPage(userId, albumId, key string, pageNum
// LogJ(q) // LogJ(q)
count := db.Count(db.Files, q); count := db.Count(db.Files, q)
db.Files. db.Files.
Find(q). Find(q).
@@ -92,7 +92,7 @@ func (this *FileService) DeleteImage(userId, fileId string) (bool, string) {
file := info.File{} file := info.File{}
db.GetByIdAndUserId(db.Files, fileId, userId, &file) db.GetByIdAndUserId(db.Files, fileId, userId, &file)
if(file.FileId != "") { if file.FileId != "" {
if db.DeleteByIdAndUserId(db.Files, fileId, userId) { if db.DeleteByIdAndUserId(db.Files, fileId, userId) {
// delete image // delete image
// TODO // TODO
@@ -203,7 +203,7 @@ func (this *FileService) GetFile(userId, fileId string) string {
for _, noteId := range noteIds { for _, noteId := range noteIds {
note := noteService.GetNoteById(noteId.Hex()) note := noteService.GetNoteById(noteId.Hex())
if shareService.HasReadPerm(note.UserId.Hex(), userId, noteId.Hex()) { if shareService.HasReadPerm(note.UserId.Hex(), userId, noteId.Hex()) {
return path; return path
} }
} }
/* /*
@@ -242,17 +242,17 @@ func (this *FileService) GetFile(userId, fileId string) string {
return "" return ""
} }
// 复制共享的笔记时, 复制其中的图片到我本地
// 复制图片 // 复制图片
func (this *FileService) CopyImage(userId, fileId, toUserId string) (bool, string) { func (this *FileService) CopyImage(userId, fileId, toUserId string) (bool, string) {
// 是否已经复制过了 // 是否已经复制过了
file2 := info.File{} file2 := info.File{}
db.GetByQ(db.Files, bson.M{"UserId": bson.ObjectIdHex(toUserId), "FromFileId": bson.ObjectIdHex(fileId)}, &file2) db.GetByQ(db.Files, bson.M{"UserId": bson.ObjectIdHex(toUserId), "FromFileId": bson.ObjectIdHex(fileId)}, &file2)
if file2.FileId != "" { if file2.FileId != "" {
return true, file2.FileId.Hex(); return true, file2.FileId.Hex()
} }
// 复制之 // 复制之
file := info.File{} file := info.File{}
db.GetByIdAndUserId(db.Files, fileId, userId, &file) db.GetByIdAndUserId(db.Files, fileId, userId, &file)
@@ -261,18 +261,20 @@ func (this *FileService) CopyImage(userId, fileId, toUserId string) (bool, strin
} }
_, ext := SplitFilename(file.Name) _, ext := SplitFilename(file.Name)
newFilename := NewGuid() + ext guid := NewGuid()
newFilename := guid + ext
dir := "files/" + toUserId + "/images" // TODO 统一目录格式
// dir := "files/" + toUserId + "/images"
dir := "files/" + GetRandomFilePath(toUserId, guid) + "/images"
filePath := dir + "/" + newFilename filePath := dir + "/" + newFilename
err := os.MkdirAll(dir, 0755) err := os.MkdirAll(revel.BasePath+dir, 0755)
if err != nil { if err != nil {
return false, "" return false, ""
} }
_, err = CopyFile(revel.BasePath+"/"+file.Path, revel.BasePath+"/"+filePath) _, err = CopyFile(revel.BasePath+"/"+file.Path, revel.BasePath+"/"+filePath)
if err != nil { if err != nil {
Log(err)
return false, "" return false, ""
} }
@@ -281,7 +283,7 @@ func (this *FileService) CopyImage(userId, fileId, toUserId string) (bool, strin
Path: filePath, Path: filePath,
Size: file.Size, Size: file.Size,
FromFileId: file.FileId} FromFileId: file.FileId}
id := bson.NewObjectId(); id := bson.NewObjectId()
fileInfo.FileId = id fileInfo.FileId = id
fileId = id.Hex() fileId = id.Hex()
Ok, _ := this.AddImage(fileInfo, "", toUserId, false) Ok, _ := this.AddImage(fileInfo, "", toUserId, false)
@@ -296,7 +298,7 @@ func (this *FileService) CopyImage(userId, fileId, toUserId string) (bool, strin
func (this *FileService) IsMyFile(userId, fileId string) bool { func (this *FileService) IsMyFile(userId, fileId string) bool {
// 如果有问题会panic // 如果有问题会panic
if !bson.IsObjectIdHex(fileId) || !bson.IsObjectIdHex(userId) { if !bson.IsObjectIdHex(fileId) || !bson.IsObjectIdHex(userId) {
return false; return false
} }
return db.Has(db.Files, bson.M{"UserId": bson.ObjectIdHex(userId), "_id": bson.ObjectIdHex(fileId)}) return db.Has(db.Files, bson.M{"UserId": bson.ObjectIdHex(userId), "_id": bson.ObjectIdHex(fileId)})
} }
+19 -17
View File
@@ -1,8 +1,8 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"time" "time"
@@ -24,6 +24,7 @@ func (this *GroupService) AddGroup(userId, title string) (bool, info.Group) {
} }
return db.Insert(db.Groups, group), group return db.Insert(db.Groups, group), group
} }
// 删除分组 // 删除分组
// 判断是否有好友 // 判断是否有好友
func (this *GroupService) DeleteGroup(userId, groupId string) (ok bool, msg string) { func (this *GroupService) DeleteGroup(userId, groupId string) (ok bool, msg string) {
@@ -38,8 +39,8 @@ func (this *GroupService) DeleteGroup(userId, groupId string) (ok bool, msg stri
// 删除分组后, 需要删除所有用户分享到该组的笔记本, 笔记 // 删除分组后, 需要删除所有用户分享到该组的笔记本, 笔记
shareService.DeleteAllShareNotebookGroup(groupId); shareService.DeleteAllShareNotebookGroup(groupId)
shareService.DeleteAllShareNoteGroup(groupId); shareService.DeleteAllShareNoteGroup(groupId)
db.DeleteAll(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)}) db.DeleteAll(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)})
return db.DeleteByIdAndUserId(db.Groups, groupId, userId), "" return db.DeleteByIdAndUserId(db.Groups, groupId, userId), ""
@@ -53,14 +54,14 @@ func (this *GroupService) UpdateGroupTitle(userId, groupId, title string) (ok bo
} }
// 得到用户的所有分组(包括下的所有用户) // 得到用户的所有分组(包括下的所有用户)
func (this *GroupService) GetGroupsAndUsers(userId string) ([]info.Group) { func (this *GroupService) GetGroupsAndUsers(userId string) []info.Group {
/* /*
// 得到我的分组 // 得到我的分组
groups := []info.Group{} groups := []info.Group{}
db.ListByQ(db.Groups, bson.M{"UserId": bson.ObjectIdHex(userId)}, &groups) db.ListByQ(db.Groups, bson.M{"UserId": bson.ObjectIdHex(userId)}, &groups)
*/ */
// 我的分组, 及我所属的分组 // 我的分组, 及我所属的分组
groups := this.GetGroupsContainOf(userId); groups := this.GetGroupsContainOf(userId)
// 得到其下的用户 // 得到其下的用户
for i, group := range groups { for i, group := range groups {
@@ -69,8 +70,9 @@ func (this *GroupService) GetGroupsAndUsers(userId string) ([]info.Group) {
} }
return groups return groups
} }
// 仅仅得到所有分组 // 仅仅得到所有分组
func (this *GroupService) GetGroups(userId string) ([]info.Group) { func (this *GroupService) GetGroups(userId string) []info.Group {
// 得到分组s // 得到分组s
groups := []info.Group{} groups := []info.Group{}
db.ListByQ(db.Groups, bson.M{"UserId": bson.ObjectIdHex(userId)}, &groups) db.ListByQ(db.Groups, bson.M{"UserId": bson.ObjectIdHex(userId)}, &groups)
@@ -78,7 +80,7 @@ func (this *GroupService) GetGroups(userId string) ([]info.Group) {
} }
// 得到我的和我所属组的ids // 得到我的和我所属组的ids
func (this *GroupService) GetMineAndBelongToGroupIds(userId string) ([]bson.ObjectId) { func (this *GroupService) GetMineAndBelongToGroupIds(userId string) []bson.ObjectId {
// 所属组 // 所属组
groupIds := this.GetBelongToGroupIds(userId) groupIds := this.GetBelongToGroupIds(userId)
@@ -126,7 +128,7 @@ func (this *GroupService) GetGroupsContainOf(userId string) []info.Group {
} }
// 得到分组, shareService用 // 得到分组, shareService用
func (this *GroupService) GetGroup(userId, groupId string) (info.Group) { func (this *GroupService) GetGroup(userId, groupId string) info.Group {
// 得到分组s // 得到分组s
group := info.Group{} group := info.Group{}
db.GetByIdAndUserId(db.Groups, groupId, userId, &group) db.GetByIdAndUserId(db.Groups, groupId, userId, &group)
@@ -134,7 +136,7 @@ func (this *GroupService) GetGroup(userId, groupId string) (info.Group) {
} }
// 得到某分组下的用户 // 得到某分组下的用户
func (this *GroupService) GetUsers(groupId string) ([]info.User) { func (this *GroupService) GetUsers(groupId string) []info.User {
// 得到UserIds // 得到UserIds
groupUsers := []info.GroupUser{} groupUsers := []info.GroupUser{}
db.ListByQWithFields(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)}, []string{"UserId"}, &groupUsers) db.ListByQWithFields(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)}, []string{"UserId"}, &groupUsers)
@@ -150,7 +152,7 @@ func (this *GroupService) GetUsers(groupId string) ([]info.User) {
} }
// 得到我所属的所有分组ids // 得到我所属的所有分组ids
func (this *GroupService) GetBelongToGroupIds(userId string) ([]bson.ObjectId) { func (this *GroupService) GetBelongToGroupIds(userId string) []bson.ObjectId {
// 得到UserIds // 得到UserIds
groupUsers := []info.GroupUser{} groupUsers := []info.GroupUser{}
db.ListByQWithFields(db.GroupUsers, bson.M{"UserId": bson.ObjectIdHex(userId)}, []string{"GroupId"}, &groupUsers) db.ListByQWithFields(db.GroupUsers, bson.M{"UserId": bson.ObjectIdHex(userId)}, []string{"GroupId"}, &groupUsers)
@@ -183,16 +185,16 @@ func (this *GroupService) AddUser(ownUserId, groupId, userId string) (ok bool, m
// groupId是否是ownUserId的? // groupId是否是ownUserId的?
/* /*
if !this.IsExistsGroupUser(ownUserId, groupId) { if !this.IsExistsGroupUser(ownUserId, groupId) {
return false, "forbidden" return false, "forbiddenNotMyGroup"
} }
*/ */
if !this.isMyGroup(ownUserId, groupId) { if !this.isMyGroup(ownUserId, groupId) {
return false, "forbidden" return false, "forbiddenNotMyGroup"
} }
// 是否已存在 // 是否已存在
if db.Has(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId), "UserId": bson.ObjectIdHex(userId)}) { if db.Has(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId), "UserId": bson.ObjectIdHex(userId)}) {
return false, "hasUsers" return false, "userExistsInGroup"
} }
return db.Insert(db.GroupUsers, info.GroupUser{ return db.Insert(db.GroupUsers, info.GroupUser{
@@ -208,16 +210,16 @@ func (this *GroupService) DeleteUser(ownUserId, groupId, userId string) (ok bool
// groupId是否是ownUserId的? // groupId是否是ownUserId的?
/* /*
if !this.IsExistsGroupUser(ownUserId, groupId) { if !this.IsExistsGroupUser(ownUserId, groupId) {
return false, "forbidden" return false, "forbiddenNotMyGroup"
} }
*/ */
if !this.isMyGroup(ownUserId, groupId) { if !this.isMyGroup(ownUserId, groupId) {
return false, "forbidden" return false, "forbiddenNotMyGroup"
} }
// 删除该用户分享到本组的笔记本, 笔记 // 删除该用户分享到本组的笔记本, 笔记
shareService.DeleteShareNotebookGroupWhenDeleteGroupUser(userId, groupId); shareService.DeleteShareNotebookGroupWhenDeleteGroupUser(userId, groupId)
shareService.DeleteShareNoteGroupWhenDeleteGroupUser(userId, groupId); shareService.DeleteShareNoteGroupWhenDeleteGroupUser(userId, groupId)
return db.Delete(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId), "UserId": bson.ObjectIdHex(userId)}), "" return db.Delete(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId), "UserId": bson.ObjectIdHex(userId)}), ""
} }
+1 -1
View File
@@ -1,8 +1,8 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
// "time" // "time"
+4 -4
View File
@@ -1,8 +1,8 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"regexp" "regexp"
@@ -13,7 +13,7 @@ type NoteImageService struct {
} }
// 通过id, userId得到noteIds // 通过id, userId得到noteIds
func (this *NoteImageService) GetNoteIds(imageId string) ([]bson.ObjectId) { func (this *NoteImageService) GetNoteIds(imageId string) []bson.ObjectId {
noteImages := []info.NoteImage{} noteImages := []info.NoteImage{}
db.ListByQWithFields(db.NoteImages, bson.M{"ImageId": bson.ObjectIdHex(imageId)}, []string{"NoteId"}, &noteImages) db.ListByQWithFields(db.NoteImages, bson.M{"ImageId": bson.ObjectIdHex(imageId)}, []string{"NoteId"}, &noteImages)
@@ -123,9 +123,9 @@ func (this *NoteImageService) CopyNoteImages(fromNoteId, fromUserId, newNoteId,
return "getImage?fileId=" + replaceFileId return "getImage?fileId=" + replaceFileId
} }
return each return each
}); })
return content; return content
} }
// //
+280 -47
View File
@@ -1,10 +1,12 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"regexp"
"strings"
"time" "time"
) )
@@ -17,6 +19,7 @@ func (this *NoteService) GetNote(noteId, userId string) (note info.Note) {
db.GetByIdAndUserId(db.Notes, noteId, userId, &note) db.GetByIdAndUserId(db.Notes, noteId, userId, &note)
return return
} }
// fileService调用 // fileService调用
// 不能是已经删除了的, life bug, 客户端删除后, 竟然还能在web上打开 // 不能是已经删除了的, life bug, 客户端删除后, 竟然还能在web上打开
func (this *NoteService) GetNoteById(noteId string) (note info.Note) { func (this *NoteService) GetNoteById(noteId string) (note info.Note) {
@@ -35,6 +38,7 @@ func (this *NoteService) GetNoteByIdAndUserId(noteId, userId string) (note info.
db.GetByQ(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId), "IsDeleted": false}, &note) db.GetByQ(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId), "IsDeleted": false}, &note)
return return
} }
// 得到blog, blogService用 // 得到blog, blogService用
// 不要传userId, 因为是公开的 // 不要传userId, 因为是公开的
func (this *NoteService) GetBlogNote(noteId string) (note info.Note) { func (this *NoteService) GetBlogNote(noteId string) (note info.Note) {
@@ -43,6 +47,7 @@ func (this *NoteService) GetBlogNote(noteId string) (note info.Note) {
"IsBlog": true, "IsTrash": false, "IsDeleted": false}, &note) "IsBlog": true, "IsTrash": false, "IsDeleted": false}, &note)
return return
} }
// 通过id, userId得到noteContent // 通过id, userId得到noteContent
func (this *NoteService) GetNoteContent(noteContentId, userId string) (noteContent info.NoteContent) { func (this *NoteService) GetNoteContent(noteContentId, userId string) (noteContent info.NoteContent) {
noteContent = info.NoteContent{} noteContent = info.NoteContent{}
@@ -64,7 +69,7 @@ func (this *NoteService) GetSyncNotes(userId string, afterUsn, maxEntry int) []i
q := db.Notes.Find(bson.M{ q := db.Notes.Find(bson.M{
"UserId": bson.ObjectIdHex(userId), "UserId": bson.ObjectIdHex(userId),
"Usn": bson.M{"$gt": afterUsn}, "Usn": bson.M{"$gt": afterUsn},
}); })
q.Sort("Usn").Limit(maxEntry).All(&notes) q.Sort("Usn").Limit(maxEntry).All(&notes)
return this.ToApiNotes(notes) return this.ToApiNotes(notes)
@@ -75,7 +80,7 @@ func (this *NoteService) ToApiNotes(notes []info.Note) []info.ApiNote {
// 2, 得到所有图片, 附件信息 // 2, 得到所有图片, 附件信息
// 查images表, attachs表 // 查images表, attachs表
if len(notes) > 0 { if len(notes) > 0 {
noteIds := make([]bson.ObjectId, len(notes)); noteIds := make([]bson.ObjectId, len(notes))
for i, note := range notes { for i, note := range notes {
noteIds[i] = note.NoteId noteIds[i] = note.NoteId
} }
@@ -92,7 +97,6 @@ func (this *NoteService) ToApiNotes(notes []info.Note) []info.ApiNote {
return []info.ApiNote{} return []info.ApiNote{}
} }
// note与apiNote的转换 // note与apiNote的转换
func (this *NoteService) ToApiNote(note *info.Note, files []info.NoteFile) info.ApiNote { func (this *NoteService) ToApiNote(note *info.Note, files []info.NoteFile) info.ApiNote {
apiNote := info.ApiNote{ apiNote := info.ApiNote{
@@ -121,7 +125,7 @@ func (this *NoteService) ToApiNote(note *info.Note, files []info.NoteFile) info.
// 查images表, attachs表 // 查images表, attachs表
// [待测] // [待测]
func (this *NoteService) getFiles(noteIds []bson.ObjectId) map[string][]info.NoteFile { func (this *NoteService) getFiles(noteIds []bson.ObjectId) map[string][]info.NoteFile {
noteImages := noteImageService.getImagesByNoteIds(noteIds); noteImages := noteImageService.getImagesByNoteIds(noteIds)
noteAttachs := attachService.getAttachsByNoteIds(noteIds) noteAttachs := attachService.getAttachsByNoteIds(noteIds)
noteFilesMap := map[string][]info.NoteFile{} noteFilesMap := map[string][]info.NoteFile{}
@@ -135,7 +139,7 @@ func (this *NoteService) getFiles(noteIds []bson.ObjectId) map[string][]info.Not
noteFiles = append(noteFiles, info.NoteFile{ noteFiles = append(noteFiles, info.NoteFile{
FileId: image.FileId.Hex(), FileId: image.FileId.Hex(),
Type: image.Type, Type: image.Type,
}); })
} }
} }
@@ -147,7 +151,7 @@ func (this *NoteService) getFiles(noteIds []bson.ObjectId) map[string][]info.Not
Type: attach.Type, Type: attach.Type,
Title: attach.Title, Title: attach.Title,
IsAttach: true, IsAttach: true,
}); })
} }
} }
@@ -173,7 +177,7 @@ func (this *NoteService) ListNotes(userId, notebookId string,
query["NotebookId"] = bson.ObjectIdHex(notebookId) query["NotebookId"] = bson.ObjectIdHex(notebookId)
} }
q := db.Notes.Find(query); q := db.Notes.Find(query)
// 总记录数 // 总记录数
count, _ = q.Count() count, _ = q.Count()
@@ -201,6 +205,7 @@ func (this *NoteService) ListNotesByNoteIdsWithPageSort(noteIds []bson.ObjectId,
All(&notes) All(&notes)
return return
} }
// shareService调用 // shareService调用
func (this *NoteService) ListNotesByNoteIds(noteIds []bson.ObjectId) (notes []info.Note) { func (this *NoteService) ListNotesByNoteIds(noteIds []bson.ObjectId) (notes []info.Note) {
notes = []info.Note{} notes = []info.Note{}
@@ -210,6 +215,7 @@ func (this *NoteService) ListNotesByNoteIds(noteIds []bson.ObjectId) (notes []in
All(&notes) All(&notes)
return return
} }
// blog需要 // blog需要
func (this *NoteService) ListNoteContentsByNoteIds(noteIds []bson.ObjectId) (notes []info.NoteContent) { func (this *NoteService) ListNoteContentsByNoteIds(noteIds []bson.ObjectId) (notes []info.NoteContent) {
notes = []info.NoteContent{} notes = []info.NoteContent{}
@@ -219,6 +225,7 @@ func (this *NoteService) ListNoteContentsByNoteIds(noteIds []bson.ObjectId) (not
All(&notes) All(&notes)
return return
} }
// 只得到abstract, 不需要content // 只得到abstract, 不需要content
func (this *NoteService) ListNoteAbstractsByNoteIds(noteIds []bson.ObjectId) (notes []info.NoteContent) { func (this *NoteService) ListNoteAbstractsByNoteIds(noteIds []bson.ObjectId) (notes []info.NoteContent) {
notes = []info.NoteContent{} notes = []info.NoteContent{}
@@ -236,15 +243,18 @@ func (this *NoteService) ListNoteContentByNoteIds(noteIds []bson.ObjectId) (note
// [ok] // [ok]
func (this *NoteService) AddNote(note info.Note, fromApi bool) info.Note { func (this *NoteService) AddNote(note info.Note, fromApi bool) info.Note {
if(note.NoteId.Hex() == "") { if note.NoteId.Hex() == "" {
noteId := bson.NewObjectId(); noteId := bson.NewObjectId()
note.NoteId = noteId; note.NoteId = noteId
} }
note.CreatedTime = time.Now()
note.UpdatedTime = note.CreatedTime // 关于创建时间, 可能是客户端发来, 此时判断时间是否有
note.CreatedTime = FixUrlTime(note.CreatedTime)
note.UpdatedTime = FixUrlTime(note.UpdatedTime)
note.IsTrash = false note.IsTrash = false
note.UpdatedUserId = note.UserId note.UpdatedUserId = note.UserId
note.UrlTitle = GetUrTitle(note.UserId.Hex(), note.Title, "note") note.UrlTitle = GetUrTitle(note.UserId.Hex(), note.Title, "note", note.NoteId.Hex())
note.Usn = userService.IncrUsn(note.UserId.Hex()) note.Usn = userService.IncrUsn(note.UserId.Hex())
notebookId := note.NotebookId.Hex() notebookId := note.NotebookId.Hex()
@@ -279,19 +289,20 @@ func (this *NoteService) AddSharedNote(note info.Note, myUserId bson.ObjectId) i
return info.Note{} return info.Note{}
} }
// 添加笔记本内容 // 添加笔记本内容
// [ok] // [ok]
func (this *NoteService) AddNoteContent(noteContent info.NoteContent) info.NoteContent { func (this *NoteService) AddNoteContent(noteContent info.NoteContent) info.NoteContent {
noteContent.CreatedTime = time.Now()
noteContent.UpdatedTime = noteContent.CreatedTime noteContent.CreatedTime = FixUrlTime(noteContent.CreatedTime)
noteContent.UpdatedTime = FixUrlTime(noteContent.UpdatedTime)
noteContent.UpdatedUserId = noteContent.UserId noteContent.UpdatedUserId = noteContent.UserId
db.Insert(db.NoteContents, noteContent) db.Insert(db.NoteContents, noteContent)
// 更新笔记图片 // 更新笔记图片
noteImageService.UpdateNoteImages(noteContent.UserId.Hex(), noteContent.NoteId.Hex(), "", noteContent.Content) noteImageService.UpdateNoteImages(noteContent.UserId.Hex(), noteContent.NoteId.Hex(), "", noteContent.Content)
return noteContent; return noteContent
} }
// API, abstract, desc需要这里获取 // API, abstract, desc需要这里获取
@@ -348,10 +359,10 @@ func (this *NoteService) AddNoteAndContentForController(note info.Note, noteCont
Log("HAS AUTH -----------") Log("HAS AUTH -----------")
} }
} }
return this.AddNoteAndContent(note, noteContent, bson.ObjectIdHex(updatedUserId)); return this.AddNoteAndContent(note, noteContent, bson.ObjectIdHex(updatedUserId))
} }
func (this *NoteService) AddNoteAndContent(note info.Note, noteContent info.NoteContent, myUserId bson.ObjectId) info.Note { func (this *NoteService) AddNoteAndContent(note info.Note, noteContent info.NoteContent, myUserId bson.ObjectId) info.Note {
if(note.NoteId.Hex() == "") { if note.NoteId.Hex() == "" {
noteId := bson.NewObjectId() noteId := bson.NewObjectId()
note.NoteId = noteId note.NoteId = noteId
} }
@@ -368,7 +379,7 @@ func (this *NoteService) AddNoteAndContent(note info.Note, noteContent info.Note
} }
func (this *NoteService) AddNoteAndContentApi(note info.Note, noteContent info.NoteContent, myUserId bson.ObjectId) info.Note { func (this *NoteService) AddNoteAndContentApi(note info.Note, noteContent info.NoteContent, myUserId bson.ObjectId) info.Note {
if(note.NoteId.Hex() == "") { if note.NoteId.Hex() == "" {
noteId := bson.NewObjectId() noteId := bson.NewObjectId()
note.NoteId = noteId note.NoteId = noteId
} }
@@ -414,36 +425,60 @@ func (this *NoteService) UpdateNote(updatedUserId, noteId string, needUpdate bso
delete(needUpdate, "Desc") delete(needUpdate, "Desc")
} }
needUpdate["UpdatedUserId"] = bson.ObjectIdHex(updatedUserId); needUpdate["UpdatedUserId"] = bson.ObjectIdHex(updatedUserId)
needUpdate["UpdatedTime"] = time.Now();
afterUsn := userService.IncrUsn(userId); // 可以将时间传过来
updatedTime, ok := needUpdate["UpdatedTime"].(time.Time)
if ok {
needUpdate["UpdatedTime"] = FixUrlTime(updatedTime)
} else {
needUpdate["UpdatedTime"] = time.Now()
}
afterUsn := userService.IncrUsn(userId)
needUpdate["Usn"] = afterUsn needUpdate["Usn"] = afterUsn
// 添加tag2 needRecountTags := false
// TODO 这个tag去掉, 添加tag另外添加, 不要这个
if tags, ok := needUpdate["Tags"]; ok {
tagService.AddTagsI(userId, tags)
}
// 是否修改了isBlog // 是否修改了isBlog
// 也要修改noteContents的IsBlog // 也要修改noteContents的IsBlog
if isBlog, ok := needUpdate["IsBlog"]; ok { if isBlog, ok := needUpdate["IsBlog"]; ok {
isBlog2 := isBlog.(bool) isBlog2 := isBlog.(bool)
if note.IsBlog != isBlog2 { if note.IsBlog != isBlog2 {
this.UpdateNoteContentIsBlog(noteId, userId, isBlog2); this.UpdateNoteContentIsBlog(noteId, userId, isBlog2)
// 重新发布成博客 // 重新发布成博客
if !note.IsBlog { if !note.IsBlog {
needUpdate["PublicTime"] = needUpdate["UpdatedTime"] needUpdate["PublicTime"] = needUpdate["UpdatedTime"]
} }
needRecountTags = true
} }
} }
ok := db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, needUpdate) // 添加tag2
// TODO 这个tag去掉, 添加tag另外添加, 不要这个
if tags, ok := needUpdate["Tags"]; ok {
tagService.AddTagsI(userId, tags)
// 如果是博客, 标签改了, 那么重新计算
if note.IsBlog {
needRecountTags = true
}
}
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, needUpdate)
if !ok { if !ok {
return ok, "", 0 return ok, "", 0
} }
if needRecountTags {
// 重新计算tags
go (func() {
blogService.ReCountBlogTags(userId)
})()
}
// 重新获取之 // 重新获取之
note = this.GetNoteById(noteId) note = this.GetNoteById(noteId)
@@ -456,14 +491,19 @@ func (this *NoteService) UpdateNote(updatedUserId, noteId string, needUpdate bso
notebookId := notebookIdI.(bson.ObjectId) notebookId := notebookIdI.(bson.ObjectId)
if notebookId != "" { if notebookId != "" {
notebookService.ReCountNotebookNumberNotes(note.NotebookId.Hex()) notebookService.ReCountNotebookNumberNotes(note.NotebookId.Hex())
hasRecount = true
notebookService.ReCountNotebookNumberNotes(notebookId.Hex()) notebookService.ReCountNotebookNumberNotes(notebookId.Hex())
hasRecount = true
} }
} }
// 不要多次更新, isTrash = false, = true都要重新统计 // 不要多次更新, isTrash = false, = true都要重新统计
if isTrashI, ok := needUpdate["IsTrash"]; ok {
// 如果是垃圾, 则删除之共享
isTrash := isTrashI.(bool)
if isTrash {
shareService.DeleteShareNoteAll(noteId, userId)
}
if !hasRecount { if !hasRecount {
if _, ok := needUpdate["IsTrash"]; ok {
notebookService.ReCountNotebookNumberNotes(note.NotebookId.Hex()) notebookService.ReCountNotebookNumberNotes(note.NotebookId.Hex())
} }
} }
@@ -503,7 +543,9 @@ func (this *NoteService) UpdateNoteTitle(userId, updatedUserId, noteId, title st
// [ok] TODO perm未测 // [ok] TODO perm未测
// hasBeforeUpdateNote 之前是否更新过note其它信息, 如果有更新, usn不用更新 // hasBeforeUpdateNote 之前是否更新过note其它信息, 如果有更新, usn不用更新
// TODO abstract这里生成 // TODO abstract这里生成
func (this *NoteService) UpdateNoteContent(updatedUserId, noteId, content, abstract string, hasBeforeUpdateNote bool, usn int) (bool, string, int) { func (this *NoteService) UpdateNoteContent(updatedUserId, noteId, content, abstract string,
hasBeforeUpdateNote bool,
usn int, updatedTime time.Time) (bool, string, int) {
// 是否已自定义 // 是否已自定义
note := this.GetNoteById(noteId) note := this.GetNoteById(noteId)
if note.NoteId == "" { if note.NoteId == "" {
@@ -518,11 +560,13 @@ func (this *NoteService) UpdateNoteContent(updatedUserId, noteId, content, abstr
} }
} }
updatedTime = FixUrlTime(updatedTime)
// abstract重置 // abstract重置
data := bson.M{"UpdatedUserId": bson.ObjectIdHex(updatedUserId), data := bson.M{"UpdatedUserId": bson.ObjectIdHex(updatedUserId),
"Content": content, "Content": content,
"Abstract": abstract, "Abstract": abstract,
"UpdatedTime": time.Now()} "UpdatedTime": updatedTime}
if note.IsBlog && note.HasSelfDefined { if note.IsBlog && note.HasSelfDefined {
delete(data, "Abstract") delete(data, "Abstract")
@@ -589,7 +633,7 @@ func (this *NoteService) ToBlog(userId, noteId string, isBlog, isTop bool) bool
ok := db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, noteUpdate) ok := db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, noteUpdate)
// 重新计算tags // 重新计算tags
go (func() { go (func() {
this.UpdateNoteContentIsBlog(noteId, userId, isBlog); this.UpdateNoteContentIsBlog(noteId, userId, isBlog)
blogService.ReCountBlogTags(userId) blogService.ReCountBlogTags(userId)
})() })()
@@ -623,7 +667,7 @@ func (this *NoteService) MoveNote(noteId, notebookId, userId string) info.Note {
} }
} }
return this.GetNote(noteId, userId); return this.GetNote(noteId, userId)
} }
return info.Note{} return info.Note{}
} }
@@ -643,10 +687,11 @@ func (this *NoteService) updateToNotebookBlog(noteId, notebookId, userId string)
} }
return false return false
} }
// 判断是否是blog // 判断是否是blog
func (this *NoteService) IsBlog(noteId string) bool { func (this *NoteService) IsBlog(noteId string) bool {
note := info.Note{} note := info.Note{}
db.GetByQWithFields(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, []string{"IsBlog"}, &note); db.GetByQWithFields(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, []string{"IsBlog"}, &note)
return note.IsBlog return note.IsBlog
} }
@@ -660,11 +705,11 @@ func (this *NoteService) CopyNote(noteId, notebookId, userId string) info.Note {
noteContent := this.GetNoteContent(noteId, userId) noteContent := this.GetNoteContent(noteId, userId)
// 重新生成noteId // 重新生成noteId
note.NoteId = bson.NewObjectId(); note.NoteId = bson.NewObjectId()
note.NotebookId = bson.ObjectIdHex(notebookId) note.NotebookId = bson.ObjectIdHex(notebookId)
noteContent.NoteId = note.NoteId noteContent.NoteId = note.NoteId
note = this.AddNoteAndContent(note, noteContent, note.UserId); note = this.AddNoteAndContent(note, noteContent, note.UserId)
// 更新blog状态 // 更新blog状态
isBlog := this.updateToNotebookBlog(note.NoteId.Hex(), notebookId, userId) isBlog := this.updateToNotebookBlog(note.NoteId.Hex(), notebookId, userId)
@@ -693,7 +738,7 @@ func (this *NoteService) CopySharedNote(noteId, notebookId, fromUserId, myUserId
noteContent := this.GetNoteContent(noteId, fromUserId) noteContent := this.GetNoteContent(noteId, fromUserId)
// 重新生成noteId // 重新生成noteId
note.NoteId = bson.NewObjectId(); note.NoteId = bson.NewObjectId()
note.NotebookId = bson.ObjectIdHex(notebookId) note.NotebookId = bson.ObjectIdHex(notebookId)
note.UserId = bson.ObjectIdHex(myUserId) note.UserId = bson.ObjectIdHex(myUserId)
note.IsTop = false note.IsTop = false
@@ -712,7 +757,7 @@ func (this *NoteService) CopySharedNote(noteId, notebookId, fromUserId, myUserId
attachService.CopyAttachs(noteId, note.NoteId.Hex(), myUserId) attachService.CopyAttachs(noteId, note.NoteId.Hex(), myUserId)
// 添加之 // 添加之
note = this.AddNoteAndContent(note, noteContent, note.UserId); note = this.AddNoteAndContent(note, noteContent, note.UserId)
// 更新blog状态 // 更新blog状态
isBlog := this.updateToNotebookBlog(note.NoteId.Hex(), notebookId, myUserId) isBlog := this.updateToNotebookBlog(note.NoteId.Hex(), notebookId, myUserId)
@@ -758,7 +803,7 @@ func (this *NoteService) SearchNote(key, userId string, pageNumber, pageSize int
if isBlog { if isBlog {
query["IsBlog"] = true query["IsBlog"] = true
} }
q := db.Notes.Find(query); q := db.Notes.Find(query)
// 总记录数 // 总记录数
count, _ = q.Count() count, _ = q.Count()
@@ -783,7 +828,11 @@ func (this *NoteService) searchNoteFromContent(notes []info.Note, userId, key st
noteIds[i] = note.NoteId noteIds[i] = note.NoteId
} }
noteContents := []info.NoteContent{} noteContents := []info.NoteContent{}
query := bson.M{"_id": bson.M{"$nin": noteIds}, "UserId": bson.ObjectIdHex(userId), "Content": bson.M{"$regex": bson.RegEx{".*?" + key + ".*", "i"}}} query := bson.M{
"_id": bson.M{"$nin": noteIds},
"UserId": bson.ObjectIdHex(userId),
"Content": bson.M{"$regex": bson.RegEx{".*?" + key + ".*", "i"}},
}
if isBlog { if isBlog {
query["IsBlog"] = true query["IsBlog"] = true
} }
@@ -794,7 +843,7 @@ func (this *NoteService) searchNoteFromContent(notes []info.Note, userId, key st
Select(bson.M{"_id": true}). Select(bson.M{"_id": true}).
All(&noteContents) All(&noteContents)
var lenContent = len(noteContents) var lenContent = len(noteContents)
if(lenContent == 0) { if lenContent == 0 {
return notes return notes
} }
@@ -823,7 +872,7 @@ func (this *NoteService) SearchNoteByTags(tags []string, userId string, pageNumb
"IsTrash": false, "IsTrash": false,
"Tags": bson.M{"$all": tags}} "Tags": bson.M{"$all": tags}}
q := db.Notes.Find(query); q := db.Notes.Find(query)
// 总记录数 // 总记录数
count, _ = q.Count() count, _ = q.Count()
@@ -881,7 +930,7 @@ func (this *NoteService) UpdateNoteToDeleteTag(userId string, targetTag string)
if tag == targetTag { if tag == targetTag {
tags = tags tags = tags
tags = append(tags[:i], tags[i+1:]...) tags = append(tags[:i], tags[i+1:]...)
break; break
} }
} }
usn := userService.IncrUsn(userId) usn := userService.IncrUsn(userId)
@@ -890,3 +939,187 @@ func (this *NoteService) UpdateNoteToDeleteTag(userId string, targetTag string)
} }
return ret return ret
} }
// api
// 得到笔记的内容, 此时将笔记内的链接转成标准的Leanote Url
// 将笔记的图片, 附件链接转换成 site.url/file/getImage?fileId=xxx, site.url/file/getAttach?fileId=xxxx
func (this *NoteService) FixContentBad(content string, isMarkdown bool) string {
baseUrl := configService.GetSiteUrl()
baseUrlPattern := baseUrl
// 避免https的url
if baseUrl[0:8] == "https://" {
baseUrlPattern = strings.Replace(baseUrl, "https://", "https*://", 1)
} else {
baseUrlPattern = strings.Replace(baseUrl, "http://", "https*://", 1)
}
patterns := []map[string]string{
map[string]string{"src": "src", "middle": "/file/outputImage", "param": "fileId", "to": "getImage?fileId="},
map[string]string{"src": "href", "middle": "/attach/download", "param": "attachId", "to": "getAttach?fileId="},
// 该链接已失效, 不再支持
map[string]string{"src": "href", "middle": "/attach/downloadAll", "param": "noteId", "to": "getAllAttachs?noteId="},
}
for _, eachPattern := range patterns {
if !isMarkdown {
// 富文本处理
// <img src="http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1">
// <a href="http://leanote.com/attach/download?attachId=5504243a38f4111dcb00017d"></a>
var reg *regexp.Regexp
if eachPattern["src"] == "src" {
reg, _ = regexp.Compile("<img(?:[^>]+?)(" + eachPattern["src"] + `=['"]*` + baseUrlPattern + eachPattern["middle"] + `\?` + eachPattern["param"] + `=([a-z0-9A-Z]{24})["']*)[^>]*>`)
} else {
reg, _ = regexp.Compile("<a(?:[^>]+?)(" + eachPattern["src"] + `=['"]*` + baseUrlPattern + eachPattern["middle"] + `\?` + eachPattern["param"] + `=([a-z0-9A-Z]{24})["']*)[^>]*>`)
}
finds := reg.FindAllStringSubmatch(content, -1) // 查找所有的
for _, eachFind := range finds {
if len(eachFind) == 3 {
// 这一行会非常慢!, content是全部的内容, 多次replace导致
content = strings.Replace(content,
eachFind[1],
eachPattern["src"]+"=\""+baseUrl+"/api/file/"+eachPattern["to"]+eachFind[2]+"\"",
1)
}
}
} else {
// markdown处理
// ![](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1)
// [selection 2.html](http://leanote.com/attach/download?attachId=5504262638f4111dcb00017f)
// [all.tar.gz](http://leanote.com/attach/downloadAll?noteId=5503b57d59f81b4eb4000000)
pre := "!" // 默认图片
if eachPattern["src"] == "href" { // 是attach
pre = ""
}
regImageMarkdown, _ := regexp.Compile(pre + `\[([^]]*?)\]\(` + baseUrlPattern + eachPattern["middle"] + `\?` + eachPattern["param"] + `=([a-z0-9A-Z]{24})\)`)
findsImageMarkdown := regImageMarkdown.FindAllStringSubmatch(content, -1) // 查找所有的
// [[![](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1) 5503537b38f4111dcb0000d1] [![你好啊, 我很好, 为什么?](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1) 5503537b38f4111dcb0000d1]]
for _, eachFind := range findsImageMarkdown {
// [![你好啊, 我很好, 为什么?](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1) 你好啊, 我很好, 为什么? 5503537b38f4111dcb0000d1]
if len(eachFind) == 3 {
content = strings.Replace(content, eachFind[0], pre+"["+eachFind[1]+"]("+baseUrl+"/api/file/"+eachPattern["to"]+eachFind[2]+")", 1)
}
}
}
}
return content
}
// 性能更好, 5倍的差距
func (this *NoteService) FixContent(content string, isMarkdown bool) string {
baseUrl := configService.GetSiteUrl()
baseUrlPattern := baseUrl
// 避免https的url
if baseUrl[0:8] == "https://" {
baseUrlPattern = strings.Replace(baseUrl, "https://", "https*://", 1)
} else {
baseUrlPattern = strings.Replace(baseUrl, "http://", "https*://", 1)
}
patterns := []map[string]string{
map[string]string{"src": "src", "middle": "/file/outputImage", "param": "fileId", "to": "getImage?fileId="},
map[string]string{"src": "href", "middle": "/attach/download", "param": "attachId", "to": "getAttach?fileId="},
// 该链接已失效, 不再支持
map[string]string{"src": "href", "middle": "/attach/downloadAll", "param": "noteId", "to": "getAllAttachs?noteId="},
}
for _, eachPattern := range patterns {
if !isMarkdown {
// 富文本处理
// <img src="http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1">
// <a href="http://leanote.com/attach/download?attachId=5504243a38f4111dcb00017d"></a>
var reg *regexp.Regexp
var reg2 *regexp.Regexp
if eachPattern["src"] == "src" {
reg, _ = regexp.Compile("<img(?:[^>]+?)(?:" + eachPattern["src"] + `=['"]*` + baseUrlPattern + eachPattern["middle"] + `\?` + eachPattern["param"] + `=(?:[a-z0-9A-Z]{24})["']*)[^>]*>`)
reg2, _ = regexp.Compile("<img(?:[^>]+?)(" + eachPattern["src"] + `=['"]*` + baseUrlPattern + eachPattern["middle"] + `\?` + eachPattern["param"] + `=([a-z0-9A-Z]{24})["']*)[^>]*>`)
} else {
reg, _ = regexp.Compile("<a(?:[^>]+?)(?:" + eachPattern["src"] + `=['"]*` + baseUrlPattern + eachPattern["middle"] + `\?` + eachPattern["param"] + `=(?:[a-z0-9A-Z]{24})["']*)[^>]*>`)
reg2, _ = regexp.Compile("<a(?:[^>]+?)(" + eachPattern["src"] + `=['"]*` + baseUrlPattern + eachPattern["middle"] + `\?` + eachPattern["param"] + `=([a-z0-9A-Z]{24})["']*)[^>]*>`)
}
content = reg.ReplaceAllStringFunc(content, func(str string) string {
// str=这样的
// <img src="http://localhost:9000/file/outputImage?fileId=563d706e99c37b48e0000001" alt="" data-mce-src="http://localhost:9000/file/outputImage?fileId=563d706e99c37b48e0000002">
eachFind := reg2.FindStringSubmatch(str)
str = strings.Replace(str,
eachFind[1],
eachPattern["src"]+"=\""+baseUrl+"/api/file/"+eachPattern["to"]+eachFind[2]+"\"",
1)
// fmt.Println(str)
return str
})
/*
finds := reg.FindAllStringSubmatch(content, -1) // 查找所有的
for _, eachFind := range finds {
if len(eachFind) == 3 {
// 这一行会非常慢!, content是全部的内容, 多次replace导致
content = strings.Replace(content,
eachFind[1],
eachPattern["src"]+"=\""+baseUrl+"/api/file/"+eachPattern["to"]+eachFind[2]+"\"",
1)
}
}
*/
} else {
// markdown处理
// ![](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1)
// [selection 2.html](http://leanote.com/attach/download?attachId=5504262638f4111dcb00017f)
// [all.tar.gz](http://leanote.com/attach/downloadAll?noteId=5503b57d59f81b4eb4000000)
pre := "!" // 默认图片
if eachPattern["src"] == "href" { // 是attach
pre = ""
}
regImageMarkdown, _ := regexp.Compile(pre + `\[(?:[^]]*?)\]\(` + baseUrlPattern + eachPattern["middle"] + `\?` + eachPattern["param"] + `=(?:[a-z0-9A-Z]{24})\)`)
regImageMarkdown2, _ := regexp.Compile(pre + `\[([^]]*?)\]\(` + baseUrlPattern + eachPattern["middle"] + `\?` + eachPattern["param"] + `=([a-z0-9A-Z]{24})\)`)
content = regImageMarkdown.ReplaceAllStringFunc(content, func(str string) string {
// str=这样的
// <img src="http://localhost:9000/file/outputImage?fileId=563d706e99c37b48e0000001" alt="" data-mce-src="http://localhost:9000/file/outputImage?fileId=563d706e99c37b48e0000002">
eachFind := regImageMarkdown2.FindStringSubmatch(str)
str = strings.Replace(str, eachFind[0], pre+"["+eachFind[1]+"]("+baseUrl+"/api/file/"+eachPattern["to"]+eachFind[2]+")", 1)
// fmt.Println(str)
return str
})
/*
findsImageMarkdown := regImageMarkdown.FindAllStringSubmatch(content, -1) // 查找所有的
// [[![](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1) 5503537b38f4111dcb0000d1] [![你好啊, 我很好, 为什么?](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1) 5503537b38f4111dcb0000d1]]
for _, eachFind := range findsImageMarkdown {
// [![你好啊, 我很好, 为什么?](http://leanote.com/file/outputImage?fileId=5503537b38f4111dcb0000d1) 你好啊, 我很好, 为什么? 5503537b38f4111dcb0000d1]
if len(eachFind) == 3 {
content = strings.Replace(content, eachFind[0], pre+"["+eachFind[1]+"]("+baseUrl+"/api/file/"+eachPattern["to"]+eachFind[2]+")", 1)
}
}
*/
}
}
return content
}
+25 -20
View File
@@ -2,13 +2,13 @@ package service
import ( import (
// "fmt" // "fmt"
"gopkg.in/mgo.v2/bson"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson"
"sort" "sort"
"time"
"strings" "strings"
"time"
// "html" // "html"
) )
@@ -42,7 +42,7 @@ func ParseAndSortNotebooks(userNotebooks []info.Notebook, noParentDelete, needSo
for _, each := range userNotebooks { for _, each := range userNotebooks {
newNotebooks := info.Notebooks{Subs: info.SubNotebooks{}} newNotebooks := info.Notebooks{Subs: info.SubNotebooks{}}
newNotebooks.NotebookId = each.NotebookId newNotebooks.NotebookId = each.NotebookId
newNotebooks.Title = each.Title; newNotebooks.Title = each.Title
// newNotebooks.Title = html.EscapeString(each.Title) // newNotebooks.Title = html.EscapeString(each.Title)
newNotebooks.Title = strings.Replace(strings.Replace(each.Title, "<script>", "", -1), "</script", "", -1) newNotebooks.Title = strings.Replace(strings.Replace(each.Title, "<script>", "", -1), "</script", "", -1)
newNotebooks.Seq = each.Seq newNotebooks.Seq = each.Seq
@@ -116,9 +116,9 @@ func (this *NotebookService) GetNotebookByUserIdAndUrlTitle(userId, notebookIdOr
} }
// 同步的方法 // 同步的方法
func (this *NotebookService) GeSyncNotebooks(userId string, afterUsn, maxEntry int) ([]info.Notebook) { func (this *NotebookService) GeSyncNotebooks(userId string, afterUsn, maxEntry int) []info.Notebook {
notebooks := []info.Notebook{} notebooks := []info.Notebook{}
q := db.Notebooks.Find(bson.M{"UserId": bson.ObjectIdHex(userId), "Usn": bson.M{"$gt": afterUsn}}); q := db.Notebooks.Find(bson.M{"UserId": bson.ObjectIdHex(userId), "Usn": bson.M{"$gt": afterUsn}})
q.Sort("Usn").Limit(maxEntry).All(&notebooks) q.Sort("Usn").Limit(maxEntry).All(&notebooks)
return notebooks return notebooks
} }
@@ -156,9 +156,13 @@ func (this *NotebookService) GetNotebooksByNotebookIds(notebookIds []bson.Object
} }
// 添加 // 添加
// [ok]
func (this *NotebookService) AddNotebook(notebook info.Notebook) (bool, info.Notebook) { func (this *NotebookService) AddNotebook(notebook info.Notebook) (bool, info.Notebook) {
notebook.UrlTitle = GetUrTitle(notebook.UserId.Hex(), notebook.Title, "notebook")
if notebook.NotebookId == "" {
notebook.NotebookId = bson.NewObjectId()
}
notebook.UrlTitle = GetUrTitle(notebook.UserId.Hex(), notebook.Title, "notebook", notebook.NotebookId.Hex())
notebook.Usn = userService.IncrUsn(notebook.UserId.Hex()) notebook.Usn = userService.IncrUsn(notebook.UserId.Hex())
now := time.Now() now := time.Now()
notebook.CreatedTime = now notebook.CreatedTime = now
@@ -169,6 +173,7 @@ func (this *NotebookService) AddNotebook(notebook info.Notebook) (bool, info.Not
} }
return true, notebook return true, notebook
} }
// 更新笔记, api // 更新笔记, api
func (this *NotebookService) UpdateNotebookApi(userId, notebookId, title, parentNotebookId string, seq, usn int) (bool, string, info.Notebook) { func (this *NotebookService) UpdateNotebookApi(userId, notebookId, title, parentNotebookId string, seq, usn int) (bool, string, info.Notebook) {
if notebookId == "" { if notebookId == "" {
@@ -183,16 +188,16 @@ func (this *NotebookService) UpdateNotebookApi(userId, notebookId, title, parent
} else if notebook.Usn != usn { } else if notebook.Usn != usn {
return false, "conflict", notebook return false, "conflict", notebook
} }
notebook.Usn = userService.IncrUsn(userId); notebook.Usn = userService.IncrUsn(userId)
notebook.Title = title; notebook.Title = title
updates := bson.M{"Title": title, "Usn": notebook.Usn, "Seq": seq, "UpdatedTime": time.Now()}; updates := bson.M{"Title": title, "Usn": notebook.Usn, "Seq": seq, "UpdatedTime": time.Now()}
if(parentNotebookId != "" && bson.IsObjectIdHex(parentNotebookId)) { if parentNotebookId != "" && bson.IsObjectIdHex(parentNotebookId) {
updates["ParentNotebookId"] = bson.ObjectIdHex(parentNotebookId); updates["ParentNotebookId"] = bson.ObjectIdHex(parentNotebookId)
} else { } else {
updates["ParentNotebookId"] = ""; updates["ParentNotebookId"] = ""
} }
ok := db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, updates); ok := db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, updates)
if ok { if ok {
return ok, "", this.GetNotebookById(notebookId) return ok, "", this.GetNotebookById(notebookId)
} }
@@ -202,7 +207,7 @@ func (this *NotebookService) UpdateNotebookApi(userId, notebookId, title, parent
// 判断是否是blog // 判断是否是blog
func (this *NotebookService) IsBlog(notebookId string) bool { func (this *NotebookService) IsBlog(notebookId string) bool {
notebook := info.Notebook{} notebook := info.Notebook{}
db.GetByQWithFields(db.Notebooks, bson.M{"_id": bson.ObjectIdHex(notebookId)}, []string{"IsBlog"}, &notebook); db.GetByQWithFields(db.Notebooks, bson.M{"_id": bson.ObjectIdHex(notebookId)}, []string{"IsBlog"}, &notebook)
return notebook.IsBlog return notebook.IsBlog
} }
@@ -228,13 +233,13 @@ func (this *NotebookService) UpdateNotebookTitle(notebookId, userId, title strin
// 更新notebook // 更新notebook
func (this *NotebookService) UpdateNotebook(userId, notebookId string, needUpdate bson.M) bool { func (this *NotebookService) UpdateNotebook(userId, notebookId string, needUpdate bson.M) bool {
needUpdate["UpdatedTime"] = time.Now(); needUpdate["UpdatedTime"] = time.Now()
needUpdate["Usn"] = userService.IncrUsn(userId) needUpdate["Usn"] = userService.IncrUsn(userId)
return db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, needUpdate) return db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, needUpdate)
} }
// ToBlog or Not // ToBlog or Not
func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) (bool) { func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) bool {
updates := bson.M{"IsBlog": isBlog, "Usn": userService.IncrUsn(userId)} updates := bson.M{"IsBlog": isBlog, "Usn": userService.IncrUsn(userId)}
// 笔记本 // 笔记本
db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, updates) db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, updates)
@@ -329,10 +334,10 @@ func (this *NotebookService) SortNotebooks(userId string, notebookId2Seqs map[st
func (this *NotebookService) DragNotebooks(userId string, curNotebookId string, parentNotebookId string, siblings []string) bool { func (this *NotebookService) DragNotebooks(userId string, curNotebookId string, parentNotebookId string, siblings []string) bool {
ok := false ok := false
// 如果没parentNotebookId, 则parentNotebookId设空 // 如果没parentNotebookId, 则parentNotebookId设空
if(parentNotebookId == "") { if parentNotebookId == "" {
ok = db.UpdateByIdAndUserIdMap(db.Notebooks, curNotebookId, userId, bson.M{"ParentNotebookId": "", "Usn": userService.IncrUsn(userId)}); ok = db.UpdateByIdAndUserIdMap(db.Notebooks, curNotebookId, userId, bson.M{"ParentNotebookId": "", "Usn": userService.IncrUsn(userId)})
} else { } else {
ok = db.UpdateByIdAndUserIdMap(db.Notebooks, curNotebookId, userId, bson.M{"ParentNotebookId": bson.ObjectIdHex(parentNotebookId), "Usn": userService.IncrUsn(userId)}); ok = db.UpdateByIdAndUserIdMap(db.Notebooks, curNotebookId, userId, bson.M{"ParentNotebookId": bson.ObjectIdHex(parentNotebookId), "Usn": userService.IncrUsn(userId)})
} }
if !ok { if !ok {
+6 -4
View File
@@ -1,10 +1,10 @@
package service package service
import ( import (
"gopkg.in/mgo.v2/bson"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson"
) )
// 找回密码 // 找回密码
@@ -34,6 +34,7 @@ func (this *PwdService) FindPwd(email string) (ok bool, msg string) {
return return
} }
// 重置密码时
// 修改密码 // 修改密码
// 先验证 // 先验证
func (this *PwdService) UpdatePwd(token, pwd string) (bool, string) { func (this *PwdService) UpdatePwd(token, pwd string) (bool, string) {
@@ -45,11 +46,12 @@ func (this *PwdService) UpdatePwd(token, pwd string) (bool, string) {
if ok, msg, tokenInfo = tokenService.VerifyToken(token, info.TokenPwd); !ok { if ok, msg, tokenInfo = tokenService.VerifyToken(token, info.TokenPwd); !ok {
return ok, msg return ok, msg
} }
digest, err := GenerateHash(pwd)
if err != nil { passwd := GenPwd(pwd)
if passwd == "" {
return false, "GenerateHash error" return false, "GenerateHash error"
} }
passwd := string(digest)
// 修改密码之 // 修改密码之
ok = db.UpdateByQField(db.Users, bson.M{"_id": tokenInfo.UserId}, "Pwd", passwd) ok = db.UpdateByQField(db.Users, bson.M{"_id": tokenInfo.UserId}, "Pwd", passwd)
+4 -1
View File
@@ -1,8 +1,8 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"time" "time"
@@ -17,6 +17,7 @@ func (this *SessionService) Update(sessionId, key string, value interface{}) boo
return db.UpdateByQMap(db.Sessions, bson.M{"SessionId": sessionId}, return db.UpdateByQMap(db.Sessions, bson.M{"SessionId": sessionId},
bson.M{key: value, "UpdatedTime": time.Now()}) bson.M{key: value, "UpdatedTime": time.Now()})
} }
// 注销时清空session // 注销时清空session
func (this *SessionService) Clear(sessionId string) bool { func (this *SessionService) Clear(sessionId string) bool {
return db.Delete(db.Sessions, bson.M{"SessionId": sessionId}) return db.Delete(db.Sessions, bson.M{"SessionId": sessionId})
@@ -45,10 +46,12 @@ func (this *SessionService) LoginTimesIsOver(sessionId string) bool {
session := this.Get(sessionId) session := this.Get(sessionId)
return session.LoginTimes > 5 return session.LoginTimes > 5
} }
// 登录成功后清空错误次数 // 登录成功后清空错误次数
func (this *SessionService) ClearLoginTimes(sessionId string) bool { func (this *SessionService) ClearLoginTimes(sessionId string) bool {
return this.Update(sessionId, "LoginTimes", 0) return this.Update(sessionId, "LoginTimes", 0)
} }
// 增加错误次数 // 增加错误次数
func (this *SessionService) IncrLoginTimes(sessionId string) bool { func (this *SessionService) IncrLoginTimes(sessionId string) bool {
session := this.Get(sessionId) session := this.Get(sessionId)
+46 -44
View File
@@ -1,12 +1,12 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"time"
"sort" "sort"
"time"
) )
// 共享Notebook, Note服务 // 共享Notebook, Note服务
@@ -45,7 +45,7 @@ func (this *ShareService) getOrQ(userId string) bson.M {
// 不是trash的 // 不是trash的
q["$or"] = orQ q["$or"] = orQ
} else { } else {
q["ToUserId"] = bson.ObjectIdHex(userId); q["ToUserId"] = bson.ObjectIdHex(userId)
} }
return q return q
} }
@@ -68,12 +68,12 @@ func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksB
userIds := append(userIds1, userIds2...) userIds := append(userIds1, userIds2...)
userInfos := userService.GetUserInfosOrderBySeq(userIds); userInfos := userService.GetUserInfosOrderBySeq(userIds)
// 不要我的id // 不要我的id
for i, userInfo := range userInfos { for i, userInfo := range userInfos {
if userInfo.UserId.Hex() == myUserId { if userInfo.UserId.Hex() == myUserId {
userInfos = append(userInfos[:i], userInfos[i+1:]...) userInfos = append(userInfos[:i], userInfos[i+1:]...)
break; break
} }
} }
@@ -115,7 +115,7 @@ func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksB
userId := eachSub.Notebook.UserId userId := eachSub.Notebook.UserId
// 我自己的, 算了 // 我自己的, 算了
if userId.Hex() == myUserId { if userId.Hex() == myUserId {
continue; continue
} }
if _, ok := shareNotebooksByUsersMap[userId]; ok { if _, ok := shareNotebooksByUsersMap[userId]; ok {
@@ -124,7 +124,7 @@ func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksB
shareNotebooksByUsersMap[userId] = []info.ShareNotebooks{eachSub} shareNotebooksByUsersMap[userId] = []info.ShareNotebooks{eachSub}
} }
} }
shareNotebooksByUser := info.ShareNotebooksByUser{}; shareNotebooksByUser := info.ShareNotebooksByUser{}
for userId, eachShareNotebooks := range shareNotebooksByUsersMap { for userId, eachShareNotebooks := range shareNotebooksByUsersMap {
// 4, 按用户排序 // 4, 按用户排序
shareNotebooksByUser[userId.Hex()] = sortSubShareNotebooks(eachShareNotebooks) shareNotebooksByUser[userId.Hex()] = sortSubShareNotebooks(eachShareNotebooks)
@@ -173,11 +173,11 @@ func (this *ShareService) parseToSubShareNotebooks(subNotebooks *info.SubNoteboo
// 得到共享笔记本下的notes // 得到共享笔记本下的notes
func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, sharedUserId string, func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, sharedUserId string,
page, pageSize int, sortField string, isAsc bool) ([]info.ShareNoteWithPerm) { page, pageSize int, sortField string, isAsc bool) []info.ShareNoteWithPerm {
// 1 首先判断是否真的sharedUserId 共享了 notebookId 给 myUserId // 1 首先判断是否真的sharedUserId 共享了 notebookId 给 myUserId
q := this.getOrQ(myUserId) q := this.getOrQ(myUserId)
q["NotebookId"] = bson.ObjectIdHex(notebookId); q["NotebookId"] = bson.ObjectIdHex(notebookId)
q["UserId"] = bson.ObjectIdHex(sharedUserId); q["UserId"] = bson.ObjectIdHex(sharedUserId)
shareNotebook := info.ShareNotebook{} shareNotebook := info.ShareNotebook{}
db.GetByQ(db.ShareNotebooks, db.GetByQ(db.ShareNotebooks,
q, q,
@@ -190,7 +190,7 @@ func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, share
perm := shareNotebook.Perm perm := shareNotebook.Perm
// 2 得到该notebook下分页显示所有的notes // 2 得到该notebook下分页显示所有的notes
_, notes := noteService.ListNotes(sharedUserId, notebookId, false, page, pageSize, sortField, isAsc, false); _, notes := noteService.ListNotes(sharedUserId, notebookId, false, page, pageSize, sortField, isAsc, false)
// 3 添加权限信息 // 3 添加权限信息
// 3.1 如果该notebook自己有其它权限信息, 比如1, 那么覆盖notebook的权限信息 // 3.1 如果该notebook自己有其它权限信息, 比如1, 那么覆盖notebook的权限信息
@@ -210,12 +210,12 @@ func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, share
} }
} }
Log("笔记权限") Log("笔记权限")
LogJ(notePerms); LogJ(notePerms)
// 3.2 组合 // 3.2 组合
notesWithPerm := make([]info.ShareNoteWithPerm, len(notes)) notesWithPerm := make([]info.ShareNoteWithPerm, len(notes))
for i, each := range notes { for i, each := range notes {
thisPerm := perm; thisPerm := perm
if selfPerm, ok := notePerms[each.NoteId]; ok { if selfPerm, ok := notePerms[each.NoteId]; ok {
thisPerm = selfPerm thisPerm = selfPerm
} }
@@ -247,13 +247,13 @@ func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, share
// 可以这样! 到时将零散的共享noteId放在用户基本数据中 // 可以这样! 到时将零散的共享noteId放在用户基本数据中
// 这里不好排序 // 这里不好排序
func (this *ShareService) ListShareNotes(myUserId, sharedUserId string, func (this *ShareService) ListShareNotes(myUserId, sharedUserId string,
pageNumber, pageSize int, sortField string, isAsc bool) ([]info.ShareNoteWithPerm) { pageNumber, pageSize int, sortField string, isAsc bool) []info.ShareNoteWithPerm {
skipNum, _ := parsePageAndSort(pageNumber, pageSize, sortField, isAsc) skipNum, _ := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
shareNotes := []info.ShareNote{} shareNotes := []info.ShareNote{}
q := this.getOrQ(myUserId) q := this.getOrQ(myUserId)
q["UserId"] = bson.ObjectIdHex(sharedUserId); q["UserId"] = bson.ObjectIdHex(sharedUserId)
db.ShareNotes. db.ShareNotes.
Find(q). Find(q).
@@ -297,7 +297,7 @@ func (this *ShareService) notes2NotesWithPerm(notes []info.Note) {
// [ok] // [ok]
func (this *ShareService) AddShareNotebook1(shareNotebook info.ShareNotebook) bool { func (this *ShareService) AddShareNotebook1(shareNotebook info.ShareNotebook) bool {
// 添加一条记录说明两者存在关系 // 添加一条记录说明两者存在关系
this.AddHasShareNote(shareNotebook.UserId.Hex(), shareNotebook.ToUserId.Hex()); this.AddHasShareNote(shareNotebook.UserId.Hex(), shareNotebook.ToUserId.Hex())
shareNotebook.CreatedTime = time.Now() shareNotebook.CreatedTime = time.Now()
return db.Insert(db.ShareNotebooks, shareNotebook) return db.Insert(db.ShareNotebooks, shareNotebook)
@@ -316,13 +316,13 @@ func (this *ShareService) AddShareNotebook(notebookId string, perm int, userId,
// 第三方注册时没有email // 第三方注册时没有email
func (this *ShareService) AddShareNotebookToUserId(notebookId string, perm int, userId, toUserId string) (bool, string, string) { func (this *ShareService) AddShareNotebookToUserId(notebookId string, perm int, userId, toUserId string) (bool, string, string) {
// 添加一条记录说明两者存在关系 // 添加一条记录说明两者存在关系
this.AddHasShareNote(userId, toUserId); this.AddHasShareNote(userId, toUserId)
// 先删除之 // 先删除之
db.Delete(db.ShareNotebooks, bson.M{"NotebookId": bson.ObjectIdHex(notebookId), db.Delete(db.ShareNotebooks, bson.M{"NotebookId": bson.ObjectIdHex(notebookId),
"UserId": bson.ObjectIdHex(userId), "UserId": bson.ObjectIdHex(userId),
"ToUserId": bson.ObjectIdHex(toUserId), "ToUserId": bson.ObjectIdHex(toUserId),
}); })
shareNotebook := info.ShareNotebook{NotebookId: bson.ObjectIdHex(notebookId), shareNotebook := info.ShareNotebook{NotebookId: bson.ObjectIdHex(notebookId),
UserId: bson.ObjectIdHex(userId), UserId: bson.ObjectIdHex(userId),
@@ -353,13 +353,13 @@ func (this *ShareService) AddShareNote(noteId string, perm int, userId, email st
// 第三方测试没有userId // 第三方测试没有userId
func (this *ShareService) AddShareNoteToUserId(noteId string, perm int, userId, toUserId string) (bool, string, string) { func (this *ShareService) AddShareNoteToUserId(noteId string, perm int, userId, toUserId string) (bool, string, string) {
// 添加一条记录说明两者存在关系 // 添加一条记录说明两者存在关系
this.AddHasShareNote(userId, toUserId); this.AddHasShareNote(userId, toUserId)
// 先删除之 // 先删除之
db.Delete(db.ShareNotes, bson.M{"NoteId": bson.ObjectIdHex(noteId), db.Delete(db.ShareNotes, bson.M{"NoteId": bson.ObjectIdHex(noteId),
"UserId": bson.ObjectIdHex(userId), "UserId": bson.ObjectIdHex(userId),
"ToUserId": bson.ObjectIdHex(toUserId), "ToUserId": bson.ObjectIdHex(toUserId),
}); })
shareNote := info.ShareNote{NoteId: bson.ObjectIdHex(noteId), shareNote := info.ShareNote{NoteId: bson.ObjectIdHex(noteId),
UserId: bson.ObjectIdHex(userId), UserId: bson.ObjectIdHex(userId),
@@ -370,7 +370,6 @@ func (this *ShareService) AddShareNoteToUserId(noteId string, perm int, userId,
return db.Insert(db.ShareNotes, shareNote), "", toUserId return db.Insert(db.ShareNotes, shareNote), "", toUserId
} }
// updatedUserId是否有查看userId noteId的权限? // updatedUserId是否有查看userId noteId的权限?
// userId是所有者 // userId是所有者
func (this *ShareService) HasReadPerm(userId, updatedUserId, noteId string) bool { func (this *ShareService) HasReadPerm(userId, updatedUserId, noteId string) bool {
@@ -443,13 +442,14 @@ func (this *ShareService) HasUpdateNotebookPerm(userId, updatedUserId, notebookI
// 共享note, notebook时使用 // 共享note, notebook时使用
func (this *ShareService) AddHasShareNote(userId, toUserId string) bool { func (this *ShareService) AddHasShareNote(userId, toUserId string) bool {
db.Insert(db.HasShareNotes, info.HasShareNote{UserId: bson.ObjectIdHex(userId), ToUserId: bson.ObjectIdHex(toUserId)}) db.Insert(db.HasShareNotes, info.HasShareNote{UserId: bson.ObjectIdHex(userId), ToUserId: bson.ObjectIdHex(toUserId)})
return true; return true
} }
// userId是否被共享了noteId // userId是否被共享了noteId
func (this *ShareService) HasSharedNote(noteId, myUserId string) bool { func (this *ShareService) HasSharedNote(noteId, myUserId string) bool {
return db.Has(db.ShareNotes, bson.M{"ToUserId": bson.ObjectIdHex(myUserId), "NoteId": bson.ObjectIdHex(noteId)}) return db.Has(db.ShareNotes, bson.M{"ToUserId": bson.ObjectIdHex(myUserId), "NoteId": bson.ObjectIdHex(noteId)})
} }
// noteId的notebook是否共享了给我 // noteId的notebook是否共享了给我
func (this *ShareService) HasSharedNotebook(noteId, myUserId, sharedUserId string) bool { func (this *ShareService) HasSharedNotebook(noteId, myUserId, sharedUserId string) bool {
notebookId := noteService.GetNotebookId(noteId) notebookId := noteService.GetNotebookId(noteId)
@@ -470,7 +470,8 @@ func (this *ShareService) GetShareNoteContent(noteId, myUserId, sharedUserId str
// 或者, 其notebook共享了我 // 或者, 其notebook共享了我
// Log(this.HasSharedNote(noteId, myUserId)) // Log(this.HasSharedNote(noteId, myUserId))
// Log(this.HasSharedNotebook(noteId, myUserId, sharedUserId)) // Log(this.HasSharedNotebook(noteId, myUserId, sharedUserId))
Log(this.HasReadPerm(sharedUserId, myUserId, noteId)) // Log(this.HasReadPerm(sharedUserId, myUserId, noteId))
if this.HasReadPerm(sharedUserId, myUserId, noteId) { if this.HasReadPerm(sharedUserId, myUserId, noteId) {
// if this.HasSharedNote(noteId, myUserId) || this.HasSharedNotebook(noteId, myUserId, sharedUserId) { // if this.HasSharedNote(noteId, myUserId) || this.HasSharedNotebook(noteId, myUserId, sharedUserId) {
db.Get(db.NoteContents, noteId, &noteContent) db.Get(db.NoteContents, noteId, &noteContent)
@@ -591,7 +592,6 @@ func (this *ShareService) ListNotebookShareUserInfo(notebookId, userId string) [
return shareUserInfos return shareUserInfos
} }
//---------------- //----------------
// 改变note share权限 // 改变note share权限
func (this *ShareService) UpdateShareNotePerm(noteId string, perm int, userId, toUserId string) bool { func (this *ShareService) UpdateShareNotePerm(noteId string, perm int, userId, toUserId string) bool {
@@ -622,6 +622,7 @@ func (this *ShareService) DeleteShareNoteAll(noteId string, userId string) bool
return db.DeleteAll(db.ShareNotes, return db.DeleteAll(db.ShareNotes,
bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId)}) bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId)})
} }
// 删除share notebook // 删除share notebook
func (this *ShareService) DeleteShareNotebook(notebookId string, userId, toUserId string) bool { func (this *ShareService) DeleteShareNotebook(notebookId string, userId, toUserId string) bool {
return db.DeleteAll(db.ShareNotebooks, return db.DeleteAll(db.ShareNotebooks,
@@ -631,9 +632,9 @@ func (this *ShareService) DeleteShareNotebook(notebookId string, userId, toUserI
// 删除userId分享给toUserId的所有 // 删除userId分享给toUserId的所有
func (this *ShareService) DeleteUserShareNoteAndNotebook(userId, toUserId string) bool { func (this *ShareService) DeleteUserShareNoteAndNotebook(userId, toUserId string) bool {
query := bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)} query := bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)}
db.DeleteAll(db.ShareNotebooks, query); db.DeleteAll(db.ShareNotebooks, query)
db.DeleteAll(db.ShareNotes, query); db.DeleteAll(db.ShareNotes, query)
db.DeleteAll(db.HasShareNotes, query); db.DeleteAll(db.HasShareNotes, query)
return true return true
} }
@@ -641,10 +642,10 @@ func (this *ShareService) DeleteUserShareNoteAndNotebook(userId, toUserId string
// 用户userId是否有修改noteId的权限 // 用户userId是否有修改noteId的权限
func (this *ShareService) HasUpdateNotePerm(noteId, userId string) bool { func (this *ShareService) HasUpdateNotePerm(noteId, userId string) bool {
if noteId == "" || userId == "" { if noteId == "" || userId == "" {
return false; return false
} }
note := noteService.GetNoteById(noteId) note := noteService.GetNoteById(noteId)
LogJ(note); LogJ(note)
if note.UserId != "" { if note.UserId != "" {
noteUserId := note.UserId.Hex() noteUserId := note.UserId.Hex()
if noteUserId != userId { if noteUserId != userId {
@@ -652,20 +653,20 @@ func (this *ShareService) HasUpdateNotePerm(noteId, userId string) bool {
if this.HasUpdatePerm(noteUserId, userId, noteId) { if this.HasUpdatePerm(noteUserId, userId, noteId) {
return true return true
} else { } else {
return false; return false
} }
} else { } else {
return true return true
} }
} else { } else {
return false; return false
} }
} }
// 用户userId是否有查看noteId的权限 // 用户userId是否有查看noteId的权限
func (this *ShareService) HasReadNotePerm(noteId, userId string) bool { func (this *ShareService) HasReadNotePerm(noteId, userId string) bool {
if noteId == "" || userId == "" { if noteId == "" || userId == "" {
return false; return false
} }
note := noteService.GetNoteById(noteId) note := noteService.GetNoteById(noteId)
if note.UserId != "" { if note.UserId != "" {
@@ -675,13 +676,13 @@ func (this *ShareService) HasReadNotePerm(noteId, userId string) bool {
if this.HasReadPerm(noteUserId, userId, noteId) { if this.HasReadPerm(noteUserId, userId, noteId) {
return true return true
} else { } else {
return false; return false
} }
} else { } else {
return true return true
} }
} else { } else {
return false; return false
} }
} }
@@ -708,7 +709,7 @@ func (this *ShareService) GetNoteShareGroups(noteId, userId string) []info.Share
if !ok { if !ok {
share = info.ShareNote{} share = info.ShareNote{}
} }
share.ToGroup = group; share.ToGroup = group
shares2[i] = share shares2[i] = share
} }
@@ -716,7 +717,7 @@ func (this *ShareService) GetNoteShareGroups(noteId, userId string) []info.Share
} }
// 共享笔记给分组 // 共享笔记给分组
func (this *ShareService) AddShareNoteGroup(userId, noteId, groupId string, perm int) (bool) { func (this *ShareService) AddShareNoteGroup(userId, noteId, groupId string, perm int) bool {
if !groupService.IsExistsGroupUser(userId, groupId) { if !groupService.IsExistsGroupUser(userId, groupId) {
return false return false
} }
@@ -738,7 +739,7 @@ func (this *ShareService) DeleteShareNoteGroup(userId, noteId, groupId string) b
return db.Delete(db.ShareNotes, bson.M{"NoteId": bson.ObjectIdHex(noteId), return db.Delete(db.ShareNotes, bson.M{"NoteId": bson.ObjectIdHex(noteId),
"UserId": bson.ObjectIdHex(userId), "UserId": bson.ObjectIdHex(userId),
"ToGroupId": bson.ObjectIdHex(groupId), "ToGroupId": bson.ObjectIdHex(groupId),
}); })
} }
//------- //-------
@@ -764,14 +765,15 @@ func (this *ShareService) GetNotebookShareGroups(notebookId, userId string) []in
if !ok { if !ok {
share = info.ShareNotebook{} share = info.ShareNotebook{}
} }
share.ToGroup = group; share.ToGroup = group
shares2[i] = share shares2[i] = share
} }
return shares2 return shares2
} }
// 共享笔记给分组 // 共享笔记给分组
func (this *ShareService) AddShareNotebookGroup(userId, notebookId, groupId string, perm int) (bool) { func (this *ShareService) AddShareNotebookGroup(userId, notebookId, groupId string, perm int) bool {
if !groupService.IsExistsGroupUser(userId, groupId) { if !groupService.IsExistsGroupUser(userId, groupId) {
return false return false
} }
@@ -793,7 +795,7 @@ func (this *ShareService) DeleteShareNotebookGroup(userId, notebookId, groupId s
return db.Delete(db.ShareNotebooks, bson.M{"NotebookId": bson.ObjectIdHex(notebookId), return db.Delete(db.ShareNotebooks, bson.M{"NotebookId": bson.ObjectIdHex(notebookId),
"UserId": bson.ObjectIdHex(userId), "UserId": bson.ObjectIdHex(userId),
"ToGroupId": bson.ObjectIdHex(groupId), "ToGroupId": bson.ObjectIdHex(groupId),
}); })
} }
//-------------------- //--------------------
@@ -803,12 +805,12 @@ func (this *ShareService) DeleteShareNotebookGroup(userId, notebookId, groupId s
func (this *ShareService) DeleteAllShareNotebookGroup(groupId string) bool { func (this *ShareService) DeleteAllShareNotebookGroup(groupId string) bool {
return db.Delete(db.ShareNotebooks, bson.M{ return db.Delete(db.ShareNotebooks, bson.M{
"ToGroupId": bson.ObjectIdHex(groupId), "ToGroupId": bson.ObjectIdHex(groupId),
}); })
} }
func (this *ShareService) DeleteAllShareNoteGroup(groupId string) bool { func (this *ShareService) DeleteAllShareNoteGroup(groupId string) bool {
return db.Delete(db.ShareNotes, bson.M{ return db.Delete(db.ShareNotes, bson.M{
"ToGroupId": bson.ObjectIdHex(groupId), "ToGroupId": bson.ObjectIdHex(groupId),
}); })
} }
//-------------------- //--------------------
@@ -819,12 +821,12 @@ func (this *ShareService) DeleteShareNotebookGroupWhenDeleteGroupUser(userId, gr
return db.Delete(db.ShareNotebooks, bson.M{ return db.Delete(db.ShareNotebooks, bson.M{
"UserId": bson.ObjectIdHex(userId), "UserId": bson.ObjectIdHex(userId),
"ToGroupId": bson.ObjectIdHex(groupId), "ToGroupId": bson.ObjectIdHex(groupId),
}); })
} }
func (this *ShareService) DeleteShareNoteGroupWhenDeleteGroupUser(userId, groupId string) bool { func (this *ShareService) DeleteShareNoteGroupWhenDeleteGroupUser(userId, groupId string) bool {
return db.Delete(db.ShareNotes, bson.M{ return db.Delete(db.ShareNotes, bson.M{
"UserId": bson.ObjectIdHex(userId), "UserId": bson.ObjectIdHex(userId),
"ToGroupId": bson.ObjectIdHex(groupId), "ToGroupId": bson.ObjectIdHex(groupId),
}); })
} }
+1 -1
View File
@@ -1,8 +1,8 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
// "time" // "time"
+6 -6
View File
@@ -1,8 +1,8 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"time" "time"
@@ -83,7 +83,7 @@ func (this *TagService) AddOrUpdateTag(userId string, tag string) info.NoteTag {
func (this *TagService) GetTags(userId string) []info.NoteTag { func (this *TagService) GetTags(userId string) []info.NoteTag {
tags := []info.NoteTag{} tags := []info.NoteTag{}
query := bson.M{"UserId": bson.ObjectIdHex(userId), "IsDeleted": false} query := bson.M{"UserId": bson.ObjectIdHex(userId), "IsDeleted": false}
q := db.NoteTags.Find(query); q := db.NoteTags.Find(query)
sortFieldR := "-UpdatedTime" sortFieldR := "-UpdatedTime"
q.Sort(sortFieldR).All(&tags) q.Sort(sortFieldR).All(&tags)
return tags return tags
@@ -95,7 +95,7 @@ func (this *TagService) GetTags(userId string) []info.NoteTag {
func (this *TagService) DeleteTag(userId string, tag string) map[string]int { func (this *TagService) DeleteTag(userId string, tag string) map[string]int {
usn := userService.IncrUsn(userId) usn := userService.IncrUsn(userId)
if db.UpdateByQMap(db.NoteTags, bson.M{"UserId": bson.ObjectIdHex(userId), "Tag": tag}, bson.M{"Usn": usn, "IsDeleted": true}) { if db.UpdateByQMap(db.NoteTags, bson.M{"UserId": bson.ObjectIdHex(userId), "Tag": tag}, bson.M{"Usn": usn, "IsDeleted": true}) {
return noteService.UpdateNoteToDeleteTag(userId, tag); return noteService.UpdateNoteToDeleteTag(userId, tag)
} }
return map[string]int{} return map[string]int{}
} }
@@ -124,14 +124,14 @@ func (this *TagService) reCountTagCount(userId string, tags []string) {
return return
} }
for _, tag := range tags { for _, tag := range tags {
this.AddOrUpdateTag(userId, tag); this.AddOrUpdateTag(userId, tag)
} }
} }
// 同步用 // 同步用
func (this *TagService) GeSyncTags(userId string, afterUsn, maxEntry int) ([]info.NoteTag) { func (this *TagService) GeSyncTags(userId string, afterUsn, maxEntry int) []info.NoteTag {
noteTags := []info.NoteTag{} noteTags := []info.NoteTag{}
q := db.NoteTags.Find(bson.M{"UserId": bson.ObjectIdHex(userId), "Usn": bson.M{"$gt": afterUsn}}); q := db.NoteTags.Find(bson.M{"UserId": bson.ObjectIdHex(userId), "Usn": bson.M{"$gt": afterUsn}})
q.Sort("Usn").Limit(maxEntry).All(&noteTags) q.Sort("Usn").Limit(maxEntry).All(&noteTags)
return noteTags return noteTags
} }
+26 -27
View File
@@ -1,20 +1,20 @@
package service package service
import ( import (
"github.com/revel/revel" "encoding/json"
"github.com/leanote/leanote/app/info" "fmt"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/lea/archive" "github.com/leanote/leanote/app/lea/archive"
"github.com/revel/revel"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"time"
"strings"
"os"
"fmt"
"html/template" "html/template"
"regexp"
"io/ioutil" "io/ioutil"
"encoding/json" "os"
"regexp"
"strings"
"time"
) )
// 主题 // 主题
@@ -29,6 +29,7 @@ var fixedStyle = "blog_left_fixed"
func (this *ThemeService) getDefaultThemeBasePath() string { func (this *ThemeService) getDefaultThemeBasePath() string {
return revel.BasePath + "/public/blog/themes" return revel.BasePath + "/public/blog/themes"
} }
// 默认主题路径 // 默认主题路径
func (this *ThemeService) getDefaultThemePath(style string) string { func (this *ThemeService) getDefaultThemePath(style string) string {
if style == elegantStyle { if style == elegantStyle {
@@ -39,6 +40,7 @@ func (this *ThemeService) getDefaultThemePath(style string) string {
return this.getDefaultThemeBasePath() + "/default" return this.getDefaultThemeBasePath() + "/default"
} }
} }
// blogService用 // blogService用
func (this *ThemeService) GetDefaultThemePath(style string) string { func (this *ThemeService) GetDefaultThemePath(style string) string {
if style == elegantStyle { if style == elegantStyle {
@@ -141,7 +143,7 @@ func (this *ThemeService) NewTheme(userId string) (ok bool, themeId string) {
themeService.NewThemeForFirst(userBlog) themeService.NewThemeForFirst(userBlog)
} }
// 再copy一个默认主题 // 再copy一个默认主题
userBlog.Style = "defaultStyle"; userBlog.Style = "defaultStyle"
ok, themeId = this.CopyDefaultTheme(userBlog) ok, themeId = this.CopyDefaultTheme(userBlog)
return return
} }
@@ -227,7 +229,7 @@ func (this *ThemeService) GetUserThemes(userId string) (theme info.Theme, themes
// 创建时间逆序 // 创建时间逆序
query := bson.M{"UserId": bson.ObjectIdHex(userId)} query := bson.M{"UserId": bson.ObjectIdHex(userId)}
q := db.Themes.Find(query); q := db.Themes.Find(query)
q.Sort("-CreatedTime").All(&themes) q.Sort("-CreatedTime").All(&themes)
if len(themes) == 0 { if len(themes) == 0 {
userBlog := blogService.GetUserBlog(userId) userBlog := blogService.GetUserBlog(userId)
@@ -285,6 +287,7 @@ func (this *ThemeService) GetThemePath(userId, themeId string) string {
} }
return "" return ""
} }
// 更新模板内容 // 更新模板内容
func (this *ThemeService) UpdateTplContent(userId, themeId, filename, content string) (ok bool, msg string) { func (this *ThemeService) UpdateTplContent(userId, themeId, filename, content string) (ok bool, msg string) {
basePath := this.GetThemeAbsolutePath(userId, themeId) basePath := this.GetThemeAbsolutePath(userId, themeId)
@@ -375,7 +378,6 @@ func (this *ThemeService) PublicTheme(userId, themeId string) (ok bool) {
return false return false
} }
// 导出主题 // 导出主题
func (this *ThemeService) ExportTheme(userId, themeId string) (ok bool, path string) { func (this *ThemeService) ExportTheme(userId, themeId string) (ok bool, path string) {
theme := this.GetThemeById(themeId) theme := this.GetThemeById(themeId)
@@ -406,6 +408,7 @@ func (this *ThemeService) ExportTheme(userId, themeId string) (ok bool, path str
return true, targetName return true, targetName
} }
// 导入主题 // 导入主题
// path == /llllllll/..../public/upload/.../aa.zip, 绝对路径 // path == /llllllll/..../public/upload/.../aa.zip, 绝对路径
func (this *ThemeService) ImportTheme(userId, path string) (ok bool, msg string) { func (this *ThemeService) ImportTheme(userId, path string) (ok bool, msg string) {
@@ -525,7 +528,7 @@ func (this *ThemeService) InstallTheme(userId, themeId string) (ok bool) {
ok = db.Insert(db.Themes, theme) ok = db.Insert(db.Themes, theme)
// 激活之 // 激活之
this.ActiveTheme(userId, themeId); this.ActiveTheme(userId, themeId)
return ok return ok
} }
@@ -538,10 +541,10 @@ func (this *ThemeService) ValidateTheme(path string, filename, newContent string
// 建立一个有向图 // 建立一个有向图
// 将该path下的所有文件提出, 得到文件的引用情况 // 将该path下的所有文件提出, 得到文件的引用情况
files := ListDir(path) files := ListDir(path)
LogJ(files); LogJ(files)
size := len(files) size := len(files)
if(size > 100) { if size > 100 {
ok = false; ok = false
msg = "tooManyFiles" msg = "tooManyFiles"
return return
} }
@@ -559,7 +562,7 @@ func (this *ThemeService) ValidateTheme(path string, filename, newContent string
// 得到文件内容, 和建立索引, 每个文件都有一个index, 对应数组位置 // 得到文件内容, 和建立索引, 每个文件都有一个index, 对应数组位置
for _, t := range files { for _, t := range files {
if !strings.Contains(t, ".html") { if !strings.Contains(t, ".html") {
continue; continue
} }
if t != filename { if t != filename {
fileBytes, err := ioutil.ReadFile(path + "/" + t) fileBytes, err := ioutil.ReadFile(path + "/" + t)
@@ -567,7 +570,7 @@ func (this *ThemeService) ValidateTheme(path string, filename, newContent string
continue continue
} }
fileIndexMap[t] = index; fileIndexMap[t] = index
// html内容 // html内容
fileStr := string(fileBytes) fileStr := string(fileBytes)
fileContent[t] = fileStr fileContent[t] = fileStr
@@ -607,7 +610,7 @@ func (this *ThemeService) ValidateTheme(path string, filename, newContent string
} else { } else {
ok = true ok = true
} }
return; return
} }
// 检测有向图是否有环, DFS // 检测有向图是否有环, DFS
@@ -615,9 +618,7 @@ func (this *ThemeService) hasRound(vector [][]int, size int) (ok bool) {
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
visited := make([]int, size) visited := make([]int, size)
if this.hasRoundEach(vector, i, size, visited) { if this.hasRoundEach(vector, i, size, visited) {
Log(">>") return true
Log(i);
return true;
} }
} }
return false return false
@@ -626,17 +627,15 @@ func (this *ThemeService) hasRound(vector [][]int, size int) (ok bool) {
// 从每个节点出发, 判断是否有环 // 从每个节点出发, 判断是否有环
func (this *ThemeService) hasRoundEach(vector [][]int, index int, size int, visited []int) (ok bool) { func (this *ThemeService) hasRoundEach(vector [][]int, index int, size int, visited []int) (ok bool) {
if visited[index] > 0 { if visited[index] > 0 {
Log("<")
Log(index)
return true return true
} }
visited[index] = 1; visited[index] = 1
// 遍历它的孩子 // 遍历它的孩子
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
if vector[index][i] > 0 { if vector[index][i] > 0 {
return this.hasRoundEach(vector, i, size, visited); return this.hasRoundEach(vector, i, size, visited)
} }
} }
visited[index] = 0; visited[index] = 0
return false; return false
} }
+1 -1
View File
@@ -1,10 +1,10 @@
package service package service
import ( import (
"gopkg.in/mgo.v2/bson"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson"
"time" "time"
) )
+15 -5
View File
@@ -1,9 +1,9 @@
package service package service
import ( import (
"gopkg.in/mgo.v2/bson"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
"gopkg.in/mgo.v2/bson"
) )
// 回收站 // 回收站
@@ -25,9 +25,9 @@ type TrashService struct {
// 应该放在回收站里 // 应该放在回收站里
// 有trashService // 有trashService
func (this *TrashService) DeleteNote(noteId, userId string) bool { func (this *TrashService) DeleteNote(noteId, userId string) bool {
note := noteService.GetNote(noteId, userId); note := noteService.GetNote(noteId, userId)
// 如果是垃圾, 则彻底删除 // 如果是垃圾, 则彻底删除
if (note.IsTrash) { if note.IsTrash {
return this.DeleteTrash(noteId, userId) return this.DeleteTrash(noteId, userId)
} }
@@ -63,12 +63,12 @@ func (this *TrashService) recoverNote(noteId, notebookId, userId string) bool {
bson.M{"$set": bson.M{"IsTrash": false, bson.M{"$set": bson.M{"IsTrash": false,
"Usn": userService.IncrUsn(userId), "Usn": userService.IncrUsn(userId),
"NotebookId": bson.ObjectIdHex(notebookId)}}) "NotebookId": bson.ObjectIdHex(notebookId)}})
return re; return re
} }
// 删除trash // 删除trash
func (this *TrashService) DeleteTrash(noteId, userId string) bool { func (this *TrashService) DeleteTrash(noteId, userId string) bool {
note := noteService.GetNote(noteId, userId); note := noteService.GetNote(noteId, userId)
if note.NoteId == "" { if note.NoteId == "" {
return false return false
} }
@@ -85,6 +85,9 @@ func (this *TrashService) DeleteTrash(noteId, userId string) bool {
// delete content // delete content
ok = db.DeleteByIdAndUserId(db.NoteContents, noteId, userId) ok = db.DeleteByIdAndUserId(db.NoteContents, noteId, userId)
// 删除content history
ok = db.DeleteByIdAndUserId(db.NoteContentHistories, noteId, userId)
// 重新统计tag's count // 重新统计tag's count
// TODO 这里会改变tag's Usn // TODO 这里会改变tag's Usn
tagService.reCountTagCount(userId, note.Tags) tagService.reCountTagCount(userId, note.Tags)
@@ -115,6 +118,13 @@ func (this *TrashService) DeleteTrashApi(noteId, userId string, usn int) (bool,
// delete content // delete content
ok = db.DeleteByIdAndUserId(db.NoteContents, noteId, userId) ok = db.DeleteByIdAndUserId(db.NoteContents, noteId, userId)
// 删除content history
ok = db.DeleteByIdAndUserId(db.NoteContentHistories, noteId, userId)
// 一个BUG, iOS删除直接调用这个API, 结果没有重新recount
// recount notebooks' notes number
notebookService.ReCountNotebookNumberNotes(note.NotebookId.Hex())
return ok, "", afterUsn return ok, "", afterUsn
} }
+6 -7
View File
@@ -1,14 +1,13 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/db"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"time" "time"
) )
type UpgradeService struct { type UpgradeService struct {
} }
@@ -66,7 +65,7 @@ func (this *UpgradeService) UpgradeBetaToBeta2(userId string) (ok bool, msg stri
data["RecommendTime"] = note.UpdatedTime data["RecommendTime"] = note.UpdatedTime
Log("Time " + noteId) Log("Time " + noteId)
} }
data["UrlTitle"] = GetUrTitle(note.UserId.Hex(), note.Title, "note") data["UrlTitle"] = GetUrTitle(note.UserId.Hex(), note.Title, "note", noteId)
db.UpdateByIdAndUserIdMap2(db.Notes, note.NoteId, note.UserId, data) db.UpdateByIdAndUserIdMap2(db.Notes, note.NoteId, note.UserId, data)
Log(noteId) Log(noteId)
} }
@@ -78,7 +77,7 @@ func (this *UpgradeService) UpgradeBetaToBeta2(userId string) (ok bool, msg stri
for _, notebook := range notebooks { for _, notebook := range notebooks {
notebookId := notebook.NotebookId.Hex() notebookId := notebook.NotebookId.Hex()
data := bson.M{} data := bson.M{}
data["UrlTitle"] = GetUrTitle(notebook.UserId.Hex(), notebook.Title, "notebook") data["UrlTitle"] = GetUrTitle(notebook.UserId.Hex(), notebook.Title, "notebook", notebookId)
db.UpdateByIdAndUserIdMap2(db.Notebooks, notebook.NotebookId, notebook.UserId, data) db.UpdateByIdAndUserIdMap2(db.Notebooks, notebook.NotebookId, notebook.UserId, data)
Log(notebookId) Log(notebookId)
} }
@@ -164,17 +163,17 @@ func (this *UpgradeService) Api(userId string) (ok bool, msg string) {
// notebook // notebook
db.UpdateByQField(db.Notebooks, bson.M{}, "IsDeleted", false) db.UpdateByQField(db.Notebooks, bson.M{}, "IsDeleted", false)
this.setNotebookUsn(); this.setNotebookUsn()
// note // note
// 1-N // 1-N
db.UpdateByQField(db.Notes, bson.M{}, "IsDeleted", false) db.UpdateByQField(db.Notes, bson.M{}, "IsDeleted", false)
this.setNoteUsn(); this.setNoteUsn()
// tag // tag
// 1-N // 1-N
/// tag, 要重新插入, 将之前的Tag表迁移到NoteTag中 /// tag, 要重新插入, 将之前的Tag表迁移到NoteTag中
this.moveTag(); this.moveTag()
configService.UpdateGlobalStringConfig(userId, "UpgradeBetaToBeta4", "1") configService.UpdateGlobalStringConfig(userId, "UpgradeBetaToBeta4", "1")
+20 -35
View File
@@ -1,12 +1,12 @@
package service package service
import ( import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea" . "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"time"
"strings" "strings"
"time"
) )
type UserService struct { type UserService struct {
@@ -47,8 +47,8 @@ func (this *UserService) AddUser(user info.User) bool {
go func() { go func() {
emailService.RegisterSendActiveEmail(user, user.Email) emailService.RegisterSendActiveEmail(user, user.Email)
// 发送给我 life@leanote.com // 发送给我 life@leanote.com
emailService.SendEmail("life@leanote.com", "新增用户", "{header}用户名" + user.Email + "{footer}"); // emailService.SendEmail("life@leanote.com", "新增用户", "{header}用户名"+user.Email+"{footer}")
}(); }()
} }
return db.Insert(db.Users, user) return db.Insert(db.Users, user)
@@ -110,7 +110,7 @@ func (this *UserService) setUserLogo(user *info.User) {
} }
if user.Logo != "" && !strings.HasPrefix(user.Logo, "http") { if user.Logo != "" && !strings.HasPrefix(user.Logo, "http") {
user.Logo = strings.Trim(user.Logo, "/") user.Logo = strings.Trim(user.Logo, "/")
user.Logo = configService.GetSiteUrl() + "/" + user.Logo user.Logo = "/" + user.Logo
} }
} }
@@ -129,6 +129,7 @@ func (this *UserService) GetUserInfo(userId string) info.User {
this.setUserLogo(&user) this.setUserLogo(&user)
return user return user
} }
// 得到用户信息 email // 得到用户信息 email
func (this *UserService) GetUserInfoByEmail(email string) info.User { func (this *UserService) GetUserInfoByEmail(email string) info.User {
user := info.User{} user := info.User{}
@@ -137,6 +138,7 @@ func (this *UserService) GetUserInfoByEmail(email string) info.User {
this.setUserLogo(&user) this.setUserLogo(&user)
return user return user
} }
// 得到用户信息 username // 得到用户信息 username
func (this *UserService) GetUserInfoByUsername(username string) info.User { func (this *UserService) GetUserInfoByUsername(username string) info.User {
user := info.User{} user := info.User{}
@@ -163,6 +165,7 @@ func (this *UserService) ListUserInfosByEmails(emails []string) []info.User {
db.ListByQ(db.Users, bson.M{"Email": bson.M{"$in": emails}}, &users) db.ListByQ(db.Users, bson.M{"Email": bson.M{"$in": emails}}, &users)
return users return users
} }
// 用户信息即可 // 用户信息即可
func (this *UserService) MapUserInfoByUserIds(userIds []bson.ObjectId) map[bson.ObjectId]info.User { func (this *UserService) MapUserInfoByUserIds(userIds []bson.ObjectId) map[bson.ObjectId]info.User {
users := []info.User{} users := []info.User{}
@@ -175,6 +178,7 @@ func (this *UserService) MapUserInfoByUserIds(userIds []bson.ObjectId) map[bson.
} }
return userMap return userMap
} }
// 用户信息和博客设置信息 // 用户信息和博客设置信息
func (this *UserService) MapUserInfoAndBlogInfosByUserIds(userIds []bson.ObjectId) map[bson.ObjectId]info.User { func (this *UserService) MapUserInfoAndBlogInfosByUserIds(userIds []bson.ObjectId) map[bson.ObjectId]info.User {
return this.MapUserInfoByUserIds(userIds) return this.MapUserInfoByUserIds(userIds)
@@ -249,7 +253,7 @@ func (this *UserService) GetUserAndBlog(userId string) info.UserAndBlog {
// 通过ids得到users, 按id的顺序组织users // 通过ids得到users, 按id的顺序组织users
func (this *UserService) GetUserInfosOrderBySeq(userIds []bson.ObjectId) []info.User { func (this *UserService) GetUserInfosOrderBySeq(userIds []bson.ObjectId) []info.User {
users := []info.User{} users := []info.User{}
db.ListByQ(db.Users, bson.M{"_id": bson.M{"$in": userIds}}, &users); db.ListByQ(db.Users, bson.M{"_id": bson.M{"$in": userIds}}, &users)
usersMap := map[bson.ObjectId]info.User{} usersMap := map[bson.ObjectId]info.User{}
for _, user := range users { for _, user := range users {
@@ -257,7 +261,7 @@ func (this *UserService) GetUserInfosOrderBySeq(userIds []bson.ObjectId) []info.
} }
hasAppend := map[bson.ObjectId]bool{} // 为了防止userIds有重复的 hasAppend := map[bson.ObjectId]bool{} // 为了防止userIds有重复的
users2 := []info.User{}; users2 := []info.User{}
for _, userId := range userIds { for _, userId := range userIds {
if user, ok := usersMap[userId]; ok && !hasAppend[userId] { if user, ok := usersMap[userId]; ok && !hasAppend[userId] {
hasAppend[userId] = true hasAppend[userId] = true
@@ -300,7 +304,7 @@ func (this *UserService) UpdateUsername(userId, username string) (bool, string)
} }
// 修改头像 // 修改头像
func (this *UserService) UpdateAvatar(userId, avatarPath string) (bool) { func (this *UserService) UpdateAvatar(userId, avatarPath string) bool {
userIdO := bson.ObjectIdHex(userId) userIdO := bson.ObjectIdHex(userId)
return db.UpdateByQField(db.Users, bson.M{"_id": userIdO}, "Logo", avatarPath) return db.UpdateByQField(db.Users, bson.M{"_id": userIdO}, "Logo", avatarPath)
} }
@@ -337,7 +341,7 @@ func (this *UserService) ResetPwd(adminUserId, userId, pwd string) (ok bool, msg
} }
// 修改主题 // 修改主题
func (this *UserService) UpdateTheme(userId, theme string) (bool) { func (this *UserService) UpdateTheme(userId, theme string) bool {
ok := db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Theme", theme) ok := db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Theme", theme)
return ok return ok
} }
@@ -408,26 +412,6 @@ func (this *UserService) UpdateEmail(token string) (ok bool, msg, email string)
return return
} }
//---------
// 第三方添加账号
func (this *UserService) ThirdAddUser(userId, email, pwd string) (ok bool, msg string) {
// 判断该用户是否已有了帐户
userInfo := this.GetUserInfo(userId)
if userInfo.Email != "" {
msg = "你已有帐户"
return
}
// 判断email是否存在
if this.IsExistsUser(email) {
msg = "该用户已存在"
return
}
ok = db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, bson.M{"Email": email, "Pwd": Md5(pwd)})
return
}
//------------ //------------
// 偏好设置 // 偏好设置
@@ -436,6 +420,7 @@ func (this *UserService)UpdateColumnWidth(userId string, notebookWidth, noteList
return db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, return db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)},
bson.M{"NotebookWidth": notebookWidth, "NoteListWidth": noteListWidth, "MdEditorWidth": mdEditorWidth}) bson.M{"NotebookWidth": notebookWidth, "NoteListWidth": noteListWidth, "MdEditorWidth": mdEditorWidth})
} }
// 左侧是否隐藏 // 左侧是否隐藏
func (this *UserService) UpdateLeftIsMin(userId string, leftIsMin bool) bool { func (this *UserService) UpdateLeftIsMin(userId string, leftIsMin bool) bool {
return db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, bson.M{"LeftIsMin": leftIsMin}) return db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, bson.M{"LeftIsMin": leftIsMin})
@@ -454,7 +439,7 @@ func (this *UserService) ListUsers(pageNumber, pageSize int, sortField string, i
} }
query["$or"] = orQ query["$or"] = orQ
} }
q := db.Users.Find(query); q := db.Users.Find(query)
// 总记录数 // 总记录数
count, _ := q.Count() count, _ := q.Count()
// 列表 // 列表
@@ -479,9 +464,9 @@ func (this *UserService) GetAllUserByFilter(userFilterEmail, userFilterWhiteList
bson.M{"Username": bson.M{"$regex": bson.RegEx{".*?" + userFilterEmail + ".*", "i"}}}, bson.M{"Username": bson.M{"$regex": bson.RegEx{".*?" + userFilterEmail + ".*", "i"}}},
) )
} }
if(userFilterWhiteList != "") { if userFilterWhiteList != "" {
userFilterWhiteList = strings.Replace(userFilterWhiteList, "\r", "", -1) userFilterWhiteList = strings.Replace(userFilterWhiteList, "\r", "", -1)
emails := strings.Split(userFilterWhiteList, "\n"); emails := strings.Split(userFilterWhiteList, "\n")
orQ = append(orQ, bson.M{"Email": bson.M{"$in": emails}}) orQ = append(orQ, bson.M{"Email": bson.M{"$in": emails}})
} }
if len(orQ) > 0 { if len(orQ) > 0 {
@@ -489,16 +474,16 @@ func (this *UserService) GetAllUserByFilter(userFilterEmail, userFilterWhiteList
} }
emailQ := bson.M{} emailQ := bson.M{}
if(userFilterBlackList != "") { if userFilterBlackList != "" {
userFilterWhiteList = strings.Replace(userFilterBlackList, "\r", "", -1) userFilterWhiteList = strings.Replace(userFilterBlackList, "\r", "", -1)
bEmails := strings.Split(userFilterBlackList, "\n"); bEmails := strings.Split(userFilterBlackList, "\n")
emailQ["$nin"] = bEmails emailQ["$nin"] = bEmails
query["Email"] = emailQ query["Email"] = emailQ
} }
LogJ(query) LogJ(query)
users := []info.User{} users := []info.User{}
q := db.Users.Find(query); q := db.Users.Find(query)
q.All(&users) q.All(&users)
Log(len(users)) Log(len(users))
+1 -2
View File
@@ -1,7 +1,6 @@
package service package service
import ( import ()
)
// service 通用方法 // service 通用方法
+23 -6
View File
@@ -1,13 +1,14 @@
package service package service
import ( import (
"regexp"
"strings"
"net/url"
"strconv"
"gopkg.in/mgo.v2"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
. "github.com/leanote/leanote/app/lea"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"net/url"
"regexp"
"strconv"
"strings"
) )
// init service, for share service bettween services // init service, for share service bettween services
@@ -150,12 +151,28 @@ func getUniqueUrlTitle(userId string, urlTitle string, types string, padding int
return urlTitle2 return urlTitle2
} }
// 截取id 24位变成12位
// 先md5, 再取12位
func subIdHalf(id string) string {
idMd5 := Md5(id)
return idMd5[:12]
}
// types == note,notebook,single // types == note,notebook,single
func GetUrTitle(userId string, title string, types string) string { // id noteId, notebookId, singleId 当title没的时候才有用, 用它来替换
func GetUrTitle(userId string, title string, types string, id string) string {
urlTitle := strings.Trim(title, " ") urlTitle := strings.Trim(title, " ")
if urlTitle == "" { if urlTitle == "" {
if id == "" {
urlTitle = "Untitled-" + userId urlTitle = "Untitled-" + userId
} else {
urlTitle = subIdHalf(id)
} }
// 不允许title是ObjectId
} else if bson.IsObjectIdHex(title) {
urlTitle = subIdHalf(id)
}
urlTitle = fixUrlTitle(urlTitle) urlTitle = fixUrlTitle(urlTitle)
return getUniqueUrlTitle(userId, urlTitle, types, 1) return getUniqueUrlTitle(userId, urlTitle, types, 1)
} }
+1 -1
View File
@@ -1,8 +1,8 @@
package tests package tests
import ( import (
"testing"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"testing"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
"github.com/leanote/leanote/app/service" "github.com/leanote/leanote/app/service"
// "gopkg.in/mgo.v2" // "gopkg.in/mgo.v2"
+1 -1
View File
@@ -1,8 +1,8 @@
package tests package tests
import ( import (
"testing"
"github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/db"
"testing"
// . "github.com/leanote/leanote/app/lea" // . "github.com/leanote/leanote/app/lea"
// "github.com/leanote/leanote/app/service" // "github.com/leanote/leanote/app/service"
// "gopkg.in/mgo.v2" // "gopkg.in/mgo.v2"
+1
View File
@@ -1,3 +1,4 @@
package tests package tests
func a() { func a() {
} }
+9
View File
@@ -131,6 +131,15 @@
</span> </span>
</a> </a>
<ul class="nav lt"> <ul class="nav lt">
<li>
<a href="/admin/t?t=setting/site_url">
<span>
Site's URL
</span>
</a>
</li>
<li> <li>
<a href="/admin/t?t=setting/home_page"> <a href="/admin/t?t=setting/home_page">
<span> <span>
+51
View File
@@ -0,0 +1,51 @@
{{template "admin/top.html" .}}
<div class="m-b-md"> <h3 class="m-b-none">Site's URL</h3></div>
<div class="row">
<div class="col-sm-6">
<form id="add_user_form">
<section class="panel panel-default">
<div class="panel-body">
<div class="form-group">
<label>Site's URL</label>
<input type="text" class="form-control" name="siteUrl" value="{{.str.siteUrl}}" placeholder="http://localhost:9000">
Please note that if the value isn't blank, it will override the "siteUrl" configuration on app.conf.
<br>
Site's URL will be used to upload images, find password, and send email...
</div>
</div>
<footer class="panel-footer text-right bg-light lter">
<button type="submit" id="submit" class="btn btn-success btn-s-xs">Submit</button>
</footer>
</section>
</form>
</div>
</div>
{{template "admin/footer.html" .}}
<script src="/public/admin/js/jquery-validation-1.13.0/jquery.validate.js"></script>
<script>
$(function() {
init_validator("#add_user_form");
$("#submit").click(function(e){
e.preventDefault();
var t = this;
if($("#add_user_form").valid()) {
$(t).button('loading');
ajaxPost("/adminSetting/doSiteUrl", getFormJsonData("add_user_form"), function(ret){
$(t).button('reset');
if(!ret.Ok) {
art.alert(ret.Msg);
} else {
art.tips("Success");
}
});
}
});
});
</script>
{{template "admin/end.html" .}}
+10 -7
View File
@@ -16,12 +16,15 @@
<script src="/public/admin/js/ie/excanvas.js"></script> <script src="/public/admin/js/ie/excanvas.js"></script>
<![endif]--> <![endif]-->
</head> </head>
<body class=""> <body class="lang-{{$.locale}}">
<section class="vbox"> <section class="vbox">
<header class="bg-dark dk header navbar navbar-fixed-top-xs"> <header class="bg-dark dk header navbar navbar-fixed-top-xs">
<div class="navbar-header aside-md clearfix" id="logo">
<a href="/admin/index" class="navbar-brand" data-toggle="fullscreen"></a> <div class="navbar-header logo-ctn">
<div>Admin</div> <a href="/admin/index" class="navbar-brand clearfix" data-toggle="fullscreen">
<span id="logo"></span>
<span class="logo-title">Admin</span>
</a>
</div> </div>
<ul class="nav navbar-nav navbar-right m-n hidden-xs nav-user"> <ul class="nav navbar-nav navbar-right m-n hidden-xs nav-user">
@@ -37,16 +40,16 @@
</li> </li>
<li class="hidden-xs"> <li class="hidden-xs">
<a href="http://lea.leanote.com" class="dk" target="_blank"> <a href="http://lea.leanote.com" class="dk" target="_blank">
lea++ Leanote Explore
</a> </a>
</li> </li>
<li class="hidden-xs"> <li class="hidden-xs">
<a href="/note" class="dk" target="_blank"> <a href="/note" class="dk">
My Note My Note
</a> </a>
</li> </li>
<li class="hidden-xs"> <li class="hidden-xs">
<a href="/blog" class="dk" target="_blank"> <a href="/blog" class="dk">
My Blog My Blog
</a> </a>
</li> </li>
-19
View File
@@ -1,19 +0,0 @@
{{template "blog/header.html" .}}
<div id="postsContainer">
<div id="posts">
<div class="each-post">
<div class="title">
{{msg . "aboutMe"}}
</div>
<div class="created-time">
</div>
<div class="desc">
{{.userBlog.AboutMe | raw}}
</div>
</div>
</div>
</div>
{{template "blog/footer.html" .}}
-204
View File
@@ -1,204 +0,0 @@
<!-- 赞 -->
<div class="entry-controls clearfix">
<div class="vote-section-wrapper clearfix">
<button class="btn btn-default btn-zan" id="likeBtn"><i class="fa fa-thumbs-o-up"></i> <span id="likeNum">{{.blog.LikeNum}}</span> {{msg . "like"}}</button>
<span class="control-item read-counts"><i class="fa fa-eye"></i> {{if .blog.ReadNum}}{{.blog.ReadNum}}{{else}}1{{end}} {{msg . "viewers"}}</span>
</div>
<div class="right-section">
<div id="weixinQRCode"></div>
<!-- google+
<g:plusone size=”medium”></g:plusone>
-->
<button class="btn btn-share btn-default btn-weibo"><i class="fa fa-weibo"></i> {{msg . "sinaWeibo"}}</button>
<button class="btn btn-share btn-default btn-weixin"><i class="fa fa-wechat"></i> {{msg . "weixin"}}</button>
<div class="dropdown" style="display: inline-block; cursor: pointer; padding: 5px 10px;">
<!-- open -->
<div class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown">
<i class="fa fa-share-square-o"></i>
{{msg . "moreShare"}}
</div>
<ul class="dropdown-menu" role="menu">
<li><a href="#" class="btn-share tencent-weibo"><i class="fa fa-tencent-weibo"></i> {{msg . "tencentWeibo"}}</a></li>
<li><a href="#" class="btn-share qq"><i class="fa fa-qq"></i> {{msg . "qqZone"}}</a></li>
<li><a href="#" class="btn-share renren"><i class="fa fa-renren"></i> {{msg . "renren"}}</a></li>
</ul>
</div>
<!-- 举报 -->
{{if eq .locale "zh"}}
<div style="display: inline-block">
<a id="reportBtn"><i class="fa fa-flag-o"></i> {{msg . "report"}}</a>
</div>
{{end}}
</div>
<div class="voters clearfix" id="likers">
</div>
</div>
<script type="text/x-jsrender" id="tLikers">
[[for users]]
<a id="liker_[[:UserId]]" href="[[:~root.blogUrl]]/[[:Username]]" target="_blank" class="voter">
[[if Logo]]
<img alt="avatar" class="avatar-small" src="[[:Logo]]">
[[else]]
<img alt="avatar" class="avatar-small" src="/images/blog/default_avatar.png">
[[/if]]
</a>
[[/for]]
</script>
{{if and .userBlog.CanComment (not (eq .userBlog.CommentType "disqus"))}}
<script type="text/x-jsrender" id="tComments">
[[for comments]]
<li class="comment-item">
<!-- 头像 -->
<a ui-hovercard="" target="_blank" class="avatar-link" title="[[:UserInfo.Username]]" href="[[:~root.blogUrl]]/[[:UserInfo.Username]]">
<img class="avatar" src="[[:UserInfo.Logo]]">
</a>
<!-- 评论 -->
<div class="comment-body">
<div class="comment-hd">
<a href="[[:~root.blogUrl]]/[[:UserInfo.Username]]" target="_blank" >[[:UserInfo.Username]]</a>
[[if IsAuthorComment]]
<span>({{msg . "author"}})</span>
[[/if]]
<!-- 回复其它人 -->
[[if ToUserInfo]]
<span class="in-reply-to">
{{rawMsg . "reply"}}
<a href="[[:~root.blogUrl]]/[[:ToUserInfo.Username]]">[[:ToUserInfo.Username]]</a>
</span>
[[if ToUserIsAuthor]]
<span>({{msg . "author"}})</span>
[[/if]]
[[/if]]
</div>
<div class="comment-content ng-binding" ng-bind-html="comment.content">
[[html:Content]]
</div>
<div class="comment-ft clearfix" data-comment-id="[[:CommentId]]" >
<span title="" ui-time="" class="date">[[:PublishDate]] </span>
<span class="like-num [[if !LikeNum]]hide[[/if]]" title="[[:LikeNum]] {{rawMsg . "like"}}"><span class="like-num-i">[[:LikeNum]]</span> {{rawMsg . "like"}}</span></span>
[[if ~root.visitUserInfo.UserId]]
[[if IsMyNote && !IsMyComment]]
<a href="javascript:;" class="comment-trash op-link "><i class="fa fa-trash"></i> {{rawMsg . "delete"}}</a>
[[/if]]
[[if !IsMyComment]]
<a href="javascript:;" class="comment-reply op-link ">
<i class="fa fa-reply"></i>
{{rawMsg . "reply"}}
</a>
<a href="javascript:;" class="comment-like op-link"><i class="fa fa-thumbs-o-up"></i> <span class="like-text">[[if IsILikeIt]]{{rawMsg . "unlike"}}[[else]]{{rawMsg . "like"}}[[/if]]</span></a>
{{if eq .locale "zh"}}
<a href="javascript:;" class="comment-report op-link "><i class="fa fa-flag-o"></i> {{rawMsg . "report"}}</a>
{{end}}
[[else]]
<a href="javascript:;" class="comment-trash op-link "><i class="fa fa-trash"></i> {{rawMsg . "delete"}}</a>
[[/if]]
[[/if]]
</div>
<!-- 回复该评论 -->
[[if ~root.visitUserInfo.UserId]]
<form class="comment-form comment-box-ft">
<div class="clearfix">
<div class="avatar-wrap">
<img class="avatar" src="[[:~root.visitUserInfo.Logo]]">
</div>
<div class="editor-wrap">
<textarea class="editable" id="commentContent" name="commentContent" placeholder="{{rawMsg . "reply"}}"></textarea>
</div>
</div>
<div class="command clearfix" style="display: block;">
<button class="reply-comment-btn save btn btn-primary" data-comment-id="[[:CommentId]]">{{rawMsg . "comment"}}</button>
<a class="cancel reply-cancel btn-link">{{rawMsg . "cancel"}}</a>
</div>
</form>
[[/if]]
</div>
</li>
[[/for]]
</script>
<!-- 评论 -->
<div class="comment-box hide">
{{if .visitUserInfo.UserId}}
<form class="comment-form comment-box-ft" id="commentForm">
<div class="clearfix">
<div class="avatar-wrap">
<img class="avatar" src="{{.visitUserInfo.Logo}}">
</div>
<div class="editor-wrap">
<textarea class="editable" id="commentContent" name="commentContent" placeholder="{{msg . "comment"}}" style="height: 100px;"></textarea>
</div>
</div>
<div class="command clearfix" style="display: block;">
<button id="commentBtn" class="reply-comment-btn save btn btn-primary">{{msg . "comment"}}</button>
</div>
</form>
{{else}}
<div class="needLogin">
<a onclick="goLogin()">{{msg . "signIn"}}</a>, {{msg . "submitComment"}}.
<br />
没有帐号? <a onclick="goRegister()">{{msg . "signUp"}}</a>
</div>
{{end}}
<div class="box-header">
<span class="counter">
<i class="icon icon-comment"></i><span id="commentNum">{{.blog.CommentNum}}</span> {{msg . "comments"}}
</span>
</div>
<ul id="comments">
</ul>
</div>
<div id="moreComments">
<div class="hide comments-more">
<a>More...</a>
</div>
<div class="comments-loading">
<img src="/images/loading-32.gif" />
</div>
</div>
{{if eq .locale "zh"}}
<div id="reportMsg" class="hide">
<form class="report-form" name="reportForm">
<ul class="options clearfix">
<li><label><input required="" value="{{msg . "reportReason1"}}" name="reason" type="radio">{{msg . "reportReason1"}}</label></li>
<li><label><input required="" value="{{msg . "reportReason2"}}" name="reason" type="radio">{{msg . "reportReason2"}}</label></li>
<li><label><input required="" value="{{msg . "reportReason3"}}" name="reason" type="radio">{{msg . "reportReason3"}}</label></li>
<li><label><input required="" value="{{msg . "reportReason4"}}" name="reason" type="radio">{{msg . "reportReason4"}}</label></li>
<li><label><input required="" value="" name="reason" type="radio">{{msg . "other"}}</label></li>
</ul>
<p class="input-container" style="display: none">
<input placeholder="{{msg . "reportReason"}}" type="text" name="detail" class="form-control reason-text basic-input" />
</p>
<p class="footnote"></p>
</form>
</div>
{{end}}
{{end}}
{{if and .userBlog.CanComment (eq .userBlog.CommentType "disqus")}}
<div id="disqus_thread"></div>
<!-- comment -->
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = '{{.userBlog.DisqusId}}'; // required: replace example with your forum shortname
var disqus_identifier = '{{.userBlog.UserId.Hex}}/{{.blog.NoteId.Hex}}/{{.blog.Title}}'; // 博客链接
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
{{end}}
-56
View File
@@ -1,56 +0,0 @@
<div id="footerContainer">
{{$userId := .userBlog.UserId.Hex}}
<div class="container" id="footer">
<div class="col-md-4">
<h3>{{msg . "blogNavs"}}</h3>
<ul>
<li><a href="{{$.blogUrl}}/{{$.userInfo.Username}}">{{msg . "home"}}</a></li>
{{range .notebooks}}
<li>
<a href="{{$.cateUrl}}/{{.NotebookId.Hex}}">{{.Title}}</a>
</li>
{{end}}
<li><a href="{{$.aboutMeUrl}}">{{msg . "aboutMe"}}</a></li>
</ul>
</div>
<div class="col-md-4">
<h3>{{msg . "latestPosts"}}</h3>
<ul>
{{range .recentBlogs}}
<li title="{{.Title}}"><a href="{{$.blogUrl}}/view/{{.NoteId.Hex}}/">{{.Title}}</a></li>
{{end}}
</ul>
</div>
<div class="col-md-4">
<h3>{{msg . "quickLinks"}}</h3>
<ul>
<li><a href="{{$.noteUrl}}">{{msg . "myNote"}}</a></li>
<li><a href="{{$.siteUrl}}/login">leanote {{msg . "login"}}</a></li>
<li><a href="http://leanote.com" target="_blank">leanote {{msg . "home"}}</a></li>
<li><a href="http://lea.leanote.com" target="_blank">lea++</a></li>
<li><a href="http://bbs.leanote.com" target="_blank">leanote {{msg . "community"}}</a></li>
<li><a href="https://github.com/leanote/leanote" target="_blank">leanote github</a></li>
</ul>
</div>
</div>
</div>
<script src="{{$.siteUrl}}/js/jquery-1.9.0.min.js"></script>
<script src="{{$.siteUrl}}/js/bootstrap-min.js"></script>
<script src="{{$.siteUrl}}/js/bootstrap-hover-dropdown.js"></script>
<script src="{{$.siteUrl}}/js/i18n/blog.{{.locale}}.js"></script>
{{if not .isMe}}
<script src="{{$.siteUrl}}/blog/isMe.js?userId={{.userBlog.UserId.Hex}}"></script>
{{end}}
<script>
// 搜索
function search(e) {
var key = $("#searchInput").val();
if(!key) {
location.href = "{{$.searchUrl}}";
} else {
var tpl = '<form action="{{$.searchUrl}}" method="get">';
tpl += '<input name="key" value="' + key + '" />';
tpl += "</form";
$(tpl).submit();
}
}␍</script>
-104
View File
@@ -1,104 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="keywords" content="leanote,leanote.com">
<meta name="description" content="leanote, {{msg $ "moto"}}">
<meta name="author" content="leanote">
<title>{{.title}}</title>
<!-- Bootstrap core CSS -->
<link href="{{.siteUrl}}/css/bootstrap.css" rel="stylesheet">
<!-- 字体必须同一域 -->
{{if .set}}
<link href="{{.siteUrl}}/css/font-awesome-4.2.0/css/font-awesome.css" rel="stylesheet">
{{else}}
<link href="{{$.staticUrl}}/css/font-awesome-4.2.0/css/font-awesome.css" rel="stylesheet">
{{end}}
<link id="styleLink" href="{{.siteUrl}}/css/blog/{{if .userBlog.Style}}{{.userBlog.Style}}{{else}}blog_default{{end}}.css" rel="stylesheet">
<link href="{{.siteUrl}}/css/blog/comment.css" rel="stylesheet">
<script>
function log(o) {
}
</script>
<style>
</style>
</head>
<body>
<div id="headerAndNav" >
<div id="headerContainer" class="container">
<!-- 头部可放博客名, 导航 -->
<div id="header">
{{$userId := .userBlog.UserId.Hex}} <!-- 可不要了 -->
{{$username := .userInfo.Username}}
<h1>
<a href="{{.indexUrl}}" id="logo">
{{if .userBlog.Logo}}
<img src="{{.userBlog.Logo}}" title="{{.userBlog.Title}}"/>
{{else}}
{{.userBlog.Title | raw}}
{{end}}
</a>
</h1>
<div id="blogDesc">
{{.userBlog.SubTitle | raw}}
</div>
</div>
</div>
<!-- Static navbar -->
<div class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{.indexUrl}}">
{{if .userBlog.Logo}}
<img src="{{.userBlog.Logo}}" title="{{.userBlog.Title}}"/>
{{else}}
{{.userBlog.Title | raw}}
{{end}}
</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
{{$navNotebookId := .notebookId}}
<li class="{{if .index}}active{{end}}"><a href="{{.indexUrl}}">{{msg . "home"}}</a></li>
{{range .notebooks}}
{{$notebookId := .NotebookId.Hex}}
<li class="{{if $navNotebookId}}{{if eq $navNotebookId $notebookId}}active{{else}}{{end}}{{end}}">
<a href="{{$.cateUrl}}/{{$notebookId}}"
>{{.Title}}</a>
</li>
{{end}}
<li class="{{if .aboutMe}}active{{end}}"><a href="{{.aboutMeUrl}}">{{msg . "aboutMe"}}</a></li>
<!-- 同源上传logo -->
<li class="is-me {{if .set}}active{{end}} {{if not .isMe}}hide{{end}}" ><a href="{{$.siteUrl}}/blog/set/">{{msg . "blogSet"}}</a></li>
<li><a href="{{$.noteUrl}}" class="is-me {{if not .isMe}}hide{{end}}">{{msg . "myNote"}}</a></li>
</ul>
<form class="navbar-form navbar-right" id="search" onsubmit="search(event);return false;">
<div class="input-group">
<span class="input-group-addon" id="searchIcon" onclick="search(event);"><i class="fa fa-search"></i></span>
<input type="text" placeholder="search" id="searchInput" class="form-control" value="{{.key}}">
</div>
</form>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<script>
var UserInfo = {UserId: "{{$userId}}", Email: "{{.userInfo.Email}}", Username: "{{.userInfo.Username}}"};
var UserBlogInfo={CanComment: {{.userBlog.CanComment}}, CommentType: "{{.userBlog.CommentType}}"};
var indexUrl = "{{$.indexUrl}}";
var viewUrl = "{{$.viewUrl}}";
var blogUrl = "{{$.blogUrl}}";
var staticUrl = "{{$.staticUrl}}"; // blog.leanote.com, life.leanote.com, aaa.com
</script>
-73
View File
@@ -1,73 +0,0 @@
<!-- This file is Depreciated -->
<link href="/public/mdeditor/editor/google-code-prettify/prettify.css" type="text/css" rel="stylesheet">
<script src="/public/mdeditor/editor/google-code-prettify/prettify.js"></script>
<script>
$("pre").addClass("prettyprint linenums");
prettyPrint();
</script>
<!--
<script type="text/javascript" src="/js/syntaxhighlighter/scripts/shCore.js"></script>
<link href="/js/syntaxhighlighter/styles/shCore.css" rel="stylesheet" type="text/css" />
<link href="/js/syntaxhighlighter/styles/shThemeDefault.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
    $(function () {
var pathPrefix = "/js/syntaxhighlighter/scripts/";
        var map = {
"brush: jscript": "shBrushJScript.js",
         "brush: c#": "shBrushCSharp.js",
        "brush: css": "shBrushCss.js",
        "brush: cpp": "shBrushCpp.js",
        "brush: java": "shBrushJava.js",
        "brush: xml": "shBrushXml.js",
        "brush: php": "shBrushPhp.js",
        "brush: perl": "shBrushPerl.js",
        "brush: python": "shBrushPython.js",
        "brush: ruby": "shBrushRuby.js",
        "brush: sql": "shBrushSql.js"}
        var needLoadCount = 0;
        var alreadyLoadCount = 0;
$('pre[class]').each(function() {
var brush = $(this).attr("class");
var js = map[brush]
if (js) {
                needLoadCount++;
map[brush] = null; // 不要重复加载
loadJS(pathPrefix + js, function () {
                    alreadyLoadCount++;
                    if (alreadyLoadCount == needLoadCount) {
//setTimeout(function() {
                        SyntaxHighlighter.highlight();
//}, 500);
                    }
                });
}
});
    });
function loadJS(url, callback) {
$.getScript(url, function() {
callback();
});
}
 
/*
function loadJS(url, callback, charset) {
    var script = document.createElement('script');
    script.onload = script.onreadystatechange = function () {
        if (script && script.readyState && /^(?!(?:loaded|complete)$)/.test(script.readyState)) return;
        script.onload = script.onreadystatechange = null;
        script.src = '';
        script.parentNode.removeChild(script);
        script = null;
        if (callback) callback();
    };
    script.charset = charset || document.charset || document.characterSet;
    script.src = url;
    try { document.getElementsByTagName("head")[0].appendChild(script); } catch (e) { }
}
*/
</script>
-->
-50
View File
@@ -1,50 +0,0 @@
{{template "blog/header.html" .}}
<div id="postsContainer">
<div class="container">
{{if .notebookId}}
<h2>{{msg . "blogClass"}} - {{.notebook.Title}}</h2>
{{end}}
</div>
<div id="posts">
{{$G := .}}
{{range .blogs}}
<div class="each-post">
<div class="title">
<a href="{{$.viewUrl}}/{{.NoteId.Hex}}" title="{{msg $ "fullBlog"}}">
{{.Title}}
</a>
</div>
<div class="created-time">
<i class="fa fa-bookmark-o"></i>
{{if .Tags}}
{{blogTags $ .Tags}}
{{else}}
{{msg $ "noTag"}}
{{end}}
|
<i class="fa fa-calendar"></i> {{msg $ "updatedTime"}} {{.UpdatedTime | datetime}} |
<i class="fa fa-calendar"></i> {{msg $ "createdTime"}} {{.CreatedTime | datetime}}
</div>
<div class="desc">
{{.Content | raw}}
</div>
<a class="more" href="{{$.viewUrl}}/{{.NoteId.Hex}}" title="{{msg $ "fullBlog"}}">{{msg $ "more"}}.</a>
</div>
{{end}}
<!-- 分页 -->
<ul class="pager">
{{if .notebookId}}
{{set $ "pageUrl" (concatStr $.cateUrl "/" .notebookId)}}
{{else}}
{{set $ "pageUrl" $.indexUrl}}
{{end}}
{{page $.pageUrl .page .pageSize .count}}
</ul>
</div>
</div>
{{template "blog/footer.html" .}}
{{template "blog/highlight.html"}}
</body>
</html>
-45
View File
@@ -1,45 +0,0 @@
{{template "blog/header.html" .}}
<div id="postsContainer">
<div class="container">
<h2>{{msg . "search"}} - {{.key}} </h2>
</div>
<div id="posts">
{{range .blogs}}
<div class="each-post">
<div class="title">
<a href="{{$.viewUrl}}/{{.NoteId.Hex}}" title="{{msg $ "fullBlog"}}">
{{.Title}}
</a>
</div>
<div class="created-time">
<i class="fa fa-bookmark-o"></i>
{{if .Tags}}
{{blogTags $ .Tags}}
{{else}}
{{msg $ "noTag"}}
{{end}}
|
<i class="fa fa-calendar"></i> {{msg $ "updatedTime"}} {{.UpdatedTime | datetime}} |
<i class="fa fa-calendar"></i> {{msg $ "createdTime"}} {{.CreatedTime | datetime}}
</div>
<div class="desc">
{{.Content | raw}}
</div>
<a class="more" href="{{$.viewUrl}}/{{.NoteId.Hex}}" title="{{msg $ "fullBlog"}}">{{msg $ "more"}}</a>
</div>
{{end}}
{{if not .blogs }}
<div class="each-post">
{{msg . "none"}}
</div>
{{end}}
</div>
</div>
{{template "blog/footer.html" .}}
{{template "blog/highlight.html"}}
</body>
</html>
-323
View File
@@ -1,323 +0,0 @@
{{template "blog/header.html" .}}
<!-- set页面不是自定义域名和二级域名页 -->
<link rel="stylesheet" href="{{.siteUrl}}/tinymce/skins/custom/skin.min.css" type="text/css">
<style>
.tab-pane {
padding-top: 10px;
}
</style>
<div id="postsContainer">
<div id="posts">
<ul id="myTab" class="nav nav-tabs">
<li class="active"><a href="#baseInfo" data-toggle="tab">{{msg . "baseInfoSet"}}</a></li>
<li class=""><a href="#commentInfo" data-toggle="tab">{{msg . "commentSet"}}</a></li>
<li class=""><a href="#styleInfo" data-toggle="tab">{{msg . "themeSet"}}</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane" id="styleInfo">
<form class="form-horizontal" role="form">
<div class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<div class="alert alert-success" id="styleMsg" style="display: none; margin-bottom: 3px;"></div>
</div>
</div>
<div class="form-group">
<label for="Style" class="col-sm-2 control-label">{{msg . "theme"}}</label>
<div class="col-sm-10" style="margin-top: 6px;" id="themeList">
<label>
<img class="preview" src="{{$.siteUrl}}/images/blog/theme/default.png" />
<input type="radio" name="Style"
value="blog_default"
{{if not .userBlog.Style}}
checked="checked"
{{else}}
{{if eq .userBlog.Style "blog_default"}}
checked="checked"
{{end}}
{{end}}>
{{msg . "default"}}
</label>
<label>
<img class="preview" src="{{$.siteUrl}}/images/blog/theme/elegent.png" />
<input type="radio" name="Style"
value="blog_daqi"
{{if eq .userBlog.Style "blog_daqi"}}checked="checked"{{end}}>
{{msg . "elegant"}}
</label>
<label>
<img class="preview" src="{{$.siteUrl}}/images/blog/theme/left_nav_fix.png" />
<input type="radio" name="Style"
value="blog_left_fixed"
{{if eq .userBlog.Style "blog_left_fixed"}}checked="checked"{{end}}>
{{msg . "navFixed"}}
</label>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button class="btn btn-success">{{msg . "save"}}</button>
<span class="msg"></span>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="commentInfo">
<form class="form-horizontal" role="form">
<div class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<div class="alert alert-success" id="commentMsg" style="display: none; margin-bottom: 3px;"></div>
</div>
</div>
<div class="form-group">
<label for="subTitle" class="col-sm-2 control-label">{{msg . "chooseComment"}}</label>
<div class="col-sm-10">
<label>
<input type="checkbox" id="CanComment" name="CanComment"
{{if .userBlog.CanComment}}checked="checked"{{end}} > {{msg . "openComment"}}
</label>
<br />
<div id="commentSet" {{if not .userBlog.CanComment}}style="display: none"{{end}}>
<label>
<input type="radio"
name="commentType"
value="default"
{{if or (not .userBlog.CommentType) (eq .userBlog.CommentType "default")}}checked="checked"{{end}} > Default
</label>
<label>
<input type="radio" name="commentType" id="disqus"
value="disqus"
{{if eq .userBlog.CommentType "disqus"}}checked="checked"{{end}} > Disqus
</label>
<div id="disqusSet" {{if not (eq .userBlog.CommentType "disqus")}}style="display: none"{{end}}>
<label for="DisqusId">Disqus Id</label> <input type="text"
class="form-control" style="display: inline; width: 50%"
id="DisqusId" name="DisqusId"
value="{{if .userBlog.DisqusId}}{{.userBlog.DisqusId}}{{else}}leanote{{end}}">
<br />
{{msg . "disqusHelp"}}
<a target="_blank" href="http://leanote.com/blog/view/52db8463e01c530ef8000001">{{msg . "needHelp"}}</a>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button class="btn btn-success">{{msg . "save"}}</button>
<span class="msg"></span>
</div>
</div>
</form>
</div>
<div class="tab-pane active" id="baseInfo">
<div class="form-horizontal" role="form" id="userBlogForm">
<div class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<div class="alert alert-success" id="msg"
style="display: none; margin-bottom: 3px;"></div>
</div>
</div>
<div class="form-group">
<label for="title" class="col-sm-2 control-label">{{msg . "blogName"}}</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="Title" name="Title"
placeholder="eg: leanote's blog"
value="{{if .userBlog.Title}}{{.userBlog.Title}}{{else}}{{.userInfo.Email}} 's blog{{end}}">
</div>
</div>
<div class="form-group">
<label for="logo" class="col-sm-2 control-label">{{msg . "blogLogo"}}</label>
<div class="col-sm-10">
<input type="hidden" name="Logo" id="Logo"
value="{{.userBlog.Logo}}" />
<form id="formLogo" action="{{$.siteUrl}}/file/uploadBlogLogo" method="post"
enctype="multipart/form-data" target="logoTarget"
onsubmit="inProgress()">
<input type="file" class="form-control" id="logo2" name="file"
onChange='$("#formLogo").submit();' />
{{msg . "blogLogoTips"}}
<div id="logoImg"
{{if .userBlog.Logo }}
{{else}}
style="display: none"{{end}}
>
<img src="{{.userBlog.Logo}}" style="height: 40px" /> <a
href="#" id="deleteLogo">{{msg . "delete"}}</a>
</div>
</form>
<iframe id="logoTarget" name="logoTarget" src="#"
style="display: none"></iframe>
</div>
</div>
<div class="form-group">
<label for="subTitle" class="col-sm-2 control-label">{{msg . "blogDesc"}}</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="SubTitle"
name="SubTitle" value="{{.userBlog.SubTitle}}"
placeholder="eg: leanote, Not Just A Notebook">
</div>
</div>
<div class="form-group">
<label for="aboutMe" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<div id="popularToolbar"></div>
</div>
</div>
<div class="form-group">
<label for="aboutMe" class="col-sm-2 control-label">{{msg . "aboutMe"}}</label>
<div class="col-sm-10">
<textarea id="AboutMe" name="AboutMe">{{.userBlog.AboutMe}}</textarea>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button class="btn btn-success">{{msg . "save"}}</button>
<span class="msg"></span>
</div>
</div>
</div>
</div>
</div>
</div>
{{template "blog/footer.html" .}}
<script src="{{.siteUrl}}/js/common-min.js"></script>
<script type="text/javascript" src="{{.siteUrl}}/tinymce/tinymce.min.js"></script>
<script>
var urlPrefix = "{{.siteUrl}}";
$(function() {
tinymce.init({
selector : "#AboutMe",
content_css : [ "/css/bootstrap.css", "/css/editor/editor.css" ],
skin : "custom",
language : "{{.locale}}",
height : 300,
width : "100%",
skin : "custom",
plugins : [
"advlist autolink link leanote_image lists charmap hr ",
"searchreplace visualblocks visualchars leanote_code tabfocus",
"table contextmenu directionality textcolor paste fullpage textcolor"],
toolbar1 : "formatselect |fontselect fontsizeselect| forecolor backcolor | bold italic underline strikethrough | bullist numlist |",
menubar : false,
toolbar_items_size : 'small',
statusbar : false,
font_formats : "Arial=arial,helvetica,sans-serif;"
+ "Arial Black=arial black,avant garde;"
+ "Times New Roman=times new roman,times;"
+ "Courier New=courier new,courier;"
+ "Tahoma=tahoma,arial,helvetica,sans-serif;"
+ "Verdana=verdana,geneva;" + "宋体=SimSun;"
+ "新宋体=NSimSun;" + "黑体=SimHei;"
+ "微软雅黑=Microsoft YaHei",
block_formats : "Header 1=h1;Header 2=h2;Header 3=h3; Header 4=h4;Pre=pre;Paragraph=p"
});
$("#deleteLogo").click(function() {
$("#Logo").val("");
$("#logoImg").hide();
});
$("#CanComment").click(function() {
if ($(this).is(":checked")) {
$("#commentSet").show();
} else {
$("#commentSet").hide();
}
});
$("input[name='commentType']").click(function() {
if ($("input[name='commentType']:checked").val() == "disqus") {
$("#disqusSet").show();
} else {
$("#disqusSet").hide();
}
});
// 基本设置
$("#baseInfo .btn-success").click(function() {
var data = {
Title : $("#Title").val(),
SubTitle : $("#SubTitle").val(),
Logo : $("#Logo").val(),
AboutMe : getEditorContent()
}
post("/blog/setUserBlogBase", data, function(ret) {
showMsg2($("#baseInfo .msg"), "{{msg . "saveSuccess"}}", 2000);
$("#blogDesc").html(data.SubTitle);
$("#logo").html(data.Title);
if(data.Logo) {
$("#logo").html(t('<img src="?" />', urlPrefix + "/" + data.Logo));
}
}, this);
});
// 评论
$("#commentInfo .btn-success").click(function(e) {
e.preventDefault();
var data = {
CanComment : $("#CanComment").is(":checked"),
CommentType: $("input[name='commentType']:checked").val(),
DisqusId : $("#DisqusId").val(),
}
post("/blog/setUserBlogComment", data, function(ret) {
showMsg2($("#commentInfo .msg"), "{{msg . "saveSuccess"}}", 2000);
}, this);
});
// 主题
$("#styleInfo .btn-success").click(function(e) {
e.preventDefault();
var data = {
Style : $("input[name='Style']:checked").val()
}
post("/blog/setUserBlogStyle", data, function(ret) {
showMsg2($("#styleInfo .msg"), "{{msg . "saveSuccess"}}", 2000);
}, this);
});
$("input[name='Style']").click(function() {
$("#styleLink").attr("href", "/css/blog/" + $(this).val() + ".css");
});
});
function inProgress() {
}
// filename, result, resultCode
function uploadFinish(ret) {
if (ret) {
if (ret.resultCode == '1') {
$("#logoImg img").attr("src", urlPrefix + "/" + ret.filename).parent().show();
$("#Logo").val(ret.filename);
return;
}
alert(ret.result);
return;
}
// 上传出错
alert("上传出错");
}
</script>
</div>
</body>
</html>
-125
View File
@@ -1,125 +0,0 @@
{{template "blog/header.html" .}}
<div id="postsContainer">
<div id="posts">
<div class="each-post">
<div class="title">
{{.blog.Title}}
</div>
<div class="created-time">
<i class="fa fa-bookmark-o"></i>
{{if .blog.Tags}}
{{blogTags $ .blog.Tags}}
{{else}}
{{msg . "noTag"}}
{{end}}
|
<i class="fa fa-calendar"></i> {{msg . "updatedTime"}} {{.blog.UpdatedTime | datetime}} |
<i class="fa fa-calendar"></i> {{msg . "createdTime"}} {{.blog.CreatedTime | datetime}}
</div>
<div class="mobile-created-time">
{{ if .userInfo.Logo}}
<img src="{{.userInfo.Logo}}" id="userLogo">
{{else}}
<img src="{{$.siteUrl}}/images/blog/default_avatar.png" id="userLogo">
{{end}}
{{.userInfo.Username}}
{{if .blog.Tags}}
&nbsp;
<i class="fa fa-bookmark-o" style="color: #666"></i>
{{blogTags $ .blog.Tags}}
{{end}}
</div>
<div class="desc" id="content">
{{if .blog.IsMarkdown }}
<div id="markdownContent" style="display: none">
<!-- 用textarea装html, 防止得到的值失真 -->
<textarea>
{{.blog.Content | raw}}
</textarea>
</div>
<div style="padding: 20px; text-align: center">
<img src="/images/loading-32.gif" />
</div>
{{else}}
{{.blog.Content | raw}}
{{end}}
<div id="desc" class="hide">{{.blog.Desc}}</div>
</div>
<!-- comment -->
{{template "blog/comment.html" .}}
</div>
</div>
</div>
{{template "blog/footer.html" .}}
{{template "blog/highlight.html"}}
<div id="blogNav">
<div id="blogNavNav">
<i class="fa fa-align-justify" title="文档导航"></i>
<span>{{msg . "blogNav"}}</span>
</div>
<div id="blogNavContent">
</div>
</div>
<script>
var visitUserInfo = eval("(" + {{.visitUserInfoJson}} + ")");
var urlPrefix = "{{.siteUrl}}";
var noteId = "{{.blog.NoteId.Hex}}";
var preLikeNum = +"{{.blog.LikeNum}}";
var commentNum = +"{{.blog.CommentNum}}";
</script>
<script src="/js/app/blog/common.js"></script>
<script src="/js/jsrender.js"></script>
<script src="/js/jquery-cookie-min.js"></script>
<script src="/js/bootstrap-dialog.min.js"></script>
<script src="/js/jquery.qrcode.min.js"></script>
<script src="/js/app/blog/view.js"></script>
{{if .blog.IsMarkdown }}
<script src="/public/mdeditor/editor/pagedown/Markdown.Converter.js"></script>
<script src="/public/mdeditor/editor/pagedown/Markdown.Sanitizer.js"></script>
<script src="/public/mdeditor/editor/pagedown/Markdown.Editor.js"></script>
<script src="/public/mdeditor/editor/pagedown/local/Markdown.local.zh.js"></script>
<script src="/public/mdeditor/editor/Markdown.Extra.js"></script>
<!--mathjax-->
<script type="text/x-mathjax-config">
MathJax.Hub.Config({ tex2jax: { inlineMath: [['$','$'], ["\\(","\\)"]], processEscapes: true }, messageStyle: "none"});
</script>
<script src="/public/mdeditor/editor/mathJax.js"></script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script>
var content = $.trim($("#markdownContent textarea").val());
// $("#markdownContent").html("");
var converter = Markdown.getSanitizingConverter();
Markdown.Extra.init(converter, {extensions: ["tables", "fenced_code_gfm", "def_list"]});
var html = converter.makeHtml(content);
$("#content").html(html);
$("pre").addClass("prettyprint linenums");
prettyPrint();
MathJax.Hub.Queue(["Typeset",MathJax.Hub,"wmd-preview"]);
initNav();
weixin();
</script>
{{else}}
<script>
$(function() {
initNav();
weixin();
});
</script>
{{end}}
<!--google+
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"> {lang: 'zh-CN'} </script>
-->
</body>
</html>
+6 -6
View File
@@ -50,12 +50,12 @@ table tr:nth-child(2n) {
{{ if .userBlog.Logo}} {{ if .userBlog.Logo}}
<img src="{{.userBlog.Logo}}" id="logo"> <img src="{{.userBlog.Logo}}" id="logo">
{{else}} {{else}}
<img src="{{$.siteUrl}}/images/blog/default_avatar.png" id="logo"> <img src="/images/blog/default_avatar.png" id="logo">
{{end}} {{end}}
{{.userInfo.Username}} {{.userInfo.Username}}
--> -->
{{if .blog.Tags}} {{if .blog.Tags}}
<img src="{{$.siteUrl}}/images/blog/tag.png" id="tag"> <img src="/images/blog/tag.png" id="tag">
{{blogTagsForExport $ .blog.Tags}} {{blogTagsForExport $ .blog.Tags}}
{{end}} {{end}}
</div> </div>
@@ -79,7 +79,7 @@ table tr:nth-child(2n) {
<!-- <!--
<div id="footer"> <div id="footer">
<p class="split"></p> <p class="split"></p>
<a href="http://leanote.com"><img src="{{.siteUrl}}/images/logo/leanote_icon_blue.png" id="leanote_logo"/></a> <a href="http://leanote.com"><img src="/images/logo/leanote_icon_blue.png" id="leanote_logo"/></a>
<p> <p>
<a href="http://leanote.com">Leanote</a> <a href="http://leanote.com">Leanote</a>
<br /> <br />
@@ -88,10 +88,10 @@ table tr:nth-child(2n) {
</div> </div>
--> -->
<script src="{{.siteUrl}}/js/jquery-1.9.0.min.js"></script> <script src="/js/jquery-1.9.0.min.js"></script>
<link href="{{.siteUrl}}/public/mdeditor/editor/google-code-prettify/prettify.css" type="text/css" rel="stylesheet"> <link href="/public/js/google-code-prettify/prettify.css" type="text/css" rel="stylesheet">
<script src="{{.siteUrl}}/public/mdeditor/editor/google-code-prettify/prettify.js"></script> <script src="/public/js/google-code-prettify/prettify.js"></script>
<script> <script>
function ok() { function ok() {
+2 -2
View File
@@ -2,7 +2,7 @@
<section id="box" class="animated fadeInUp"> <section id="box" class="animated fadeInUp">
<div> <div>
<h1 id="logo">leanote</h1> <h1 id="logo"></h1>
<div id="boxForm"> <div id="boxForm">
<div id="boxHeader">{{msg . "findPassword"}}</div> <div id="boxHeader">{{msg . "findPassword"}}</div>
<form> <form>
@@ -27,7 +27,7 @@
<a href="/index">{{msg . "home"}}</a> <a href="/index">{{msg . "home"}}</a>
</p> </p>
<p> <p>
<a href="/index">leanote</a> © 2014-2015 <a href="https://leanote.com">Leanote</a> © 2014-2016
</p> </p>
</div> </div>
+2 -2
View File
@@ -2,7 +2,7 @@
<section id="box" class="animated fadeInUp"> <section id="box" class="animated fadeInUp">
<div> <div>
<h1 id="logo">leanote</h1> <h1 id="logo"></h1>
<div id="boxForm"> <div id="boxForm">
<div id="boxHeader">{{msg . "updatePassword"}}</div> <div id="boxHeader">{{msg . "updatePassword"}}</div>
<form> <form>
@@ -36,7 +36,7 @@
<a href="/index">{{msg . "home"}}</a> <a href="/index">{{msg . "home"}}</a>
</p> </p>
<p> <p>
<a href="/index">leanote</a> © 2014-2015 <a href="https://leanote.com">Leanote</a> © 2014-2016
</p> </p>
</div> </div>
Loaded 100 of 1159 files, more files were not shown because too many files have changed in this diff. Show more