Compare commits
90 Commits
feature-pd
...
1.4.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5b006aae7 | ||
|
|
90bd07cdcc | ||
|
|
92576e9239 | ||
|
|
c58e6874c2 | ||
|
|
cfebf00cf1 | ||
|
|
19be0990da | ||
|
|
3f27e4b0d4 | ||
|
|
4710fb6686 | ||
|
|
28324c0178 | ||
|
|
f270ade8d7 | ||
|
|
3b3e665a9f | ||
|
|
bfa85e2d34 | ||
|
|
fcf270a521 | ||
|
|
eba113c73c | ||
|
|
41f63156ea | ||
|
|
f54fe397c3 | ||
|
|
6f157289d3 | ||
|
|
65792d020c | ||
|
|
926882dce6 | ||
|
|
f834f469fc | ||
|
|
06d42c36f0 | ||
|
|
17d513a9de | ||
|
|
8cc00c1f66 | ||
|
|
cb433d9392 | ||
|
|
86ca1efd11 | ||
|
|
263f978c54 | ||
|
|
c8af7eda5d | ||
|
|
3724811802 | ||
|
|
10ff48267f | ||
|
|
cd0913aec0 | ||
|
|
f8d4c2ef20 | ||
|
|
f16b5e816e | ||
|
|
9a9968760a | ||
|
|
b1f36dfbf1 | ||
|
|
bc0e09f222 | ||
|
|
0dab71e72b | ||
|
|
10f23c19ab | ||
|
|
bba57ea302 | ||
|
|
f052117989 | ||
|
|
df4ec53647 | ||
|
|
a7eaf6114a | ||
|
|
b25bf0e16c | ||
|
|
d13447e6d0 | ||
|
|
6a1e84da0c | ||
|
|
51aeb7d46e | ||
|
|
2dbd025768 | ||
|
|
d52d80d529 | ||
|
|
2000bc585b | ||
|
|
8301a1e515 | ||
|
|
bee65eb36d | ||
|
|
78199583b0 | ||
|
|
28d5678349 | ||
|
|
e97c468f6e | ||
|
|
5d18554542 | ||
|
|
3ff0a9e09c | ||
|
|
6a753682b7 | ||
|
|
ce491e62c3 | ||
|
|
e4b847b731 | ||
|
|
a12b285a35 | ||
|
|
7f0ada8016 | ||
|
|
bac5ab4d79 | ||
|
|
b362406819 | ||
|
|
9e2edbb987 | ||
|
|
7809d00787 | ||
|
|
cba69444a8 | ||
|
|
5e02816c09 | ||
|
|
20b085aeae | ||
|
|
0f5e683a4f | ||
|
|
e134ca7244 | ||
|
|
6818574605 | ||
|
|
6eea03f81e | ||
|
|
1242834b7f | ||
|
|
1844513f08 | ||
|
|
b0be7a14d2 | ||
|
|
7e17c68dba | ||
|
|
6259f15ffa | ||
|
|
f65d027a0d | ||
|
|
e9e2ca50ee | ||
|
|
a64ef8517e | ||
|
|
c9bda60554 | ||
|
|
c3478520c0 | ||
|
|
8346ffe915 | ||
|
|
f49b046601 | ||
|
|
263c03291e | ||
|
|
29244c247e | ||
|
|
320de8637f | ||
|
|
33bc6bf84b | ||
|
|
0cd2c42b68 | ||
|
|
1716acf9e0 | ||
|
|
45477119d4 |
228
Gulpfile.js
228
Gulpfile.js
@@ -21,7 +21,7 @@ gulp.task('concatDepJs', function() {
|
||||
var jss = [
|
||||
'js/jquery-1.9.0.min.js',
|
||||
'js/jquery.ztree.all-3.5-min.js',
|
||||
'tinymce/tinymce.full.min.js', // 使用打成的包, 加载速度快
|
||||
// 'tinymce/tinymce.full.min.js', // 使用打成的包, 加载速度快
|
||||
// 'libs/ace/ace.js',
|
||||
'js/jQuery-slimScroll-1.3.0/jquery.slimscroll-min.js',
|
||||
'js/contextmenu/jquery.contextmenu-min.js',
|
||||
@@ -62,11 +62,39 @@ gulp.task('concatAppJs', function() {
|
||||
.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为一个文件
|
||||
gulp.task('concatMarkdownJs', function() {
|
||||
var jss = [
|
||||
'js/require.js',
|
||||
'dist/main.min.js',
|
||||
'md/main.min.js',
|
||||
];
|
||||
|
||||
for(var i in jss) {
|
||||
@@ -80,6 +108,24 @@ gulp.task('concatMarkdownJs', function() {
|
||||
.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
|
||||
// TODO 加?t=2323232, 强制浏览器更新, 一般只需要把app.min.js上加
|
||||
gulp.task('devToProHtml', function() {
|
||||
@@ -88,28 +134,40 @@ gulp.task('devToProHtml', function() {
|
||||
.pipe(replace(/<!-- dev -->[.\s\S]+?<!-- \/dev -->/g, '')) // 把dev 去掉
|
||||
.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_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(/plugins\/main.js/, "plugins/main.min.js")) // 替换
|
||||
// 连续两个空行换成一个空行, 没用
|
||||
.pipe(replace(/\n\n/g, '\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(/\r\n\r\n/g, '\r\n'))
|
||||
.pipe(replace('console.log(o);', ''))
|
||||
.pipe(replace('console.trace(o);', ''))
|
||||
// .pipe(minifyHtml()) // 不行, 压缩后golang报错
|
||||
.pipe(rename('note.html'))
|
||||
.pipe(gulp.dest(noteProBase));
|
||||
});
|
||||
|
||||
// Get used keys
|
||||
// 只获取需要js i18n的key
|
||||
var path = require('path');
|
||||
gulp.task('i18n', function() {
|
||||
var keys = {};
|
||||
var reg = /getMsg\(["']+(.+?)["']+/g;
|
||||
// {rule: "required", msg: "inputNewPassword"},
|
||||
var reg2 = /msg: ?"?([0-9a-zA-Z]*)"?/g;
|
||||
function getKey(data) {
|
||||
while(ret = reg.exec(data)) {
|
||||
keys[ret[1]] = 1;
|
||||
}
|
||||
|
||||
while(ret2 = reg2.exec(data)) {
|
||||
keys[ret2[1]] = 1;
|
||||
}
|
||||
}
|
||||
// 先获取需要的key
|
||||
function ls(ff) {
|
||||
@@ -137,13 +195,15 @@ gulp.task('i18n', function() {
|
||||
|
||||
ls(base + '/admin');
|
||||
ls(base + '/blog');
|
||||
ls(base + '/dist');
|
||||
ls(base + '/md');
|
||||
ls(base + '/js');
|
||||
ls(base + '/album');
|
||||
ls(base + '/libs');
|
||||
ls(base + '/member');
|
||||
ls(base + '/tinymce');
|
||||
|
||||
ls(leanoteBase + '/app/views');
|
||||
|
||||
console.log('parsed');
|
||||
|
||||
// msg.zh
|
||||
@@ -170,9 +230,18 @@ gulp.task('i18n', function() {
|
||||
}
|
||||
|
||||
// msg.zh, msg.js
|
||||
function genI18nJsFile(fromFilename, keys) {
|
||||
var msgs = getAllMsgs(leanoteBase + '/messages/' + fromFilename);
|
||||
var toFilename = fromFilename + '.js';
|
||||
function genI18nJsFile(fromFilename, otherNames, keys) {
|
||||
var msgs = {};
|
||||
otherNames.unshift(fromFilename);
|
||||
// console.log(fromFilename);
|
||||
// console.log(otherNames);
|
||||
otherNames.forEach(function (name) {
|
||||
var tmpMsgs = getAllMsgs(leanoteBase + '/messages/' + name);
|
||||
for (var i in tmpMsgs) {
|
||||
msgs[i] = tmpMsgs[i];
|
||||
}
|
||||
});
|
||||
|
||||
var toMsgs = {};
|
||||
for (var i in msgs) {
|
||||
// 只要需要的
|
||||
@@ -190,18 +259,23 @@ gulp.task('i18n', function() {
|
||||
'}' +
|
||||
'return key;' +
|
||||
'}';
|
||||
|
||||
// 写入到文件中
|
||||
var toFilename = fromFilename + '.js';
|
||||
fs.writeFile(base + '/js/i18n/' + toFilename, str);
|
||||
}
|
||||
|
||||
genI18nJsFile('msg.zh', keys);
|
||||
genI18nJsFile('msg.en', keys);
|
||||
genI18nJsFile('msg.fr', keys);
|
||||
genI18nJsFile('blog.zh', keys);
|
||||
genI18nJsFile('blog.en', keys);
|
||||
genI18nJsFile('blog.fr', keys);
|
||||
});
|
||||
// 必须要的
|
||||
// keys.push();
|
||||
|
||||
genI18nJsFile('blog.zh', [], keys);
|
||||
genI18nJsFile('blog.en', [], keys);
|
||||
genI18nJsFile('blog.fr', [], keys);
|
||||
|
||||
genI18nJsFile('msg.fr', ['member.fr', 'markdown.fr', 'album.fr'], keys);
|
||||
genI18nJsFile('msg.zh', ['member.zh', 'markdown.zh', 'album.zh'], keys);
|
||||
genI18nJsFile('msg.en', ['member.en', 'markdown.en', 'album.en'], keys);
|
||||
});
|
||||
|
||||
// 合并album需要的js
|
||||
gulp.task('concatAlbumJs', function() {
|
||||
@@ -236,78 +310,9 @@ gulp.task('concatAlbumJs', function() {
|
||||
.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
|
||||
// !! You must has tinymce_dev on public/
|
||||
var tinymceBase = base + '/tinymce_dev';
|
||||
// please set the right path on your own env
|
||||
var tinymceBase = '/Users/life/leanote/leanote-tools/tinymce_4.1.9_leanote_public';
|
||||
gulp.task('tinymce', function() {
|
||||
// 先清理
|
||||
fs.unlink(tinymceBase + '/js/tinymce/tinymce.dev.js');
|
||||
@@ -317,7 +322,7 @@ gulp.task('tinymce', function() {
|
||||
|
||||
var cp = require('child_process');
|
||||
|
||||
var bundleCmd = 'grunt bundle --themes leanote --plugins autolink,link,leaui_image,leaui_mind,lists,hr,paste,searchreplace,leanote_nav,leanote_code,tabfocus,table,directionality,textcolor';
|
||||
var bundleCmd = 'grunt bundle --themes leanote --plugins autolink,link,leaui_image,lists,hr,paste,searchreplace,leanote_nav,leanote_code,tabfocus,table,directionality,textcolor';
|
||||
// build
|
||||
cp.exec('grunt minify', {cwd: tinymceBase}, function(err, stdout, stderr) {
|
||||
console.log('stdout: ' + stdout);
|
||||
@@ -340,6 +345,47 @@ gulp.task('concatCss', function() {
|
||||
.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('default', ['concat', 'plugins', 'minifycss', 'i18n', 'concatAlbumJs', 'html']);
|
||||
|
||||
139
README.md
139
README.md
@@ -1,49 +1,62 @@
|
||||
|
||||
# Leanote
|
||||
[](https://gitter.im/leanote/leanote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
[](https://travis-ci.org/leanote/leanote)
|
||||
[](https://gitter.im/leanote/leanote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
## 1. Introduction
|
||||
|
||||
Leanote, not just a notepad!
|
||||
Leanote, Not Just A Notepad!
|
||||

|
||||
|
||||
**Some Features**
|
||||
|
||||
* Knowledge: Manage your knowledge in leanote. leanote contains the tinymce editor and a markdown editor, just enjoy yourself writing.
|
||||
* Share: Share your knowledge with your friends in leanote. You can invite your friends to join your notepad in the cloud so you can share knowledge.
|
||||
* Knowledge: Manage your knowledge in Leanote. Leanote contains the tinymce editor and a markdown editor, just enjoy yourself writing.
|
||||
* Share: Share your knowledge with your friends in Leanote. You can invite your friends to join your notepad in the cloud so you can share knowledge.
|
||||
* Cooperation: Collaborate with friends to improve your skills.
|
||||
* Blog: Publish your knowledge and make leanote your blog.
|
||||
* Blog: Publish your knowledge and make Leanote your blog.
|
||||
|
||||
## 2. Why we created leanote
|
||||
**Other Features**
|
||||
|
||||
* Support Markdown
|
||||
* Writting mode
|
||||
* Export note to PDF
|
||||
* Note batch operation
|
||||
* Custom theme for blog
|
||||
|
||||
## 2. Why we created Leanote
|
||||
To be honest, our inspiration comes from Evernote. We use Evernote to manage our knowledge everyday. But we find that:
|
||||
* Evernote's editor can't meet our needs, it does not have document navigation, it does not render code properly (as a programmer, syntax highlighted code rendering is a basic need), it cannot resize images and so forth
|
||||
* We like markdown, but Evernote does not support it.
|
||||
* We want to share our knowledge, so all of us have our blogs (e.g. on Wordpress) and our Evernote accounts, but why can not those two be one!
|
||||
* ......
|
||||
|
||||
## 3. How to install leanote
|
||||
## 3. How to install Leanote
|
||||
|
||||
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 develop distribution installation tutorial](https://github.com/leanote/leanote/wiki/leanote-develop-distribution-installation-tutorial)
|
||||
Leanote contains: Leanote Web & Server (this repository), [Desktop app](https://github.com/leanote/desktop-app), [iOS](https://github.com/leanote/leanote-ios), [Android](https://github.com/leanote/leanote-android). And all the products are open source!
|
||||
|
||||
## 4. How to develop leanote
|
||||
You can install Leanote on your server, and use Leanote App (Desktop, iOs, Android) to sync notes with your self-hosted server.
|
||||
|
||||
Welcome to sign up on https://leanote.com, Leanote team provide a stable and reliable service for you.
|
||||
|
||||
More information about how to install Leanote please see:
|
||||
|
||||
* [Leanote binary installation tutorial](https://github.com/leanote/leanote/wiki/leanote-binary-distribution-installation-tutorial)
|
||||
* [Leanote source installation tutorial](https://github.com/leanote/leanote/wiki/leanote-source-installation-tutorial)
|
||||
|
||||
## 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)
|
||||
|
||||
|
||||
## 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)
|
||||
* [leanote blog theme api](https://github.com/leanote/leanote/wiki/leanote-blog-theme-api_en)
|
||||
|
||||
More docs please see [wiki](https://github.com/leanote/leanote/wiki).
|
||||
Please see [wiki](https://github.com/leanote/leanote/wiki).
|
||||
|
||||
## 6. Contributors
|
||||
Thank you to all the [contributors](https://github.com/leanote/leanote/graphs/contributors) on
|
||||
this project. Your help is much appreciated.
|
||||
|
||||
## 7.Join us
|
||||
|
||||
Please fork this repository and contribute back using [pull requests](https://github.com/leanote/leanote/pulls).
|
||||
|
||||
If you find some problems or has some good ideas, please submit [issues](https://github.com/leanote/leanote/issues).
|
||||
@@ -54,21 +67,99 @@ You are always welcomed!
|
||||
Support us, [donate us](http://leanote.org/#donate). And thanks [donators](http://leanote.leanote.com/post/leanote-donation-list).
|
||||
|
||||
## 9. Related projects
|
||||
* [Leanote Desktop App](https://github.com/leanote/desktop-app), [Download](http://app.leanote.com)
|
||||
* [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/Dminter/leanote-android-client), development phase
|
||||
|
||||
And also, you are welcome to join us.
|
||||
* [Leanote Desktop App](https://github.com/leanote/desktop-app), [Download](http://app.leanote.com)
|
||||
* [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
|
||||
|
||||
Yare are welcome to join us.
|
||||
|
||||
## 9. Support & Join us
|
||||
|
||||
* Email: leanote@leanote.com
|
||||
* [Leanote BBS](http://bbs.leanote.com)
|
||||
* [Leanote Google Group](https://groups.google.com/forum/#!forum/leanote)
|
||||
* QQ Group: 158716820, 256076853
|
||||
|
||||
* QQ Group: 256076853, 158716820
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
[中文](README_zh.md)
|
||||
|
||||
# Leanote
|
||||
|
||||
## 1. 介绍
|
||||
|
||||
Leanote, 不只是笔记!
|
||||
|
||||
**特性**
|
||||
|
||||
* 知识管理: 通过Leanote来管理知识, Leanote有易操作的界面, 包含两款编辑器富文本编辑器和Markdown编辑器. 在Leanote, 你可以尽情享受写作.
|
||||
* 博客: Leanote也可以作为你的博客, 将知识公开成博客, 让Leanote把你的知识传播的更远!
|
||||
* 分享: 你也可以通过分享知识给好友, 让好友拥有你的知识.
|
||||
* 协作: 在分享的同时也可以与好友一起协作知识.
|
||||
|
||||
**一些其它特性**
|
||||
|
||||
* 支持Markdown编辑
|
||||
* 写作模式
|
||||
* 支持PDF导出
|
||||
* 支持批量操作
|
||||
* 博客自定义主题, 实现高度定制化
|
||||
|
||||
## 2. 为什么我们要创建Leanote?
|
||||
说实话, 我们曾是evernote的忠实粉丝, 但是我们也发现evernote的不足:
|
||||
* evernote的编辑器不能满足我们的需求, 不能贴代码(格式会乱掉, 作为程序员, 代码是我们的基本需求啊), 图片不能缩放.
|
||||
* 我们是markdown的爱好者, 可是evernote竟然没有.
|
||||
* 我们也想将知识公开, 所以我们有自己的博客, 如wordpress, 但为什么这两者不能合二为一呢?
|
||||
* 还有...
|
||||
|
||||
## 3.安装Leanote
|
||||
|
||||
Leanote云笔记产品包括: Leanote Web & Server(即本仓库), 桌面客户端, ios, android. 4端全部开源! 你可以下载它安装在自己的服务器上, Leanote的客户端可以连接自建的服务.
|
||||
|
||||
欢迎在 https://leanote.com 上注册, 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%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进行二次开发
|
||||
|
||||
请查看 [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 相关文档
|
||||
* [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 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)
|
||||
* [How to develop leanote 如何开发Leanote](https://github.com/leanote/leanote/wiki/How-to-develop-leanote-如何开发leanote)
|
||||
|
||||
更多文档请查看 [wiki](https://github.com/leanote/leanote/wiki).
|
||||
|
||||
## 6. 贡献者
|
||||
|
||||
谢谢 [贡献者](https://github.com/leanote/leanote/graphs/contributors) 的贡献, Leanote因有你们而更完美!
|
||||
|
||||
## 7. 加入我们
|
||||
|
||||
欢迎提交[pull requests](https://github.com/leanote/leanote/pulls) 到Leanote.
|
||||
|
||||
有任何问题或建议, 欢迎提交[issue](https://github.com/leanote/leanote/issues).
|
||||
|
||||
Leanote还有很多问题, 如果你喜欢它, 欢迎加入我们一起完善Leanote.
|
||||
|
||||
## 8. 捐赠
|
||||
支持我们, [捐赠Leanote](http://leanote.org/#donate). 感谢[捐赠者](http://leanote.leanote.com/post/leanote-donation-list), 谢谢你们的鼓励, Leanote会一直坚持!
|
||||
|
||||
## 9. 其它相关项目
|
||||
* [Leanote Desktop App](https://github.com/leanote/desktop-app), [下载地址](http://app.leanote.com)
|
||||
* [Leanote iOS](https://github.com/leanote/leanote-ios), [从App Store下载](https://itunes.apple.com/zn/app/leanote/id1022302858?mt=8)
|
||||
* [Leanote Android](https://github.com/leanote/leanote-android), 开发阶段
|
||||
|
||||
欢迎加入我们!
|
||||
|
||||
## 联系&加入我们
|
||||
* Email: leanote@leanote.com
|
||||
* [Leanote 社区](http://bbs.leanote.com)
|
||||
* QQ群: 256076853, 158716820(已满)
|
||||
* [Leanote Google Group](https://groups.google.com/forum/#!forum/leanote)
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/revel/cmd/harness"
|
||||
"fmt"
|
||||
"github.com/revel/cmd/harness"
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -15,5 +15,5 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Ok")
|
||||
// panicOnError(reverr, "Failed to build")
|
||||
}
|
||||
// panicOnError(reverr, "Failed to build")
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ type Album struct {
|
||||
|
||||
// 图片管理, iframe
|
||||
func (c Album) Index() revel.Result {
|
||||
c.SetLocale();
|
||||
c.SetLocale()
|
||||
return c.RenderTemplate("album/index.html")
|
||||
}
|
||||
|
||||
|
||||
@@ -2,18 +2,18 @@ package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "encoding/json"
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
"io"
|
||||
"fmt"
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
)
|
||||
|
||||
// 附件
|
||||
@@ -31,44 +31,46 @@ func (c Attach) uploadAttach(noteId string) (re info.Re) {
|
||||
var resultMsg = "error" // 错误信息
|
||||
var Ok = false
|
||||
var fileInfo info.Attach
|
||||
|
||||
|
||||
re = info.NewRe()
|
||||
|
||||
|
||||
defer func() {
|
||||
re.Id = fileId // 只是id, 没有其它信息
|
||||
re.Msg = resultMsg
|
||||
re.Ok = Ok
|
||||
re.Item = fileInfo
|
||||
}()
|
||||
|
||||
|
||||
// 判断是否有权限为笔记添加附件
|
||||
if !shareService.HasUpdateNotePerm(noteId, c.GetUserId()) {
|
||||
return re
|
||||
}
|
||||
|
||||
|
||||
file, handel, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
return re
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
|
||||
data, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return re
|
||||
}
|
||||
// > 5M?
|
||||
maxFileSize := configService.GetUploadSize("uploadAttachSize");
|
||||
maxFileSize := configService.GetUploadSize("uploadAttachSize")
|
||||
if maxFileSize <= 0 {
|
||||
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)
|
||||
return re
|
||||
}
|
||||
|
||||
|
||||
// 生成上传路径
|
||||
filePath := "files/" + c.GetUserId() + "/attachs"
|
||||
dir := revel.BasePath + "/" + filePath
|
||||
// filePath := "files/" + c.GetUserId() + "/attachs"
|
||||
newGuid := NewGuid()
|
||||
filePath := "files/" + GetRandomFilePath(c.GetUserId(), newGuid) + "/attachs"
|
||||
dir := revel.BasePath + "/" + filePath
|
||||
err = os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return re
|
||||
@@ -76,13 +78,13 @@ func (c Attach) uploadAttach(noteId string) (re info.Re) {
|
||||
// 生成新的文件名
|
||||
filename := handel.Filename
|
||||
_, ext := SplitFilename(filename) // .doc
|
||||
filename = NewGuid() + ext
|
||||
toPath := dir + "/" + filename;
|
||||
filename = newGuid + ext
|
||||
toPath := dir + "/" + filename
|
||||
err = ioutil.WriteFile(toPath, data, 0777)
|
||||
if err != nil {
|
||||
return re
|
||||
}
|
||||
|
||||
|
||||
// add File to db
|
||||
fileType := ""
|
||||
if ext != "" {
|
||||
@@ -90,22 +92,22 @@ func (c Attach) uploadAttach(noteId string) (re info.Re) {
|
||||
}
|
||||
filesize := GetFilesize(toPath)
|
||||
fileInfo = info.Attach{Name: filename,
|
||||
Title: handel.Filename,
|
||||
NoteId: bson.ObjectIdHex(noteId),
|
||||
Title: handel.Filename,
|
||||
NoteId: bson.ObjectIdHex(noteId),
|
||||
UploadUserId: c.GetObjectUserId(),
|
||||
Path: filePath + "/" + filename,
|
||||
Type: fileType,
|
||||
Size: filesize}
|
||||
|
||||
id := bson.NewObjectId();
|
||||
Path: filePath + "/" + filename,
|
||||
Type: fileType,
|
||||
Size: filesize}
|
||||
|
||||
id := bson.NewObjectId()
|
||||
fileInfo.AttachId = id
|
||||
fileId = id.Hex()
|
||||
Ok, resultMsg = attachService.AddAttach(fileInfo, false)
|
||||
if resultMsg != "" {
|
||||
resultMsg = c.Message(resultMsg)
|
||||
}
|
||||
|
||||
fileInfo.Path = ""; // 不要返回
|
||||
|
||||
fileInfo.Path = "" // 不要返回
|
||||
if Ok {
|
||||
resultMsg = "success"
|
||||
}
|
||||
@@ -130,15 +132,15 @@ func (c Attach) GetAttachs(noteId 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
|
||||
if path == "" {
|
||||
return c.RenderText("")
|
||||
}
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(path, "/")
|
||||
file, _ := os.Open(fn)
|
||||
return c.RenderBinary(file, attach.Title, revel.Attachment, time.Now()) // revel.Attachment
|
||||
// return c.RenderFile(file, revel.Attachment) // revel.Attachment
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(path, "/")
|
||||
file, _ := os.Open(fn)
|
||||
return c.RenderBinary(file, attach.Title, revel.Attachment, time.Now()) // revel.Attachment
|
||||
// return c.RenderFile(file, revel.Attachment) // revel.Attachment
|
||||
}
|
||||
|
||||
func (c Attach) DownloadAll(noteId string) revel.Result {
|
||||
@@ -151,69 +153,75 @@ func (c Attach) DownloadAll(noteId string) revel.Result {
|
||||
if attachs == nil || len(attachs) == 0 {
|
||||
return c.RenderText("")
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
dir := revel.BasePath + "/files/tmp"
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
dir := revel.BasePath + "/files/tmp"
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
filename := note.Title + ".tar.gz"
|
||||
if note.Title == "" {
|
||||
filename = "all.tar.gz"
|
||||
}
|
||||
|
||||
|
||||
dir := revel.BasePath + "/files/attach_all"
|
||||
|
||||
if !MkdirAll(dir) {
|
||||
return c.RenderText("error")
|
||||
}
|
||||
|
||||
// file write
|
||||
fw, err := os.Create(revel.BasePath + "/files/" + filename)
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
// defer fw.Close() // 不需要关闭, 还要读取给用户下载
|
||||
|
||||
// gzip write
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
|
||||
// tar write
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
|
||||
// 遍历文件列表
|
||||
for _, attach := range attachs {
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(attach.Path, "/")
|
||||
fr, err := os.Open(fn)
|
||||
fileInfo, _ := fr.Stat()
|
||||
if err != nil {
|
||||
fw, err := os.Create(dir + "/" + filename)
|
||||
if err != nil {
|
||||
return c.RenderText("error")
|
||||
}
|
||||
// defer fw.Close() // 不需要关闭, 还要读取给用户下载
|
||||
|
||||
// gzip write
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
|
||||
// tar write
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
|
||||
// 遍历文件列表
|
||||
for _, attach := range attachs {
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(attach.Path, "/")
|
||||
fr, err := os.Open(fn)
|
||||
fileInfo, _ := fr.Stat()
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// 信息头
|
||||
h := new(tar.Header)
|
||||
h.Name = attach.Title
|
||||
h.Size = fileInfo.Size()
|
||||
h.Mode = int64(fileInfo.Mode())
|
||||
h.ModTime = fileInfo.ModTime()
|
||||
|
||||
// 写信息头
|
||||
err = tw.WriteHeader(h)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 写文件
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} // for
|
||||
|
||||
// tw.Close()
|
||||
// gw.Close()
|
||||
// fw.Close()
|
||||
// file, _ := os.Open(dir + "/" + filename)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// 信息头
|
||||
h := new(tar.Header)
|
||||
h.Name = attach.Title
|
||||
h.Size = fileInfo.Size()
|
||||
h.Mode = int64(fileInfo.Mode())
|
||||
h.ModTime = fileInfo.ModTime()
|
||||
|
||||
// 写信息头
|
||||
err = tw.WriteHeader(h)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 写文件
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} // for
|
||||
|
||||
// tw.Close()
|
||||
// gw.Close()
|
||||
// fw.Close()
|
||||
// file, _ := os.Open(dir + "/" + filename)
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "strconv"
|
||||
"github.com/revel/revel"
|
||||
"strings"
|
||||
// "strconv"
|
||||
)
|
||||
|
||||
// 用户登录/注销/找回密码
|
||||
@@ -21,14 +22,14 @@ func (c Auth) Login(email, from string) revel.Result {
|
||||
c.RenderArgs["email"] = email
|
||||
c.RenderArgs["from"] = from
|
||||
c.RenderArgs["openRegister"] = configService.IsOpenRegister()
|
||||
|
||||
|
||||
sessionId := c.Session.Id()
|
||||
if sessionService.LoginTimesIsOver(sessionId) {
|
||||
c.RenderArgs["needCaptcha"] = true
|
||||
}
|
||||
|
||||
|
||||
c.SetLocale()
|
||||
|
||||
|
||||
if c.Has("demo") {
|
||||
c.RenderArgs["demo"] = true
|
||||
c.RenderArgs["email"] = "demo@leanote.com"
|
||||
@@ -49,14 +50,14 @@ func (c Auth) doLogin(email, pwd string) revel.Result {
|
||||
c.SetSession(userInfo)
|
||||
sessionService.ClearLoginTimes(sessionId)
|
||||
return c.RenderJson(info.Re{Ok: true})
|
||||
}
|
||||
|
||||
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) DoLogin(email, pwd string, captcha string) revel.Result {
|
||||
sessionId := c.Session.Id()
|
||||
var msg = ""
|
||||
|
||||
|
||||
// > 5次需要验证码, 直到登录成功
|
||||
if sessionService.LoginTimesIsOver(sessionId) && sessionService.GetCaptcha(sessionId) != captcha {
|
||||
msg = "captchaError"
|
||||
@@ -66,15 +67,16 @@ func (c Auth) DoLogin(email, pwd string, captcha string) revel.Result {
|
||||
// 登录错误, 则错误次数++
|
||||
msg = "wrongUsernameOrPassword"
|
||||
sessionService.IncrLoginTimes(sessionId)
|
||||
} else {
|
||||
} else {
|
||||
c.SetSession(userInfo)
|
||||
sessionService.ClearLoginTimes(sessionId)
|
||||
return c.RenderJson(info.Re{Ok: true})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
sessionId := c.Session.Id()
|
||||
@@ -90,8 +92,8 @@ func (c Auth) Demo() revel.Result {
|
||||
|
||||
userInfo, err := authService.Login(email, pwd)
|
||||
if err != nil {
|
||||
return c.RenderJson(info.Re{Ok: false})
|
||||
} else {
|
||||
return c.RenderJson(info.Re{Ok: false})
|
||||
} else {
|
||||
c.SetSession(userInfo)
|
||||
return c.Redirect("/note")
|
||||
}
|
||||
@@ -107,7 +109,7 @@ func (c Auth) Register(from, iu string) revel.Result {
|
||||
c.SetLocale()
|
||||
c.RenderArgs["from"] = from
|
||||
c.RenderArgs["iu"] = iu
|
||||
|
||||
|
||||
c.RenderArgs["title"] = c.Message("register")
|
||||
c.RenderArgs["subTitle"] = c.Message("register")
|
||||
return c.RenderTemplate("home/register.html")
|
||||
@@ -116,30 +118,33 @@ func (c Auth) DoRegister(email, pwd, iu string) revel.Result {
|
||||
if !configService.IsOpenRegister() {
|
||||
return c.Redirect("/index")
|
||||
}
|
||||
|
||||
re := info.NewRe();
|
||||
|
||||
|
||||
re := info.NewRe()
|
||||
|
||||
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 {
|
||||
return c.RenderRe(re);
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
|
||||
|
||||
email = strings.ToLower(email)
|
||||
|
||||
// 注册
|
||||
re.Ok, re.Msg = authService.Register(email, pwd, iu)
|
||||
|
||||
|
||||
// 注册成功, 则立即登录之
|
||||
if re.Ok {
|
||||
c.doLogin(email, pwd)
|
||||
}
|
||||
|
||||
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
|
||||
//--------
|
||||
// 找回密码
|
||||
func (c Auth) FindPassword() revel.Result {
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = c.Message("findPassword")
|
||||
c.RenderArgs["subTitle"] = c.Message("findPassword")
|
||||
return c.RenderTemplate("home/find_password.html")
|
||||
@@ -150,30 +155,33 @@ func (c Auth) DoFindPassword(email string) revel.Result {
|
||||
re.Ok = true
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 点击链接后, 先验证之
|
||||
func (c Auth) FindPassword2(token string) revel.Result {
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = c.Message("findPassword")
|
||||
c.RenderArgs["subTitle"] = c.Message("findPassword")
|
||||
if token == "" {
|
||||
return c.RenderTemplate("find_password2_timeout.html")
|
||||
}
|
||||
ok, _, findPwd := tokenService.VerifyToken(token, info.TokenPwd);
|
||||
ok, _, findPwd := tokenService.VerifyToken(token, info.TokenPwd)
|
||||
if !ok {
|
||||
return c.RenderTemplate("home/find_password2_timeout.html")
|
||||
}
|
||||
c.RenderArgs["findPwd"] = findPwd
|
||||
|
||||
|
||||
c.RenderArgs["title"] = c.Message("updatePassword")
|
||||
c.RenderArgs["subTitle"] = c.Message("updatePassword")
|
||||
|
||||
|
||||
return c.RenderTemplate("home/find_password2.html")
|
||||
}
|
||||
|
||||
// 找回密码修改密码
|
||||
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 {
|
||||
return c.RenderRe(re);
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
|
||||
// 修改之
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"encoding/json"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
"github.com/revel/revel"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
"bytes"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
// 公用Controller, 其它Controller继承它
|
||||
@@ -56,29 +56,29 @@ func (c BaseController) GetUsername() string {
|
||||
// 得到用户信息
|
||||
func (c BaseController) GetUserInfo() info.User {
|
||||
if userId, ok := c.Session["UserId"]; ok && userId != "" {
|
||||
return userService.GetUserInfo(userId);
|
||||
return userService.GetUserInfo(userId)
|
||||
/*
|
||||
notebookWidth, _ := strconv.Atoi(c.Session["NotebookWidth"])
|
||||
noteListWidth, _ := strconv.Atoi(c.Session["NoteListWidth"])
|
||||
mdEditorWidth, _ := strconv.Atoi(c.Session["MdEditorWidth"])
|
||||
LogJ(c.Session)
|
||||
user := info.User{UserId: bson.ObjectIdHex(userId),
|
||||
Email: c.Session["Email"],
|
||||
Logo: c.Session["Logo"],
|
||||
Username: c.Session["Username"],
|
||||
UsernameRaw: c.Session["UsernameRaw"],
|
||||
Theme: c.Session["Theme"],
|
||||
NotebookWidth: notebookWidth,
|
||||
NoteListWidth: noteListWidth,
|
||||
MdEditorWidth: mdEditorWidth,
|
||||
notebookWidth, _ := strconv.Atoi(c.Session["NotebookWidth"])
|
||||
noteListWidth, _ := strconv.Atoi(c.Session["NoteListWidth"])
|
||||
mdEditorWidth, _ := strconv.Atoi(c.Session["MdEditorWidth"])
|
||||
LogJ(c.Session)
|
||||
user := info.User{UserId: bson.ObjectIdHex(userId),
|
||||
Email: c.Session["Email"],
|
||||
Logo: c.Session["Logo"],
|
||||
Username: c.Session["Username"],
|
||||
UsernameRaw: c.Session["UsernameRaw"],
|
||||
Theme: c.Session["Theme"],
|
||||
NotebookWidth: notebookWidth,
|
||||
NoteListWidth: noteListWidth,
|
||||
MdEditorWidth: mdEditorWidth,
|
||||
}
|
||||
if c.Session["Verified"] == "1" {
|
||||
user.Verified = true
|
||||
}
|
||||
if c.Session["Verified"] == "1" {
|
||||
user.Verified = true
|
||||
}
|
||||
if c.Session["LeftIsMin"] == "1" {
|
||||
user.LeftIsMin = true
|
||||
}
|
||||
return user
|
||||
if c.Session["LeftIsMin"] == "1" {
|
||||
user.LeftIsMin = true
|
||||
}
|
||||
return user
|
||||
*/
|
||||
}
|
||||
return info.User{}
|
||||
@@ -86,7 +86,7 @@ func (c BaseController) GetUserInfo() info.User {
|
||||
|
||||
func (c BaseController) GetUserAndBlogUrl() info.UserAndBlogUrl {
|
||||
if userId, ok := c.Session["UserId"]; ok && userId != "" {
|
||||
return userService.GetUserAndBlogUrl(userId);
|
||||
return userService.GetUserAndBlogUrl(userId)
|
||||
}
|
||||
return info.UserAndBlogUrl{}
|
||||
}
|
||||
@@ -107,16 +107,16 @@ func (c BaseController) SetSession(userInfo info.User) {
|
||||
c.Session["UsernameRaw"] = userInfo.UsernameRaw
|
||||
c.Session["Theme"] = userInfo.Theme
|
||||
c.Session["Logo"] = userInfo.Logo
|
||||
|
||||
|
||||
c.Session["NotebookWidth"] = strconv.Itoa(userInfo.NotebookWidth)
|
||||
c.Session["NoteListWidth"] = strconv.Itoa(userInfo.NoteListWidth)
|
||||
|
||||
|
||||
if userInfo.Verified {
|
||||
c.Session["Verified"] = "1"
|
||||
} else {
|
||||
c.Session["Verified"] = "0"
|
||||
}
|
||||
|
||||
|
||||
if userInfo.LeftIsMin {
|
||||
c.Session["LeftIsMin"] = "1"
|
||||
} else {
|
||||
@@ -139,8 +139,8 @@ func (c BaseController) UpdateSession(key, value string) {
|
||||
|
||||
// 返回json
|
||||
func (c BaseController) Json(i interface{}) string {
|
||||
// b, _ := json.MarshalIndent(i, "", " ")
|
||||
b, _ := json.Marshal(i)
|
||||
// b, _ := json.MarshalIndent(i, "", " ")
|
||||
b, _ := json.Marshal(i)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
@@ -157,9 +157,9 @@ func (c BaseController) GetPage() int {
|
||||
// 判断是否含有某参数
|
||||
func (c BaseController) Has(key string) bool {
|
||||
if _, ok := c.Params.Values[key]; ok {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -169,12 +169,12 @@ func (c Blog) GetPage(page, count int, list interface{}) info.Page {
|
||||
*/
|
||||
|
||||
func (c BaseController) GetTotalPage(page, count int) int {
|
||||
return int(math.Ceil(float64(count)/float64(page)))
|
||||
return int(math.Ceil(float64(count) / float64(page)))
|
||||
}
|
||||
|
||||
//-------------
|
||||
func (c BaseController) E404() revel.Result {
|
||||
c.RenderArgs["title"] = "404";
|
||||
c.RenderArgs["title"] = "404"
|
||||
return c.NotFound("", nil)
|
||||
}
|
||||
|
||||
@@ -187,15 +187,15 @@ func (c BaseController) SetLocale() string {
|
||||
lang = locale[0:pos]
|
||||
}
|
||||
if lang != "zh" && lang != "en" {
|
||||
lang = "en";
|
||||
lang = "en"
|
||||
}
|
||||
c.RenderArgs["locale"] = lang;
|
||||
c.RenderArgs["siteUrl"] = configService.GetSiteUrl();
|
||||
|
||||
c.RenderArgs["locale"] = lang
|
||||
c.RenderArgs["siteUrl"] = configService.GetSiteUrl()
|
||||
|
||||
c.RenderArgs["blogUrl"] = configService.GetBlogUrl()
|
||||
c.RenderArgs["leaUrl"] = configService.GetLeaUrl()
|
||||
c.RenderArgs["noteUrl"] = configService.GetNoteUrl()
|
||||
|
||||
|
||||
return lang
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ func (c BaseController) SetLocale() string {
|
||||
func (c BaseController) SetUserInfo() info.User {
|
||||
userInfo := c.GetUserInfo()
|
||||
c.RenderArgs["userInfo"] = userInfo
|
||||
if(userInfo.Username == configService.GetAdminUsername()) {
|
||||
if userInfo.Username == configService.GetAdminUsername() {
|
||||
c.RenderArgs["isAdmin"] = true
|
||||
}
|
||||
return userInfo
|
||||
@@ -222,10 +222,10 @@ func (c BaseController) RenderTemplateStr(templatePath string) string {
|
||||
Template: template,
|
||||
RenderArgs: c.RenderArgs, // 把args给它
|
||||
}
|
||||
|
||||
|
||||
var buffer bytes.Buffer
|
||||
tpl.Template.Render(&buffer, c.RenderArgs)
|
||||
return buffer.String();
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// json, result
|
||||
@@ -234,7 +234,7 @@ func (c BaseController) RenderTemplateStr(templatePath string) string {
|
||||
func (c BaseController) RenderRe(re info.Re) revel.Result {
|
||||
oldMsg := re.Msg
|
||||
if re.Msg != "" {
|
||||
if(strings.Contains(re.Msg, "-")) {
|
||||
if strings.Contains(re.Msg, "-") {
|
||||
msgAndValues := strings.Split(re.Msg, "-")
|
||||
if len(msgAndValues) == 2 {
|
||||
re.Msg = c.Message(msgAndValues[0], msgAndValues[1])
|
||||
|
||||
@@ -57,9 +57,9 @@ func (c Blog) render(templateName string, themePath string) revel.Result {
|
||||
isPreview = true
|
||||
themePath = themePath2.(string)
|
||||
c.setPreviewUrl()
|
||||
|
||||
|
||||
// 因为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)
|
||||
}
|
||||
@@ -119,9 +119,9 @@ func (c Blog) setPreviewUrl() {
|
||||
indexUrl = blogUrl + "/" + userIdOrEmail
|
||||
cateUrl = blogUrl + "/cate/" + userIdOrEmail // /notebookId
|
||||
|
||||
postUrl = blogUrl + "/post/" + userIdOrEmail // /xxxxx
|
||||
postUrl = blogUrl + "/post/" + userIdOrEmail // /xxxxx
|
||||
searchUrl = blogUrl + "/search/" + userIdOrEmail // blog.leanote.com/search/userId
|
||||
singleUrl = blogUrl + "/single/" + userIdOrEmail // blog.leanote.com/single/singleId
|
||||
singleUrl = blogUrl + "/single/" + userIdOrEmail // blog.leanote.com/single/singleId
|
||||
archiveUrl = blogUrl + "/archives/" + userIdOrEmail // blog.leanote.com/archive/userId
|
||||
tagsUrl = blogUrl + "/tags/" + userIdOrEmail // blog.leanote.com/archive/userId
|
||||
|
||||
@@ -220,7 +220,7 @@ func (c Blog) getCates(userBlog info.UserBlog) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 之后添加没有排序的
|
||||
for _, n := range notebooks {
|
||||
id := n.NotebookId.Hex()
|
||||
@@ -234,19 +234,19 @@ func (c Blog) getCates(userBlog info.UserBlog) {
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// LogJ(">>")
|
||||
// LogJ(cates)
|
||||
|
||||
|
||||
// LogJ(">>")
|
||||
// LogJ(cates)
|
||||
|
||||
// 建立层级
|
||||
hasParent := map[string]bool{} // 有父的cate
|
||||
for _, cate := range cates {
|
||||
parentCateId := cate.ParentCateId
|
||||
if parentCateId != "" {
|
||||
if parentCate, ok := cateMap[parentCateId]; ok {
|
||||
// Log("________")
|
||||
// LogJ(parentCate)
|
||||
// LogJ(cate)
|
||||
// Log("________")
|
||||
// LogJ(parentCate)
|
||||
// LogJ(cate)
|
||||
if parentCate.Children == nil {
|
||||
parentCate.Children = []*info.Cate{cate}
|
||||
} else {
|
||||
@@ -256,7 +256,7 @@ func (c Blog) getCates(userBlog info.UserBlog) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 得到没有父的cate, 作为第一级cate
|
||||
catesTree := []*info.Cate{}
|
||||
for _, cate := range cates {
|
||||
@@ -264,7 +264,7 @@ func (c Blog) getCates(userBlog info.UserBlog) {
|
||||
catesTree = append(catesTree, cate)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
c.RenderArgs["cates"] = cates
|
||||
c.RenderArgs["catesTree"] = catesTree
|
||||
}
|
||||
@@ -348,10 +348,10 @@ func (c Blog) blogCommon(userId string, userBlog info.UserBlog, userInfo info.Us
|
||||
// 得到主题信息
|
||||
themeInfo := themeService.GetThemeInfo(userBlog.ThemeId.Hex(), userBlog.Style)
|
||||
c.RenderArgs["themeInfo"] = themeInfo
|
||||
|
||||
// Log(">>")
|
||||
// Log(userBlog.Style)
|
||||
// Log(userBlog.ThemeId.Hex())
|
||||
|
||||
// Log(">>")
|
||||
// Log(userBlog.Style)
|
||||
// Log(userBlog.ThemeId.Hex())
|
||||
|
||||
return true, userBlog
|
||||
}
|
||||
@@ -507,6 +507,7 @@ func (c Blog) Archives(userIdOrEmail string, cateId string, year, month int) (re
|
||||
// 进入某个用户的博客
|
||||
var blogPageSize = 5
|
||||
var searchBlogPageSize = 30
|
||||
|
||||
// 分类 /cate/xxxxxxxx?notebookId=1212
|
||||
func (c Blog) Cate(userIdOrEmail string, notebookId string) (re revel.Result) {
|
||||
// 自定义域名
|
||||
@@ -833,7 +834,7 @@ func (c Blog) GetComments(noteId string, callback string) revel.Result {
|
||||
result["comments"] = comments
|
||||
result["commentUserInfo"] = commentUserInfo
|
||||
re.Item = result
|
||||
|
||||
|
||||
if callback != "" {
|
||||
return c.RenderJsonP(callback, result)
|
||||
}
|
||||
|
||||
@@ -2,17 +2,17 @@ package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "encoding/json"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/lea/captcha"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "os"
|
||||
// "path"
|
||||
// "strconv"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "os"
|
||||
// "path"
|
||||
// "strconv"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@@ -22,22 +22,23 @@ type Captcha struct {
|
||||
}
|
||||
|
||||
type Ca string
|
||||
|
||||
func (r Ca) Apply(req *revel.Request, resp *revel.Response) {
|
||||
resp.WriteHeader(http.StatusOK, "image/png")
|
||||
resp.WriteHeader(http.StatusOK, "image/png")
|
||||
}
|
||||
|
||||
func (c Captcha) Get() revel.Result {
|
||||
c.Response.ContentType = "image/png"
|
||||
image, str := captcha.Fetch()
|
||||
image.WriteTo(c.Response.Out)
|
||||
|
||||
|
||||
sessionId := c.Session["_ID"]
|
||||
// LogJ(c.Session)
|
||||
// Log("------")
|
||||
// Log(str)
|
||||
// Log(sessionId)
|
||||
Log("..")
|
||||
// LogJ(c.Session)
|
||||
// Log("------")
|
||||
// Log(str)
|
||||
// Log(sessionId)
|
||||
Log("..")
|
||||
sessionService.SetCaptcha(sessionId, str)
|
||||
|
||||
|
||||
return c.Render()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@ package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// "encoding/json"
|
||||
"fmt"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/lea/netutil"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"fmt"
|
||||
// "strconv"
|
||||
// "strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -22,8 +22,8 @@ type File struct {
|
||||
// 上传的是博客logo
|
||||
// TODO logo不要设置权限, 另外的目录
|
||||
func (c File) UploadBlogLogo() revel.Result {
|
||||
re := c.uploadImage("blogLogo", "");
|
||||
|
||||
re := c.uploadImage("blogLogo", "")
|
||||
|
||||
c.RenderArgs["fileUrlPath"] = re.Id
|
||||
c.RenderArgs["resultCode"] = re.Code
|
||||
c.RenderArgs["resultMsg"] = re.Msg
|
||||
@@ -34,39 +34,41 @@ func (c File) UploadBlogLogo() revel.Result {
|
||||
// 拖拉上传, pasteImage
|
||||
// noteId 是为了判断是否是协作的note, 如果是则需要复制一份到note owner中
|
||||
func (c File) PasteImage(noteId string) revel.Result {
|
||||
re := c.uploadImage("pasteImage", "");
|
||||
|
||||
userId := c.GetUserId()
|
||||
note := noteService.GetNoteById(noteId)
|
||||
if note.UserId != "" {
|
||||
noteUserId := note.UserId.Hex()
|
||||
if noteUserId != userId {
|
||||
// 是否是有权限协作的
|
||||
if shareService.HasUpdatePerm(noteUserId, userId, noteId) {
|
||||
// 复制图片之, 图片复制给noteUserId
|
||||
_, re.Id = fileService.CopyImage(userId, re.Id, noteUserId)
|
||||
} else {
|
||||
// 怎么可能在这个笔记下paste图片呢?
|
||||
// 正常情况下不会
|
||||
re := c.uploadImage("pasteImage", "")
|
||||
|
||||
if noteId != "" {
|
||||
userId := c.GetUserId()
|
||||
note := noteService.GetNoteById(noteId)
|
||||
if note.UserId != "" {
|
||||
noteUserId := note.UserId.Hex()
|
||||
if noteUserId != userId {
|
||||
// 是否是有权限协作的
|
||||
if shareService.HasUpdatePerm(noteUserId, userId, noteId) {
|
||||
// 复制图片之, 图片复制给noteUserId
|
||||
_, re.Id = fileService.CopyImage(userId, re.Id, noteUserId)
|
||||
} else {
|
||||
// 怎么可能在这个笔记下paste图片呢?
|
||||
// 正常情况下不会
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 头像设置
|
||||
func (c File) UploadAvatar() revel.Result {
|
||||
re := c.uploadImage("logo", "");
|
||||
|
||||
re := c.uploadImage("logo", "")
|
||||
|
||||
c.RenderArgs["fileUrlPath"] = re.Id
|
||||
c.RenderArgs["resultCode"] = re.Code
|
||||
c.RenderArgs["resultMsg"] = re.Msg
|
||||
|
||||
|
||||
if re.Ok {
|
||||
re.Ok = userService.UpdateAvatar(c.GetUserId(), re.Id)
|
||||
if re.Ok {
|
||||
c.UpdateSession("Logo", re.Id);
|
||||
c.UpdateSession("Logo", re.Id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,16 +102,17 @@ func (c File) uploadImage(from, albumId string) (re info.Re) {
|
||||
return re
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
|
||||
// 生成上传路径
|
||||
newGuid := NewGuid()
|
||||
|
||||
|
||||
userId := c.GetUserId()
|
||||
|
||||
if(from == "logo" || from == "blogLogo") {
|
||||
|
||||
if from == "logo" || from == "blogLogo" {
|
||||
fileUrlPath = "public/upload/" + Digest3(userId) + "/" + userId + "/images/logo"
|
||||
} 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
|
||||
@@ -122,6 +125,7 @@ func (c File) uploadImage(from, albumId string) (re info.Re) {
|
||||
|
||||
var ext string
|
||||
if from == "pasteImage" {
|
||||
handel.Filename = c.Message("unTitled")
|
||||
ext = ".png" // TODO 可能不是png类型
|
||||
} else {
|
||||
_, ext = SplitFilename(filename)
|
||||
@@ -180,8 +184,8 @@ func (c File) uploadImage(from, albumId string) (re info.Re) {
|
||||
id := bson.NewObjectId()
|
||||
fileInfo.FileId = id
|
||||
fileId = id.Hex()
|
||||
|
||||
if(from == "logo" || from == "blogLogo") {
|
||||
|
||||
if from == "logo" || from == "blogLogo" {
|
||||
fileId = fileUrlPath
|
||||
}
|
||||
|
||||
@@ -217,13 +221,13 @@ func (c File) DeleteImage(fileId string) revel.Result {
|
||||
// 输出image
|
||||
// 权限判断
|
||||
func (c File) OutputImage(noteId, fileId string) revel.Result {
|
||||
path := fileService.GetFile(c.GetUserId(), fileId); // 得到路径
|
||||
path := fileService.GetFile(c.GetUserId(), fileId) // 得到路径
|
||||
if path == "" {
|
||||
return c.RenderText("")
|
||||
}
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(path, "/")
|
||||
file, _ := os.Open(fn)
|
||||
return c.RenderFile(file, revel.Inline) // revel.Attachment
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(path, "/")
|
||||
file, _ := os.Open(fn)
|
||||
return c.RenderFile(file, revel.Inline) // revel.Attachment
|
||||
}
|
||||
|
||||
// 协作时复制图片到owner
|
||||
@@ -242,7 +246,8 @@ func (c File) CopyHttpImage(src string) revel.Result {
|
||||
// 生成上传路径
|
||||
newGuid := NewGuid()
|
||||
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
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
@@ -265,7 +270,7 @@ func (c File) CopyHttpImage(src string) revel.Result {
|
||||
fileInfo.FileId = id
|
||||
|
||||
re.Id = id.Hex()
|
||||
// re.Item = fileInfo.Path
|
||||
// re.Item = fileInfo.Path
|
||||
re.Ok, re.Msg = fileService.AddImage(fileInfo, "", c.GetUserId(), true)
|
||||
|
||||
return c.RenderJson(re)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
)
|
||||
|
||||
// 首页
|
||||
@@ -13,31 +13,32 @@ type Index struct {
|
||||
}
|
||||
|
||||
func (c Index) Default() revel.Result {
|
||||
if configService.HomePageIsAdminsBlog(){
|
||||
if configService.HomePageIsAdminsBlog() {
|
||||
blog := Blog{c.BaseController}
|
||||
return blog.Index(configService.GetAdminUsername());
|
||||
return blog.Index(configService.GetAdminUsername())
|
||||
}
|
||||
return c.Index()
|
||||
}
|
||||
|
||||
// leanote展示页, 没有登录的, 或已登录明确要进该页的
|
||||
func (c Index) Index() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.RenderArgs["title"] = "leanote"
|
||||
c.RenderArgs["openRegister"] = configService.GlobalStringConfigs["openRegister"]
|
||||
c.SetLocale()
|
||||
|
||||
return c.RenderTemplate("home/index.html");
|
||||
|
||||
return c.RenderTemplate("home/index.html")
|
||||
}
|
||||
|
||||
// 建议
|
||||
func (c Index) Suggestion(addr, suggestion string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = suggestionService.AddSuggestion(info.Suggestion{Addr: addr, UserId: c.GetObjectUserId(), Suggestion: suggestion})
|
||||
|
||||
|
||||
// 发给我
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,6 @@ type NoteContentHistory struct {
|
||||
// 得到list
|
||||
func (c NoteContentHistory) ListHistories(noteId string) revel.Result {
|
||||
histories := noteContentHistoryService.ListHistories(noteId, c.GetUserId())
|
||||
|
||||
|
||||
return c.RenderJson(histories)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,9 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
"fmt"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
"fmt"
|
||||
// "bytes"
|
||||
// "os"
|
||||
)
|
||||
@@ -30,51 +30,51 @@ func (c Note) Index(noteId, online string) revel.Result {
|
||||
userInfo := c.GetUserAndBlogUrl()
|
||||
|
||||
userId := userInfo.UserId.Hex()
|
||||
|
||||
|
||||
// 没有登录
|
||||
if userId == "" {
|
||||
return c.Redirect("/login")
|
||||
}
|
||||
|
||||
|
||||
c.RenderArgs["openRegister"] = configService.IsOpenRegister()
|
||||
|
||||
// 已登录了, 那么得到所有信息
|
||||
notebooks := notebookService.GetNotebooks(userId)
|
||||
shareNotebooks, sharedUserInfos := shareService.GetShareNotebooks(userId)
|
||||
|
||||
|
||||
// 还需要按时间排序(DESC)得到notes
|
||||
notes := []info.Note{}
|
||||
noteContent := info.NoteContent{}
|
||||
|
||||
|
||||
if len(notebooks) > 0 {
|
||||
// noteId是否存在
|
||||
// 是否传入了正确的noteId
|
||||
hasRightNoteId := false
|
||||
if IsObjectId(noteId) {
|
||||
note := noteService.GetNoteById(noteId)
|
||||
|
||||
|
||||
if note.NoteId != "" {
|
||||
var noteOwner = note.UserId.Hex()
|
||||
noteContent = noteService.GetNoteContent(noteId, noteOwner)
|
||||
|
||||
|
||||
hasRightNoteId = true
|
||||
c.RenderArgs["curNoteId"] = noteId
|
||||
c.RenderArgs["curNotebookId"] = note.NotebookId.Hex()
|
||||
|
||||
|
||||
// 打开的是共享的笔记, 那么判断是否是共享给我的默认笔记
|
||||
if noteOwner != c.GetUserId() {
|
||||
if shareService.HasReadPerm(noteOwner, c.GetUserId(), noteId) {
|
||||
// 不要获取notebook下的笔记
|
||||
// 在前端下发请求
|
||||
c.RenderArgs["curSharedNoteNotebookId"] = note.NotebookId.Hex()
|
||||
c.RenderArgs["curSharedUserId"] = noteOwner;
|
||||
// 没有读写权限
|
||||
c.RenderArgs["curSharedUserId"] = noteOwner
|
||||
// 没有读写权限
|
||||
} else {
|
||||
hasRightNoteId = false
|
||||
}
|
||||
} 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)
|
||||
if lenNotes > 1 {
|
||||
@@ -84,7 +84,7 @@ func (c Note) Index(noteId, online string) revel.Result {
|
||||
for _, note := range notes {
|
||||
if note.NoteId.Hex() != noteId {
|
||||
if i == lenNotes { // 防止越界
|
||||
break;
|
||||
break
|
||||
}
|
||||
notes2[i] = note
|
||||
i++
|
||||
@@ -94,40 +94,40 @@ 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
|
||||
}
|
||||
|
||||
|
||||
// 没有传入笔记
|
||||
// 那么得到最新笔记
|
||||
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 {
|
||||
noteContent = noteService.GetNoteContent(notes[0].NoteId.Hex(), userId)
|
||||
c.RenderArgs["curNoteId"] = notes[0].NoteId.Hex()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 当然, 还需要得到第一个notes的content
|
||||
//...
|
||||
c.RenderArgs["isAdmin"] = configService.GetAdminUsername() == userInfo.Username
|
||||
|
||||
|
||||
c.RenderArgs["userInfo"] = userInfo
|
||||
c.RenderArgs["notebooks"] = notebooks
|
||||
c.RenderArgs["shareNotebooks"] = shareNotebooks // note信息在notes列表中
|
||||
c.RenderArgs["sharedUserInfos"] = sharedUserInfos
|
||||
|
||||
|
||||
c.RenderArgs["notes"] = notes
|
||||
c.RenderArgs["noteContentJson"] = noteContent
|
||||
c.RenderArgs["noteContent"] = noteContent.Content
|
||||
|
||||
|
||||
c.RenderArgs["tags"] = tagService.GetTags(c.GetUserId())
|
||||
|
||||
|
||||
c.RenderArgs["globalConfigs"] = configService.GetGlobalConfigForUser()
|
||||
|
||||
|
||||
// return c.RenderTemplate("note/note.html")
|
||||
|
||||
if isDev, _ := revel.Config.Bool("mode.dev"); isDev && online == "" {
|
||||
@@ -162,125 +162,139 @@ func (c Note) GetNoteContent(noteId string) revel.Result {
|
||||
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
|
||||
func (c Note) UpdateNoteOrContent(noteOrContent NoteOrContent) revel.Result {
|
||||
func (c Note) UpdateNoteOrContent(noteOrContent info.NoteOrContent) revel.Result {
|
||||
// 新添加note
|
||||
if noteOrContent.IsNew {
|
||||
userId := c.GetObjectUserId();
|
||||
// myUserId := userId
|
||||
userId := c.GetObjectUserId()
|
||||
// myUserId := userId
|
||||
// 为共享新建?
|
||||
if noteOrContent.FromUserId != "" {
|
||||
userId = bson.ObjectIdHex(noteOrContent.FromUserId)
|
||||
}
|
||||
|
||||
note := info.Note{UserId: userId,
|
||||
NoteId: bson.ObjectIdHex(noteOrContent.NoteId),
|
||||
NotebookId: bson.ObjectIdHex(noteOrContent.NotebookId),
|
||||
Title: noteOrContent.Title,
|
||||
Tags: strings.Split(noteOrContent.Tags, ","),
|
||||
Desc: noteOrContent.Desc,
|
||||
ImgSrc: noteOrContent.ImgSrc,
|
||||
IsBlog: noteOrContent.IsBlog,
|
||||
|
||||
note := info.Note{UserId: userId,
|
||||
NoteId: bson.ObjectIdHex(noteOrContent.NoteId),
|
||||
NotebookId: bson.ObjectIdHex(noteOrContent.NotebookId),
|
||||
Title: noteOrContent.Title,
|
||||
Tags: strings.Split(noteOrContent.Tags, ","),
|
||||
Desc: noteOrContent.Desc,
|
||||
ImgSrc: noteOrContent.ImgSrc,
|
||||
IsBlog: noteOrContent.IsBlog,
|
||||
IsMarkdown: noteOrContent.IsMarkdown,
|
||||
};
|
||||
noteContent := info.NoteContent{NoteId: note.NoteId,
|
||||
UserId: userId,
|
||||
IsBlog: note.IsBlog,
|
||||
Content: noteOrContent.Content,
|
||||
Abstract: noteOrContent.Abstract};
|
||||
|
||||
}
|
||||
noteContent := info.NoteContent{NoteId: note.NoteId,
|
||||
UserId: userId,
|
||||
IsBlog: note.IsBlog,
|
||||
Content: noteOrContent.Content,
|
||||
Abstract: noteOrContent.Abstract}
|
||||
|
||||
note = noteService.AddNoteAndContentForController(note, noteContent, c.GetUserId())
|
||||
return c.RenderJson(note)
|
||||
}
|
||||
|
||||
|
||||
noteUpdate := bson.M{}
|
||||
needUpdateNote := false
|
||||
|
||||
|
||||
// Desc前台传来
|
||||
if c.Has("Desc") {
|
||||
needUpdateNote = true
|
||||
noteUpdate["Desc"] = noteOrContent.Desc;
|
||||
noteUpdate["Desc"] = noteOrContent.Desc
|
||||
}
|
||||
if c.Has("ImgSrc") {
|
||||
needUpdateNote = true
|
||||
noteUpdate["ImgSrc"] = noteOrContent.ImgSrc;
|
||||
noteUpdate["ImgSrc"] = noteOrContent.ImgSrc
|
||||
}
|
||||
if c.Has("Title") {
|
||||
needUpdateNote = true
|
||||
noteUpdate["Title"] = noteOrContent.Title;
|
||||
noteUpdate["Title"] = noteOrContent.Title
|
||||
}
|
||||
|
||||
|
||||
if c.Has("Tags") {
|
||||
needUpdateNote = true
|
||||
noteUpdate["Tags"] = strings.Split(noteOrContent.Tags, ",");
|
||||
noteUpdate["Tags"] = strings.Split(noteOrContent.Tags, ",")
|
||||
}
|
||||
|
||||
|
||||
// web端不控制
|
||||
if needUpdateNote {
|
||||
noteService.UpdateNote(c.GetUserId(),
|
||||
if needUpdateNote {
|
||||
noteService.UpdateNote(c.GetUserId(),
|
||||
noteOrContent.NoteId, noteUpdate, -1)
|
||||
}
|
||||
|
||||
|
||||
//-------------
|
||||
afterContentUsn := 0
|
||||
contentOk := false
|
||||
contentMsg := ""
|
||||
if c.Has("Content") {
|
||||
// noteService.UpdateNoteContent(noteOrContent.UserId, c.GetUserId(),
|
||||
// noteOrContent.NoteId, noteOrContent.Content, noteOrContent.Abstract)
|
||||
// noteService.UpdateNoteContent(noteOrContent.UserId, c.GetUserId(),
|
||||
// noteOrContent.NoteId, noteOrContent.Content, noteOrContent.Abstract)
|
||||
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(contentOk)
|
||||
Log(contentMsg)
|
||||
|
||||
|
||||
return c.RenderJson(true)
|
||||
}
|
||||
|
||||
// 删除note/ 删除别人共享给我的笔记
|
||||
// userId 是note.UserId
|
||||
func (c Note) DeleteNote(noteId, userId string, isShared bool) revel.Result {
|
||||
if(!isShared) {
|
||||
return c.RenderJson(trashService.DeleteNote(noteId, c.GetUserId()));
|
||||
func (c Note) DeleteNote(noteIds []string, isShared bool) revel.Result {
|
||||
if !isShared {
|
||||
for _, noteId := range noteIds {
|
||||
trashService.DeleteNote(noteId, c.GetUserId())
|
||||
}
|
||||
return c.RenderJson(true)
|
||||
}
|
||||
|
||||
return c.RenderJson(trashService.DeleteSharedNote(noteId, userId, c.GetUserId()));
|
||||
|
||||
for _, noteId := range noteIds {
|
||||
trashService.DeleteSharedNote(noteId, c.GetUserId())
|
||||
}
|
||||
|
||||
return c.RenderJson(true)
|
||||
}
|
||||
// 删除trash
|
||||
|
||||
// 删除trash, 已弃用, 用DeleteNote
|
||||
func (c Note) DeleteTrash(noteId string) revel.Result {
|
||||
return c.RenderJson(trashService.DeleteTrash(noteId, c.GetUserId()));
|
||||
return c.RenderJson(trashService.DeleteTrash(noteId, c.GetUserId()))
|
||||
}
|
||||
|
||||
// 移动note
|
||||
func (c Note) MoveNote(noteId, notebookId string) revel.Result {
|
||||
return c.RenderJson(noteService.MoveNote(noteId, notebookId, c.GetUserId()));
|
||||
func (c Note) MoveNote(noteIds []string, notebookId string) revel.Result {
|
||||
userId := c.GetUserId()
|
||||
for _, noteId := range noteIds {
|
||||
noteService.MoveNote(noteId, notebookId, userId)
|
||||
}
|
||||
return c.RenderJson(true)
|
||||
}
|
||||
|
||||
// 复制note
|
||||
func (c Note) CopyNote(noteId, notebookId string) revel.Result {
|
||||
return c.RenderJson(noteService.CopyNote(noteId, notebookId, c.GetUserId()));
|
||||
func (c Note) CopyNote(noteIds []string, notebookId string) revel.Result {
|
||||
copyNotes := make([]info.Note, len(noteIds))
|
||||
userId := c.GetUserId()
|
||||
for i, noteId := range noteIds {
|
||||
copyNotes[i] = noteService.CopyNote(noteId, notebookId, userId)
|
||||
}
|
||||
re := info.NewRe()
|
||||
re.Ok = true
|
||||
re.Item = copyNotes
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 复制别人共享的笔记给我
|
||||
func (c Note) CopySharedNote(noteId, notebookId, fromUserId string) revel.Result {
|
||||
return c.RenderJson(noteService.CopySharedNote(noteId, notebookId, fromUserId, c.GetUserId()));
|
||||
func (c Note) CopySharedNote(noteIds []string, notebookId, fromUserId string) revel.Result {
|
||||
copyNotes := make([]info.Note, len(noteIds))
|
||||
userId := c.GetUserId()
|
||||
for i, noteId := range noteIds {
|
||||
copyNotes[i] = noteService.CopySharedNote(noteId, notebookId, fromUserId, userId)
|
||||
}
|
||||
re := info.NewRe()
|
||||
re.Ok = true
|
||||
re.Item = copyNotes
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
//------------
|
||||
@@ -290,6 +304,7 @@ func (c Note) SearchNote(key string) revel.Result {
|
||||
_, blogs := noteService.SearchNote(key, c.GetUserId(), c.GetPage(), pageSize, "UpdatedTime", false, false)
|
||||
return c.RenderJson(blogs)
|
||||
}
|
||||
|
||||
// 通过tags搜索
|
||||
func (c Note) SearchNoteByTags(tags []string) revel.Result {
|
||||
_, blogs := noteService.SearchNoteByTags(tags, c.GetUserId(), c.GetPage(), pageSize, "UpdatedTime", false)
|
||||
@@ -301,11 +316,11 @@ func (c Note) ToPdf(noteId, appKey string) revel.Result {
|
||||
// 虽然传了cookie但是这里还是不能得到userId, 所以还是通过appKey来验证之
|
||||
appKeyTrue, _ := revel.Config.String("app.secret")
|
||||
if appKeyTrue != appKey {
|
||||
return c.RenderText("error")
|
||||
return c.RenderText("auth error")
|
||||
}
|
||||
note := noteService.GetNoteById(noteId)
|
||||
if note.NoteId == "" {
|
||||
return c.RenderText("error")
|
||||
return c.RenderText("no note")
|
||||
}
|
||||
|
||||
noteUserId := note.UserId.Hex()
|
||||
@@ -315,14 +330,14 @@ func (c Note) ToPdf(noteId, appKey string) revel.Result {
|
||||
//------------------
|
||||
// 将content的图片转换为base64
|
||||
contentStr := content.Content
|
||||
|
||||
|
||||
siteUrlPattern := configService.GetSiteUrl()
|
||||
if strings.Contains(siteUrlPattern, "https") {
|
||||
siteUrlPattern = strings.Replace(siteUrlPattern, "https", "https*", 1)
|
||||
} else {
|
||||
siteUrlPattern = strings.Replace(siteUrlPattern, "http", "https*", 1)
|
||||
}
|
||||
|
||||
|
||||
regImage, _ := regexp.Compile(`<img .*?(src=('|")` + siteUrlPattern + `/(file/outputImage|api/file/getImage)\?fileId=([a-z0-9A-Z]{24})("|'))`)
|
||||
|
||||
findsImage := regImage.FindAllStringSubmatch(contentStr, -1) // 查找所有的
|
||||
@@ -394,13 +409,13 @@ func (c Note) ExportPdf(noteId string) revel.Result {
|
||||
// 是否是有权限协作的
|
||||
if !note.IsBlog && !shareService.HasReadPerm(noteUserId, userId, noteId) {
|
||||
re.Msg = "No Perm"
|
||||
return c.RenderText("error")
|
||||
return c.RenderText("No Perm")
|
||||
}
|
||||
}
|
||||
|
||||
// path 判断是否需要重新生成之
|
||||
guid := NewGuid()
|
||||
fileUrlPath := "files/" + Digest3(noteUserId) + "/" + noteUserId + "/" + Digest2(guid) + "/images/pdf"
|
||||
fileUrlPath := "files/export_pdf"
|
||||
dir := revel.BasePath + "/" + fileUrlPath
|
||||
if !MkdirAll(dir) {
|
||||
return c.RenderText("error, no dir")
|
||||
@@ -413,7 +428,7 @@ func (c Note) ExportPdf(noteId string) revel.Result {
|
||||
if appKey == "" {
|
||||
appKey, _ = revel.Config.String("app.secret")
|
||||
}
|
||||
|
||||
|
||||
// 生成之
|
||||
binPath := configService.GetGlobalStringConfig("exportPdfBinPath")
|
||||
// 默认路径
|
||||
@@ -429,9 +444,9 @@ func (c Note) ExportPdf(noteId string) revel.Result {
|
||||
// wkhtmltopdf参数大全
|
||||
var cc string
|
||||
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 {
|
||||
cc = binPath + " \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\""
|
||||
cc = binPath + " --lowquality \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\""
|
||||
}
|
||||
|
||||
cmd := exec.Command("/bin/sh", "-c", cc)
|
||||
@@ -456,7 +471,9 @@ func (c Note) ExportPdf(noteId string) revel.Result {
|
||||
}
|
||||
|
||||
// 设置/取消Blog; 置顶
|
||||
func (c Note) SetNote2Blog(noteId string, isBlog, isTop bool) revel.Result {
|
||||
re := noteService.ToBlog(c.GetUserId(), noteId, isBlog, isTop)
|
||||
return c.RenderJson(re)
|
||||
func (c Note) SetNote2Blog(noteIds []string, isBlog, isTop bool) revel.Result {
|
||||
for _, noteId := range noteIds {
|
||||
noteService.ToBlog(c.GetUserId(), noteId, isBlog, isTop)
|
||||
}
|
||||
return c.RenderJson(true)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"encoding/json"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/revel/revel"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "io/ioutil"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "io/ioutil"
|
||||
)
|
||||
|
||||
type Notebook struct {
|
||||
@@ -30,22 +30,23 @@ func (c Notebook) DeleteNotebook(notebookId string) revel.Result {
|
||||
|
||||
// 添加notebook
|
||||
func (c Notebook) AddNotebook(notebookId, title, parentNotebookId string) revel.Result {
|
||||
notebook := info.Notebook{NotebookId: bson.ObjectIdHex(notebookId),
|
||||
Title: title,
|
||||
Seq: -1,
|
||||
notebook := info.Notebook{NotebookId: bson.ObjectIdHex(notebookId),
|
||||
Title: title,
|
||||
Seq: -1,
|
||||
UserId: c.GetObjectUserId()}
|
||||
if(parentNotebookId != "") {
|
||||
if parentNotebookId != "" {
|
||||
notebook.ParentNotebookId = bson.ObjectIdHex(parentNotebookId)
|
||||
}
|
||||
|
||||
re, notebook := notebookService.AddNotebook(notebook)
|
||||
|
||||
if(re) {
|
||||
|
||||
if re {
|
||||
return c.RenderJson(notebook)
|
||||
} else {
|
||||
return c.RenderJson(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 修改标题
|
||||
func (c Notebook) UpdateNotebookTitle(notebookId, title string) revel.Result {
|
||||
return c.RenderJson(notebookService.UpdateNotebookTitle(notebookId, c.GetUserId(), title))
|
||||
@@ -53,21 +54,22 @@ func (c Notebook) UpdateNotebookTitle(notebookId, title string) revel.Result {
|
||||
|
||||
// 排序
|
||||
// 无用
|
||||
func (c Notebook) SortNotebooks(notebookId2Seqs map[string]int) revel.Result {
|
||||
return c.RenderJson(notebookService.SortNotebooks(c.GetUserId(), notebookId2Seqs))
|
||||
}
|
||||
// func (c Notebook) SortNotebooks(notebookId2Seqs map[string]int) revel.Result {
|
||||
// return c.RenderJson(notebookService.SortNotebooks(c.GetUserId(), notebookId2Seqs))
|
||||
// }
|
||||
|
||||
// 调整notebooks, 可能是排序, 可能是移动到其它笔记本下
|
||||
type DragNotebooksInfo struct {
|
||||
CurNotebookId string
|
||||
CurNotebookId string
|
||||
ParentNotebookId string
|
||||
Siblings []string
|
||||
Siblings []string
|
||||
}
|
||||
|
||||
// 传过来的data是JSON.stringfy数据
|
||||
func (c Notebook) DragNotebooks(data string) revel.Result {
|
||||
info := DragNotebooksInfo{}
|
||||
json.Unmarshal([]byte(data), &info)
|
||||
|
||||
|
||||
return c.RenderJson(notebookService.DragNotebooks(c.GetUserId(), info.CurNotebookId, info.ParentNotebookId, info.Siblings))
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@ package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "strings"
|
||||
// "time"
|
||||
// "strings"
|
||||
// "time"
|
||||
// "encoding/json"
|
||||
// "github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "github.com/leanote/leanote/app/lea/blog"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "github.com/leanote/leanote/app/lea/blog"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
// "math"
|
||||
@@ -23,7 +23,7 @@ type Preview struct {
|
||||
// 得到要预览的主题绝对路径
|
||||
func (c Preview) getPreviewThemeAbsolutePath(themeId string) bool {
|
||||
if themeId != "" {
|
||||
c.Session["themeId"] = themeId // 存到session中, 下次的url就不能带了
|
||||
c.Session["themeId"] = themeId // 存到session中, 下次的url就不能带了, 待优化, 有时会取不到
|
||||
} else {
|
||||
themeId = c.Session["themeId"] // 直接从session中获取
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func (c Preview) getPreviewThemeAbsolutePath(themeId string) bool {
|
||||
return false
|
||||
}
|
||||
theme := themeService.GetTheme(c.GetUserId(), themeId)
|
||||
|
||||
|
||||
c.RenderArgs["isPreview"] = true
|
||||
c.RenderArgs["themeId"] = themeId
|
||||
c.RenderArgs["themeInfoPreview"] = theme.Info
|
||||
@@ -47,7 +47,7 @@ func (c Preview) Index(userIdOrEmail string, themeId string) revel.Result {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Index(c.GetUserId())
|
||||
// return blog.RenderTemplate("index.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(themeId))
|
||||
// return blog.RenderTemplate("index.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(themeId))
|
||||
}
|
||||
|
||||
func (c Preview) Tag(userIdOrEmail, tag string) revel.Result {
|
||||
@@ -61,43 +61,43 @@ func (c Preview) Tags(userIdOrEmail string) revel.Result {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Tags(c.GetUserId())
|
||||
// if tag == "" {
|
||||
// return blog.RenderTemplate("tags.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
// }
|
||||
// return blog.RenderTemplate("tag_posts.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
// if tag == "" {
|
||||
// return blog.RenderTemplate("tags.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
// }
|
||||
// return blog.RenderTemplate("tag_posts.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
func (c Preview) Archives(userIdOrEmail string, notebookId string, year, month int) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Archives(c.GetUserId(), notebookId, year, month)
|
||||
// return blog.RenderTemplate("archive.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
// return blog.RenderTemplate("archive.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
func (c Preview) Cate(userIdOrEmail, notebookId string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Cate(userIdOrEmail, notebookId)
|
||||
// return blog.RenderTemplate("cate.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
// return blog.RenderTemplate("cate.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
func (c Preview) Post(userIdOrEmail, noteId string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Post(userIdOrEmail, noteId)
|
||||
// return blog.RenderTemplate("view.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
// return blog.RenderTemplate("view.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
func (c Preview) Single(userIdOrEmail, singleId string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Single(userIdOrEmail, singleId)
|
||||
// return blog.RenderTemplate("single.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
// return blog.RenderTemplate("single.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
func (c Preview) Search(userIdOrEmail, keywords string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Search(c.GetUserId(), keywords)
|
||||
// return blog.RenderTemplate("search.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
// return blog.RenderTemplate("search.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "encoding/json"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
)
|
||||
|
||||
type Share struct {
|
||||
@@ -19,20 +19,20 @@ type Share struct {
|
||||
func (c Share) AddShareNote(noteId string, emails []string, perm int) revel.Result {
|
||||
status := make(map[string]info.Re, len(emails))
|
||||
// 自己不能给自己添加共享
|
||||
myEmail := c.GetEmail();
|
||||
myEmail := c.GetEmail()
|
||||
for _, email := range emails {
|
||||
if email == "" {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
if(myEmail != email) {
|
||||
ok, msg, userId := shareService.AddShareNote(noteId, perm, c.GetUserId(), email);
|
||||
if myEmail != email {
|
||||
ok, msg, userId := shareService.AddShareNote(noteId, perm, c.GetUserId(), email)
|
||||
status[email] = info.Re{Ok: ok, Msg: msg, Id: userId}
|
||||
|
||||
|
||||
} else {
|
||||
status[email] = info.Re{Ok: false, Msg: "不能分享给自己"}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return c.RenderJson(status)
|
||||
}
|
||||
|
||||
@@ -40,19 +40,19 @@ func (c Share) AddShareNote(noteId string, emails []string, perm int) revel.Resu
|
||||
func (c Share) AddShareNotebook(notebookId string, emails []string, perm int) revel.Result {
|
||||
status := make(map[string]info.Re, len(emails))
|
||||
// 自己不能给自己添加共享
|
||||
myEmail := c.GetEmail();
|
||||
myEmail := c.GetEmail()
|
||||
for _, email := range emails {
|
||||
if email == "" {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
if(myEmail != email) {
|
||||
ok, msg, userId := shareService.AddShareNotebook(notebookId, perm, c.GetUserId(), email);
|
||||
if myEmail != email {
|
||||
ok, msg, userId := shareService.AddShareNotebook(notebookId, perm, c.GetUserId(), email)
|
||||
status[email] = info.Re{Ok: ok, Msg: msg, Id: userId}
|
||||
} else {
|
||||
status[email] = info.Re{Ok: false, Msg: "不能分享给自己"}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return c.RenderJson(status)
|
||||
}
|
||||
|
||||
@@ -62,11 +62,11 @@ func (c Share) ListShareNotes(notebookId, userId string) revel.Result {
|
||||
// 表示是默认笔记本, 不是某个特定notebook的共享
|
||||
var notes []info.ShareNoteWithPerm
|
||||
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)
|
||||
} else {
|
||||
// 有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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,106 +83,110 @@ func (c Share) GetShareNoteContent(noteId, sharedUserId string) revel.Result {
|
||||
// 还要查看该note的notebookId分享的信息
|
||||
func (c Share) ListNoteShareUserInfo(noteId string) revel.Result {
|
||||
note := noteService.GetNote(noteId, c.GetUserId())
|
||||
|
||||
|
||||
noteShareUserInfos := shareService.ListNoteShareUserInfo(noteId, c.GetUserId())
|
||||
c.RenderArgs["noteOrNotebookShareUserInfos"] = noteShareUserInfos
|
||||
|
||||
c.RenderArgs["noteOrNotebookShareUserInfos"] = noteShareUserInfos
|
||||
|
||||
c.RenderArgs["noteOrNotebookShareGroupInfos"] = shareService.GetNoteShareGroups(noteId, c.GetUserId())
|
||||
|
||||
|
||||
c.RenderArgs["isNote"] = true
|
||||
c.RenderArgs["noteOrNotebookId"] = note.NoteId.Hex();
|
||||
c.RenderArgs["noteOrNotebookId"] = note.NoteId.Hex()
|
||||
c.RenderArgs["title"] = note.Title
|
||||
|
||||
|
||||
return c.RenderTemplate("share/note_notebook_share_user_infos.html")
|
||||
}
|
||||
func (c Share) ListNotebookShareUserInfo(notebookId string) revel.Result {
|
||||
notebook := notebookService.GetNotebook(notebookId, c.GetUserId())
|
||||
|
||||
|
||||
notebookShareUserInfos := shareService.ListNotebookShareUserInfo(notebookId, c.GetUserId())
|
||||
c.RenderArgs["noteOrNotebookShareUserInfos"] = notebookShareUserInfos
|
||||
|
||||
c.RenderArgs["noteOrNotebookShareUserInfos"] = notebookShareUserInfos
|
||||
|
||||
c.RenderArgs["noteOrNotebookShareGroupInfos"] = shareService.GetNotebookShareGroups(notebookId, c.GetUserId())
|
||||
LogJ(c.RenderArgs["noteOrNotebookShareGroupInfos"])
|
||||
|
||||
|
||||
c.RenderArgs["isNote"] = false
|
||||
c.RenderArgs["noteOrNotebookId"] = notebook.NotebookId.Hex();
|
||||
c.RenderArgs["noteOrNotebookId"] = notebook.NotebookId.Hex()
|
||||
c.RenderArgs["title"] = notebook.Title
|
||||
|
||||
|
||||
return c.RenderTemplate("share/note_notebook_share_user_infos.html")
|
||||
}
|
||||
|
||||
//------------
|
||||
// 改变share note 权限
|
||||
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 权限
|
||||
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
|
||||
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
|
||||
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, 被共享方删除
|
||||
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, 被共享方删除
|
||||
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
|
||||
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 {
|
||||
re := info.NewRe()
|
||||
re.Ok = shareService.AddShareNoteGroup(c.GetUserId(), noteId, groupId, perm);
|
||||
return c.RenderJson(re);
|
||||
re.Ok = shareService.AddShareNoteGroup(c.GetUserId(), noteId, groupId, perm)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 删除
|
||||
func (c Share) DeleteShareNoteGroup(noteId, groupId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = shareService.DeleteShareNoteGroup(c.GetUserId(), noteId, groupId);
|
||||
return c.RenderJson(re);
|
||||
re.Ok = shareService.DeleteShareNoteGroup(c.GetUserId(), noteId, groupId)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 更新, 也是一样, 先删后加
|
||||
func (c Share) UpdateShareNoteGroupPerm(noteId, groupId string, perm int) revel.Result {
|
||||
return c.AddShareNoteGroup(noteId, groupId, perm)
|
||||
}
|
||||
|
||||
|
||||
//------
|
||||
|
||||
// 将笔记分享给分组
|
||||
func (c Share) AddShareNotebookGroup(notebookId, groupId string, perm int) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = shareService.AddShareNotebookGroup(c.GetUserId(), notebookId, groupId, perm);
|
||||
return c.RenderJson(re);
|
||||
re.Ok = shareService.AddShareNotebookGroup(c.GetUserId(), notebookId, groupId, perm)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 删除
|
||||
func (c Share) DeleteShareNotebookGroup(notebookId, groupId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = shareService.DeleteShareNotebookGroup(c.GetUserId(), notebookId, groupId);
|
||||
return c.RenderJson(re);
|
||||
re.Ok = shareService.DeleteShareNotebookGroup(c.GetUserId(), notebookId, groupId)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 更新, 也是一样, 先删后加
|
||||
func (c Share) UpdateShareNotebookGroupPerm(notebookId, groupId string, perm int) revel.Result {
|
||||
return c.AddShareNotebookGroup(notebookId, groupId, perm)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "encoding/json"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// "os/exec"
|
||||
// "os/exec"
|
||||
)
|
||||
|
||||
type Tag struct {
|
||||
@@ -27,4 +27,4 @@ func (c Tag) DeleteTag(tag string) revel.Result {
|
||||
ret.Ok = true
|
||||
ret.Item = tagService.DeleteTag(c.GetUserId(), tag)
|
||||
return c.RenderJson(ret)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,16 @@ package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "encoding/json"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "os"
|
||||
// "path"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "os"
|
||||
// "path"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -32,18 +32,18 @@ func (c User) UpdateUsername(username string) revel.Result {
|
||||
re := info.NewRe()
|
||||
if c.GetUserId() == configService.GetGlobalStringConfig("demoUserId") {
|
||||
re.Msg = "cannotUpdateDemo"
|
||||
return c.RenderRe(re);
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
if(re.Ok) {
|
||||
if re.Ok {
|
||||
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()
|
||||
if c.GetUserId() == configService.GetGlobalStringConfig("demoUserId") {
|
||||
re.Msg = "cannotUpdateDemo"
|
||||
return c.RenderRe(re);
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
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 {
|
||||
return c.RenderRe(re);
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
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 {
|
||||
re := info.NewRe();
|
||||
re := info.NewRe()
|
||||
re.Ok = userService.UpdateTheme(c.GetUserId(), theme)
|
||||
if re.Ok {
|
||||
c.UpdateSession("Theme", theme)
|
||||
}
|
||||
return c.RenderJson(re);
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 发送邀请链接
|
||||
func (c User) SendRegisterEmail(content, toEmail string) revel.Result {
|
||||
re := info.NewRe()
|
||||
if content == "" || !IsEmail(toEmail) {
|
||||
return c.RenderJson(re);
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
re.Ok = emailService.SendInviteEmail(c.GetUserInfo(), toEmail, content)
|
||||
return c.RenderJson(re);
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
//---------------------------
|
||||
@@ -93,79 +93,43 @@ func (c User) ReSendActiveEmail() revel.Result {
|
||||
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 {
|
||||
c.SetUserInfo();
|
||||
|
||||
c.SetUserInfo()
|
||||
|
||||
ok, msg, email := userService.UpdateEmail(token)
|
||||
|
||||
|
||||
c.RenderArgs["title"] = "验证邮箱"
|
||||
c.RenderArgs["ok"] = ok
|
||||
c.RenderArgs["msg"] = msg
|
||||
c.RenderArgs["email"] = email
|
||||
|
||||
|
||||
// 修改session
|
||||
if ok {
|
||||
c.UpdateSession("Email", email)
|
||||
}
|
||||
|
||||
|
||||
return c.RenderTemplate("user/update_email.html")
|
||||
}
|
||||
|
||||
// 注册后激活邮箱
|
||||
func (c User) ActiveEmail(token string) revel.Result {
|
||||
c.SetUserInfo();
|
||||
|
||||
c.SetUserInfo()
|
||||
|
||||
ok, msg, email := userService.ActiveEmail(token)
|
||||
|
||||
|
||||
// 需要修改session
|
||||
if ok {
|
||||
c.UpdateSession("Verified", "1");
|
||||
c.UpdateSession("Verified", "1")
|
||||
}
|
||||
|
||||
|
||||
c.RenderArgs["title"] = "验证邮箱"
|
||||
c.RenderArgs["ok"] = ok
|
||||
c.RenderArgs["msg"] = msg
|
||||
c.RenderArgs["email"] = email
|
||||
|
||||
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)
|
||||
return c.RenderTemplate("user/active_email.html")
|
||||
}
|
||||
|
||||
//-----------------
|
||||
@@ -174,10 +138,10 @@ func (c User) UpdateColumnWidth(notebookWidth, noteListWidth, mdEditorWidth int)
|
||||
re := info.NewRe()
|
||||
re.Ok = userService.UpdateColumnWidth(c.GetUserId(), notebookWidth, noteListWidth, mdEditorWidth)
|
||||
if re.Ok {
|
||||
c.UpdateSession("NotebookWidth", strconv.Itoa(notebookWidth));
|
||||
c.UpdateSession("NoteListWidth", strconv.Itoa(noteListWidth));
|
||||
c.UpdateSession("MdEditorWidth", strconv.Itoa(mdEditorWidth));
|
||||
|
||||
c.UpdateSession("NotebookWidth", strconv.Itoa(notebookWidth))
|
||||
c.UpdateSession("NoteListWidth", strconv.Itoa(noteListWidth))
|
||||
c.UpdateSession("MdEditorWidth", strconv.Itoa(mdEditorWidth))
|
||||
|
||||
LogJ(c.Session)
|
||||
}
|
||||
return c.RenderJson(re)
|
||||
@@ -187,9 +151,9 @@ func (c User) UpdateLeftIsMin(leftIsMin bool) revel.Result {
|
||||
re.Ok = userService.UpdateLeftIsMin(c.GetUserId(), leftIsMin)
|
||||
if re.Ok {
|
||||
if leftIsMin {
|
||||
c.UpdateSession("LeftIsMin", "1");
|
||||
c.UpdateSession("LeftIsMin", "1")
|
||||
} else {
|
||||
c.UpdateSession("LeftIsMin", "0");
|
||||
c.UpdateSession("LeftIsMin", "0")
|
||||
}
|
||||
}
|
||||
return c.RenderJson(re)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
// "github.com/revel/revel"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "encoding/json"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "github.com/revel/revel"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "encoding/json"
|
||||
"github.com/leanote/leanote/app/controllers"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "strconv"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -20,26 +20,26 @@ type AdminBaseController struct {
|
||||
|
||||
// 得到sorterField 和 isAsc
|
||||
// okSorter = ['email', 'username']
|
||||
func (c AdminBaseController) getSorter(sorterField string, isAsc bool, okSorter []string) (string, bool){
|
||||
func (c AdminBaseController) getSorter(sorterField string, isAsc bool, okSorter []string) (string, bool) {
|
||||
sorter := ""
|
||||
c.Params.Bind(&sorter, "sorter")
|
||||
if sorter == "" {
|
||||
return sorterField, isAsc;
|
||||
return sorterField, isAsc
|
||||
}
|
||||
|
||||
|
||||
// sorter形式 email-up, email-down
|
||||
s2 := strings.Split(sorter, "-")
|
||||
if len(s2) != 2 {
|
||||
return sorterField, isAsc;
|
||||
return sorterField, isAsc
|
||||
}
|
||||
|
||||
|
||||
// 必须是可用的sorter
|
||||
if okSorter != nil && len(okSorter) > 0 {
|
||||
if !InArray(okSorter, s2[0]) {
|
||||
return sorterField, isAsc;
|
||||
return sorterField, isAsc
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sorterField = strings.Title(s2[0])
|
||||
if s2[1] == "up" {
|
||||
isAsc = true
|
||||
@@ -47,7 +47,7 @@ func (c AdminBaseController) getSorter(sorterField string, isAsc bool, okSorter
|
||||
isAsc = false
|
||||
}
|
||||
c.RenderArgs["sorter"] = sorter
|
||||
return sorterField, isAsc;
|
||||
return sorterField, isAsc
|
||||
}
|
||||
|
||||
func (c AdminBaseController) updateConfig(keys []string) {
|
||||
@@ -56,4 +56,4 @@ func (c AdminBaseController) updateConfig(keys []string) {
|
||||
v := c.Params.Values.Get(key)
|
||||
configService.UpdateGlobalStringConfig(userId, key, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package admin
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
)
|
||||
|
||||
@@ -15,16 +15,16 @@ type AdminBlog struct {
|
||||
// admin 主页
|
||||
func (c AdminBlog) Index(sorter, keywords string) revel.Result {
|
||||
pageNumber := c.GetPage()
|
||||
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "userId", "isRecommed", "createdTime"});
|
||||
pageInfo, blogs := blogService.ListAllBlogs("", "", keywords, false, pageNumber, userPageSize, sorterField, isAsc);
|
||||
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "userId", "isRecommed", "createdTime"})
|
||||
pageInfo, blogs := blogService.ListAllBlogs("", "", keywords, false, pageNumber, userPageSize, sorterField, isAsc)
|
||||
c.RenderArgs["pageInfo"] = pageInfo
|
||||
c.RenderArgs["blogs"] = blogs
|
||||
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 {
|
||||
re := info.NewRe()
|
||||
re.Ok = blogService.SetRecommend(noteId, recommend);
|
||||
re.Ok = blogService.SetRecommend(noteId, recommend)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
@@ -13,15 +13,15 @@ type Admin struct {
|
||||
// admin 主页
|
||||
func (c Admin) Index() revel.Result {
|
||||
c.SetUserInfo()
|
||||
|
||||
|
||||
c.RenderArgs["title"] = "leanote"
|
||||
c.SetLocale()
|
||||
|
||||
|
||||
c.RenderArgs["countUser"] = userService.CountUser()
|
||||
c.RenderArgs["countNote"] = noteService.CountNote("")
|
||||
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 {
|
||||
return c.RenderTemplate("admin/" + view);
|
||||
}
|
||||
return c.RenderTemplate("admin/" + view)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"os"
|
||||
"io"
|
||||
"time"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 数据管理, 备份和恢复
|
||||
@@ -22,18 +22,18 @@ func (c AdminData) Index() revel.Result {
|
||||
// 逆序之
|
||||
backups2 := make([]map[string]string, len(backups))
|
||||
j := 0
|
||||
for i := len(backups)-1; i >= 0; i-- {
|
||||
for i := len(backups) - 1; i >= 0; i-- {
|
||||
backups2[j] = backups[i]
|
||||
j++
|
||||
}
|
||||
c.RenderArgs["backups"] = backups2
|
||||
return c.RenderTemplate("admin/data/index.html");
|
||||
return c.RenderTemplate("admin/data/index.html")
|
||||
}
|
||||
|
||||
func (c AdminData) Backup() revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok, re.Msg = configService.Backup("")
|
||||
return c.RenderJson(re)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 还原
|
||||
@@ -51,7 +51,7 @@ func (c AdminData) Delete(createdTime string) revel.Result {
|
||||
func (c AdminData) UpdateRemark(createdTime, remark string) revel.Result {
|
||||
re := info.Re{}
|
||||
re.Ok, re.Msg = configService.UpdateBackupRemark(createdTime, remark)
|
||||
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
func (c AdminData) Download(createdTime string) revel.Result {
|
||||
@@ -59,56 +59,56 @@ func (c AdminData) Download(createdTime string) revel.Result {
|
||||
if !ok {
|
||||
return c.RenderText("")
|
||||
}
|
||||
|
||||
|
||||
dbname, _ := revel.Config.String("db.dbname")
|
||||
path := backup["path"] + "/" + dbname
|
||||
allFiles := ListDir(path)
|
||||
|
||||
allFiles := ListDir(path)
|
||||
|
||||
filename := "backup_" + dbname + "_" + backup["createdTime"] + ".tar.gz"
|
||||
|
||||
|
||||
// file write
|
||||
fw, err := os.Create(revel.BasePath + "/files/" + filename)
|
||||
if err != nil {
|
||||
fw, err := os.Create(revel.BasePath + "/files/" + filename)
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
// defer fw.Close() // 不需要关闭, 还要读取给用户下载
|
||||
// gzip write
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
|
||||
// tar write
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
|
||||
// 遍历文件列表
|
||||
for _, file := range allFiles {
|
||||
}
|
||||
// defer fw.Close() // 不需要关闭, 还要读取给用户下载
|
||||
// gzip write
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
|
||||
// tar write
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
|
||||
// 遍历文件列表
|
||||
for _, file := range allFiles {
|
||||
fn := path + "/" + file
|
||||
fr, err := os.Open(fn)
|
||||
fileInfo, _ := fr.Stat()
|
||||
if err != nil {
|
||||
fr, err := os.Open(fn)
|
||||
fileInfo, _ := fr.Stat()
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// 信息头
|
||||
h := new(tar.Header)
|
||||
h.Name = file
|
||||
h.Size = fileInfo.Size()
|
||||
h.Mode = int64(fileInfo.Mode())
|
||||
h.ModTime = fileInfo.ModTime()
|
||||
|
||||
// 写信息头
|
||||
err = tw.WriteHeader(h)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 写文件
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} // for
|
||||
|
||||
return c.RenderBinary(fw, filename, revel.Attachment, time.Now()) // revel.Attachm
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// 信息头
|
||||
h := new(tar.Header)
|
||||
h.Name = file
|
||||
h.Size = fileInfo.Size()
|
||||
h.Mode = int64(fileInfo.Mode())
|
||||
h.ModTime = fileInfo.ModTime()
|
||||
|
||||
// 写信息头
|
||||
err = tw.WriteHeader(h)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 写文件
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} // for
|
||||
|
||||
return c.RenderBinary(fw, filename, revel.Attachment, time.Now()) // revel.Attachm
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"strings"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// admin 首页
|
||||
@@ -25,14 +25,14 @@ func (c AdminEmail) Blog() revel.Result {
|
||||
newTags := configService.GetGlobalArrayConfig("newTags")
|
||||
c.RenderArgs["recommendTags"] = strings.Join(recommendTags, ",")
|
||||
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 {
|
||||
re := info.NewRe()
|
||||
|
||||
|
||||
re.Ok = configService.UpdateGlobalArrayConfig(c.GetUserId(), "recommendTags", strings.Split(recommendTags, ","))
|
||||
re.Ok = configService.UpdateGlobalArrayConfig(c.GetUserId(), "newTags", strings.Split(newTags, ","))
|
||||
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
@@ -41,24 +41,24 @@ func (c AdminEmail) DoBlogTag(recommendTags, newTags string) revel.Result {
|
||||
func (c AdminEmail) Demo() revel.Result {
|
||||
c.RenderArgs["demoUsername"] = configService.GetGlobalStringConfig("demoUsername")
|
||||
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 {
|
||||
re := info.NewRe()
|
||||
|
||||
|
||||
userInfo, err := authService.Login(demoUsername, demoPassword)
|
||||
if err != nil {
|
||||
return c.RenderJson(info.Re{Ok: false})
|
||||
}
|
||||
if userInfo.UserId == "" {
|
||||
re.Msg = "The User is Not Exists";
|
||||
re.Msg = "The User is Not Exists"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "demoUserId", userInfo.UserId.Hex())
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "demoUsername", demoUsername)
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "demoPassword", demoPassword)
|
||||
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ func (c AdminEmail) DoDemo(demoUsername, demoPassword string) revel.Result {
|
||||
// 长微博的bin路径phantomJs
|
||||
func (c AdminEmail) ToImage() revel.Result {
|
||||
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 {
|
||||
re := info.NewRe()
|
||||
@@ -80,13 +80,13 @@ func (c AdminEmail) Set(emailHost, emailPort, emailUsername, emailPassword strin
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "emailPort", emailPort)
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "emailUsername", emailUsername)
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "emailPassword", emailPassword)
|
||||
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
func (c AdminEmail) Template() revel.Result {
|
||||
re := info.NewRe()
|
||||
|
||||
keys := []string{"emailTemplateHeader", "emailTemplateFooter",
|
||||
|
||||
keys := []string{"emailTemplateHeader", "emailTemplateFooter",
|
||||
"emailTemplateRegisterSubject",
|
||||
"emailTemplateRegister",
|
||||
"emailTemplateFindPasswordSubject",
|
||||
@@ -98,7 +98,7 @@ func (c AdminEmail) Template() revel.Result {
|
||||
"emailTemplateCommentSubject",
|
||||
"emailTemplateComment",
|
||||
}
|
||||
|
||||
|
||||
userId := c.GetUserId()
|
||||
for _, key := range keys {
|
||||
v := c.Params.Values.Get(key)
|
||||
@@ -113,7 +113,7 @@ func (c AdminEmail) Template() revel.Result {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
re.Ok = true
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
@@ -121,100 +121,99 @@ func (c AdminEmail) Template() revel.Result {
|
||||
// 发送Email
|
||||
func (c AdminEmail) SendEmailToEmails(sendEmails, latestEmailSubject, latestEmailBody string, verified, saveAsOldEmail bool) revel.Result {
|
||||
re := info.NewRe()
|
||||
|
||||
|
||||
c.updateConfig([]string{"sendEmails", "latestEmailSubject", "latestEmailBody"})
|
||||
|
||||
|
||||
if latestEmailSubject == "" || latestEmailBody == "" {
|
||||
re.Msg = "subject or body is blank"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
if saveAsOldEmail {
|
||||
oldEmails := configService.GetGlobalMapConfig("oldEmails")
|
||||
oldEmails[latestEmailSubject] = latestEmailBody
|
||||
configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails);
|
||||
configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails)
|
||||
}
|
||||
|
||||
|
||||
sendEmails = strings.Replace(sendEmails, "\r", "", -1)
|
||||
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)
|
||||
}
|
||||
|
||||
// 发送Email
|
||||
func (c AdminEmail) SendToUsers2(emails, latestEmailSubject, latestEmailBody string, verified, saveAsOldEmail bool) revel.Result {
|
||||
re := info.NewRe()
|
||||
|
||||
|
||||
c.updateConfig([]string{"sendEmails", "latestEmailSubject", "latestEmailBody"})
|
||||
|
||||
|
||||
if latestEmailSubject == "" || latestEmailBody == "" {
|
||||
re.Msg = "subject or body is blank"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
if saveAsOldEmail {
|
||||
oldEmails := configService.GetGlobalMapConfig("oldEmails")
|
||||
oldEmails[latestEmailSubject] = latestEmailBody
|
||||
configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails);
|
||||
configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails)
|
||||
}
|
||||
|
||||
|
||||
emails = strings.Replace(emails, "\r", "", -1)
|
||||
emailsArr := strings.Split(emails, "\n")
|
||||
|
||||
|
||||
users := userService.ListUserInfosByEmails(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)
|
||||
}
|
||||
|
||||
// send Email dialog
|
||||
func (c AdminEmail) SendEmailDialog(emails string) revel.Result{
|
||||
func (c AdminEmail) SendEmailDialog(emails string) revel.Result {
|
||||
emailsArr := strings.Split(emails, ",")
|
||||
emailsNl := strings.Join(emailsArr, "\n")
|
||||
|
||||
|
||||
c.RenderArgs["emailsNl"] = emailsNl
|
||||
c.RenderArgs["str"] = configService.GlobalStringConfigs
|
||||
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 {
|
||||
re := info.NewRe()
|
||||
|
||||
|
||||
c.updateConfig([]string{"userFilterEmail", "userFilterWhiteList", "userFilterBlackList", "latestEmailSubject", "latestEmailBody"})
|
||||
|
||||
|
||||
if latestEmailSubject == "" || latestEmailBody == "" {
|
||||
re.Msg = "subject or body is blank"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
if saveAsOldEmail {
|
||||
oldEmails := configService.GetGlobalMapConfig("oldEmails")
|
||||
oldEmails[latestEmailSubject] = latestEmailBody
|
||||
configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails);
|
||||
configService.UpdateGlobalMapConfig(c.GetUserId(), "oldEmails", oldEmails)
|
||||
}
|
||||
|
||||
|
||||
users := userService.GetAllUserByFilter(userFilterEmail, userFilterWhiteList, userFilterBlackList, verified)
|
||||
|
||||
if(users == nil || len(users) == 0) {
|
||||
|
||||
if users == nil || len(users) == 0 {
|
||||
re.Ok = false
|
||||
re.Msg = "no users"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
re.Ok, re.Msg = emailService.SendEmailToUsers(users, latestEmailSubject, latestEmailBody);
|
||||
if(!re.Ok) {
|
||||
|
||||
re.Ok, re.Msg = emailService.SendEmailToUsers(users, latestEmailSubject, latestEmailBody)
|
||||
if !re.Ok {
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
re.Ok = true
|
||||
re.Msg = "users:" + strconv.Itoa(len(users))
|
||||
|
||||
|
||||
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 {
|
||||
pageNumber := c.GetPage()
|
||||
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"email", "ok", "subject", "createdTime"});
|
||||
pageInfo, emails := emailService.ListEmailLogs(pageNumber, userPageSize, sorterField, isAsc, keywords);
|
||||
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"email", "ok", "subject", "createdTime"})
|
||||
pageInfo, emails := emailService.ListEmailLogs(pageNumber, userPageSize, sorterField, isAsc, keywords)
|
||||
c.RenderArgs["pageInfo"] = pageInfo
|
||||
c.RenderArgs["emails"] = emails
|
||||
c.RenderArgs["keywords"] = keywords
|
||||
return c.RenderTemplate("admin/email/list.html");
|
||||
}
|
||||
return c.RenderTemplate("admin/email/list.html")
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ package admin
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"fmt"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"strings"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// admin 首页
|
||||
@@ -25,24 +25,24 @@ func (c AdminSetting) Blog() revel.Result {
|
||||
newTags := configService.GetGlobalArrayConfig("newTags")
|
||||
c.RenderArgs["recommendTags"] = strings.Join(recommendTags, ",")
|
||||
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 {
|
||||
re := info.NewRe()
|
||||
|
||||
|
||||
re.Ok = configService.UpdateGlobalArrayConfig(c.GetUserId(), "recommendTags", strings.Split(recommendTags, ","))
|
||||
re.Ok = configService.UpdateGlobalArrayConfig(c.GetUserId(), "newTags", strings.Split(newTags, ","))
|
||||
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 共享设置
|
||||
func (c AdminSetting) ShareNote(registerSharedUserId string,
|
||||
registerSharedNotebookPerms, registerSharedNotePerms []int,
|
||||
func (c AdminSetting) ShareNote(registerSharedUserId string,
|
||||
registerSharedNotebookPerms, registerSharedNotePerms []int,
|
||||
registerSharedNotebookIds, registerSharedNoteIds, registerCopyNoteIds []string) revel.Result {
|
||||
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -51,25 +51,25 @@ func (c AdminSetting) ShareNote(registerSharedUserId string,
|
||||
func (c AdminSetting) Demo() revel.Result {
|
||||
c.RenderArgs["demoUsername"] = configService.GetGlobalStringConfig("demoUsername")
|
||||
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 {
|
||||
re := info.NewRe()
|
||||
|
||||
|
||||
userInfo, err := authService.Login(demoUsername, demoPassword)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return c.RenderJson(info.Re{Ok: false})
|
||||
}
|
||||
if userInfo.UserId == "" {
|
||||
re.Msg = "The User is Not Exists";
|
||||
re.Msg = "The User is Not Exists"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "demoUserId", userInfo.UserId.Hex())
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "demoUsername", demoUsername)
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "demoPassword", demoPassword)
|
||||
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
@@ -83,23 +83,23 @@ func (c AdminSetting) ExportPdf(path string) revel.Result {
|
||||
func (c AdminSetting) SubDomain() revel.Result {
|
||||
c.RenderArgs["str"] = configService.GlobalStringConfigs
|
||||
c.RenderArgs["arr"] = configService.GlobalArrayConfigs
|
||||
|
||||
|
||||
c.RenderArgs["noteSubDomain"] = configService.GetGlobalStringConfig("noteSubDomain")
|
||||
c.RenderArgs["blogSubDomain"] = configService.GetGlobalStringConfig("blogSubDomain")
|
||||
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 {
|
||||
re := info.NewRe()
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "noteSubDomain", noteSubDomain)
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "blogSubDomain", blogSubDomain)
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "leaSubDomain", leaSubDomain)
|
||||
|
||||
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "allowCustomDomain", allowCustomDomain)
|
||||
re.Ok = configService.UpdateGlobalArrayConfig(c.GetUserId(), "blackSubDomains", strings.Split(blackSubDomains, ","))
|
||||
re.Ok = configService.UpdateGlobalArrayConfig(c.GetUserId(), "blackCustomDomains", strings.Split(blackCustomDomains, ","))
|
||||
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
@@ -133,4 +133,4 @@ func (c AdminSetting) UploadSize(uploadImageSize, uploadAvatarSize, uploadBlogLo
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "uploadBlogLogoSize", fmt.Sprintf("%v", uploadBlogLogoSize))
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "uploadAttachSize", fmt.Sprintf("%v", uploadAttachSize))
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ package admin
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
// "encoding/json"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// "io/ioutil"
|
||||
// "io/ioutil"
|
||||
)
|
||||
|
||||
// Upgrade controller
|
||||
@@ -14,7 +14,7 @@ type AdminUpgrade struct {
|
||||
|
||||
func (c AdminUpgrade) UpgradeBlog() revel.Result {
|
||||
upgradeService.UpgradeBlog()
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c AdminUpgrade) UpgradeBetaToBeta2() revel.Result {
|
||||
@@ -27,4 +27,4 @@ func (c AdminUpgrade) UpgradeBeta3ToBeta4() revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok, re.Msg = upgradeService.Api(c.GetUserId())
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "time"
|
||||
"github.com/revel/revel"
|
||||
// "time"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
)
|
||||
|
||||
@@ -15,37 +15,38 @@ type AdminUser struct {
|
||||
|
||||
// admin 主页
|
||||
var userPageSize = 10
|
||||
|
||||
func (c AdminUser) Index(sorter, keywords string, pageSize int) revel.Result {
|
||||
pageNumber := c.GetPage()
|
||||
if userPageSize == 0 {
|
||||
pageSize = userPageSize
|
||||
}
|
||||
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"email", "username", "verified", "createdTime", "accountType"});
|
||||
pageInfo, users := userService.ListUsers(pageNumber, pageSize, sorterField, isAsc, keywords);
|
||||
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"email", "username", "verified", "createdTime", "accountType"})
|
||||
pageInfo, users := userService.ListUsers(pageNumber, pageSize, sorterField, isAsc, keywords)
|
||||
c.RenderArgs["pageInfo"] = pageInfo
|
||||
c.RenderArgs["users"] = users
|
||||
c.RenderArgs["keywords"] = keywords
|
||||
return c.RenderTemplate("admin/user/list.html");
|
||||
return c.RenderTemplate("admin/user/list.html")
|
||||
}
|
||||
|
||||
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 {
|
||||
re := info.NewRe();
|
||||
|
||||
re := info.NewRe()
|
||||
|
||||
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 {
|
||||
return c.RenderRe(re);
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
|
||||
|
||||
// 注册
|
||||
re.Ok, re.Msg = authService.Register(email, pwd, "")
|
||||
|
||||
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
|
||||
@@ -53,14 +54,14 @@ func (c AdminUser) Register(email, pwd string) revel.Result {
|
||||
func (c AdminUser) ResetPwd(userId string) revel.Result {
|
||||
userInfo := userService.GetUserInfo(userId)
|
||||
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 {
|
||||
re := info.NewRe();
|
||||
re := info.NewRe()
|
||||
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)
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/service"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/service"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
// "strings"
|
||||
// "strings"
|
||||
)
|
||||
|
||||
var userService *service.UserService
|
||||
@@ -19,9 +19,9 @@ var blogService *service.BlogService
|
||||
var tagService *service.TagService
|
||||
var pwdService *service.PwdService
|
||||
var tokenService *service.TokenService
|
||||
var suggestionService *service.SuggestionService
|
||||
var albumService *service.AlbumService
|
||||
var noteImageService *service.NoteImageService
|
||||
var suggestionService *service.SuggestionService
|
||||
var albumService *service.AlbumService
|
||||
var noteImageService *service.NoteImageService
|
||||
var fileService *service.FileService
|
||||
var attachService *service.AttachService
|
||||
var configService *service.ConfigService
|
||||
@@ -31,31 +31,32 @@ var upgradeService *service.UpgradeService
|
||||
// 拦截器
|
||||
// 不需要拦截的url
|
||||
// Index 除了Note之外都不需要
|
||||
var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": true,
|
||||
"Login": true,
|
||||
"DoLogin": true,
|
||||
"Logout": true,
|
||||
"Register": true,
|
||||
"DoRegister": true,
|
||||
"FindPasswword": true,
|
||||
"DoFindPassword": true,
|
||||
"FindPassword2": true,
|
||||
"FindPasswordUpdate": true,
|
||||
"Suggestion": true,
|
||||
},
|
||||
var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": true,
|
||||
"Login": true,
|
||||
"DoLogin": true,
|
||||
"Logout": true,
|
||||
"Register": true,
|
||||
"DoRegister": true,
|
||||
"FindPasswword": true,
|
||||
"DoFindPassword": true,
|
||||
"FindPassword2": true,
|
||||
"FindPasswordUpdate": true,
|
||||
"Suggestion": true,
|
||||
},
|
||||
"Blog": map[string]bool{"Index": true,
|
||||
"View": true,
|
||||
"AboutMe": true,
|
||||
"View": true,
|
||||
"AboutMe": true,
|
||||
"SearchBlog": true,
|
||||
},
|
||||
},
|
||||
// 用户的激活与修改邮箱都不需要登录, 通过链接地址
|
||||
"User": map[string]bool{"UpdateEmail": true,
|
||||
"ActiveEmail":true,
|
||||
},
|
||||
"Oauth": map[string]bool{"GithubCallback": true},
|
||||
"File": map[string]bool{"OutputImage": true, "OutputFile": true},
|
||||
"ActiveEmail": true,
|
||||
},
|
||||
"Oauth": map[string]bool{"GithubCallback": true},
|
||||
"File": map[string]bool{"OutputImage": true, "OutputFile": true},
|
||||
"Attach": map[string]bool{"Download": true, "DownloadAll": true},
|
||||
}
|
||||
|
||||
func needValidate(controller, method string) bool {
|
||||
// 在里面
|
||||
if v, ok := commonUrl[controller]; ok {
|
||||
@@ -66,33 +67,33 @@ func needValidate(controller, method string) bool {
|
||||
return true
|
||||
} else {
|
||||
// controller不在这里的, 肯定要验证
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
}
|
||||
func AuthInterceptor(c *revel.Controller) revel.Result {
|
||||
// 全部变成首字大写
|
||||
/*
|
||||
var controller = strings.Title(c.Name)
|
||||
var method = strings.Title(c.MethodName)
|
||||
// 是否需要验证?
|
||||
if !needValidate(controller, method) {
|
||||
return nil
|
||||
}
|
||||
var controller = strings.Title(c.Name)
|
||||
var method = strings.Title(c.MethodName)
|
||||
// 是否需要验证?
|
||||
if !needValidate(controller, method) {
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// 验证是否已登录
|
||||
// 必须是管理员
|
||||
if username, ok := c.Session["Username"]; ok && username == configService.GetAdminUsername() {
|
||||
return nil // 已登录
|
||||
}
|
||||
|
||||
|
||||
// 没有登录, 判断是否是ajax操作
|
||||
if c.Request.Header.Get("X-Requested-With") == "XMLHttpRequest" {
|
||||
re := info.NewRe()
|
||||
re.Msg = "NOTLOGIN"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
return c.Redirect("/login")
|
||||
}
|
||||
|
||||
@@ -110,7 +111,7 @@ func InitService() {
|
||||
tokenService = service.TokenS
|
||||
noteImageService = service.NoteImageS
|
||||
fileService = service.FileS
|
||||
albumService= service.AlbumS
|
||||
albumService = service.AlbumS
|
||||
attachService = service.AttachS
|
||||
pwdService = service.PwdS
|
||||
suggestionService = service.SuggestionS
|
||||
|
||||
@@ -23,7 +23,7 @@ type ApiAuth struct {
|
||||
// 失败返回 {Ok: false, Msg: ""}
|
||||
func (c ApiAuth) Login(email, pwd string) revel.Result {
|
||||
var msg = ""
|
||||
|
||||
|
||||
userInfo, err := authService.Login(email, pwd)
|
||||
if err == nil {
|
||||
token := bson.NewObjectId().Hex()
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"github.com/revel/revel"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// "encoding/json"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/controllers"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"os"
|
||||
// "fmt"
|
||||
// "fmt"
|
||||
"io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
@@ -43,75 +43,76 @@ func (c ApiBaseContrller) getUserInfo() info.User {
|
||||
|
||||
// 上传附件
|
||||
func (c ApiBaseContrller) uploadAttach(name string, noteId string) (ok bool, msg string, id string) {
|
||||
userId := c.getUserId();
|
||||
|
||||
userId := c.getUserId()
|
||||
|
||||
// 判断是否有权限为笔记添加附件
|
||||
// 如果笔记还没有添加是不是会有问题
|
||||
/*
|
||||
if !shareService.HasUpdateNotePerm(noteId, userId) {
|
||||
return
|
||||
}
|
||||
if !shareService.HasUpdateNotePerm(noteId, userId) {
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
file, handel, err := c.Request.FormFile(name)
|
||||
if err != nil {
|
||||
return
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
|
||||
data, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return
|
||||
return
|
||||
}
|
||||
// > 5M?
|
||||
maxFileSize := configService.GetUploadSize("uploadAttachSize");
|
||||
maxFileSize := configService.GetUploadSize("uploadAttachSize")
|
||||
if maxFileSize <= 0 {
|
||||
maxFileSize = 1000
|
||||
}
|
||||
if(float64(len(data)) > maxFileSize * float64(1024*1024)) {
|
||||
msg = "fileIsTooLarge"
|
||||
return
|
||||
if float64(len(data)) > maxFileSize*float64(1024*1024) {
|
||||
msg = "fileIsTooLarge"
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 生成上传路径
|
||||
newGuid := NewGuid()
|
||||
filePath := "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/attachs"
|
||||
|
||||
dir := revel.BasePath + "/" + filePath
|
||||
// filePath := "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/attachs"
|
||||
filePath := "files/" + GetRandomFilePath(userId, newGuid) + "/attachs"
|
||||
|
||||
dir := revel.BasePath + "/" + filePath
|
||||
err = os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return
|
||||
return
|
||||
}
|
||||
// 生成新的文件名
|
||||
filename := handel.Filename
|
||||
_, ext := SplitFilename(filename) // .doc
|
||||
filename = newGuid + ext
|
||||
toPath := dir + "/" + filename;
|
||||
toPath := dir + "/" + filename
|
||||
err = ioutil.WriteFile(toPath, data, 0777)
|
||||
if err != nil {
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// add File to db
|
||||
fileType := ""
|
||||
if ext != "" {
|
||||
fileType = strings.ToLower(ext[1:])
|
||||
}
|
||||
filesize := GetFilesize(toPath)
|
||||
fileInfo := info.Attach{AttachId: bson.NewObjectId(),
|
||||
Name: filename,
|
||||
Title: handel.Filename,
|
||||
NoteId: bson.ObjectIdHex(noteId),
|
||||
fileInfo := info.Attach{AttachId: bson.NewObjectId(),
|
||||
Name: filename,
|
||||
Title: handel.Filename,
|
||||
NoteId: bson.ObjectIdHex(noteId),
|
||||
UploadUserId: bson.ObjectIdHex(userId),
|
||||
Path: filePath + "/" + filename,
|
||||
Type: fileType,
|
||||
Size: filesize}
|
||||
|
||||
Path: filePath + "/" + filename,
|
||||
Type: fileType,
|
||||
Size: filesize}
|
||||
|
||||
ok, msg = attachService.AddAttach(fileInfo, true)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
id = fileInfo.AttachId.Hex()
|
||||
return
|
||||
}
|
||||
@@ -123,16 +124,17 @@ func (c ApiBaseContrller) upload(name string, noteId string, isAttach bool) (ok
|
||||
}
|
||||
file, handel, err := c.Request.FormFile(name)
|
||||
if err != nil {
|
||||
return
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
|
||||
newGuid := NewGuid()
|
||||
// 生成上传路径
|
||||
userId := c.getUserId()
|
||||
fileUrlPath := "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/images"
|
||||
|
||||
dir := revel.BasePath + "/" + fileUrlPath
|
||||
// fileUrlPath := "files/" + Digest3(userId) + "/" + userId + "/" + Digest2(newGuid) + "/images"
|
||||
fileUrlPath := "files/" + GetRandomFilePath(userId, newGuid) + "/images"
|
||||
|
||||
dir := revel.BasePath + "/" + fileUrlPath
|
||||
err = os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -140,7 +142,7 @@ func (c ApiBaseContrller) upload(name string, noteId string, isAttach bool) (ok
|
||||
// 生成新的文件名
|
||||
filename := handel.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"
|
||||
return
|
||||
}
|
||||
@@ -150,35 +152,35 @@ func (c ApiBaseContrller) upload(name string, noteId string, isAttach bool) (ok
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
maxFileSize := configService.GetUploadSize("uploadImageSize");
|
||||
|
||||
maxFileSize := configService.GetUploadSize("uploadImageSize")
|
||||
if maxFileSize <= 0 {
|
||||
maxFileSize = 1000
|
||||
}
|
||||
|
||||
|
||||
// > 2M?
|
||||
if(float64(len(data)) > maxFileSize * float64(1024*1024)) {
|
||||
if float64(len(data)) > maxFileSize*float64(1024*1024) {
|
||||
msg = "fileIsTooLarge"
|
||||
return
|
||||
}
|
||||
|
||||
toPath := dir + "/" + filename;
|
||||
|
||||
toPath := dir + "/" + filename
|
||||
err = ioutil.WriteFile(toPath, data, 0777)
|
||||
if err != nil {
|
||||
return
|
||||
return
|
||||
}
|
||||
// 改变成gif图片
|
||||
_, toPathGif := TransToGif(toPath, 0, true)
|
||||
filename = GetFilename(toPathGif)
|
||||
filesize := GetFilesize(toPathGif)
|
||||
fileUrlPath += "/" + filename
|
||||
|
||||
|
||||
// File
|
||||
fileInfo := info.File{FileId: bson.NewObjectId(),
|
||||
Name: filename,
|
||||
Name: filename,
|
||||
Title: handel.Filename,
|
||||
Path: fileUrlPath,
|
||||
Size: filesize}
|
||||
Path: fileUrlPath,
|
||||
Size: filesize}
|
||||
ok, msg = fileService.AddImage(fileInfo, "", c.getUserId(), true)
|
||||
if ok {
|
||||
id = fileInfo.FileId.Hex()
|
||||
|
||||
@@ -3,18 +3,18 @@ package api
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "github.com/leanote/leanote/app/lea/netutil"
|
||||
// "github.com/leanote/leanote/app/info"
|
||||
// "io/ioutil"
|
||||
// "github.com/leanote/leanote/app/info"
|
||||
// "io/ioutil"
|
||||
"os"
|
||||
// "strconv"
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
"time"
|
||||
"strings"
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 文件操作, 图片, 头像上传, 输出
|
||||
@@ -73,14 +73,14 @@ func (c ApiFile) GetImage(fileId string) revel.Result {
|
||||
// 下载附件
|
||||
// [OK]
|
||||
func (c ApiFile) GetAttach(fileId string) revel.Result {
|
||||
attach := attachService.GetAttach(fileId, c.getUserId()); // 得到路径
|
||||
attach := attachService.GetAttach(fileId, c.getUserId()) // 得到路径
|
||||
path := attach.Path
|
||||
if path == "" {
|
||||
return c.RenderText("No Such File")
|
||||
}
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(path, "/")
|
||||
file, _ := os.Open(fn)
|
||||
return c.RenderBinary(file, attach.Title, revel.Attachment, time.Now()) // revel.Attachment
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(path, "/")
|
||||
file, _ := os.Open(fn)
|
||||
return c.RenderBinary(file, attach.Title, revel.Attachment, time.Now()) // revel.Attachment
|
||||
}
|
||||
|
||||
// 下载所有附件
|
||||
@@ -95,70 +95,69 @@ func (c ApiFile) GetAllAttachs(noteId string) revel.Result {
|
||||
if attachs == nil || len(attachs) == 0 {
|
||||
return c.RenderText("")
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
dir := revel.BasePath + "/files/tmp"
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
dir := revel.BasePath + "/files/tmp"
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
filename := note.Title + ".tar.gz"
|
||||
if note.Title == "" {
|
||||
filename = "all.tar.gz"
|
||||
}
|
||||
|
||||
// file write
|
||||
fw, err := os.Create(revel.BasePath + "/files/" + filename)
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
// defer fw.Close() // 不需要关闭, 还要读取给用户下载
|
||||
|
||||
// gzip write
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
|
||||
// tar write
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
|
||||
// 遍历文件列表
|
||||
for _, attach := range attachs {
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(attach.Path, "/")
|
||||
fr, err := os.Open(fn)
|
||||
fileInfo, _ := fr.Stat()
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// 信息头
|
||||
h := new(tar.Header)
|
||||
h.Name = attach.Title
|
||||
h.Size = fileInfo.Size()
|
||||
h.Mode = int64(fileInfo.Mode())
|
||||
h.ModTime = fileInfo.ModTime()
|
||||
|
||||
// 写信息头
|
||||
err = tw.WriteHeader(h)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 写文件
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} // for
|
||||
|
||||
// tw.Close()
|
||||
// gw.Close()
|
||||
// fw.Close()
|
||||
// file, _ := os.Open(dir + "/" + filename)
|
||||
// fw.Seek(0, 0)
|
||||
return c.RenderBinary(fw, filename, revel.Attachment, time.Now()) // revel.Attachment
|
||||
}
|
||||
|
||||
// file write
|
||||
fw, err := os.Create(revel.BasePath + "/files/" + filename)
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
// defer fw.Close() // 不需要关闭, 还要读取给用户下载
|
||||
|
||||
// gzip write
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
|
||||
// tar write
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
|
||||
// 遍历文件列表
|
||||
for _, attach := range attachs {
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(attach.Path, "/")
|
||||
fr, err := os.Open(fn)
|
||||
fileInfo, _ := fr.Stat()
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// 信息头
|
||||
h := new(tar.Header)
|
||||
h.Name = attach.Title
|
||||
h.Size = fileInfo.Size()
|
||||
h.Mode = int64(fileInfo.Mode())
|
||||
h.ModTime = fileInfo.ModTime()
|
||||
|
||||
// 写信息头
|
||||
err = tw.WriteHeader(h)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 写文件
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} // for
|
||||
|
||||
// tw.Close()
|
||||
// gw.Close()
|
||||
// fw.Close()
|
||||
// file, _ := os.Open(dir + "/" + filename)
|
||||
// fw.Seek(0, 0)
|
||||
return c.RenderBinary(fw, filename, revel.Attachment, time.Now()) // revel.Attachment
|
||||
}
|
||||
|
||||
@@ -6,11 +6,10 @@ import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"regexp"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
"os/exec"
|
||||
"os"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
@@ -58,7 +57,7 @@ func (c ApiNote) GetSyncNotes(afterUsn, maxEntry int) revel.Result {
|
||||
// 得到笔记本下的笔记
|
||||
// [OK]
|
||||
func (c ApiNote) GetNotes(notebookId string) revel.Result {
|
||||
if notebookId != "" && !bson.IsObjectIdHex(notebookId) {
|
||||
if notebookId != "" && !bson.IsObjectIdHex(notebookId) {
|
||||
re := info.NewApiRe()
|
||||
re.Msg = "notebookIdInvalid"
|
||||
return c.RenderJson(re)
|
||||
@@ -72,7 +71,7 @@ func (c ApiNote) GetNotes(notebookId string) revel.Result {
|
||||
func (c ApiNote) GetTrashNotes() revel.Result {
|
||||
_, notes := noteService.ListNotes(c.getUserId(), "", true, c.GetPage(), pageSize, defaultSortField, false, false)
|
||||
return c.RenderJson(noteService.ToApiNotes(notes))
|
||||
|
||||
|
||||
}
|
||||
|
||||
// get Note
|
||||
@@ -85,7 +84,6 @@ func (c ApiNote) GetTrashNotes() revel.Result {
|
||||
"Title": "asdfadsf--=",
|
||||
"Desc": "",
|
||||
"Tags": [
|
||||
""
|
||||
],
|
||||
"Abstract": "",
|
||||
"Content": "",
|
||||
@@ -95,7 +93,7 @@ func (c ApiNote) GetTrashNotes() revel.Result {
|
||||
"Usn": 8,
|
||||
"Files": [
|
||||
{
|
||||
"FileId": "551975d599c37b970f000002",
|
||||
"FileId": "551975d599c37b970f000000",
|
||||
"LocalFileId": "",
|
||||
"Type": "",
|
||||
"Title": "",
|
||||
@@ -103,18 +101,18 @@ func (c ApiNote) GetTrashNotes() revel.Result {
|
||||
"IsAttach": false
|
||||
},
|
||||
{
|
||||
"FileId": "551975de99c37b970f000003",
|
||||
"FileId": "551975de99c37b970f000001",
|
||||
"LocalFileId": "",
|
||||
"Type": "doc",
|
||||
"Title": "李铁-简历-ali-print-en.doc",
|
||||
"Title": "李铁-print-en.doc",
|
||||
"HasBody": false,
|
||||
"IsAttach": true
|
||||
},
|
||||
{
|
||||
"FileId": "551975de99c37b970f000004",
|
||||
"FileId": "551975de99c37b970f000002",
|
||||
"LocalFileId": "",
|
||||
"Type": "doc",
|
||||
"Title": "李铁-简历-ali-print.doc",
|
||||
"Title": "李铁-print.doc",
|
||||
"HasBody": false,
|
||||
"IsAttach": true
|
||||
}
|
||||
@@ -125,12 +123,12 @@ func (c ApiNote) GetTrashNotes() revel.Result {
|
||||
}
|
||||
*/
|
||||
func (c ApiNote) GetNote(noteId string) revel.Result {
|
||||
if !bson.IsObjectIdHex(noteId) {
|
||||
if !bson.IsObjectIdHex(noteId) {
|
||||
re := info.NewApiRe()
|
||||
re.Msg = "noteIdInvalid"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
note := noteService.GetNote(noteId, c.getUserId())
|
||||
if note.NoteId == "" {
|
||||
re := info.NewApiRe()
|
||||
@@ -145,71 +143,13 @@ func (c ApiNote) GetNote(noteId string) revel.Result {
|
||||
// [OK]
|
||||
func (c ApiNote) GetNoteAndContent(noteId string) revel.Result {
|
||||
noteAndContent := noteService.GetNoteAndContent(noteId, c.getUserId())
|
||||
|
||||
|
||||
apiNotes := noteService.ToApiNotes([]info.Note{noteAndContent.Note})
|
||||
apiNote := apiNotes[0]
|
||||
apiNote.Content = noteAndContent.Content
|
||||
apiNote.Content = noteService.FixContent(noteAndContent.Content, noteAndContent.IsMarkdown)
|
||||
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处理
|
||||
// 
|
||||
// [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) // 查找所有的
|
||||
// [[ 5503537b38f4111dcb0000d1] [ 5503537b38f4111dcb0000d1]]
|
||||
for _, eachFind := range findsImageMarkdown {
|
||||
// [ 你好啊, 我很好, 为什么? 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链接是
|
||||
// https://leanote.com/api/file/getImage?fileId=xx
|
||||
// https://leanote.com/api/file/getAttach?fileId=xx
|
||||
@@ -222,28 +162,28 @@ func (c ApiNote) fixPostNotecontent(noteOrContent *info.ApiNote) {
|
||||
if files != nil && len(files) > 0 {
|
||||
for _, file := range files {
|
||||
if file.LocalFileId != "" {
|
||||
noteOrContent.Content = strings.Replace(noteOrContent.Content, "fileId=" + file.LocalFileId, "fileId=" + file.FileId, -1)
|
||||
noteOrContent.Content = strings.Replace(noteOrContent.Content, "fileId="+file.LocalFileId, "fileId="+file.FileId, -1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 得到内容
|
||||
// [OK]
|
||||
func (c ApiNote) GetNoteContent(noteId string) revel.Result {
|
||||
userId := c.getUserId()
|
||||
note := noteService.GetNote(noteId, userId)
|
||||
// re := info.NewRe()
|
||||
noteContent := noteService.GetNoteContent(noteId, c.getUserId())
|
||||
noteContent := noteService.GetNoteContent(noteId, userId)
|
||||
if noteContent.Content != "" {
|
||||
noteContent.Content = c.fixContent(noteContent.Content)
|
||||
noteContent.Content = noteService.FixContent(noteContent.Content, note.IsMarkdown)
|
||||
}
|
||||
|
||||
|
||||
apiNoteContent := info.ApiNoteContent{
|
||||
NoteId: noteContent.NoteId,
|
||||
UserId: noteContent.UserId,
|
||||
NoteId: noteContent.NoteId,
|
||||
UserId: noteContent.UserId,
|
||||
Content: noteContent.Content,
|
||||
}
|
||||
|
||||
// re.Item = noteContent
|
||||
|
||||
return c.RenderJson(apiNoteContent)
|
||||
}
|
||||
|
||||
@@ -255,12 +195,13 @@ func (c ApiNote) AddNote(noteOrContent info.ApiNote) revel.Result {
|
||||
myUserId := userId
|
||||
// 为共享新建?
|
||||
/*
|
||||
if noteOrContent.FromUserId != "" {
|
||||
userId = bson.ObjectIdHex(noteOrContent.FromUserId)
|
||||
}
|
||||
if noteOrContent.FromUserId != "" {
|
||||
userId = bson.ObjectIdHex(noteOrContent.FromUserId)
|
||||
}
|
||||
*/
|
||||
// Log(noteOrContent.Title)
|
||||
// LogJ(noteOrContent)
|
||||
// LogJ(noteOrContent)
|
||||
|
||||
/*
|
||||
LogJ(c.Params)
|
||||
for name, _ := range c.Params.Files {
|
||||
@@ -315,8 +256,8 @@ func (c ApiNote) AddNote(noteOrContent info.ApiNote) revel.Result {
|
||||
|
||||
c.fixPostNotecontent(¬eOrContent)
|
||||
|
||||
// Log("Add")
|
||||
// LogJ(noteOrContent)
|
||||
// Log("Add")
|
||||
// LogJ(noteOrContent)
|
||||
|
||||
// return c.RenderJson(re)
|
||||
|
||||
@@ -326,16 +267,21 @@ func (c ApiNote) AddNote(noteOrContent info.ApiNote) revel.Result {
|
||||
Title: noteOrContent.Title,
|
||||
Tags: noteOrContent.Tags,
|
||||
Desc: noteOrContent.Desc,
|
||||
// ImgSrc: noteOrContent.ImgSrc,
|
||||
IsBlog: noteOrContent.IsBlog,
|
||||
IsMarkdown: noteOrContent.IsMarkdown,
|
||||
AttachNum: attachNum,
|
||||
// ImgSrc: noteOrContent.ImgSrc,
|
||||
IsBlog: noteOrContent.IsBlog,
|
||||
IsMarkdown: noteOrContent.IsMarkdown,
|
||||
AttachNum: attachNum,
|
||||
CreatedTime: noteOrContent.CreatedTime,
|
||||
UpdatedTime: noteOrContent.UpdatedTime,
|
||||
}
|
||||
noteContent := info.NoteContent{NoteId: note.NoteId,
|
||||
UserId: userId,
|
||||
IsBlog: note.IsBlog,
|
||||
Content: noteOrContent.Content,
|
||||
Abstract: noteOrContent.Abstract}
|
||||
UserId: userId,
|
||||
IsBlog: note.IsBlog,
|
||||
Content: noteOrContent.Content,
|
||||
Abstract: noteOrContent.Abstract,
|
||||
CreatedTime: noteOrContent.CreatedTime,
|
||||
UpdatedTime: noteOrContent.UpdatedTime,
|
||||
}
|
||||
|
||||
// 通过内容得到Desc, abstract
|
||||
if noteOrContent.Abstract == "" {
|
||||
@@ -346,7 +292,7 @@ func (c ApiNote) AddNote(noteOrContent info.ApiNote) revel.Result {
|
||||
}
|
||||
|
||||
note = noteService.AddNoteAndContentApi(note, noteContent, myUserId)
|
||||
|
||||
|
||||
if note.NoteId == "" {
|
||||
re.Ok = false
|
||||
return c.RenderJson(re)
|
||||
@@ -386,8 +332,8 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// Log("_____________")
|
||||
// LogJ(noteOrContent)
|
||||
// Log("_____________")
|
||||
// LogJ(noteOrContent)
|
||||
/*
|
||||
LogJ(c.Params.Files)
|
||||
LogJ(c.Request.Header)
|
||||
@@ -410,14 +356,14 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
|
||||
// 如果传了files
|
||||
// TODO 测试
|
||||
/*
|
||||
for key, v := range c.Params.Values {
|
||||
Log(key)
|
||||
Log(v)
|
||||
}
|
||||
for key, v := range c.Params.Values {
|
||||
Log(key)
|
||||
Log(v)
|
||||
}
|
||||
*/
|
||||
// Log(c.Has("Files[0]"))
|
||||
if c.Has("Files[0][LocalFileId]") {
|
||||
// LogJ(c.Params.Files)
|
||||
// Log(c.Has("Files[0]"))
|
||||
if c.Has("Files[0][LocalFileId]") {
|
||||
// LogJ(c.Params.Files)
|
||||
if noteOrContent.Files != nil && len(noteOrContent.Files) > 0 {
|
||||
for i, file := range noteOrContent.Files {
|
||||
if file.HasBody {
|
||||
@@ -444,25 +390,26 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log("after upload")
|
||||
// LogJ(noteOrContent.Files)
|
||||
|
||||
// Log("after upload")
|
||||
// LogJ(noteOrContent.Files)
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 移到外面来, 删除最后一个file时也要处理, 不然总删不掉
|
||||
// 附件问题, 根据Files, 有些要删除的, 只留下这些
|
||||
attachService.UpdateOrDeleteAttachApi(noteId, userId, noteOrContent.Files)
|
||||
|
||||
|
||||
// Desc前台传来
|
||||
if c.Has("Desc") {
|
||||
needUpdateNote = true
|
||||
noteUpdate["Desc"] = noteOrContent.Desc
|
||||
}
|
||||
/*
|
||||
if c.Has("ImgSrc") {
|
||||
needUpdateNote = true
|
||||
noteUpdate["ImgSrc"] = noteOrContent.ImgSrc
|
||||
}
|
||||
if c.Has("ImgSrc") {
|
||||
needUpdateNote = true
|
||||
noteUpdate["ImgSrc"] = noteOrContent.ImgSrc
|
||||
}
|
||||
*/
|
||||
if c.Has("Title") {
|
||||
needUpdateNote = true
|
||||
@@ -472,7 +419,7 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
|
||||
needUpdateNote = true
|
||||
noteUpdate["IsTrash"] = noteOrContent.IsTrash
|
||||
}
|
||||
|
||||
|
||||
// 是否是博客
|
||||
if c.Has("IsBlog") {
|
||||
needUpdateNote = true
|
||||
@@ -509,6 +456,8 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
|
||||
}
|
||||
}
|
||||
|
||||
noteUpdate["UpdatedTime"] = noteOrContent.UpdatedTime
|
||||
|
||||
afterNoteUsn := 0
|
||||
noteOk := false
|
||||
noteMsg := ""
|
||||
@@ -532,10 +481,16 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
|
||||
if noteOrContent.Abstract == "" {
|
||||
noteOrContent.Abstract = SubStringHTML(noteOrContent.Content, 200, "")
|
||||
}
|
||||
// Log("--------> afte fixed")
|
||||
// Log(noteOrContent.Content)
|
||||
|
||||
// Log("--------> afte fixed")
|
||||
// Log(noteOrContent.Content)
|
||||
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 {
|
||||
@@ -556,8 +511,8 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
|
||||
noteOrContent.Usn = re.Usn
|
||||
noteOrContent.UpdatedTime = time.Now()
|
||||
|
||||
// Log("after upload")
|
||||
// LogJ(noteOrContent.Files)
|
||||
// Log("after upload")
|
||||
// LogJ(noteOrContent.Files)
|
||||
noteOrContent.UserId = c.getUserId()
|
||||
|
||||
return c.RenderJson(noteOrContent)
|
||||
@@ -585,7 +540,6 @@ func (c ApiNote) GetHistories(noteId string) revel.Result {
|
||||
|
||||
// 0.2 新增
|
||||
// 导出成PDF
|
||||
// test localhost:9000/api/note/exportPdf?noteId=554f07bf05fcd15fa9000000&token=562211dc99c37ba6a7000001
|
||||
func (c ApiNote) ExportPdf(noteId string) revel.Result {
|
||||
re := info.NewApiRe()
|
||||
userId := c.getUserId()
|
||||
@@ -593,7 +547,7 @@ func (c ApiNote) ExportPdf(noteId string) revel.Result {
|
||||
re.Msg = "noteNotExists"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
note := noteService.GetNoteById(noteId)
|
||||
if note.NoteId == "" {
|
||||
re.Msg = "noteNotExists"
|
||||
@@ -612,7 +566,7 @@ func (c ApiNote) ExportPdf(noteId string) revel.Result {
|
||||
|
||||
// path 判断是否需要重新生成之
|
||||
guid := NewGuid()
|
||||
fileUrlPath := "files/" + Digest3(noteUserId) + "/" + noteUserId + "/" + Digest2(guid) + "/images/pdf"
|
||||
fileUrlPath := "files/export_pdf"
|
||||
dir := revel.BasePath + "/" + fileUrlPath
|
||||
if !MkdirAll(dir) {
|
||||
re.Msg = "noDir"
|
||||
@@ -625,7 +579,7 @@ func (c ApiNote) ExportPdf(noteId string) revel.Result {
|
||||
if appKey == "" {
|
||||
appKey, _ = revel.Config.String("app.secret")
|
||||
}
|
||||
|
||||
|
||||
// 生成之
|
||||
binPath := configService.GetGlobalStringConfig("exportPdfBinPath")
|
||||
// 默认路径
|
||||
@@ -635,15 +589,15 @@ func (c ApiNote) ExportPdf(noteId string) revel.Result {
|
||||
|
||||
url := configService.GetSiteUrl() + "/note/toPdf?noteId=" + noteId + "&appKey=" + appKey
|
||||
var cc string
|
||||
if(note.IsMarkdown) {
|
||||
cc = binPath + " --window-status done \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\""
|
||||
if note.IsMarkdown {
|
||||
cc = binPath + " --lowquality --window-status done \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\""
|
||||
} else {
|
||||
cc = binPath + " \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\""
|
||||
cc = binPath + " --lowquality \"" + url + "\" \"" + path + "\"" // \"" + cookieDomain + "\" \"" + cookieName + "\" \"" + cookieValue + "\""
|
||||
}
|
||||
|
||||
|
||||
cmd := exec.Command("/bin/sh", "-c", cc)
|
||||
_, err := cmd.Output()
|
||||
if err != nil {
|
||||
if err != nil {
|
||||
re.Msg = "sysError"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
@@ -660,5 +614,5 @@ func (c ApiNote) ExportPdf(noteId string) revel.Result {
|
||||
} else {
|
||||
filenameReturn += ".pdf"
|
||||
}
|
||||
return c.RenderBinary(file, filenameReturn, revel.Attachment, time.Now()) // revel.Attachment
|
||||
return c.RenderBinary(file, filenameReturn, revel.Attachment, time.Now()) // revel.Attachment
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "io/ioutil"
|
||||
)
|
||||
|
||||
@@ -30,17 +30,17 @@ func (c ApiNotebook) fixNotebook(notebook *info.Notebook) info.ApiNotebook {
|
||||
return info.ApiNotebook{}
|
||||
}
|
||||
return info.ApiNotebook{
|
||||
NotebookId : notebook.NotebookId,
|
||||
UserId : notebook.UserId,
|
||||
ParentNotebookId : notebook.ParentNotebookId,
|
||||
Seq : notebook.Seq,
|
||||
Title : notebook.Title,
|
||||
UrlTitle : notebook.UrlTitle,
|
||||
IsBlog : notebook.IsBlog,
|
||||
CreatedTime : notebook.CreatedTime,
|
||||
UpdatedTime : notebook.UpdatedTime,
|
||||
Usn: notebook.Usn,
|
||||
IsDeleted: notebook.IsDeleted,
|
||||
NotebookId: notebook.NotebookId,
|
||||
UserId: notebook.UserId,
|
||||
ParentNotebookId: notebook.ParentNotebookId,
|
||||
Seq: notebook.Seq,
|
||||
Title: notebook.Title,
|
||||
UrlTitle: notebook.UrlTitle,
|
||||
IsBlog: notebook.IsBlog,
|
||||
CreatedTime: notebook.CreatedTime,
|
||||
UpdatedTime: notebook.UpdatedTime,
|
||||
Usn: notebook.Usn,
|
||||
IsDeleted: notebook.IsDeleted,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ func (c ApiNotebook) AddNotebook(title, parentNotebookId string, seq int) revel.
|
||||
// [OK]
|
||||
func (c ApiNotebook) UpdateNotebook(notebookId, title, parentNotebookId string, seq, usn int) revel.Result {
|
||||
re := info.NewApiRe()
|
||||
|
||||
|
||||
ok, msg, notebook := notebookService.UpdateNotebookApi(c.getUserId(), notebookId, title, parentNotebookId, seq, usn)
|
||||
if !ok {
|
||||
re.Ok = false
|
||||
|
||||
@@ -3,7 +3,7 @@ package api
|
||||
import (
|
||||
"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"
|
||||
// "io/ioutil"
|
||||
)
|
||||
@@ -53,4 +53,4 @@ func (c ApiTag) DeleteTag(tag string, usn int) revel.Result {
|
||||
re := info.NewReUpdate()
|
||||
re.Ok, re.Msg, re.Usn = tagService.DeleteTagApi(c.getUserId(), tag, usn)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,15 @@ package api
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
"io/ioutil"
|
||||
"io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
"os"
|
||||
"os"
|
||||
|
||||
// "path"
|
||||
// "strconv"
|
||||
@@ -31,10 +31,10 @@ func (c ApiUser) Info() revel.Result {
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
apiUser := info.ApiUser{
|
||||
UserId: userInfo.UserId.Hex(),
|
||||
UserId: userInfo.UserId.Hex(),
|
||||
Username: userInfo.Username,
|
||||
Email: userInfo.Email,
|
||||
Logo: userInfo.Logo,
|
||||
Email: userInfo.Email,
|
||||
Logo: userInfo.Logo,
|
||||
Verified: userInfo.Verified,
|
||||
}
|
||||
return c.RenderJson(apiUser)
|
||||
@@ -82,7 +82,6 @@ func (c ApiUser) GetSyncState() revel.Result {
|
||||
return c.RenderJson(ret)
|
||||
}
|
||||
|
||||
|
||||
// 头像设置
|
||||
// 参数file=文件
|
||||
// 成功返回{Logo: url} 头像新url
|
||||
@@ -112,7 +111,7 @@ func (c ApiUser) uploadImage() (ok bool, msg, url string) {
|
||||
defer file.Close()
|
||||
// 生成上传路径
|
||||
fileUrlPath = "public/upload/" + c.getUserId() + "/images/logo"
|
||||
|
||||
|
||||
dir := revel.BasePath + "/" + fileUrlPath
|
||||
err = os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
@@ -122,11 +121,11 @@ func (c ApiUser) uploadImage() (ok bool, msg, url string) {
|
||||
filename := handel.Filename
|
||||
|
||||
var ext string
|
||||
|
||||
|
||||
_, ext = SplitFilename(filename)
|
||||
if ext != ".gif" && ext != ".jpg" && ext != ".png" && ext != ".bmp" && ext != ".jpeg" {
|
||||
msg = "notImage"
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
filename = NewGuid() + ext
|
||||
@@ -148,8 +147,8 @@ func (c ApiUser) uploadImage() (ok bool, msg, url string) {
|
||||
LogJ(err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
ok = true
|
||||
url = configService.GetSiteUrl() + "/" + fileUrlPath + "/" + filename
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package api
|
||||
import (
|
||||
"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"
|
||||
"strings"
|
||||
)
|
||||
@@ -46,10 +46,10 @@ const (
|
||||
// 不需要拦截的url
|
||||
var commonUrl = map[string]map[string]bool{"ApiAuth": map[string]bool{"Login": true,
|
||||
"Register": true,
|
||||
},
|
||||
},
|
||||
// 文件的操作也不用登录, userId会从session中获取
|
||||
"ApiFile": map[string]bool{"GetImage": true,
|
||||
"GetAttach": true,
|
||||
"GetAttach": true,
|
||||
"GetAllAttachs": true,
|
||||
},
|
||||
}
|
||||
@@ -90,15 +90,15 @@ func AuthInterceptor(c *revel.Controller) revel.Result {
|
||||
if noToken && userId == "" {
|
||||
// 从session中获取, api/file/getImage, api/file/getAttach, api/file/getAllAttach
|
||||
// 客户端
|
||||
userId, _ = c.Session["UserId"];
|
||||
userId, _ = c.Session["UserId"]
|
||||
}
|
||||
c.Session["_userId"] = userId
|
||||
|
||||
|
||||
// 是否需要验证?
|
||||
if !needValidate(controller, method) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
if userId != "" {
|
||||
return nil // 已登录
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/service"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/lea/blog"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/service"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
"strings"
|
||||
)
|
||||
@@ -68,7 +68,7 @@ var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": tru
|
||||
},
|
||||
"Oauth": map[string]bool{"GithubCallback": 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 {
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package member
|
||||
|
||||
import (
|
||||
// "github.com/revel/revel"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "encoding/json"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "github.com/revel/revel"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "encoding/json"
|
||||
"github.com/leanote/leanote/app/controllers"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "strconv"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -20,26 +20,26 @@ type MemberBaseController struct {
|
||||
|
||||
// 得到sorterField 和 isAsc
|
||||
// okSorter = ['email', 'username']
|
||||
func (c MemberBaseController) getSorter(sorterField string, isAsc bool, okSorter []string) (string, bool){
|
||||
func (c MemberBaseController) getSorter(sorterField string, isAsc bool, okSorter []string) (string, bool) {
|
||||
sorter := ""
|
||||
c.Params.Bind(&sorter, "sorter")
|
||||
if sorter == "" {
|
||||
return sorterField, isAsc;
|
||||
return sorterField, isAsc
|
||||
}
|
||||
|
||||
|
||||
// sorter形式 email-up, email-down
|
||||
s2 := strings.Split(sorter, "-")
|
||||
if len(s2) != 2 {
|
||||
return sorterField, isAsc;
|
||||
return sorterField, isAsc
|
||||
}
|
||||
|
||||
|
||||
// 必须是可用的sorter
|
||||
if okSorter != nil && len(okSorter) > 0 {
|
||||
if !InArray(okSorter, s2[0]) {
|
||||
return sorterField, isAsc;
|
||||
return sorterField, isAsc
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sorterField = strings.Title(s2[0])
|
||||
if s2[1] == "up" {
|
||||
isAsc = true
|
||||
@@ -47,7 +47,7 @@ func (c MemberBaseController) getSorter(sorterField string, isAsc bool, okSorter
|
||||
isAsc = false
|
||||
}
|
||||
c.RenderArgs["sorter"] = sorter
|
||||
return sorterField, isAsc;
|
||||
return sorterField, isAsc
|
||||
}
|
||||
|
||||
func (c MemberBaseController) updateConfig(keys []string) {
|
||||
@@ -56,4 +56,4 @@ func (c MemberBaseController) updateConfig(keys []string) {
|
||||
v := c.Params.Values.Get(key)
|
||||
configService.UpdateGlobalStringConfig(userId, key, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func (c MemberBlog) Index(sorter, keywords string) revel.Result {
|
||||
userInfo := userService.GetUserInfo(userId)
|
||||
c.RenderArgs["userInfo"] = userInfo
|
||||
|
||||
c.RenderArgs["title"] = "Posts"
|
||||
c.RenderArgs["title"] = c.Message("Posts")
|
||||
pageNumber := c.GetPage()
|
||||
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "urlTitle", "updatedTime", "publicTime", "createdTime"})
|
||||
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())
|
||||
c.RenderArgs["userAndBlog"] = userAndBlog
|
||||
|
||||
c.common()
|
||||
|
||||
return c.RenderTemplate("member/blog/list.html")
|
||||
}
|
||||
|
||||
@@ -97,7 +99,8 @@ func (c MemberBlog) UpdateBlogUrlTitle(noteId, urlTitle string) revel.Result {
|
||||
|
||||
// 修改笔记的urlTitle
|
||||
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())
|
||||
if !note.Note.IsBlog {
|
||||
return c.E404()
|
||||
@@ -107,7 +110,6 @@ func (c MemberBlog) UpdateBlogAbstract(noteId string) revel.Result {
|
||||
return c.RenderTemplate("member/blog/update_abstract.html")
|
||||
}
|
||||
func (c MemberBlog) DoUpdateBlogAbstract(noteId, imgSrc, desc, abstract string) revel.Result {
|
||||
|
||||
re := info.NewRe()
|
||||
re.Ok = blogService.UpateBlogAbstract(c.GetUserId(), noteId, imgSrc, desc, abstract)
|
||||
return c.RenderJson(re)
|
||||
@@ -116,24 +118,24 @@ func (c MemberBlog) DoUpdateBlogAbstract(noteId, imgSrc, desc, abstract string)
|
||||
// 基本信息设置
|
||||
func (c MemberBlog) Base() revel.Result {
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Blog Base Info"
|
||||
c.RenderArgs["title"] = c.Message("Blog Base Info")
|
||||
return c.RenderTemplate("member/blog/base.html")
|
||||
}
|
||||
func (c MemberBlog) Comment() revel.Result {
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Comment"
|
||||
c.RenderArgs["title"] = c.Message("Comment")
|
||||
return c.RenderTemplate("member/blog/comment.html")
|
||||
}
|
||||
|
||||
func (c MemberBlog) Paging() revel.Result {
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Paging"
|
||||
c.RenderArgs["title"] = c.Message("Paging")
|
||||
return c.RenderTemplate("member/blog/paging.html")
|
||||
}
|
||||
|
||||
func (c MemberBlog) Cate() revel.Result {
|
||||
userBlog := c.common()
|
||||
c.RenderArgs["title"] = "Cate"
|
||||
c.RenderArgs["title"] = c.Message("Category")
|
||||
|
||||
notebooks := blogService.ListBlogNotebooks(c.GetUserId())
|
||||
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 {
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Add Single"
|
||||
c.RenderArgs["title"] = c.Message("Add Single")
|
||||
c.RenderArgs["singleId"] = singleId
|
||||
if singleId != "" {
|
||||
c.RenderArgs["title"] = "Update Single"
|
||||
c.RenderArgs["title"] = c.Message("Update Single")
|
||||
c.RenderArgs["single"] = blogService.GetSingle(singleId)
|
||||
}
|
||||
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 {
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Cate"
|
||||
c.RenderArgs["title"] = c.Message("Single")
|
||||
c.RenderArgs["singles"] = blogService.GetSingles(c.GetUserId())
|
||||
|
||||
return c.RenderTemplate("member/blog/single.html")
|
||||
@@ -234,7 +236,7 @@ func (c MemberBlog) Theme() revel.Result {
|
||||
|
||||
c.RenderArgs["optionThemes"] = themeService.GetDefaultThemes()
|
||||
|
||||
c.RenderArgs["title"] = "Theme"
|
||||
c.RenderArgs["title"] = c.Message("Theme")
|
||||
return c.RenderTemplate("member/blog/theme.html")
|
||||
}
|
||||
|
||||
@@ -251,7 +253,7 @@ func (c MemberBlog) UpdateTheme(themeId string, isNew int) revel.Result {
|
||||
}
|
||||
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Upate Theme"
|
||||
c.RenderArgs["title"] = c.Message("Update Theme")
|
||||
c.RenderArgs["isNew"] = isNew
|
||||
|
||||
// 先复制之
|
||||
@@ -443,8 +445,8 @@ func (c MemberBlog) ImportTheme() revel.Result {
|
||||
if err != nil {
|
||||
re.Msg = fmt.Sprintf("%v", err)
|
||||
return c.RenderJson(re)
|
||||
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
// 生成上传路径
|
||||
userId := c.GetUserId()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package member
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
// 分组管理
|
||||
@@ -14,9 +14,9 @@ type MemberGroup struct {
|
||||
func (c MemberGroup) Index() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = "My Group"
|
||||
c.RenderArgs["title"] = c.Message("My Group")
|
||||
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 主页
|
||||
func (c MemberIndex) Index() revel.Result {
|
||||
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["countBlog"] = noteService.CountBlog(c.GetUserId())
|
||||
|
||||
|
||||
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 {
|
||||
return c.RenderTemplate("admin/" + view);
|
||||
}
|
||||
return c.RenderTemplate("admin/" + view)
|
||||
}
|
||||
|
||||
@@ -13,34 +13,28 @@ type MemberUser struct {
|
||||
func (c MemberUser) Username() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = "Username"
|
||||
return c.RenderTemplate("member/user/username.html");
|
||||
c.RenderArgs["title"] = c.Message("Username")
|
||||
return c.RenderTemplate("member/user/username.html")
|
||||
}
|
||||
|
||||
func (c MemberUser) Email() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = "Email"
|
||||
return c.RenderTemplate("member/user/email.html");
|
||||
c.RenderArgs["title"] = c.Message("Email")
|
||||
return c.RenderTemplate("member/user/email.html")
|
||||
}
|
||||
|
||||
func (c MemberUser) Password() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = "Password"
|
||||
return c.RenderTemplate("member/user/password.html");
|
||||
c.RenderArgs["title"] = c.Message("Password")
|
||||
return c.RenderTemplate("member/user/password.html")
|
||||
}
|
||||
|
||||
func (c MemberUser) Avatar() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = "Avatar"
|
||||
c.RenderArgs["title"] = c.Message("Avatar")
|
||||
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");
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package member
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/service"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/service"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
// "strings"
|
||||
// "strings"
|
||||
)
|
||||
|
||||
var userService *service.UserService
|
||||
@@ -20,9 +20,9 @@ var blogService *service.BlogService
|
||||
var tagService *service.TagService
|
||||
var pwdService *service.PwdService
|
||||
var tokenService *service.TokenService
|
||||
var suggestionService *service.SuggestionService
|
||||
var albumService *service.AlbumService
|
||||
var noteImageService *service.NoteImageService
|
||||
var suggestionService *service.SuggestionService
|
||||
var albumService *service.AlbumService
|
||||
var noteImageService *service.NoteImageService
|
||||
var fileService *service.FileService
|
||||
var attachService *service.AttachService
|
||||
var configService *service.ConfigService
|
||||
@@ -33,31 +33,32 @@ var themeService *service.ThemeService
|
||||
// 拦截器
|
||||
// 不需要拦截的url
|
||||
// Index 除了Note之外都不需要
|
||||
var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": true,
|
||||
"Login": true,
|
||||
"DoLogin": true,
|
||||
"Logout": true,
|
||||
"Register": true,
|
||||
"DoRegister": true,
|
||||
"FindPasswword": true,
|
||||
"DoFindPassword": true,
|
||||
"FindPassword2": true,
|
||||
"FindPasswordUpdate": true,
|
||||
"Suggestion": true,
|
||||
},
|
||||
var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": true,
|
||||
"Login": true,
|
||||
"DoLogin": true,
|
||||
"Logout": true,
|
||||
"Register": true,
|
||||
"DoRegister": true,
|
||||
"FindPasswword": true,
|
||||
"DoFindPassword": true,
|
||||
"FindPassword2": true,
|
||||
"FindPasswordUpdate": true,
|
||||
"Suggestion": true,
|
||||
},
|
||||
"Blog": map[string]bool{"Index": true,
|
||||
"View": true,
|
||||
"AboutMe": true,
|
||||
"View": true,
|
||||
"AboutMe": true,
|
||||
"SearchBlog": true,
|
||||
},
|
||||
},
|
||||
// 用户的激活与修改邮箱都不需要登录, 通过链接地址
|
||||
"User": map[string]bool{"UpdateEmail": true,
|
||||
"ActiveEmail":true,
|
||||
},
|
||||
"Oauth": map[string]bool{"GithubCallback": true},
|
||||
"File": map[string]bool{"OutputImage": true, "OutputFile": true},
|
||||
"ActiveEmail": true,
|
||||
},
|
||||
"Oauth": map[string]bool{"GithubCallback": true},
|
||||
"File": map[string]bool{"OutputImage": true, "OutputFile": true},
|
||||
"Attach": map[string]bool{"Download": true, "DownloadAll": true},
|
||||
}
|
||||
|
||||
func needValidate(controller, method string) bool {
|
||||
// 在里面
|
||||
if v, ok := commonUrl[controller]; ok {
|
||||
@@ -68,33 +69,33 @@ func needValidate(controller, method string) bool {
|
||||
return true
|
||||
} else {
|
||||
// controller不在这里的, 肯定要验证
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
}
|
||||
func AuthInterceptor(c *revel.Controller) revel.Result {
|
||||
// 全部变成首字大写
|
||||
/*
|
||||
var controller = strings.Title(c.Name)
|
||||
var method = strings.Title(c.MethodName)
|
||||
// 是否需要验证?
|
||||
if !needValidate(controller, method) {
|
||||
return nil
|
||||
}
|
||||
var controller = strings.Title(c.Name)
|
||||
var method = strings.Title(c.MethodName)
|
||||
// 是否需要验证?
|
||||
if !needValidate(controller, method) {
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// 验证是否已登录
|
||||
// 必须是管理员
|
||||
if _, ok := c.Session["Username"]; ok {
|
||||
return nil // 已登录
|
||||
}
|
||||
|
||||
|
||||
// 没有登录, 判断是否是ajax操作
|
||||
if c.Request.Header.Get("X-Requested-With") == "XMLHttpRequest" {
|
||||
re := info.NewRe()
|
||||
re.Msg = "NOTLOGIN"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
return c.Redirect("/login")
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ func InitService() {
|
||||
tokenService = service.TokenS
|
||||
noteImageService = service.NoteImageS
|
||||
fileService = service.FileS
|
||||
albumService= service.AlbumS
|
||||
albumService = service.AlbumS
|
||||
attachService = service.AttachS
|
||||
pwdService = service.PwdS
|
||||
suggestionService = service.SuggestionS
|
||||
@@ -131,4 +132,4 @@ func init() {
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &MemberGroup{})
|
||||
revel.OnAppStart(func() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
包括基本信息设置
|
||||
博客设置
|
||||
@@ -2,8 +2,8 @@ package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/revel/revel"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
"gopkg.in/mgo.v2"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"strings"
|
||||
@@ -61,7 +61,7 @@ var Sessions *mgo.Collection
|
||||
func Init(url, dbname string) {
|
||||
ok := true
|
||||
config := revel.Config
|
||||
if url == "" {
|
||||
if url == "" {
|
||||
url, ok = config.String("db.url")
|
||||
if !ok {
|
||||
url, ok = config.String("db.urlEnv")
|
||||
@@ -71,7 +71,7 @@ func Init(url, dbname string) {
|
||||
} else {
|
||||
Log("get db conf from db.url: " + url)
|
||||
}
|
||||
|
||||
|
||||
if ok {
|
||||
// get dbname from urlEnv
|
||||
urls := strings.Split(url, "/")
|
||||
@@ -81,7 +81,7 @@ func Init(url, dbname string) {
|
||||
if dbname == "" {
|
||||
dbname, _ = config.String("db.dbname")
|
||||
}
|
||||
|
||||
|
||||
// get db config from host, port, username, password
|
||||
if !ok {
|
||||
host, _ := revel.Config.String("db.host")
|
||||
@@ -124,7 +124,7 @@ func Init(url, dbname string) {
|
||||
|
||||
// user
|
||||
Users = Session.DB(dbname).C("users")
|
||||
// group
|
||||
// group
|
||||
Groups = Session.DB(dbname).C("groups")
|
||||
GroupUsers = Session.DB(dbname).C("group_users")
|
||||
|
||||
@@ -360,15 +360,15 @@ func Err(err error) bool {
|
||||
// 每个请求之前都要检查!!
|
||||
func CheckMongoSessionLost() {
|
||||
// fmt.Println("检查CheckMongoSessionLostErr")
|
||||
err := Session.Ping()
|
||||
if err != nil {
|
||||
Log("Lost connection to db!")
|
||||
Session.Refresh()
|
||||
err = Session.Ping()
|
||||
if err == nil {
|
||||
Log("Reconnect to db successful.")
|
||||
} else {
|
||||
Log("重连失败!!!! 警告")
|
||||
}
|
||||
}
|
||||
err := Session.Ping()
|
||||
if err != nil {
|
||||
Log("Lost connection to db!")
|
||||
Session.Refresh()
|
||||
err = Session.Ping()
|
||||
if err == nil {
|
||||
Log("Reconnect to db successful.")
|
||||
} else {
|
||||
Log("重连失败!!!! 警告")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"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)
|
||||
@@ -22,41 +23,41 @@ func parse(filename string) {
|
||||
}
|
||||
for true {
|
||||
line, _, err := reader.ReadLine()
|
||||
|
||||
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
// 对每一行进行处理
|
||||
if line[0] == '#' || line[1] == '#' {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
lineStr := string(line)
|
||||
|
||||
|
||||
// 找到第一个=位置
|
||||
pos := strings.Index(lineStr, "=")
|
||||
|
||||
|
||||
if pos < 0 {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
key := string(line[0:pos])
|
||||
value := string(line[pos+1:])
|
||||
|
||||
// fmt.Println(lineStr)
|
||||
// fmt.Println(value)
|
||||
|
||||
|
||||
// fmt.Println(lineStr)
|
||||
// fmt.Println(value)
|
||||
|
||||
msg[key] = value
|
||||
}
|
||||
|
||||
|
||||
// JSON
|
||||
b, _ := json.Marshal(msg)
|
||||
str := string(b)
|
||||
fmt.Println(str);
|
||||
|
||||
fmt.Println(str)
|
||||
|
||||
targetName := targetBasePath + filename + ".js"
|
||||
file2, err2 := os.OpenFile(targetName, os.O_RDWR|os.O_CREATE, 0644)
|
||||
if err2 != nil {
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package info
|
||||
|
||||
import (
|
||||
"time"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
)
|
||||
|
||||
//---------
|
||||
// 数据结构
|
||||
//---------
|
||||
type NoteFile struct {
|
||||
FileId string // 服务器端Id
|
||||
FileId string // 服务器端Id
|
||||
LocalFileId string // 客户端Id
|
||||
Type string // images/png, doc, xls, 根据fileName确定
|
||||
Title string
|
||||
HasBody bool // 传过来的值是否要更新内容
|
||||
IsAttach bool // 是否是附件, 不是附件就是图片
|
||||
Type string // images/png, doc, xls, 根据fileName确定
|
||||
Title string
|
||||
HasBody bool // 传过来的值是否要更新内容
|
||||
IsAttach bool // 是否是附件, 不是附件就是图片
|
||||
}
|
||||
type ApiNote struct {
|
||||
NoteId string
|
||||
@@ -22,32 +22,31 @@ type ApiNote struct {
|
||||
UserId string
|
||||
Title string
|
||||
Desc string
|
||||
// ImgSrc string
|
||||
// ImgSrc string
|
||||
Tags []string
|
||||
Abstract string
|
||||
Content string
|
||||
IsMarkdown bool
|
||||
// FromUserId string // 为共享而新建
|
||||
IsBlog bool // 是否是blog, 更新note不需要修改, 添加note时才有可能用到, 此时需要判断notebook是否设为Blog
|
||||
IsTrash bool
|
||||
IsDeleted bool
|
||||
Usn int
|
||||
Files []NoteFile
|
||||
// FromUserId string // 为共享而新建
|
||||
IsBlog bool // 是否是blog, 更新note不需要修改, 添加note时才有可能用到, 此时需要判断notebook是否设为Blog
|
||||
IsTrash bool
|
||||
IsDeleted bool
|
||||
Usn int
|
||||
Files []NoteFile
|
||||
CreatedTime time.Time
|
||||
UpdatedTime time.Time
|
||||
PublicTime time.Time
|
||||
PublicTime time.Time
|
||||
}
|
||||
|
||||
|
||||
// 内容
|
||||
type ApiNoteContent struct {
|
||||
NoteId bson.ObjectId `bson:"_id,omitempty"`
|
||||
UserId bson.ObjectId `bson:"UserId"`
|
||||
|
||||
Content string `Content`
|
||||
Content string `Content`
|
||||
|
||||
// CreatedTime time.Time `CreatedTime`
|
||||
// UpdatedTime time.Time `UpdatedTime`
|
||||
// CreatedTime time.Time `CreatedTime`
|
||||
// UpdatedTime time.Time `UpdatedTime`
|
||||
}
|
||||
|
||||
// 转换
|
||||
@@ -61,11 +60,11 @@ func NoteToApiNote(note Note, files []NoteFile) ApiNote {
|
||||
//----------
|
||||
|
||||
type ApiUser struct {
|
||||
UserId string
|
||||
UserId string
|
||||
Username string
|
||||
Email string
|
||||
Email string
|
||||
Verified bool
|
||||
Logo string
|
||||
Logo string
|
||||
}
|
||||
|
||||
//----------
|
||||
@@ -81,8 +80,8 @@ type ApiNotebook struct {
|
||||
IsBlog bool `IsBlog,omitempty` // 是否是Blog 2013/12/29 新加
|
||||
CreatedTime time.Time `CreatedTime,omitempty`
|
||||
UpdatedTime time.Time `UpdatedTime,omitempty`
|
||||
Usn int `Usn` // UpdateSequenceNum
|
||||
IsDeleted bool `IsDeleted`
|
||||
Usn int `Usn` // UpdateSequenceNum
|
||||
IsDeleted bool `IsDeleted`
|
||||
}
|
||||
|
||||
//---------
|
||||
@@ -91,7 +90,7 @@ type ApiNotebook struct {
|
||||
|
||||
// 一般返回
|
||||
type ApiRe struct {
|
||||
Ok bool
|
||||
Ok bool
|
||||
Msg string
|
||||
}
|
||||
|
||||
@@ -101,19 +100,20 @@ func NewApiRe() ApiRe {
|
||||
|
||||
// auth
|
||||
type AuthOk struct {
|
||||
Ok bool
|
||||
Token string
|
||||
UserId bson.ObjectId
|
||||
Email string
|
||||
Ok bool
|
||||
Token string
|
||||
UserId bson.ObjectId
|
||||
Email string
|
||||
Username string
|
||||
}
|
||||
|
||||
// 供notebook, note, tag更新的返回数据用
|
||||
type ReUpdate struct {
|
||||
Ok bool
|
||||
Ok bool
|
||||
Msg string
|
||||
Usn int
|
||||
}
|
||||
|
||||
func NewReUpdate() ReUpdate {
|
||||
return ReUpdate{Ok: false}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,15 +7,15 @@ import (
|
||||
|
||||
// Attach belongs to note
|
||||
type Attach struct {
|
||||
AttachId bson.ObjectId `bson:"_id,omitempty"` //
|
||||
NoteId bson.ObjectId `bson:"NoteId"` //
|
||||
UploadUserId bson.ObjectId `bson:"UploadUserId"` // 可以不是note owner, 协作者userId
|
||||
Name string `Name` // file name, md5, such as 13232312.doc
|
||||
Title string `Title` // raw file name
|
||||
Size int64 `Size` // file size (byte)
|
||||
Type string `Type` // file type, "doc" = word
|
||||
Path string `Path` // the file path such as: files/userId/attachs/adfadf.doc
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
|
||||
AttachId bson.ObjectId `bson:"_id,omitempty"` //
|
||||
NoteId bson.ObjectId `bson:"NoteId"` //
|
||||
UploadUserId bson.ObjectId `bson:"UploadUserId"` // 可以不是note owner, 协作者userId
|
||||
Name string `Name` // file name, md5, such as 13232312.doc
|
||||
Title string `Title` // raw file name
|
||||
Size int64 `Size` // file size (byte)
|
||||
Type string `Type` // file type, "doc" = word
|
||||
Path string `Path` // the file path such as: files/userId/attachs/adfadf.doc
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
|
||||
// FromFileId bson.ObjectId `bson:"FromFileId,omitempty"` // copy from fileId, for collaboration
|
||||
}
|
||||
|
||||
@@ -7,51 +7,52 @@ import (
|
||||
// 仅仅为了博客的主题
|
||||
|
||||
type BlogInfoCustom struct {
|
||||
UserId string
|
||||
Username string
|
||||
UserLogo string
|
||||
Title string
|
||||
SubTitle string
|
||||
Logo string
|
||||
UserId string
|
||||
Username string
|
||||
UserLogo string
|
||||
Title string
|
||||
SubTitle string
|
||||
Logo string
|
||||
OpenComment bool
|
||||
CommentType string
|
||||
ThemeId string
|
||||
SubDomain string
|
||||
Domain string
|
||||
ThemeId string
|
||||
SubDomain string
|
||||
Domain string
|
||||
}
|
||||
|
||||
type Post struct {
|
||||
NoteId string
|
||||
Title string
|
||||
UrlTitle string
|
||||
ImgSrc string
|
||||
NoteId string
|
||||
Title string
|
||||
UrlTitle string
|
||||
ImgSrc string
|
||||
CreatedTime time.Time
|
||||
UpdatedTime time.Time
|
||||
PublicTime time.Time
|
||||
Desc string
|
||||
Abstract string
|
||||
Content string
|
||||
Tags []string
|
||||
CommentNum int
|
||||
ReadNum int
|
||||
LikeNum int
|
||||
IsMarkdown bool
|
||||
PublicTime time.Time
|
||||
Desc string
|
||||
Abstract string
|
||||
Content string
|
||||
Tags []string
|
||||
CommentNum int
|
||||
ReadNum int
|
||||
LikeNum int
|
||||
IsMarkdown bool
|
||||
}
|
||||
|
||||
// 归档
|
||||
type ArchiveMonth struct {
|
||||
Month int
|
||||
Posts []*Post
|
||||
}
|
||||
type Archive struct {
|
||||
Year int
|
||||
Year int
|
||||
MonthAchives []ArchiveMonth
|
||||
Posts []*Post
|
||||
Posts []*Post
|
||||
}
|
||||
|
||||
type Cate struct {
|
||||
CateId string
|
||||
CateId string
|
||||
ParentCateId string
|
||||
Title string
|
||||
UrlTitle string
|
||||
Children []*Cate
|
||||
Title string
|
||||
UrlTitle string
|
||||
Children []*Cate
|
||||
}
|
||||
|
||||
@@ -9,17 +9,17 @@ import (
|
||||
|
||||
type BlogItem struct {
|
||||
Note
|
||||
Abstract string
|
||||
Content string // 可能是content的一部分, 截取. 点击more后就是整个信息了
|
||||
HasMore bool // 是否是否还有
|
||||
User User // 用户信息
|
||||
Abstract string
|
||||
Content string // 可能是content的一部分, 截取. 点击more后就是整个信息了
|
||||
HasMore bool // 是否是否还有
|
||||
User User // 用户信息
|
||||
}
|
||||
|
||||
type UserBlogBase struct {
|
||||
Logo string `Logo`
|
||||
Title string `Title` // 标题
|
||||
SubTitle string `SubTitle` // 副标题
|
||||
// AboutMe string `AboutMe` // 关于我
|
||||
// AboutMe string `AboutMe` // 关于我
|
||||
}
|
||||
|
||||
type UserBlogComment struct {
|
||||
@@ -49,32 +49,32 @@ type UserBlog struct {
|
||||
Style string `Style` // 风格
|
||||
Css string `Css` // 自定义css
|
||||
|
||||
ThemeId bson.ObjectId `ThemeId,omitempty` // 主题Id
|
||||
ThemePath string `bson:"ThemePath" json:"-"` // 不存值, 从Theme中获取, 相对路径 public/
|
||||
ThemeId bson.ObjectId `ThemeId,omitempty` // 主题Id
|
||||
ThemePath string `bson:"ThemePath" json:"-"` // 不存值, 从Theme中获取, 相对路径 public/
|
||||
|
||||
CateIds []string `CateIds,omitempty` // 分类Id, 排序好的
|
||||
Singles []map[string]string `Singles,omitempty` // 单页, 排序好的, map包含: ["Title"], ["SingleId"]
|
||||
|
||||
PerPageSize int `PerPageSize,omitempty`
|
||||
SortField string `SortField` // 排序字段
|
||||
IsAsc bool `IsAsc,omitempty` // 排序类型, 降序, 升序, 默认是false, 表示降序
|
||||
Singles []map[string]string `Singles,omitempty` // 单页, 排序好的, map包含: ["Title"], ["SingleId"]
|
||||
|
||||
PerPageSize int `PerPageSize,omitempty`
|
||||
SortField string `SortField` // 排序字段
|
||||
IsAsc bool `IsAsc,omitempty` // 排序类型, 降序, 升序, 默认是false, 表示降序
|
||||
|
||||
SubDomain string `SubDomain` // 二级域名
|
||||
Domain string `Domain` // 自定义域名
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 博客统计信息
|
||||
type BlogStat struct {
|
||||
NoteId bson.ObjectId `bson:"_id,omitempty"`
|
||||
ReadNum int `ReadNum,omitempty` // 阅读次数 2014/9/28
|
||||
LikeNum int `LikeNum,omitempty` // 点赞次数 2014/9/28
|
||||
CommentNum int `CommentNum,omitempty` // 评论次数 2014/9/28
|
||||
NoteId bson.ObjectId `bson:"_id,omitempty"`
|
||||
ReadNum int `ReadNum,omitempty` // 阅读次数 2014/9/28
|
||||
LikeNum int `LikeNum,omitempty` // 点赞次数 2014/9/28
|
||||
CommentNum int `CommentNum,omitempty` // 评论次数 2014/9/28
|
||||
}
|
||||
|
||||
// 单页
|
||||
type BlogSingle struct {
|
||||
SingleId bson.ObjectId `bson:"_id,omitempty"`
|
||||
SingleId bson.ObjectId `bson:"_id,omitempty"`
|
||||
UserId bson.ObjectId `UserId`
|
||||
Title string `Title`
|
||||
UrlTitle string `UrlTitle` // 2014/11/11
|
||||
@@ -117,12 +117,12 @@ type BlogCommentPublic struct {
|
||||
}
|
||||
|
||||
type BlogUrls struct {
|
||||
IndexUrl string
|
||||
CateUrl string
|
||||
SearchUrl string
|
||||
SingleUrl string
|
||||
PostUrl string
|
||||
ArchiveUrl string
|
||||
TagsUrl string
|
||||
IndexUrl string
|
||||
CateUrl string
|
||||
SearchUrl string
|
||||
SingleUrl string
|
||||
PostUrl string
|
||||
ArchiveUrl string
|
||||
TagsUrl string
|
||||
TagPostsUrl string
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ type Config struct {
|
||||
ConfigId bson.ObjectId `bson:"_id"`
|
||||
UserId bson.ObjectId `UserId`
|
||||
Key string `Key`
|
||||
ValueStr string `ValueStr,omitempty` // "1"
|
||||
ValueArr []string `ValueArr,omitempty` // ["1","b","c"]
|
||||
ValueMap map[string]string `ValueMap,omitempty` // {"a":"bb", "CC":"xx"}
|
||||
ValueStr string `ValueStr,omitempty` // "1"
|
||||
ValueArr []string `ValueArr,omitempty` // ["1","b","c"]
|
||||
ValueMap map[string]string `ValueMap,omitempty` // {"a":"bb", "CC":"xx"}
|
||||
ValueArrMap []map[string]string `ValueArrMap,omitempty` // [{"a":"B"}, {}, {}]
|
||||
IsArr bool `IsArr` // 是否是数组
|
||||
IsMap bool `IsMap` // 是否是Map
|
||||
|
||||
@@ -9,4 +9,4 @@ type NoteImage struct {
|
||||
NoteImageId bson.ObjectId `bson:"_id,omitempty"` // 必须要设置bson:"_id" 不然mgo不会认为是主键
|
||||
NoteId bson.ObjectId `bson:"NoteId"` // 笔记
|
||||
ImageId bson.ObjectId `bson:"ImageId"` // 图片fileId
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,15 +34,15 @@ type Note struct {
|
||||
IsMarkdown bool `IsMarkdown` // 是否是markdown笔记, 默认是false
|
||||
|
||||
AttachNum int `AttachNum` // 2014/9/21, attachments num
|
||||
|
||||
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
UpdatedTime time.Time `UpdatedTime`
|
||||
RecommendTime time.Time `RecommendTime,omitempty` // 推荐时间
|
||||
PublicTime time.Time `PublicTime,omitempty` // 发表时间, 公开为博客则设置
|
||||
UpdatedUserId bson.ObjectId `bson:"UpdatedUserId"` // 如果共享了, 并可写, 那么可能是其它他修改了
|
||||
|
||||
|
||||
// 2015/1/15, 更新序号
|
||||
Usn int `Usn` // UpdateSequenceNum
|
||||
Usn int `Usn` // UpdateSequenceNum
|
||||
|
||||
IsDeleted bool `IsDeleted` // 删除位
|
||||
}
|
||||
@@ -80,3 +80,24 @@ type NoteContentHistory struct {
|
||||
UserId bson.ObjectId `bson:"UserId"` // 所属者
|
||||
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
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ type Notebook struct {
|
||||
IsBlog bool `IsBlog,omitempty` // 是否是Blog 2013/12/29 新加
|
||||
CreatedTime time.Time `CreatedTime,omitempty`
|
||||
UpdatedTime time.Time `UpdatedTime,omitempty`
|
||||
|
||||
|
||||
// 2015/1/15, 更新序号
|
||||
Usn int `Usn` // UpdateSequenceNum
|
||||
Usn int `Usn` // UpdateSequenceNum
|
||||
IsDeleted bool `IsDeleted`
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
package info
|
||||
|
||||
import (
|
||||
)
|
||||
import ()
|
||||
|
||||
// controller ajax返回
|
||||
type Re struct {
|
||||
Ok bool
|
||||
Ok bool
|
||||
Code int
|
||||
Msg string
|
||||
Id string
|
||||
Msg string
|
||||
Id string
|
||||
List interface{}
|
||||
Item interface{}
|
||||
}
|
||||
|
||||
func NewRe() Re {
|
||||
return Re{Ok: false}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ type Session struct {
|
||||
|
||||
LoginTimes int `LoginTimes` // 登录错误时间
|
||||
Captcha string `Captcha` // 验证码
|
||||
|
||||
UserId string `UserId` // API时有值UserId
|
||||
|
||||
UserId string `UserId` // API时有值UserId
|
||||
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
UpdatedTime time.Time `UpdatedTime` // 更新时间, expire这个时间会自动清空
|
||||
|
||||
@@ -18,28 +18,28 @@ type TagNote struct {
|
||||
|
||||
// 每个用户一条记录, 存储用户的所有tags
|
||||
type Tag struct {
|
||||
UserId bson.ObjectId `bson:"_id"`
|
||||
Tags []string `Tags`
|
||||
UserId bson.ObjectId `bson:"_id"`
|
||||
Tags []string `Tags`
|
||||
}
|
||||
|
||||
// v2 版标签
|
||||
type NoteTag struct {
|
||||
TagId bson.ObjectId `bson:"_id"`
|
||||
UserId bson.ObjectId `UserId` // 谁的
|
||||
Tag string `Tag` // UserId, Tag是唯一索引
|
||||
Usn int `Usn` // Update Sequence Number
|
||||
Count int `Count` // 笔记数
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
UpdatedTime time.Time `UpdatedTime`
|
||||
IsDeleted bool `IsDeleted` // 删除位
|
||||
TagId bson.ObjectId `bson:"_id"`
|
||||
UserId bson.ObjectId `UserId` // 谁的
|
||||
Tag string `Tag` // UserId, Tag是唯一索引
|
||||
Usn int `Usn` // Update Sequence Number
|
||||
Count int `Count` // 笔记数
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
UpdatedTime time.Time `UpdatedTime`
|
||||
IsDeleted bool `IsDeleted` // 删除位
|
||||
}
|
||||
|
||||
type TagCount struct {
|
||||
TagCountId bson.ObjectId `bson:"_id,omitempty"`
|
||||
UserId bson.ObjectId `UserId` // 谁的
|
||||
Tag string `Tag`
|
||||
IsBlog bool `IsBlog` // 是否是博客的tag统计
|
||||
Count int `Count` // 统计数量
|
||||
UserId bson.ObjectId `UserId` // 谁的
|
||||
Tag string `Tag`
|
||||
IsBlog bool `IsBlog` // 是否是博客的tag统计
|
||||
Count int `Count` // 统计数量
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -18,7 +18,7 @@ type Theme struct {
|
||||
Info map[string]interface{} `Info` // 所有信息
|
||||
IsActive bool `IsActive` // 是否在用
|
||||
|
||||
IsDefault bool `IsDefault` // leanote默认主题, 如果用户修改了默认主题, 则先copy之. 也是admin用户的主题
|
||||
IsDefault bool `IsDefault` // leanote默认主题, 如果用户修改了默认主题, 则先copy之. 也是admin用户的主题
|
||||
Style string `Style,omitempty` // 之前的, 只有default的用户才有blog_default, blog_daqi, blog_left_fixed
|
||||
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
|
||||
@@ -18,7 +18,7 @@ const (
|
||||
|
||||
// 过期时间
|
||||
const (
|
||||
PwdOverHours = 2.0
|
||||
PwdOverHours = 2.0
|
||||
ActiveEmailOverHours = 48.0
|
||||
UpdateEmailOverHours = 2.0
|
||||
)
|
||||
@@ -29,4 +29,4 @@ type Token struct {
|
||||
Token string `Token`
|
||||
Type int `Type`
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,8 +73,8 @@ type UserAccount struct {
|
||||
// note主页需要
|
||||
type UserAndBlogUrl struct {
|
||||
User
|
||||
BlogUrl string `BlogUrl`
|
||||
PostUrl string `PostUrl`
|
||||
BlogUrl string `BlogUrl`
|
||||
PostUrl string `PostUrl`
|
||||
}
|
||||
|
||||
// 用户与博客信息结合, 公开
|
||||
|
||||
@@ -4,14 +4,13 @@ import (
|
||||
"math"
|
||||
)
|
||||
|
||||
|
||||
// 分页数据
|
||||
type Page struct {
|
||||
CurPage int // 当前页码
|
||||
TotalPage int // 总页
|
||||
CurPage int // 当前页码
|
||||
TotalPage int // 总页
|
||||
PerPageSize int
|
||||
Count int // 总记录数
|
||||
List interface{}
|
||||
Count int // 总记录数
|
||||
List interface{}
|
||||
}
|
||||
|
||||
func NewPage(page, perPageSize, count int, list interface{}) Page {
|
||||
|
||||
280
app/init.go
280
app/init.go
@@ -1,77 +1,77 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/service"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"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/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/route"
|
||||
"reflect"
|
||||
"fmt"
|
||||
"github.com/leanote/leanote/app/service"
|
||||
"github.com/revel/revel"
|
||||
"html/template"
|
||||
"math"
|
||||
"strings"
|
||||
"strconv"
|
||||
"time"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Filters is the default set of global filters.
|
||||
revel.Filters = []revel.Filter{
|
||||
revel.PanicFilter, // Recover from panics and display an error page instead.
|
||||
revel.PanicFilter, // Recover from panics and display an error page instead.
|
||||
route.RouterFilter,
|
||||
// revel.RouterFilter, // Use the routing table to select the right Action
|
||||
// AuthFilter, // Invoke the action.
|
||||
revel.FilterConfiguringFilter, // A hook for adding or removing per-Action filters.
|
||||
revel.ParamsFilter, // Parse parameters into Controller.Params.
|
||||
revel.SessionFilter, // Restore and write the session cookie.
|
||||
|
||||
|
||||
// 使用SessionFilter标准版从cookie中得到sessionID, 然后通过MssessionFilter从Memcache中得到
|
||||
// session, 之后MSessionFilter将session只存sessionID然后返回给SessionFilter返回到web
|
||||
// session.SessionFilter, // leanote session
|
||||
// session.MSessionFilter, // leanote memcache session
|
||||
|
||||
revel.FlashFilter, // Restore and write the flash cookie.
|
||||
revel.ValidationFilter, // Restore kept validation errors and save new ones from cookie.
|
||||
revel.I18nFilter, // Resolve the requested language
|
||||
revel.InterceptorFilter, // Run interceptors around the action.
|
||||
revel.CompressFilter, // Compress the result.
|
||||
revel.ActionInvoker, // Invoke the action.
|
||||
// session.SessionFilter, // leanote session
|
||||
// session.MSessionFilter, // leanote memcache session
|
||||
|
||||
revel.FlashFilter, // Restore and write the flash cookie.
|
||||
revel.ValidationFilter, // Restore kept validation errors and save new ones from cookie.
|
||||
revel.I18nFilter, // Resolve the requested language
|
||||
revel.InterceptorFilter, // Run interceptors around the action.
|
||||
revel.CompressFilter, // Compress the result.
|
||||
revel.ActionInvoker, // Invoke the action.
|
||||
}
|
||||
|
||||
|
||||
revel.TemplateFuncs["raw"] = func(str string) template.HTML {
|
||||
return template.HTML(str)
|
||||
}
|
||||
revel.TemplateFuncs["trim"] = func(str string) string {
|
||||
str = strings.Trim(str, " ")
|
||||
str = strings.Trim(str, " ")
|
||||
|
||||
|
||||
str = strings.Trim(str, "\n")
|
||||
str = strings.Trim(str, " ")
|
||||
|
||||
|
||||
// 以下两个空格不一样
|
||||
str = strings.Trim(str, " ")
|
||||
str = strings.Trim(str, " ")
|
||||
return str
|
||||
}
|
||||
revel.TemplateFuncs["add"] = func(i int) string {
|
||||
i = i + 1;
|
||||
i = i + 1
|
||||
return fmt.Sprintf("%v", i)
|
||||
}
|
||||
revel.TemplateFuncs["sub"] = func(i int) int {
|
||||
i = i - 1;
|
||||
i = i - 1
|
||||
return i
|
||||
}
|
||||
// 增加或减少
|
||||
revel.TemplateFuncs["incr"] = func(n, i int) int {
|
||||
n = n + i;
|
||||
n = n + i
|
||||
return n
|
||||
}
|
||||
revel.TemplateFuncs["join"] = func(arr []string) template.HTML {
|
||||
@@ -95,11 +95,11 @@ func init() {
|
||||
return v.Get("a")
|
||||
}
|
||||
revel.TemplateFuncs["json"] = func(i interface{}) string {
|
||||
b, _ := json.Marshal(i)
|
||||
b, _ := json.Marshal(i)
|
||||
return string(b)
|
||||
}
|
||||
revel.TemplateFuncs["jsonJs"] = func(i interface{}) template.JS {
|
||||
b, _ := json.Marshal(i)
|
||||
b, _ := json.Marshal(i)
|
||||
return template.JS(string(b))
|
||||
}
|
||||
revel.TemplateFuncs["datetime"] = func(t time.Time) template.HTML {
|
||||
@@ -113,10 +113,10 @@ func init() {
|
||||
t := time.Unix(int64(sec), 0)
|
||||
return template.HTML(t.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
|
||||
|
||||
// interface是否有该字段
|
||||
revel.TemplateFuncs["has"] = func(i interface{}, key string) bool {
|
||||
t := reflect.TypeOf(i)
|
||||
t := reflect.TypeOf(i)
|
||||
_, ok := t.FieldByName(key)
|
||||
return ok
|
||||
}
|
||||
@@ -130,9 +130,9 @@ func init() {
|
||||
locale, _ := renderArgs[revel.CurrentLocaleRenderArg].(string)
|
||||
tagStr := ""
|
||||
lenTags := len(tags)
|
||||
|
||||
|
||||
tagPostUrl, _ := renderArgs["tagPostsUrl"].(string)
|
||||
|
||||
|
||||
for i, tag := range tags {
|
||||
str := revel.Message(locale, tag)
|
||||
var classes = "label"
|
||||
@@ -144,24 +144,24 @@ func init() {
|
||||
} else {
|
||||
classes += " label-default"
|
||||
}
|
||||
|
||||
|
||||
classes += " label-post"
|
||||
var url = tagPostUrl + "/" + url.QueryEscape(tag)
|
||||
tagStr += "<a class=\"" + classes + "\" href=\"" + url + "\">" + str + "</a>";
|
||||
if i != lenTags - 1 {
|
||||
tagStr += "<a class=\"" + classes + "\" href=\"" + url + "\">" + str + "</a>"
|
||||
if i != lenTags-1 {
|
||||
tagStr += " "
|
||||
}
|
||||
}
|
||||
return template.HTML(tagStr)
|
||||
}
|
||||
|
||||
|
||||
revel.TemplateFuncs["blogTagsForExport"] = func(renderArgs map[string]interface{}, tags []string) template.HTML {
|
||||
if tags == nil || len(tags) == 0 {
|
||||
return ""
|
||||
}
|
||||
tagStr := ""
|
||||
lenTags := len(tags)
|
||||
|
||||
|
||||
for i, tag := range tags {
|
||||
str := tag
|
||||
var classes = "label"
|
||||
@@ -170,16 +170,16 @@ func init() {
|
||||
} else {
|
||||
classes += " label-default"
|
||||
}
|
||||
|
||||
|
||||
classes += " label-post"
|
||||
tagStr += "<span class=\"" + classes + "\" >" + str + "</span>";
|
||||
if i != lenTags - 1 {
|
||||
tagStr += "<span class=\"" + classes + "\" >" + str + "</span>"
|
||||
if i != lenTags-1 {
|
||||
tagStr += " "
|
||||
}
|
||||
}
|
||||
return template.HTML(tagStr)
|
||||
}
|
||||
|
||||
|
||||
// 不用revel的msg
|
||||
revel.TemplateFuncs["leaMsg"] = func(renderArgs map[string]interface{}, key string) template.HTML {
|
||||
locale, _ := renderArgs[revel.CurrentLocaleRenderArg].(string)
|
||||
@@ -187,7 +187,7 @@ func init() {
|
||||
if strings.HasPrefix(str, "???") {
|
||||
str = key
|
||||
}
|
||||
return template.HTML(str);
|
||||
return template.HTML(str)
|
||||
}
|
||||
|
||||
// lea++
|
||||
@@ -198,16 +198,16 @@ func init() {
|
||||
locale, _ := renderArgs[revel.CurrentLocaleRenderArg].(string)
|
||||
tagStr := ""
|
||||
lenTags := len(tags)
|
||||
|
||||
|
||||
tagPostUrl := "http://lea.leanote.com/"
|
||||
if typeStr == "recommend" {
|
||||
tagPostUrl += "?tag=";
|
||||
tagPostUrl += "?tag="
|
||||
} else if typeStr == "latest" {
|
||||
tagPostUrl += "latest?tag=";
|
||||
tagPostUrl += "latest?tag="
|
||||
} else {
|
||||
tagPostUrl += "subscription?tag=";
|
||||
tagPostUrl += "subscription?tag="
|
||||
}
|
||||
|
||||
|
||||
for i, tag := range tags {
|
||||
str := revel.Message(locale, tag)
|
||||
var classes = "label"
|
||||
@@ -221,66 +221,66 @@ func init() {
|
||||
}
|
||||
classes += " label-post"
|
||||
var url = tagPostUrl + url.QueryEscape(tag)
|
||||
tagStr += "<a class=\"" + classes + "\" href=\"" + url + "\">" + str + "</a>";
|
||||
if i != lenTags - 1 {
|
||||
tagStr += "<a class=\"" + classes + "\" href=\"" + url + "\">" + str + "</a>"
|
||||
if i != lenTags-1 {
|
||||
tagStr += " "
|
||||
}
|
||||
}
|
||||
return template.HTML(tagStr)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
revel.TemplateFuncs["blogTags"] = func(tags []string) template.HTML {
|
||||
if tags == nil || len(tags) == 0 {
|
||||
return ""
|
||||
}
|
||||
// TODO 这里判断语言, 从语言包中拿
|
||||
tagMap := map[string]string{"red": "红色", "yellow": "黄色", "blue": "蓝色", "green": "绿色"}
|
||||
tagStr := ""
|
||||
lenTags := len(tags)
|
||||
for i, tag := range tags {
|
||||
if text, ok := tagMap[tag]; ok {
|
||||
tagStr += text
|
||||
} else {
|
||||
tagStr += tag
|
||||
revel.TemplateFuncs["blogTags"] = func(tags []string) template.HTML {
|
||||
if tags == nil || len(tags) == 0 {
|
||||
return ""
|
||||
}
|
||||
if i != lenTags - 1 {
|
||||
tagStr += ","
|
||||
// TODO 这里判断语言, 从语言包中拿
|
||||
tagMap := map[string]string{"red": "红色", "yellow": "黄色", "blue": "蓝色", "green": "绿色"}
|
||||
tagStr := ""
|
||||
lenTags := len(tags)
|
||||
for i, tag := range tags {
|
||||
if text, ok := tagMap[tag]; ok {
|
||||
tagStr += text
|
||||
} else {
|
||||
tagStr += tag
|
||||
}
|
||||
if i != lenTags - 1 {
|
||||
tagStr += ","
|
||||
}
|
||||
}
|
||||
return template.HTML(tagStr)
|
||||
}
|
||||
return template.HTML(tagStr)
|
||||
}
|
||||
*/
|
||||
revel.TemplateFuncs["li"] = func(a string) string {
|
||||
return ""
|
||||
}
|
||||
// str连接
|
||||
revel.TemplateFuncs["urlConcat"] = func(url string, v... interface{}) string {
|
||||
revel.TemplateFuncs["urlConcat"] = func(url string, v ...interface{}) string {
|
||||
html := ""
|
||||
for i := 0; i < len(v); i = i + 2 {
|
||||
item := v[i]
|
||||
if i+1 == len(v) {
|
||||
break;
|
||||
break
|
||||
}
|
||||
value := v[i+1]
|
||||
if item != nil && value != nil {
|
||||
keyStr, _ := item.(string)
|
||||
valueStr, err := value.(string)
|
||||
if !err {
|
||||
valueInt, _ := value.(int)
|
||||
valueStr = strconv.Itoa(valueInt)
|
||||
}
|
||||
if keyStr != "" && valueStr != "" {
|
||||
s := keyStr + "=" + valueStr
|
||||
if html != "" {
|
||||
html += "&" + s
|
||||
} else {
|
||||
html += s
|
||||
}
|
||||
}
|
||||
}
|
||||
keyStr, _ := item.(string)
|
||||
valueStr, err := value.(string)
|
||||
if !err {
|
||||
valueInt, _ := value.(int)
|
||||
valueStr = strconv.Itoa(valueInt)
|
||||
}
|
||||
if keyStr != "" && valueStr != "" {
|
||||
s := keyStr + "=" + valueStr
|
||||
if html != "" {
|
||||
html += "&" + s
|
||||
} else {
|
||||
html += s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if html != "" {
|
||||
if strings.Index(url, "?") >= 0 {
|
||||
return url + "&" + html
|
||||
@@ -290,11 +290,11 @@ func init() {
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
|
||||
revel.TemplateFuncs["urlCond"] = func(url string, sorterI, keyords interface{}) template.HTML {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
// http://stackoverflow.com/questions/14226416/go-lang-templates-always-quotes-a-string-and-removes-comments
|
||||
revel.TemplateFuncs["rawMsg"] = func(renderArgs map[string]interface{}, message string, args ...interface{}) template.JS {
|
||||
str, ok := renderArgs[revel.CurrentLocaleRenderArg].(string)
|
||||
@@ -303,38 +303,38 @@ func init() {
|
||||
}
|
||||
return template.JS(revel.Message(str, message, args...))
|
||||
}
|
||||
|
||||
|
||||
// 为后台管理sorter th使用
|
||||
// 必须要返回HTMLAttr, 返回html, golang 会执行安全检查返回ZgotmplZ
|
||||
// sorterI 可能是nil, 所以用interfalce{}来接收
|
||||
/*
|
||||
data-url="/adminUser/index"
|
||||
data-sorter="email"
|
||||
class="th-sortable {{if eq .sorter "email-up"}}th-sort-up{{else}}{{if eq .sorter "email-down"}}th-sort-down{{end}}{{end}}"
|
||||
data-url="/adminUser/index"
|
||||
data-sorter="email"
|
||||
class="th-sortable {{if eq .sorter "email-up"}}th-sort-up{{else}}{{if eq .sorter "email-down"}}th-sort-down{{end}}{{end}}"
|
||||
*/
|
||||
revel.TemplateFuncs["sorterTh"] = func(url, sorterField string, sorterI interface{}) template.HTMLAttr {
|
||||
sorter := ""
|
||||
if sorterI != nil {
|
||||
sorter, _ = sorterI.(string)
|
||||
}
|
||||
html := "data-url=\"" + url + "\" data-sorter=\"" + sorterField + "\"";
|
||||
html += " class=\"th-sortable ";
|
||||
if sorter == sorterField + "-up" {
|
||||
html += "th-sort-up\"";
|
||||
} else if(sorter == sorterField + "-down") {
|
||||
html += "th-sort-down";
|
||||
html := "data-url=\"" + url + "\" data-sorter=\"" + sorterField + "\""
|
||||
html += " class=\"th-sortable "
|
||||
if sorter == sorterField+"-up" {
|
||||
html += "th-sort-up\""
|
||||
} else if sorter == sorterField+"-down" {
|
||||
html += "th-sort-down"
|
||||
}
|
||||
html += "\"";
|
||||
html += "\""
|
||||
return template.HTMLAttr(html)
|
||||
}
|
||||
|
||||
|
||||
// pagination
|
||||
revel.TemplateFuncs["page"] = func(urlBase string, page, pageSize, count int) template.HTML {
|
||||
if count == 0 {
|
||||
return "";
|
||||
return ""
|
||||
}
|
||||
totalPage := int(math.Ceil(float64(count)/float64(pageSize)))
|
||||
|
||||
totalPage := int(math.Ceil(float64(count) / float64(pageSize)))
|
||||
|
||||
preClass := ""
|
||||
prePage := page - 1
|
||||
if prePage == 0 {
|
||||
@@ -343,10 +343,10 @@ func init() {
|
||||
nextClass := ""
|
||||
nextPage := page + 1
|
||||
var preUrl, nextUrl string
|
||||
|
||||
preUrl = urlBase + "?page=" + strconv.Itoa(prePage)
|
||||
|
||||
preUrl = urlBase + "?page=" + strconv.Itoa(prePage)
|
||||
nextUrl = urlBase + "?page=" + strconv.Itoa(nextPage)
|
||||
|
||||
|
||||
// 没有上一页了
|
||||
if page == 1 {
|
||||
preClass = "disabled"
|
||||
@@ -364,49 +364,49 @@ func init() {
|
||||
// http://play.golang.org/p/snygrVpQva
|
||||
// http://grokbase.com/t/gg/golang-nuts/142a6dhfh3/go-nuts-text-template-using-comparison-operators-eq-gt-etc-on-non-existent-variable-causes-the-template-to-stop-outputting-but-with-no-error-correct-behaviour
|
||||
/*
|
||||
revel.TemplateFuncs["gt"] = func(a1, a2 interface{}) bool {
|
||||
switch a1.(type) {
|
||||
case string:
|
||||
switch a2.(type) {
|
||||
revel.TemplateFuncs["gt"] = func(a1, a2 interface{}) bool {
|
||||
switch a1.(type) {
|
||||
case string:
|
||||
return reflect.ValueOf(a1).String() > reflect.ValueOf(a2).String()
|
||||
}
|
||||
case int, int8, int16, int32, int64:
|
||||
switch a2.(type) {
|
||||
switch a2.(type) {
|
||||
case string:
|
||||
return reflect.ValueOf(a1).String() > reflect.ValueOf(a2).String()
|
||||
}
|
||||
case int, int8, int16, int32, int64:
|
||||
return reflect.ValueOf(a1).Int() > reflect.ValueOf(a2).Int()
|
||||
}
|
||||
case uint, uint8, uint16, uint32, uint64:
|
||||
switch a2.(type) {
|
||||
switch a2.(type) {
|
||||
case int, int8, int16, int32, int64:
|
||||
return reflect.ValueOf(a1).Int() > reflect.ValueOf(a2).Int()
|
||||
}
|
||||
case uint, uint8, uint16, uint32, uint64:
|
||||
return reflect.ValueOf(a1).Uint() > reflect.ValueOf(a2).Uint()
|
||||
}
|
||||
case float32, float64:
|
||||
switch a2.(type) {
|
||||
switch a2.(type) {
|
||||
case uint, uint8, uint16, uint32, uint64:
|
||||
return reflect.ValueOf(a1).Uint() > reflect.ValueOf(a2).Uint()
|
||||
}
|
||||
case float32, float64:
|
||||
return reflect.ValueOf(a1).Float() > reflect.ValueOf(a2).Float()
|
||||
switch a2.(type) {
|
||||
case float32, float64:
|
||||
return reflect.ValueOf(a1).Float() > reflect.ValueOf(a2).Float()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
{{range $i := N 1 10}}
|
||||
<div>{{$i}}</div>
|
||||
{{end}}
|
||||
*/
|
||||
{{range $i := N 1 10}}
|
||||
<div>{{$i}}</div>
|
||||
{{end}}
|
||||
*/
|
||||
revel.TemplateFuncs["N"] = func(start, end int) (stream chan int) {
|
||||
stream = make(chan int)
|
||||
go func() {
|
||||
for i := start; i <= end; i++ {
|
||||
stream <- i
|
||||
}
|
||||
close(stream)
|
||||
}()
|
||||
return
|
||||
stream = make(chan int)
|
||||
go func() {
|
||||
for i := start; i <= end; i++ {
|
||||
stream <- i
|
||||
}
|
||||
close(stream)
|
||||
}()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// init Email
|
||||
revel.OnAppStart(func() {
|
||||
// 数据库
|
||||
|
||||
@@ -2,8 +2,8 @@ package lea
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/revel/revel"
|
||||
"fmt"
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
func Log(i interface{}) {
|
||||
@@ -11,7 +11,7 @@ func Log(i interface{}) {
|
||||
}
|
||||
|
||||
func LogJ(i interface{}) {
|
||||
b, _ := json.MarshalIndent(i, "", " ")
|
||||
b, _ := json.MarshalIndent(i, "", " ")
|
||||
revel.INFO.Println(string(b))
|
||||
}
|
||||
|
||||
@@ -21,6 +21,6 @@ func L(i interface{}) {
|
||||
}
|
||||
|
||||
func LJ(i interface{}) {
|
||||
b, _ := json.MarshalIndent(i, "", " ")
|
||||
b, _ := json.MarshalIndent(i, "", " ")
|
||||
fmt.Println(string(b))
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package lea
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
// 发送邮件
|
||||
var host = "smtp.ym.163.com"
|
||||
var port = "25"
|
||||
@@ -12,7 +13,7 @@ var username = "noreply@leanote.com"
|
||||
var password = "---"
|
||||
|
||||
func InitEmail() {
|
||||
config := revel.Config;
|
||||
config := revel.Config
|
||||
host, _ = config.String("email.host")
|
||||
port, _ = config.String("email.port")
|
||||
username, _ = config.String("email.username")
|
||||
@@ -56,26 +57,27 @@ var bodyTpl = `
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
func SendEmailOld(to, subject, body string) bool {
|
||||
hp := strings.Split(host, ":")
|
||||
auth := smtp.PlainAuth("", username, password, hp[0])
|
||||
|
||||
|
||||
var content_type string
|
||||
|
||||
|
||||
mailtype := "html"
|
||||
if mailtype == "html" {
|
||||
content_type = "Content-Type: text/"+ mailtype + "; charset=UTF-8"
|
||||
} else{
|
||||
content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
|
||||
} else {
|
||||
content_type = "Content-Type: text/plain" + "; charset=UTF-8"
|
||||
}
|
||||
|
||||
|
||||
//body = strings.Replace(bodyTpl, "$body", body, 1)
|
||||
//body = strings.Replace(body, "$title", title, 1)
|
||||
|
||||
msg := []byte("To: " + to + "\r\nFrom: " + username + "<"+ username +">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
|
||||
msg := []byte("To: " + to + "\r\nFrom: " + username + "<" + username + ">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
|
||||
send_to := strings.Split(to, ";")
|
||||
err := smtp.SendMail(host+":"+port, auth, username, send_to, msg)
|
||||
|
||||
|
||||
if err != nil {
|
||||
Log(err)
|
||||
return false
|
||||
@@ -85,5 +87,5 @@ func SendEmailOld(to, subject, body string) bool {
|
||||
|
||||
func SendToLeanoteOld(subject, title, body string) {
|
||||
to := "leanote@leanote.com"
|
||||
SendEmailOld(to, subject, body);
|
||||
}
|
||||
SendEmailOld(to, subject, body)
|
||||
}
|
||||
|
||||
@@ -116,13 +116,13 @@ func CopyDir(source string, dest string) (err error) {
|
||||
// create sub-directories - recursively
|
||||
err = CopyDir(sourcefilepointer, destinationfilepointer)
|
||||
if err != nil {
|
||||
// fmt.Println(err)
|
||||
// fmt.Println(err)
|
||||
}
|
||||
} else {
|
||||
// perform copy
|
||||
_, err = CopyFile(sourcefilepointer, destinationfilepointer)
|
||||
if err != nil {
|
||||
// fmt.Println(err)
|
||||
// fmt.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPat
|
||||
transPath = path
|
||||
wand.Genesis()
|
||||
defer wand.Terminus()
|
||||
|
||||
|
||||
w := wand.NewMagickWand()
|
||||
defer w.Destroy()
|
||||
|
||||
@@ -24,7 +24,7 @@ func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPat
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
width := w.ImageWidth()
|
||||
height := w.ImageHeight()
|
||||
if maxWidth != 0 {
|
||||
@@ -34,14 +34,14 @@ func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPat
|
||||
width = maxWidth
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
w.SetImageFormat("GIF");
|
||||
|
||||
if err := paint.Thumbnail(w, width, height); err != nil {
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 判断是否是gif图片, 是就不用转换了
|
||||
baseName, ext := SplitFilename(path)
|
||||
var toPath string
|
||||
@@ -50,19 +50,19 @@ func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPat
|
||||
} else {
|
||||
toPath = TransferExt(path, ".gif");
|
||||
}
|
||||
|
||||
|
||||
if err := w.WriteImage(toPath); err != nil {
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if afterDelete {
|
||||
os.Remove(path)
|
||||
}
|
||||
|
||||
|
||||
ok = true
|
||||
transPath = toPath
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPat
|
||||
func Reset(path string, maxWidth uint) (ok bool, transPath string){
|
||||
wand.Genesis()
|
||||
defer wand.Terminus()
|
||||
|
||||
|
||||
w := wand.NewMagickWand()
|
||||
defer w.Destroy()
|
||||
|
||||
@@ -79,7 +79,7 @@ func Reset(path string, maxWidth uint) (ok bool, transPath string){
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
width := w.ImageWidth()
|
||||
height := w.ImageHeight()
|
||||
if maxWidth != 0 {
|
||||
@@ -93,20 +93,20 @@ func Reset(path string, maxWidth uint) (ok bool, transPath string){
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
toPath := TransferExt(path, ".gif");
|
||||
if err := w.WriteImage(toPath); err != nil {
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ok = true
|
||||
transPath = toPath
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPath string) {
|
||||
return ok, path
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ func ComparePwd(rawPwd, dbPwd string) bool {
|
||||
if len(dbPwd) == 32 {
|
||||
return Md5(rawPwd) == dbPwd
|
||||
}
|
||||
|
||||
|
||||
hex := []byte(dbPwd)
|
||||
return CompareHash(hex, rawPwd)
|
||||
}
|
||||
@@ -19,4 +19,4 @@ func GenPwd(rawPwd string) string {
|
||||
return ""
|
||||
}
|
||||
return string(digest)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package lea
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"strings"
|
||||
"fmt"
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"bytes"
|
||||
math_rand "math/rand"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"io"
|
||||
math_rand "math/rand"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 字符串
|
||||
@@ -31,14 +31,14 @@ func Digest3(str string) string {
|
||||
for _, k := range str {
|
||||
b += k
|
||||
}
|
||||
return fmt.Sprintf("%d", b % 1000)
|
||||
return fmt.Sprintf("%d", b%1000)
|
||||
}
|
||||
func Digest2(str string) string {
|
||||
var b rune = 0
|
||||
for _, k := range str {
|
||||
b += k
|
||||
}
|
||||
return fmt.Sprintf("%d", b % 100)
|
||||
return fmt.Sprintf("%d", b%100)
|
||||
}
|
||||
|
||||
// Guid
|
||||
@@ -77,7 +77,7 @@ func Substr(str string, start, length int) string {
|
||||
func substr(str string, start, length int, isRune bool) string {
|
||||
rs := []rune(str)
|
||||
rs2 := []byte(str)
|
||||
|
||||
|
||||
rl := len(rs)
|
||||
if !isRune {
|
||||
rl = len(rs2)
|
||||
@@ -161,7 +161,7 @@ func SubStringHTMLToRaw(param string, length int) string {
|
||||
continue
|
||||
} else if temp == '>' {
|
||||
isCode = false
|
||||
resultRune[n] = ' ';
|
||||
resultRune[n] = ' '
|
||||
|
||||
n++
|
||||
if n >= length {
|
||||
@@ -170,7 +170,7 @@ func SubStringHTMLToRaw(param string, length int) string {
|
||||
continue
|
||||
}
|
||||
if !isCode {
|
||||
resultRune[n] = temp;
|
||||
resultRune[n] = temp
|
||||
// s += string(temp)
|
||||
n++
|
||||
if n >= length {
|
||||
@@ -192,13 +192,13 @@ func fixHtml(result string) string {
|
||||
|
||||
// 把<div class=xxx的class=xxx去掉
|
||||
tempResult = ReplaceAll(tempResult, "<(/?[a-zA-Z]+)[^<>]*>", "<$1>")
|
||||
|
||||
|
||||
// 3 只能用正则,+stack来去有结束的
|
||||
// golang的正则暂不支持back reference, 以后可以用它来去掉重复的标签
|
||||
p, _ := regexp.Compile("<(/?[a-zA-Z]+)[^<>]*>") // 得到所有的<div>, </div>...
|
||||
strs := p.FindAllString(tempResult, -1)
|
||||
|
||||
// fmt.Println(strs)
|
||||
// fmt.Println(strs)
|
||||
stack := make([]string, len(strs))
|
||||
stackP := -1
|
||||
for _, each := range strs {
|
||||
@@ -215,14 +215,14 @@ func fixHtml(result string) string {
|
||||
// 补全tag
|
||||
if stackP != -1 {
|
||||
fmt.Println(stack[0 : stackP+1])
|
||||
|
||||
|
||||
for _, each := range stack[0 : stackP+1] {
|
||||
if each[1] != '/' {
|
||||
result += "</" + each[1:]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -241,10 +241,10 @@ func SubStringHTML(param string, length int, end string) string {
|
||||
} else {
|
||||
// 1
|
||||
n := 0
|
||||
var temp rune // 中文问题, 用rune来解决
|
||||
var temp rune // 中文问题, 用rune来解决
|
||||
isCode := false //是不是HTML代码
|
||||
isHTML := false //是不是HTML特殊字符,如
|
||||
var i = 0;
|
||||
var i = 0
|
||||
for ; i < lenStr; i++ {
|
||||
temp = rStr[i]
|
||||
if temp == '<' {
|
||||
@@ -281,11 +281,11 @@ func SubStringHTML(param string, length int, end string) string {
|
||||
html, _ := dom.Html()
|
||||
html = strings.Replace(html, "<html><head></head><body>", "", 1)
|
||||
html = strings.Replace(html, "</body></html>", "", 1)
|
||||
|
||||
|
||||
// TODO 把style="float: left"去掉
|
||||
return html
|
||||
|
||||
// 如果有错误, 则使用自己的方法补全, 有风险
|
||||
|
||||
// 如果有错误, 则使用自己的方法补全, 有风险
|
||||
} else {
|
||||
return fixHtml(result)
|
||||
}
|
||||
@@ -305,7 +305,7 @@ func IsGoodPwd(pwd string) (bool, string) {
|
||||
// 是否是email
|
||||
func IsEmail(email string) bool {
|
||||
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)
|
||||
return ok
|
||||
@@ -314,7 +314,7 @@ func IsEmail(email string) bool {
|
||||
// 是否只包含数字, 字母 -, _
|
||||
func IsUsername(username string) bool {
|
||||
if username == "" {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
ok, _ := regexp.MatchString(`[^0-9a-zA-Z_\-]`, username)
|
||||
return !ok
|
||||
@@ -351,15 +351,15 @@ func RandomPwd(num int) string {
|
||||
chars[j] = byte(i)
|
||||
j++
|
||||
}
|
||||
j--;
|
||||
|
||||
j--
|
||||
|
||||
str := ""
|
||||
math_rand.Seed(time.Now().UnixNano())
|
||||
for i := 0; i < num; i++ {
|
||||
x := math_rand.Intn(j)
|
||||
str += string(chars[x])
|
||||
}
|
||||
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
@@ -379,14 +379,14 @@ func InArray(arr []string, str string) bool {
|
||||
func FixFilename(filename string) string {
|
||||
if filename != "" {
|
||||
// 把特殊字段给替换掉
|
||||
// str := `life "%&()+,/:;<>=?@\|`
|
||||
// str := `life "%&()+,/:;<>=?@\|`
|
||||
// . == \\.
|
||||
// $ === \\$
|
||||
reg, _ := regexp.Compile("\\.|/|#|\\$|!|\\^|\\*|'| |\"|%|&|\\(|\\)|\\+|\\,|/|:|;|<|>|=|\\?|@|\\||\\\\")
|
||||
filename = reg.ReplaceAllString(filename, "-")
|
||||
filename = strings.Trim(filename, "-") // 左右单独的-去掉
|
||||
// 把空格替换成-
|
||||
// filename = strings.Replace(filename, " ", "-", -1)
|
||||
// filename = strings.Replace(filename, " ", "-", -1)
|
||||
for strings.Index(filename, "--") >= 0 { // 防止出现连续的--
|
||||
filename = strings.Replace(filename, "--", "-", -1)
|
||||
}
|
||||
@@ -394,3 +394,40 @@ func FixFilename(filename string) string {
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package lea
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// 验证
|
||||
@@ -38,15 +38,15 @@ var rulesStr = `{
|
||||
`
|
||||
var rulesMap map[string][]map[string]string
|
||||
|
||||
var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
"required": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
var rules = map[string]func(string, map[string]string) (bool, string){
|
||||
"required": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
return
|
||||
},
|
||||
"minLength": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
"minLength": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
@@ -55,7 +55,7 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
ok = len(value) >= dataI
|
||||
return
|
||||
},
|
||||
"min": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
"min": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
@@ -65,8 +65,8 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
ok = vI >= dataI
|
||||
return
|
||||
},
|
||||
|
||||
"sortField": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
|
||||
"sortField": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
@@ -74,22 +74,22 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
ok = InArray(sortFields, value)
|
||||
return
|
||||
},
|
||||
|
||||
"password": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
|
||||
"password": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
ok = len(value) >= 6
|
||||
return
|
||||
},
|
||||
"email": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
"email": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
ok = IsEmail(value)
|
||||
return
|
||||
},
|
||||
"noSpecialChars": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
"noSpecialChars": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
@@ -97,8 +97,8 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
return
|
||||
},
|
||||
// www.baidu.com
|
||||
//
|
||||
"domain": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
//
|
||||
"domain": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
ok = true
|
||||
return // 可为空
|
||||
@@ -106,16 +106,16 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
ok2, _ := regexp.MatchString(`[^0-9a-zA-Z_\.\-]`, value)
|
||||
ok = !ok2
|
||||
if !ok {
|
||||
return
|
||||
return
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
},
|
||||
// abcd
|
||||
"subDomain": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
"subDomain": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
ok = true
|
||||
return // 可为空
|
||||
return // 可为空
|
||||
}
|
||||
if len(value) < 4 {
|
||||
ok = false
|
||||
@@ -137,7 +137,7 @@ func InitVd() {
|
||||
|
||||
func Vd(name, value string) (ok bool, msg string) {
|
||||
rs, _ := rulesMap[name]
|
||||
|
||||
|
||||
for _, rule := range rs {
|
||||
ruleFunc, _ := rules[rule["rule"]]
|
||||
if ok2, msg2 := ruleFunc(value, rule); !ok2 {
|
||||
@@ -151,11 +151,11 @@ func Vd(name, value string) (ok bool, msg string) {
|
||||
if msgData != "" {
|
||||
msg += "-" + msgData
|
||||
}
|
||||
return
|
||||
return
|
||||
}
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
func Vds(m map[string]string) (ok bool, msg string) {
|
||||
@@ -166,5 +166,5 @@ func Vds(m map[string]string) (ok bool, msg string) {
|
||||
}
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package archive
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// main functions shows how to TarGz a directory/file and
|
||||
@@ -16,66 +16,66 @@ import (
|
||||
|
||||
func main() {
|
||||
/*
|
||||
os.Mkdir("/home/ty4z2008/tar", 0777)
|
||||
w, err := CopyFile("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/src/1.pdf")
|
||||
//targetfile,sourcefile
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
fmt.Println(w)
|
||||
os.Mkdir("/home/ty4z2008/tar", 0777)
|
||||
w, err := CopyFile("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/src/1.pdf")
|
||||
//targetfile,sourcefile
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
fmt.Println(w)
|
||||
|
||||
TarGz("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/test.tar.gz") //压缩
|
||||
//UnTarGz("/home/ty4z2008/1.tar.gz", "/home/ty4z2008") //解压
|
||||
os.RemoveAll("/home/ty4z2008/tar")
|
||||
*/
|
||||
// TaZip("/Users/life/Desktop/j", "/Users/life/Desktop/aaa.tar.gz")
|
||||
Zip("/Users/life/Desktop/j", "/Users/life/Desktop/aaa.zip")
|
||||
fmt.Println("ok")
|
||||
TarGz("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/test.tar.gz") //压缩
|
||||
//UnTarGz("/home/ty4z2008/1.tar.gz", "/home/ty4z2008") //解压
|
||||
os.RemoveAll("/home/ty4z2008/tar")
|
||||
*/
|
||||
// TaZip("/Users/life/Desktop/j", "/Users/life/Desktop/aaa.tar.gz")
|
||||
Zip("/Users/life/Desktop/j", "/Users/life/Desktop/aaa.zip")
|
||||
fmt.Println("ok")
|
||||
}
|
||||
|
||||
func TarGz(srcDirPath string, destFilePath string) (ok bool) {
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
}
|
||||
|
||||
|
||||
}()
|
||||
|
||||
fw, err := os.Create(destFilePath)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fw.Close()
|
||||
fw, err := os.Create(destFilePath)
|
||||
|
||||
// Gzip writer
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
// Tar writer
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
// Gzip writer
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
|
||||
// Check if it's a file or a directory
|
||||
f, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
// handle source directory
|
||||
// fmt.Println("Cerating tar.gz from directory...")
|
||||
tarGzDir(srcDirPath, path.Base(srcDirPath), tw)
|
||||
} else {
|
||||
// handle file directly
|
||||
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
||||
tarGzFile(srcDirPath, fi.Name(), tw, fi)
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
// Tar writer
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
|
||||
// Check if it's a file or a directory
|
||||
f, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
// handle source directory
|
||||
// fmt.Println("Cerating tar.gz from directory...")
|
||||
tarGzDir(srcDirPath, path.Base(srcDirPath), tw)
|
||||
} else {
|
||||
// handle file directly
|
||||
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
||||
tarGzFile(srcDirPath, fi.Name(), tw, fi)
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// Deal with directories
|
||||
@@ -83,148 +83,148 @@ func TarGz(srcDirPath string, destFilePath string) (ok bool) {
|
||||
// Every recurrence append the base path to the recPath
|
||||
// recPath is the path inside of tar.gz
|
||||
func tarGzDir(srcDirPath string, recPath string, tw *tar.Writer) {
|
||||
// Open source diretory
|
||||
dir, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
// Open source diretory
|
||||
dir, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
|
||||
// Get file info slice
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, fi := range fis {
|
||||
// Append path
|
||||
curPath := srcDirPath + "/" + fi.Name()
|
||||
// Check it is directory or file
|
||||
if fi.IsDir() {
|
||||
// Directory
|
||||
// (Directory won't add unitl all subfiles are added)
|
||||
// fmt.Printf("Adding path...%s\n", curPath)
|
||||
tarGzDir(curPath, recPath+"/"+fi.Name(), tw)
|
||||
} else {
|
||||
// File
|
||||
// fmt.Printf("Adding file...%s\n", curPath)
|
||||
}
|
||||
// Get file info slice
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, fi := range fis {
|
||||
// Append path
|
||||
curPath := srcDirPath + "/" + fi.Name()
|
||||
// Check it is directory or file
|
||||
if fi.IsDir() {
|
||||
// Directory
|
||||
// (Directory won't add unitl all subfiles are added)
|
||||
// fmt.Printf("Adding path...%s\n", curPath)
|
||||
tarGzDir(curPath, recPath+"/"+fi.Name(), tw)
|
||||
} else {
|
||||
// File
|
||||
// fmt.Printf("Adding file...%s\n", curPath)
|
||||
}
|
||||
|
||||
tarGzFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
||||
}
|
||||
tarGzFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with files
|
||||
func tarGzFile(srcFile string, recPath string, tw *tar.Writer, fi os.FileInfo) {
|
||||
if fi.IsDir() {
|
||||
// fmt.Println("??")
|
||||
// Create tar header
|
||||
hdr := new(tar.Header)
|
||||
// if last character of header name is '/' it also can be directory
|
||||
// but if you don't set Typeflag, error will occur when you untargz
|
||||
hdr.Name = recPath // + "/"
|
||||
// fmt.Println(hdr.Name)
|
||||
hdr.Typeflag = tar.TypeDir
|
||||
// hdr.Size = 0
|
||||
//hdr.Mode = 0755 | c_ISDIR
|
||||
// hdr.Mode = int64(fi.Mode()) // 加这个会有错误!!!
|
||||
// hdr.ModTime = fi.ModTime() // 加这个会有错误!!
|
||||
if fi.IsDir() {
|
||||
// fmt.Println("??")
|
||||
// Create tar header
|
||||
hdr := new(tar.Header)
|
||||
// if last character of header name is '/' it also can be directory
|
||||
// but if you don't set Typeflag, error will occur when you untargz
|
||||
hdr.Name = recPath // + "/"
|
||||
// fmt.Println(hdr.Name)
|
||||
hdr.Typeflag = tar.TypeDir
|
||||
// hdr.Size = 0
|
||||
//hdr.Mode = 0755 | c_ISDIR
|
||||
// hdr.Mode = int64(fi.Mode()) // 加这个会有错误!!!
|
||||
// hdr.ModTime = fi.ModTime() // 加这个会有错误!!
|
||||
|
||||
// Write hander
|
||||
err := tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
// File reader
|
||||
fr, err := os.Open(srcFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
// Write hander
|
||||
err := tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
// File reader
|
||||
fr, err := os.Open(srcFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// Create tar header
|
||||
hdr := new(tar.Header)
|
||||
hdr.Name = recPath
|
||||
// fmt.Println(hdr.Name)
|
||||
hdr.Size = fi.Size()
|
||||
hdr.Mode = int64(fi.Mode())
|
||||
hdr.ModTime = fi.ModTime()
|
||||
// Create tar header
|
||||
hdr := new(tar.Header)
|
||||
hdr.Name = recPath
|
||||
// fmt.Println(hdr.Name)
|
||||
hdr.Size = fi.Size()
|
||||
hdr.Mode = int64(fi.Mode())
|
||||
hdr.ModTime = fi.ModTime()
|
||||
|
||||
// Write hander
|
||||
err = tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Write hander
|
||||
err = tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Write file data
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
// Write file data
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ungzip and untar from source file to destination directory
|
||||
// you need check file exist before you call this function
|
||||
func UnTarGz(srcFilePath string, destDirPath string) {
|
||||
// fmt.Println("UnTarGzing " + srcFilePath + "...")
|
||||
// Create destination directory
|
||||
os.Mkdir(destDirPath, os.ModePerm)
|
||||
// fmt.Println("UnTarGzing " + srcFilePath + "...")
|
||||
// Create destination directory
|
||||
os.Mkdir(destDirPath, os.ModePerm)
|
||||
|
||||
fr, err := os.Open(srcFilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
fr, err := os.Open(srcFilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// Gzip reader
|
||||
gr, err := gzip.NewReader(fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer gr.Close()
|
||||
// Gzip reader
|
||||
gr, err := gzip.NewReader(fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer gr.Close()
|
||||
|
||||
// Tar reader
|
||||
tr := tar.NewReader(gr)
|
||||
// Tar reader
|
||||
tr := tar.NewReader(gr)
|
||||
|
||||
for {
|
||||
hdr, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
// End of tar archive
|
||||
break
|
||||
}
|
||||
//handleError(err)
|
||||
// fmt.Println("UnTarGzing file..." + hdr.Name)
|
||||
// Check if it is diretory or file
|
||||
if hdr.Typeflag != tar.TypeDir {
|
||||
// Get files from archive
|
||||
// Create diretory before create file
|
||||
os.MkdirAll(destDirPath+"/"+path.Dir(hdr.Name), os.ModePerm)
|
||||
// Write data to file
|
||||
fw, _ := os.Create(destDirPath + "/" + hdr.Name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = io.Copy(fw, tr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// fmt.Println("Well done!")
|
||||
for {
|
||||
hdr, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
// End of tar archive
|
||||
break
|
||||
}
|
||||
//handleError(err)
|
||||
// fmt.Println("UnTarGzing file..." + hdr.Name)
|
||||
// Check if it is diretory or file
|
||||
if hdr.Typeflag != tar.TypeDir {
|
||||
// Get files from archive
|
||||
// Create diretory before create file
|
||||
os.MkdirAll(destDirPath+"/"+path.Dir(hdr.Name), os.ModePerm)
|
||||
// Write data to file
|
||||
fw, _ := os.Create(destDirPath + "/" + hdr.Name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = io.Copy(fw, tr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// fmt.Println("Well done!")
|
||||
}
|
||||
|
||||
// Copyfile
|
||||
func CopyFile(dstName, srcName string) (written int64, err error) {
|
||||
src, err := os.Open(srcName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer dst.Close()
|
||||
return io.Copy(dst, src)
|
||||
}
|
||||
src, err := os.Open(srcName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer dst.Close()
|
||||
return io.Copy(dst, src)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package archive
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// main functions shows how to TarGz a directory/file and
|
||||
@@ -15,43 +15,43 @@ import (
|
||||
// you need check file exist before you call this function
|
||||
|
||||
func Zip(srcDirPath string, destFilePath string) (ok bool) {
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
}
|
||||
}()
|
||||
|
||||
fw, err := os.Create(destFilePath)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fw.Close()
|
||||
fw, err := os.Create(destFilePath)
|
||||
|
||||
// Tar writer
|
||||
tw := zip.NewWriter(fw)
|
||||
defer tw.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
// Check if it's a file or a directory
|
||||
f, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
// handle source directory
|
||||
// fmt.Println("Cerating tar.gz from directory...")
|
||||
zipDir(srcDirPath, path.Base(srcDirPath), tw)
|
||||
} else {
|
||||
// handle file directly
|
||||
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
||||
zipFile(srcDirPath, fi.Name(), tw, fi)
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
// Tar writer
|
||||
tw := zip.NewWriter(fw)
|
||||
defer tw.Close()
|
||||
|
||||
// Check if it's a file or a directory
|
||||
f, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
// handle source directory
|
||||
// fmt.Println("Cerating tar.gz from directory...")
|
||||
zipDir(srcDirPath, path.Base(srcDirPath), tw)
|
||||
} else {
|
||||
// handle file directly
|
||||
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
||||
zipFile(srcDirPath, fi.Name(), tw, fi)
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// Deal with directories
|
||||
@@ -59,69 +59,69 @@ func Zip(srcDirPath string, destFilePath string) (ok bool) {
|
||||
// Every recurrence append the base path to the recPath
|
||||
// recPath is the path inside of tar.gz
|
||||
func zipDir(srcDirPath string, recPath string, tw *zip.Writer) {
|
||||
// Open source diretory
|
||||
dir, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
// Open source diretory
|
||||
dir, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
|
||||
// Get file info slice
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, fi := range fis {
|
||||
// Append path
|
||||
curPath := srcDirPath + "/" + fi.Name()
|
||||
// Check it is directory or file
|
||||
if fi.IsDir() {
|
||||
// Directory
|
||||
// (Directory won't add unitl all subfiles are added)
|
||||
// fmt.Printf("Adding path...%s\n", curPath)
|
||||
zipDir(curPath, recPath+"/"+fi.Name(), tw)
|
||||
} else {
|
||||
// File
|
||||
// fmt.Printf("Adding file...%s\n", curPath)
|
||||
}
|
||||
// Get file info slice
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, fi := range fis {
|
||||
// Append path
|
||||
curPath := srcDirPath + "/" + fi.Name()
|
||||
// Check it is directory or file
|
||||
if fi.IsDir() {
|
||||
// Directory
|
||||
// (Directory won't add unitl all subfiles are added)
|
||||
// fmt.Printf("Adding path...%s\n", curPath)
|
||||
zipDir(curPath, recPath+"/"+fi.Name(), tw)
|
||||
} else {
|
||||
// File
|
||||
// fmt.Printf("Adding file...%s\n", curPath)
|
||||
}
|
||||
|
||||
zipFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
||||
}
|
||||
zipFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with files
|
||||
func zipFile(srcFile string, recPath string, tw *zip.Writer, fi os.FileInfo) {
|
||||
if fi.IsDir() {
|
||||
// fmt.Println("??")
|
||||
// Create tar header
|
||||
/*
|
||||
fh, err := zip.FileInfoHeader(fi)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fh.Name = recPath // + "/"
|
||||
err = tw.WriteHeader(hdr)
|
||||
tw.Create(recPath)
|
||||
*/
|
||||
} else {
|
||||
// File reader
|
||||
fr, err := os.Open(srcFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
if fi.IsDir() {
|
||||
// fmt.Println("??")
|
||||
// Create tar header
|
||||
/*
|
||||
fh, err := zip.FileInfoHeader(fi)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fh.Name = recPath // + "/"
|
||||
err = tw.WriteHeader(hdr)
|
||||
tw.Create(recPath)
|
||||
*/
|
||||
} else {
|
||||
// File reader
|
||||
fr, err := os.Open(srcFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// Write hander
|
||||
w, err2 := tw.Create(recPath)
|
||||
if err2 != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Write file data
|
||||
_, err = io.Copy(w, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
// Write hander
|
||||
w, err2 := tw.Create(recPath)
|
||||
if err2 != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Write file data
|
||||
_, err = io.Copy(w, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ungzip and untar from source file to destination directory
|
||||
@@ -129,33 +129,33 @@ func zipFile(srcFile string, recPath string, tw *zip.Writer, fi os.FileInfo) {
|
||||
func Unzip(srcFilePath string, destDirPath string) (ok bool, msg string) {
|
||||
ok = false
|
||||
msg = ""
|
||||
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
if err := recover(); err != nil {
|
||||
msg = fmt.Sprintf("%v", err)
|
||||
ok = false
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
os.Mkdir(destDirPath, os.ModePerm)
|
||||
r, err := zip.OpenReader(srcFilePath);
|
||||
r, err := zip.OpenReader(srcFilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer r.Close();
|
||||
defer r.Close()
|
||||
for _, f := range r.File {
|
||||
// fmt.Println("FileName : ", f.Name); // j/aaa.zip
|
||||
rc, err := f.Open();
|
||||
if err!=nil {
|
||||
// fmt.Println("FileName : ", f.Name); // j/aaa.zip
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
// 把首文件夹去掉, 即j去掉, 分离出文件夹和文件名
|
||||
paths := strings.Split(f.Name, "/")
|
||||
prePath := ""
|
||||
filename := ""
|
||||
l := len(paths)
|
||||
// fmt.Println(l)
|
||||
// fmt.Println(l)
|
||||
if l > 1 {
|
||||
// 去掉第1个文件夹
|
||||
if l == 2 {
|
||||
@@ -167,26 +167,26 @@ func Unzip(srcFilePath string, destDirPath string) (ok bool, msg string) {
|
||||
} else {
|
||||
filename = f.Name
|
||||
}
|
||||
// fmt.Println(prePath)
|
||||
|
||||
// fmt.Println(prePath)
|
||||
|
||||
// 相对于目标文件件下的路径
|
||||
destPath := destDirPath + "/" + filename
|
||||
destPath := destDirPath + "/" + filename
|
||||
if prePath != "" {
|
||||
os.MkdirAll(destDirPath + "/" + prePath, os.ModePerm)
|
||||
os.MkdirAll(destDirPath+"/"+prePath, os.ModePerm)
|
||||
destPath = destDirPath + "/" + prePath + "/" + filename
|
||||
}
|
||||
// Write data to file
|
||||
// fmt.Println(destPath)
|
||||
fw, _ := os.Create(destPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = io.Copy(fw, rc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Write data to file
|
||||
// fmt.Println(destPath)
|
||||
fw, _ := os.Create(destPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = io.Copy(fw, rc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package binder
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/controllers"
|
||||
// "github.com/leanote/leanote/app/controllers/api"
|
||||
"github.com/revel/revel"
|
||||
// "github.com/leanote/leanote/app/controllers/api"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -12,7 +11,7 @@ import (
|
||||
|
||||
// leanote binder struct
|
||||
// rewrite revel struct binder
|
||||
// not need the struct name as prefix,
|
||||
// not need the struct name as prefix,
|
||||
// eg:
|
||||
// type Note struct {Name}
|
||||
// func (c Controller) List(note Note) revel.Result {}
|
||||
@@ -34,13 +33,13 @@ var MSSBinder = revel.Binder{
|
||||
}
|
||||
return result
|
||||
},
|
||||
|
||||
|
||||
Unbind: func(output map[string]string, name string, val interface{}) {
|
||||
mapValue := reflect.ValueOf(val)
|
||||
for _, key := range mapValue.MapKeys() {
|
||||
revel.Unbind(output, fmt.Sprintf("%v", key.Interface()),
|
||||
mapValue.MapIndex(key).Interface())
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -54,55 +53,56 @@ func nextKey(key string) string {
|
||||
}
|
||||
return key[:fieldLen]
|
||||
}
|
||||
|
||||
var leanoteStructBinder = revel.Binder{
|
||||
// name == "noteOrContent"
|
||||
Bind: func(params *revel.Params, name string, typ reflect.Type) reflect.Value {
|
||||
result := reflect.New(typ).Elem() // 创建一个该类型的, 然后其field从所有的param去取
|
||||
fieldValues := make(map[string]reflect.Value)
|
||||
// fmt.Println(name)
|
||||
// fmt.Println(name)
|
||||
// fmt.Println(typ) // api.NoteFiles
|
||||
// name = files[0], files[1], noteContent
|
||||
// fmt.Println(params.Values)
|
||||
// fmt.Println(params.Values)
|
||||
/*
|
||||
map[Title:[test1] METHOD:[POST] NotebookId:[54c4f51705fcd14031000002]
|
||||
files[1][FileId]:[]
|
||||
controller:[note]
|
||||
files[1][LocalFileId]:[54c7ae27d98d0329dd000000] files[1][HasBody]:[true] files[0][FileId]:[] files[0][LocalFileId]:[54c7ae855e94ea2dba000000] action:[addNote] Content:[<p>lifedddddd</p><p><img src="app://leanote/data/54bdc65599c37b0da9000002/images/1422368307147_2.png" alt="" data-mce-src="app://leanote/data/54bdc65599c37b0da9000002/images/1422368307147_2.png" style="display: block; margin-left: auto; margin-right: auto;"></p><p><img src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae27d98d0329dd000000" alt="" data-mce-src="http://127.0.0.1:8008/api/file/getImg?fileId=54c7ae27d98d0329dd000000"></p><p><br></p><p><img src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae855e94ea2dba000000" alt="" data-mce-src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae855e94ea2dba000000" style="display: block; margin-left: auto; margin-right: auto;"></p><p><br></p><p><br></p>] IsBlog:[false] token:[user1]
|
||||
files[0][HasBody]:[true]]
|
||||
map[Title:[test1] METHOD:[POST] NotebookId:[54c4f51705fcd14031000002]
|
||||
files[1][FileId]:[]
|
||||
controller:[note]
|
||||
files[1][LocalFileId]:[54c7ae27d98d0329dd000000] files[1][HasBody]:[true] files[0][FileId]:[] files[0][LocalFileId]:[54c7ae855e94ea2dba000000] action:[addNote] Content:[<p>lifedddddd</p><p><img src="app://leanote/data/54bdc65599c37b0da9000002/images/1422368307147_2.png" alt="" data-mce-src="app://leanote/data/54bdc65599c37b0da9000002/images/1422368307147_2.png" style="display: block; margin-left: auto; margin-right: auto;"></p><p><img src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae27d98d0329dd000000" alt="" data-mce-src="http://127.0.0.1:8008/api/file/getImg?fileId=54c7ae27d98d0329dd000000"></p><p><br></p><p><img src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae855e94ea2dba000000" alt="" data-mce-src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae855e94ea2dba000000" style="display: block; margin-left: auto; margin-right: auto;"></p><p><br></p><p><br></p>] IsBlog:[false] token:[user1]
|
||||
files[0][HasBody]:[true]]
|
||||
*/
|
||||
nameIsSlice := strings.Contains(name, "[")
|
||||
// fmt.Println(params.Values["files[1]"])
|
||||
// fmt.Println(params.Values["Title"])
|
||||
for key, _ := range params.Values {// Title, Content, Files
|
||||
// fmt.Println(params.Values["files[1]"])
|
||||
// fmt.Println(params.Values["Title"])
|
||||
for key, _ := range params.Values { // Title, Content, Files
|
||||
// 这里, 如果没有点, 默认就是a.
|
||||
// life
|
||||
// fmt.Println("key:" + key); // files[0][LocalFileId]
|
||||
// fmt.Println("name:" + name); // files[0][LocalFileId]
|
||||
// fmt.Println("key:" + key); // files[0][LocalFileId]
|
||||
// fmt.Println("name:" + name); // files[0][LocalFileId]
|
||||
var suffix string
|
||||
var noPrefix = false
|
||||
if nameIsSlice && strings.HasPrefix(key, name) {
|
||||
suffix = key[len(name)+1:len(key)-1] // files[0][LocalFileId] 去掉 => LocalFileId
|
||||
} else if !strings.HasPrefix(key, name + ".") {
|
||||
suffix = key[len(name)+1 : len(key)-1] // files[0][LocalFileId] 去掉 => LocalFileId
|
||||
} else if !strings.HasPrefix(key, name+".") {
|
||||
noPrefix = true
|
||||
suffix = key
|
||||
// continue
|
||||
// continue
|
||||
} else {
|
||||
// Get the name of the struct property.
|
||||
// Strip off the prefix. e.g. foo.bar.baz => bar.baz
|
||||
suffix = key[len(name)+1:]
|
||||
}
|
||||
// fmt.Println(suffix);
|
||||
|
||||
// fmt.Println(suffix);
|
||||
|
||||
fieldName := nextKey(suffix) // e.g. bar => "bar", bar.baz => "bar", bar[0] => "bar"
|
||||
// fmt.Println(fieldName);
|
||||
// fmt.Println(fieldName);
|
||||
fieldLen := len(fieldName)
|
||||
|
||||
|
||||
if _, ok := fieldValues[fieldName]; !ok {
|
||||
// Time to bind this field. Get it and make sure we can set it.
|
||||
fieldName = strings.Title(fieldName) // 传过来title, 但struct是Title
|
||||
// fmt.Println("xx: " + fieldName)
|
||||
// fmt.Println("xx: " + fieldName)
|
||||
fieldValue := result.FieldByName(fieldName)
|
||||
// fmt.Println(fieldValue)
|
||||
// fmt.Println(fieldValue)
|
||||
if !fieldValue.IsValid() {
|
||||
continue
|
||||
}
|
||||
@@ -111,14 +111,14 @@ files[0][HasBody]:[true]]
|
||||
}
|
||||
var boundVal reflect.Value
|
||||
// 没有name前缀
|
||||
if(noPrefix) {
|
||||
if noPrefix {
|
||||
// life
|
||||
// fmt.Println("<<")
|
||||
// fmt.Println(strings.Title(key[:fieldLen]));
|
||||
// fmt.Println("<<")
|
||||
// fmt.Println(strings.Title(key[:fieldLen]));
|
||||
boundVal = revel.Bind(params, key[:fieldLen], fieldValue.Type())
|
||||
} else {
|
||||
// fmt.Println("final")
|
||||
// fmt.Println(key[:len(name)+1+fieldLen]) // files[0][HasBody
|
||||
// fmt.Println("final")
|
||||
// fmt.Println(key[:len(name)+1+fieldLen]) // files[0][HasBody
|
||||
if nameIsSlice {
|
||||
fieldLen += 1
|
||||
}
|
||||
@@ -150,7 +150,7 @@ func init() {
|
||||
revel.TypeBinders[reflect.TypeOf(info.UserBlogStyle{})] = leanoteStructBinder
|
||||
revel.TypeBinders[reflect.TypeOf(info.Notebook{})] = 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.NoteFile{})] = leanoteStructBinder
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
// "os"
|
||||
"fmt"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
@@ -40,8 +40,8 @@ type RenderTemplateResult struct {
|
||||
Template *template.Template
|
||||
PathContent map[string]string
|
||||
RenderArgs map[string]interface{}
|
||||
|
||||
IsPreview bool // 是否是预览
|
||||
|
||||
IsPreview bool // 是否是预览
|
||||
CurBlogTpl *BlogTpl
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ func (r *RenderTemplateResult) render(req *revel.Request, resp *revel.Response,
|
||||
Line: line,
|
||||
SourceLines: templateContent,
|
||||
}
|
||||
|
||||
|
||||
// 这里, 错误!!
|
||||
// 这里应该导向到本主题的错误页面
|
||||
resp.Status = 500
|
||||
@@ -117,7 +117,7 @@ func (r *RenderTemplateResult) Apply(req *revel.Request, resp *revel.Response) {
|
||||
r.render(req, resp, out) // 这里!!!
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Render the template into a temporary buffer, to see if there was an error
|
||||
// rendering the template. If not, then copy it into the response buffer.
|
||||
// Otherwise, template render errors may result in unpredictable HTML (and
|
||||
@@ -139,7 +139,7 @@ func Init() {
|
||||
fileBytes, _ := ioutil.ReadFile(revel.ViewsPath + "/Blog/" + path)
|
||||
fileStr := string(fileBytes)
|
||||
path := "blog/" + path
|
||||
// path := path
|
||||
// path := path
|
||||
BlogTplObject.PathContent[path] = fileStr
|
||||
BlogTplObject.Template.New(path).Parse(fileStr) // 以blog为根
|
||||
}
|
||||
@@ -157,7 +157,7 @@ func RenderTemplate(name string, args map[string]interface{}, basePath string, i
|
||||
// 都不会为空的
|
||||
if basePath == "" {
|
||||
path := "blog/" + name
|
||||
// path := name
|
||||
// path := name
|
||||
t := BlogTplObject.Template.Lookup(path)
|
||||
r = &RenderTemplateResult{
|
||||
Template: t,
|
||||
@@ -181,7 +181,7 @@ func RenderTemplate(name string, args map[string]interface{}, basePath string, i
|
||||
files := ListDir(basePath)
|
||||
for _, t := range files {
|
||||
if !strings.Contains(t, ".html") {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
fileBytes, err := ioutil.ReadFile(basePath + "/" + t)
|
||||
if err != nil {
|
||||
@@ -194,7 +194,7 @@ func RenderTemplate(name string, args map[string]interface{}, basePath string, i
|
||||
|
||||
// 如果本主题下没有, 则用系统的
|
||||
t := newBlogTplObject.Template.Lookup(name)
|
||||
|
||||
|
||||
if t == nil {
|
||||
path := "blog/" + name
|
||||
t = BlogTplObject.Template.Lookup(path)
|
||||
@@ -203,23 +203,21 @@ func RenderTemplate(name string, args map[string]interface{}, basePath string, i
|
||||
Template: t,
|
||||
PathContent: newBlogTplObject.PathContent, // 为了显示错误
|
||||
RenderArgs: args,
|
||||
CurBlogTpl: newBlogTplObject,
|
||||
IsPreview: isPreview,
|
||||
CurBlogTpl: newBlogTplObject,
|
||||
IsPreview: isPreview,
|
||||
}
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
|
||||
////////////////////
|
||||
//
|
||||
|
||||
|
||||
type ErrorResult struct {
|
||||
RenderArgs map[string]interface{}
|
||||
Error error
|
||||
IsPreview bool
|
||||
IsPreview bool
|
||||
CurBlogTpl *BlogTpl
|
||||
}
|
||||
|
||||
@@ -240,7 +238,7 @@ func (r ErrorResult) Apply(req *revel.Request, resp *revel.Response) {
|
||||
var err error
|
||||
templatePath := fmt.Sprintf("errors/%d.%s", status, format)
|
||||
err = nil
|
||||
// tmpl, err := revel.MainTemplateLoader.Template("index.html") // 这里找到错误页面主题
|
||||
// tmpl, err := revel.MainTemplateLoader.Template("index.html") // 这里找到错误页面主题
|
||||
|
||||
// This func shows a plaintext error message, in case the template rendering
|
||||
// doesn't work.
|
||||
@@ -297,4 +295,4 @@ func (r ErrorResult) Apply(req *revel.Request, resp *revel.Response) {
|
||||
resp.WriteHeader(http.StatusOK, "text/html; charset=utf-8")
|
||||
b.WriteTo(out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,399 +1,401 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"io"
|
||||
"math/rand"
|
||||
crand "crypto/rand"
|
||||
"time"
|
||||
"strconv"
|
||||
)
|
||||
const (
|
||||
stdWidth = 100
|
||||
stdHeight = 40
|
||||
maxSkew = 2
|
||||
crand "crypto/rand"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"io"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
fontWidth = 5
|
||||
fontHeight = 8
|
||||
blackChar = 1
|
||||
stdWidth = 100
|
||||
stdHeight = 40
|
||||
maxSkew = 2
|
||||
)
|
||||
|
||||
|
||||
const (
|
||||
fontWidth = 5
|
||||
fontHeight = 8
|
||||
blackChar = 1
|
||||
)
|
||||
|
||||
var font = [][]byte{
|
||||
{ // 0
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 1
|
||||
0, 0, 1, 0, 0,
|
||||
0, 1, 1, 0, 0,
|
||||
1, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
},
|
||||
{ // 2
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 1,
|
||||
0, 1, 1, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
},
|
||||
{ // 3
|
||||
1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 1, 1, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 4
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
},
|
||||
{ // 5
|
||||
1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 6
|
||||
0, 0, 1, 1, 1,
|
||||
0, 1, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 7
|
||||
1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
},
|
||||
{ // 8
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 9
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 1, 0, 0, 1,
|
||||
0, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 0
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 1
|
||||
0, 0, 1, 0, 0,
|
||||
0, 1, 1, 0, 0,
|
||||
1, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
},
|
||||
{ // 2
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 1,
|
||||
0, 1, 1, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
},
|
||||
{ // 3
|
||||
1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 1, 1, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 4
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
},
|
||||
{ // 5
|
||||
1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 6
|
||||
0, 0, 1, 1, 1,
|
||||
0, 1, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 7
|
||||
1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
},
|
||||
{ // 8
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 9
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 1, 0, 0, 1,
|
||||
0, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
type Image struct {
|
||||
*image.NRGBA
|
||||
color *color.NRGBA
|
||||
width int //a digit width
|
||||
height int //a digit height
|
||||
dotsize int
|
||||
*image.NRGBA
|
||||
color *color.NRGBA
|
||||
width int //a digit width
|
||||
height int //a digit height
|
||||
dotsize int
|
||||
}
|
||||
func init(){
|
||||
rand.Seed(int64(time.Second))
|
||||
|
||||
func init() {
|
||||
rand.Seed(int64(time.Second))
|
||||
}
|
||||
|
||||
|
||||
func NewImage(digits []byte, width, height int) *Image {
|
||||
img := new(Image)
|
||||
r := image.Rect(img.width, img.height, stdWidth, stdHeight)
|
||||
img.NRGBA = image.NewNRGBA(r)
|
||||
|
||||
img.color = &color.NRGBA{
|
||||
uint8(rand.Intn(129)),
|
||||
uint8(rand.Intn(129)),
|
||||
uint8(rand.Intn(129)),
|
||||
0xFF,
|
||||
}
|
||||
// Draw background (10 random circles of random brightness)
|
||||
img.calculateSizes(width, height, len(digits))
|
||||
img.fillWithCircles(10, img.dotsize)
|
||||
|
||||
maxx := width - (img.width+img.dotsize)*len(digits) - img.dotsize
|
||||
maxy := height - img.height - img.dotsize*2
|
||||
|
||||
x := rnd(img.dotsize*2, maxx)
|
||||
y := rnd(img.dotsize*2, maxy)
|
||||
|
||||
// Draw digits.
|
||||
for _, n := range digits {
|
||||
img.drawDigit(font[n], x, y)
|
||||
x += img.width + img.dotsize
|
||||
}
|
||||
|
||||
// Draw strike-through line.
|
||||
// 中间线不要
|
||||
//img.strikeThrough()
|
||||
|
||||
return img
|
||||
img := new(Image)
|
||||
r := image.Rect(img.width, img.height, stdWidth, stdHeight)
|
||||
img.NRGBA = image.NewNRGBA(r)
|
||||
|
||||
img.color = &color.NRGBA{
|
||||
uint8(rand.Intn(129)),
|
||||
uint8(rand.Intn(129)),
|
||||
uint8(rand.Intn(129)),
|
||||
0xFF,
|
||||
}
|
||||
// Draw background (10 random circles of random brightness)
|
||||
img.calculateSizes(width, height, len(digits))
|
||||
img.fillWithCircles(10, img.dotsize)
|
||||
|
||||
maxx := width - (img.width+img.dotsize)*len(digits) - img.dotsize
|
||||
maxy := height - img.height - img.dotsize*2
|
||||
|
||||
x := rnd(img.dotsize*2, maxx)
|
||||
y := rnd(img.dotsize*2, maxy)
|
||||
|
||||
// Draw digits.
|
||||
for _, n := range digits {
|
||||
img.drawDigit(font[n], x, y)
|
||||
x += img.width + img.dotsize
|
||||
}
|
||||
|
||||
// Draw strike-through line.
|
||||
// 中间线不要
|
||||
//img.strikeThrough()
|
||||
|
||||
return img
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) WriteTo(w io.Writer) (int64, error) {
|
||||
return 0, png.Encode(w, img)
|
||||
return 0, png.Encode(w, img)
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) calculateSizes(width, height, ncount int) {
|
||||
|
||||
// Goal: fit all digits inside the image.
|
||||
var border int
|
||||
if width > height {
|
||||
border = height / 5
|
||||
} else {
|
||||
border = width / 5
|
||||
}
|
||||
// Convert everything to floats for calculations.
|
||||
w := float64(width - border*2) //268
|
||||
h := float64(height - border*2) //48
|
||||
// fw takes into account 1-dot spacing between digits.
|
||||
|
||||
fw := float64(fontWidth) + 1 //6
|
||||
|
||||
fh := float64(fontHeight) //8
|
||||
nc := float64(ncount) //7
|
||||
|
||||
// Calculate the width of a single digit taking into account only the
|
||||
// width of the image.
|
||||
nw := w / nc //38
|
||||
// Calculate the height of a digit from this width.
|
||||
nh := nw * fh / fw //51
|
||||
|
||||
// Digit too high?
|
||||
|
||||
if nh > h {
|
||||
// Fit digits based on height.
|
||||
nh = h //nh = 44
|
||||
nw = fw / fh * nh
|
||||
}
|
||||
// Calculate dot size.
|
||||
img.dotsize = int(nh / fh)
|
||||
// Save everything, making the actual width smaller by 1 dot to account
|
||||
// for spacing between digits.
|
||||
img.width = int(nw)
|
||||
img.height = int(nh) - img.dotsize
|
||||
|
||||
// Goal: fit all digits inside the image.
|
||||
var border int
|
||||
if width > height {
|
||||
border = height / 5
|
||||
} else {
|
||||
border = width / 5
|
||||
}
|
||||
// Convert everything to floats for calculations.
|
||||
w := float64(width - border*2) //268
|
||||
h := float64(height - border*2) //48
|
||||
// fw takes into account 1-dot spacing between digits.
|
||||
|
||||
fw := float64(fontWidth) + 1 //6
|
||||
|
||||
fh := float64(fontHeight) //8
|
||||
nc := float64(ncount) //7
|
||||
|
||||
// Calculate the width of a single digit taking into account only the
|
||||
// width of the image.
|
||||
nw := w / nc //38
|
||||
// Calculate the height of a digit from this width.
|
||||
nh := nw * fh / fw //51
|
||||
|
||||
// Digit too high?
|
||||
|
||||
if nh > h {
|
||||
// Fit digits based on height.
|
||||
nh = h //nh = 44
|
||||
nw = fw / fh * nh
|
||||
}
|
||||
// Calculate dot size.
|
||||
img.dotsize = int(nh / fh)
|
||||
// Save everything, making the actual width smaller by 1 dot to account
|
||||
// for spacing between digits.
|
||||
img.width = int(nw)
|
||||
img.height = int(nh) - img.dotsize
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) fillWithCircles(n, maxradius int) {
|
||||
color := img.color
|
||||
maxx := img.Bounds().Max.X
|
||||
maxy := img.Bounds().Max.Y
|
||||
for i := 0; i < n; i++ {
|
||||
setRandomBrightness(color, 255)
|
||||
r := rnd(1, maxradius)
|
||||
img.drawCircle(color, rnd(r, maxx-r), rnd(r, maxy-r), r)
|
||||
}
|
||||
color := img.color
|
||||
maxx := img.Bounds().Max.X
|
||||
maxy := img.Bounds().Max.Y
|
||||
for i := 0; i < n; i++ {
|
||||
setRandomBrightness(color, 255)
|
||||
r := rnd(1, maxradius)
|
||||
img.drawCircle(color, rnd(r, maxx-r), rnd(r, maxy-r), r)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) drawHorizLine(color color.Color, fromX, toX, y int) {
|
||||
for x := fromX; x <= toX; x++ {
|
||||
img.Set(x, y, color)
|
||||
}
|
||||
for x := fromX; x <= toX; x++ {
|
||||
img.Set(x, y, color)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) drawCircle(color color.Color, x, y, radius int) {
|
||||
f := 1 - radius
|
||||
dfx := 1
|
||||
dfy := -2 * radius
|
||||
xx := 0
|
||||
yy := radius
|
||||
|
||||
img.Set(x, y+radius, color)
|
||||
img.Set(x, y-radius, color)
|
||||
img.drawHorizLine(color, x-radius, x+radius, y)
|
||||
|
||||
for xx < yy {
|
||||
if f >= 0 {
|
||||
yy--
|
||||
dfy += 2
|
||||
f += dfy
|
||||
}
|
||||
xx++
|
||||
dfx += 2
|
||||
f += dfx
|
||||
img.drawHorizLine(color, x-xx, x+xx, y+yy)
|
||||
img.drawHorizLine(color, x-xx, x+xx, y-yy)
|
||||
img.drawHorizLine(color, x-yy, x+yy, y+xx)
|
||||
img.drawHorizLine(color, x-yy, x+yy, y-xx)
|
||||
}
|
||||
f := 1 - radius
|
||||
dfx := 1
|
||||
dfy := -2 * radius
|
||||
xx := 0
|
||||
yy := radius
|
||||
|
||||
img.Set(x, y+radius, color)
|
||||
img.Set(x, y-radius, color)
|
||||
img.drawHorizLine(color, x-radius, x+radius, y)
|
||||
|
||||
for xx < yy {
|
||||
if f >= 0 {
|
||||
yy--
|
||||
dfy += 2
|
||||
f += dfy
|
||||
}
|
||||
xx++
|
||||
dfx += 2
|
||||
f += dfx
|
||||
img.drawHorizLine(color, x-xx, x+xx, y+yy)
|
||||
img.drawHorizLine(color, x-xx, x+xx, y-yy)
|
||||
img.drawHorizLine(color, x-yy, x+yy, y+xx)
|
||||
img.drawHorizLine(color, x-yy, x+yy, y-xx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) strikeThrough() {
|
||||
r := 0
|
||||
maxx := img.Bounds().Max.X
|
||||
maxy := img.Bounds().Max.Y
|
||||
y := rnd(maxy/3, maxy-maxy/3)
|
||||
for x := 0; x < maxx; x += r {
|
||||
r = rnd(1, img.dotsize/3)
|
||||
y += rnd(-img.dotsize/2, img.dotsize/2)
|
||||
if y <= 0 || y >= maxy {
|
||||
y = rnd(maxy/3, maxy-maxy/3)
|
||||
}
|
||||
img.drawCircle(img.color, x, y, r)
|
||||
}
|
||||
r := 0
|
||||
maxx := img.Bounds().Max.X
|
||||
maxy := img.Bounds().Max.Y
|
||||
y := rnd(maxy/3, maxy-maxy/3)
|
||||
for x := 0; x < maxx; x += r {
|
||||
r = rnd(1, img.dotsize/3)
|
||||
y += rnd(-img.dotsize/2, img.dotsize/2)
|
||||
if y <= 0 || y >= maxy {
|
||||
y = rnd(maxy/3, maxy-maxy/3)
|
||||
}
|
||||
img.drawCircle(img.color, x, y, r)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) drawDigit(digit []byte, x, y int) {
|
||||
skf := rand.Float64() * float64(rnd(-maxSkew, maxSkew))
|
||||
xs := float64(x)
|
||||
minr := img.dotsize / 2 // minumum radius
|
||||
maxr := img.dotsize/2 + img.dotsize/4 // maximum radius
|
||||
y += rnd(-minr, minr)
|
||||
for yy := 0; yy < fontHeight; yy++ {
|
||||
for xx := 0; xx < fontWidth; xx++ {
|
||||
if digit[yy*fontWidth+xx] != blackChar {
|
||||
continue
|
||||
}
|
||||
// Introduce random variations.
|
||||
or := rnd(minr, maxr)
|
||||
ox := x + (xx * img.dotsize) + rnd(0, or/2)
|
||||
oy := y + (yy * img.dotsize) + rnd(0, or/2)
|
||||
|
||||
img.drawCircle(img.color, ox, oy, or)
|
||||
}
|
||||
xs += skf
|
||||
x = int(xs)
|
||||
}
|
||||
skf := rand.Float64() * float64(rnd(-maxSkew, maxSkew))
|
||||
xs := float64(x)
|
||||
minr := img.dotsize / 2 // minumum radius
|
||||
maxr := img.dotsize/2 + img.dotsize/4 // maximum radius
|
||||
y += rnd(-minr, minr)
|
||||
for yy := 0; yy < fontHeight; yy++ {
|
||||
for xx := 0; xx < fontWidth; xx++ {
|
||||
if digit[yy*fontWidth+xx] != blackChar {
|
||||
continue
|
||||
}
|
||||
// Introduce random variations.
|
||||
or := rnd(minr, maxr)
|
||||
ox := x + (xx * img.dotsize) + rnd(0, or/2)
|
||||
oy := y + (yy * img.dotsize) + rnd(0, or/2)
|
||||
|
||||
img.drawCircle(img.color, ox, oy, or)
|
||||
}
|
||||
xs += skf
|
||||
x = int(xs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func setRandomBrightness(c *color.NRGBA, max uint8) {
|
||||
minc := min3(c.R, c.G, c.B)
|
||||
maxc := max3(c.R, c.G, c.B)
|
||||
if maxc > max {
|
||||
return
|
||||
}
|
||||
n := rand.Intn(int(max-maxc)) - int(minc)
|
||||
c.R = uint8(int(c.R) + n)
|
||||
c.G = uint8(int(c.G) + n)
|
||||
c.B = uint8(int(c.B) + n)
|
||||
minc := min3(c.R, c.G, c.B)
|
||||
maxc := max3(c.R, c.G, c.B)
|
||||
if maxc > max {
|
||||
return
|
||||
}
|
||||
n := rand.Intn(int(max-maxc)) - int(minc)
|
||||
c.R = uint8(int(c.R) + n)
|
||||
c.G = uint8(int(c.G) + n)
|
||||
c.B = uint8(int(c.B) + n)
|
||||
}
|
||||
|
||||
|
||||
func min3(x, y, z uint8) (o uint8) {
|
||||
o = x
|
||||
if y < o {
|
||||
o = y
|
||||
}
|
||||
if z < o {
|
||||
o = z
|
||||
}
|
||||
return
|
||||
o = x
|
||||
if y < o {
|
||||
o = y
|
||||
}
|
||||
if z < o {
|
||||
o = z
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
func max3(x, y, z uint8) (o uint8) {
|
||||
o = x
|
||||
if y > o {
|
||||
o = y
|
||||
}
|
||||
if z > o {
|
||||
o = z
|
||||
}
|
||||
return
|
||||
o = x
|
||||
if y > o {
|
||||
o = y
|
||||
}
|
||||
if z > o {
|
||||
o = z
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// rnd returns a random number in range [from, to].
|
||||
func rnd(from, to int) int {
|
||||
//println(to+1-from)
|
||||
return rand.Intn(to+1-from) + from
|
||||
//println(to+1-from)
|
||||
return rand.Intn(to+1-from) + from
|
||||
}
|
||||
|
||||
|
||||
const (
|
||||
// Standard length of uniuri string to achive ~95 bits of entropy.
|
||||
StdLen = 16
|
||||
// Length of uniurl string to achive ~119 bits of entropy, closest
|
||||
// to what can be losslessly converted to UUIDv4 (122 bits).
|
||||
UUIDLen = 20
|
||||
// Standard length of uniuri string to achive ~95 bits of entropy.
|
||||
StdLen = 16
|
||||
// Length of uniurl string to achive ~119 bits of entropy, closest
|
||||
// to what can be losslessly converted to UUIDv4 (122 bits).
|
||||
UUIDLen = 20
|
||||
)
|
||||
|
||||
|
||||
// Standard characters allowed in uniuri string.
|
||||
var StdChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
|
||||
|
||||
|
||||
// New returns a new random string of the standard length, consisting of
|
||||
// standard characters.
|
||||
func New() string {
|
||||
return NewLenChars(StdLen, StdChars)
|
||||
return NewLenChars(StdLen, StdChars)
|
||||
}
|
||||
|
||||
|
||||
// NewLen returns a new random string of the provided length, consisting of
|
||||
// standard characters.
|
||||
func NewLen(length int) string {
|
||||
return NewLenChars(length, StdChars)
|
||||
return NewLenChars(length, StdChars)
|
||||
}
|
||||
|
||||
|
||||
// NewLenChars returns a new random string of the provided length, consisting
|
||||
// of the provided byte slice of allowed characters (maximum 256).
|
||||
func NewLenChars(length int, chars []byte) string {
|
||||
b := make([]byte, length)
|
||||
r := make([]byte, length+(length/4)) // storage for random bytes.
|
||||
clen := byte(len(chars))
|
||||
maxrb := byte(256 - (256 % len(chars)))
|
||||
i := 0
|
||||
for {
|
||||
if _, err := io.ReadFull(crand.Reader, r); err != nil {
|
||||
panic("error reading from random source: " + err.Error())
|
||||
}
|
||||
for _, c := range r {
|
||||
if c >= maxrb {
|
||||
// Skip this number to avoid modulo bias.
|
||||
continue
|
||||
}
|
||||
b[i] = chars[c%clen]
|
||||
i++
|
||||
if i == length {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
b := make([]byte, length)
|
||||
r := make([]byte, length+(length/4)) // storage for random bytes.
|
||||
clen := byte(len(chars))
|
||||
maxrb := byte(256 - (256 % len(chars)))
|
||||
i := 0
|
||||
for {
|
||||
if _, err := io.ReadFull(crand.Reader, r); err != nil {
|
||||
panic("error reading from random source: " + err.Error())
|
||||
}
|
||||
for _, c := range r {
|
||||
if c >= maxrb {
|
||||
// Skip this number to avoid modulo bias.
|
||||
continue
|
||||
}
|
||||
b[i] = chars[c%clen]
|
||||
i++
|
||||
if i == length {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func Fetch() (*Image, string) {
|
||||
d := make([]byte, 4)
|
||||
s := NewLen(4)
|
||||
ss := ""
|
||||
d = []byte(s)
|
||||
for v := range d {
|
||||
d[v] %= 10
|
||||
ss += strconv.FormatInt(int64(d[v]), 32)
|
||||
}
|
||||
return NewImage(d, 100, 40), ss
|
||||
}
|
||||
d := make([]byte, 4)
|
||||
s := NewLen(4)
|
||||
ss := ""
|
||||
d = []byte(s)
|
||||
for v := range d {
|
||||
d[v] %= 10
|
||||
ss += strconv.FormatInt(int64(d[v]), 32)
|
||||
}
|
||||
return NewImage(d, 100, 40), ss
|
||||
}
|
||||
|
||||
@@ -24,29 +24,29 @@ import (
|
||||
type Html2Image struct {
|
||||
image *image.RGBA
|
||||
gc *draw2d.ImageGraphicContext
|
||||
|
||||
|
||||
// 试探
|
||||
gc2 *draw2d.ImageGraphicContext
|
||||
|
||||
|
||||
width float64 // 图片宽度
|
||||
height float64
|
||||
|
||||
|
||||
painWidth float64 // 画布宽度
|
||||
|
||||
|
||||
startX float64
|
||||
x float64
|
||||
y float64
|
||||
|
||||
|
||||
isFirstP bool // 是否是第一个段落?
|
||||
|
||||
|
||||
// 换行和段落的高度
|
||||
brY float64
|
||||
pY float64
|
||||
|
||||
|
||||
// 字体
|
||||
normalFontFamily draw2d.FontData
|
||||
boldFontFamily draw2d.FontData
|
||||
|
||||
|
||||
// preTag 之前的标签
|
||||
preTag *html.Node
|
||||
}
|
||||
@@ -58,23 +58,23 @@ func NewHtml2Image() *Html2Image {
|
||||
i, gc := h.InitGc(h.width, h.height)
|
||||
h.gc = gc;
|
||||
h.image = i
|
||||
|
||||
|
||||
// 试探
|
||||
_, h.gc2 = h.InitGc(h.width, 100)
|
||||
|
||||
h.startX = 10
|
||||
|
||||
|
||||
h.startX = 10
|
||||
|
||||
// 最初位置
|
||||
h.x = h.startX
|
||||
h.y = 80
|
||||
|
||||
|
||||
h.isFirstP = true
|
||||
|
||||
|
||||
h.normalFontFamily = draw2d.FontData{"xihei", 4, draw2d.FontStyleNormal};
|
||||
h.boldFontFamily = draw2d.FontData{"heiti", 5, draw2d.FontStyleNormal};
|
||||
|
||||
|
||||
h.SetNormalFont()
|
||||
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
@@ -86,12 +86,12 @@ func (this *Html2Image) InitGc(w, h float64) (* image.RGBA, *draw2d.ImageGraphic
|
||||
gc.SetFillColor(image.White)
|
||||
// fill the background
|
||||
// gc.Clear()
|
||||
|
||||
|
||||
draw2d.SetFontFolder(revel.BasePath + "/public/fonts/weibo")
|
||||
draw2d.Rect(gc, 0, 0, w, h) // 设置背景
|
||||
gc.FillStroke()
|
||||
gc.SetFillColor(image.Black)
|
||||
|
||||
|
||||
// 这个很耗时
|
||||
// gc.Translate(0, 0)
|
||||
return i, gc
|
||||
@@ -101,7 +101,7 @@ func (this *Html2Image) SaveToPngFile(filePath string) bool {
|
||||
// m := this.image;
|
||||
m := this.image.SubImage(image.Rect(0, 0, int(this.width), int(this.y + 20)))
|
||||
// 需要截断之
|
||||
|
||||
|
||||
f, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return false
|
||||
@@ -124,14 +124,14 @@ func (this *Html2Image) SaveToPngFile(filePath string) bool {
|
||||
func (this *Html2Image) SetSmallFont() {
|
||||
this.gc.SetFontData(this.normalFontFamily)
|
||||
this.gc2.SetFontData(this.normalFontFamily)
|
||||
|
||||
|
||||
this.gc.SetFillColor(color.NRGBA{60, 60, 60, 255})
|
||||
this.gc.SetFontSize(12)
|
||||
this.gc2.SetFontSize(12)
|
||||
|
||||
|
||||
this.brY = 16
|
||||
this.pY = 30
|
||||
|
||||
|
||||
this.painWidth = this.width - 10
|
||||
}
|
||||
|
||||
@@ -139,13 +139,13 @@ func (this *Html2Image) SetNormalFont() {
|
||||
this.gc.SetFillColor(image.Black)
|
||||
this.gc.SetFontData(this.normalFontFamily)
|
||||
this.gc2.SetFontData(this.normalFontFamily)
|
||||
|
||||
|
||||
this.gc.SetFontSize(14)
|
||||
this.gc2.SetFontSize(14)
|
||||
|
||||
|
||||
this.brY = 20
|
||||
this.pY = 30
|
||||
|
||||
|
||||
this.painWidth = this.width - 10
|
||||
}
|
||||
func (this *Html2Image) SetAColor() {
|
||||
@@ -155,16 +155,16 @@ func (this *Html2Image) SetAColor() {
|
||||
// 标题
|
||||
func (this *Html2Image) SetTitleFont() {
|
||||
this.gc.SetFillColor(image.Black)
|
||||
|
||||
|
||||
this.gc.SetFontData(this.boldFontFamily)
|
||||
this.gc2.SetFontData(this.boldFontFamily)
|
||||
|
||||
|
||||
this.gc.SetFontSize(24)
|
||||
this.gc2.SetFontSize(24)
|
||||
|
||||
|
||||
this.brY = 30
|
||||
this.pY = 60
|
||||
|
||||
|
||||
this.painWidth = this.width - 100
|
||||
}
|
||||
|
||||
@@ -175,9 +175,9 @@ func (this *Html2Image) SetHeadFont(h string) {
|
||||
|
||||
this.gc.SetFontData(this.boldFontFamily)
|
||||
this.gc2.SetFontData(this.boldFontFamily)
|
||||
|
||||
|
||||
this.painWidth = this.width - 50
|
||||
|
||||
|
||||
if h == "h1" {
|
||||
this.gc.SetFontSize(20)
|
||||
this.gc2.SetFontSize(20)
|
||||
@@ -229,7 +229,7 @@ func (this *Html2Image) IsOver(r []rune) bool {
|
||||
// 以下的方法可以极大节约时间
|
||||
// a, b, c, d := this.gc2.GetStringBounds(string(r))
|
||||
// width2 := c - a + 2
|
||||
|
||||
|
||||
// fmt.Println(width2)
|
||||
// fmt.Println(c - a)
|
||||
|
||||
@@ -268,7 +268,7 @@ func (this *Html2Image) InsertText(text string, needTest bool, prefix string) {
|
||||
this.InsertText(text, true, prefix)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
r := []rune(text)
|
||||
// 试探吧, 可能需要截取
|
||||
if !needTest || !this.IsOver(r) {
|
||||
@@ -316,17 +316,17 @@ func (this *Html2Image) InsertText(text string, needTest bool, prefix string) {
|
||||
end = i
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 这一段写上
|
||||
// println("------>" + string(r[0:end]))
|
||||
|
||||
|
||||
// 这里, 判断后面一个是否是标点符号
|
||||
end = this.includePunctuation(r, end)
|
||||
this.InsertText(string(r[0:end]), false, prefix)
|
||||
this.NewBr()
|
||||
// 之后的
|
||||
this.InsertText(string(r[end:]), true, prefix)
|
||||
|
||||
|
||||
return;
|
||||
} else {
|
||||
// 没超出, 不用计算, 但出要看是否是结尾了
|
||||
@@ -351,17 +351,17 @@ func (this *Html2Image) InsertText(text string, needTest bool, prefix string) {
|
||||
end = maxRI + 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 这一段写上
|
||||
// println("-e----->" + string(r[0:end]))
|
||||
|
||||
|
||||
// 这里, 判断后面一个是否是标点符号
|
||||
end = this.includePunctuation(r, end)
|
||||
this.InsertText(string(r[0:end]), false, prefix)
|
||||
this.NewBr()
|
||||
// 之后的
|
||||
this.InsertText(string(r[end:]), true, prefix)
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -376,9 +376,9 @@ func (this *Html2Image) SetBottom(username, url string) {
|
||||
this.gc.SetStrokeColor(color.NRGBA{200, 0, 0, 255})
|
||||
this.gc.SetLineWidth(2)
|
||||
this.gc.FillStroke()
|
||||
|
||||
|
||||
this.SetSmallFont()
|
||||
|
||||
|
||||
// 左侧写字
|
||||
this.NewP()
|
||||
this.InsertText("本文来自 " + username + " 的leanote笔记", true, " ")
|
||||
@@ -389,11 +389,11 @@ func (this *Html2Image) SetBottom(username, url string) {
|
||||
siteUrl = "http://leanote.com"
|
||||
}
|
||||
this.InsertA(siteUrl + "/blog/" + username, false)
|
||||
|
||||
|
||||
this.setLogo()
|
||||
// this.painWidth = this.width - 100
|
||||
// this.NewP()
|
||||
// this.InsertText("leanote, 不一样的笔记.", false, " ")
|
||||
// this.InsertText("leanote, 不一样的笔记.", false, " ")
|
||||
// this.NewBr()
|
||||
// this.InsertText("在这里你可以管理自己的知识", false, " ")
|
||||
// this.NewBr()
|
||||
@@ -401,7 +401,7 @@ func (this *Html2Image) SetBottom(username, url string) {
|
||||
// this.NewBr()
|
||||
// this.InsertText("并且还可以将笔记设为博客公开", false, " ")
|
||||
// this.InsertText(". 赶紧加入吧! leanote.com", false, "")
|
||||
//
|
||||
//
|
||||
// Logo
|
||||
}
|
||||
|
||||
@@ -411,7 +411,7 @@ func (this *Html2Image) setImage(path string, x, y float64) {
|
||||
return;
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
var m1 image.Image
|
||||
_, ext := lea.SplitFilename(path)
|
||||
if ext == ".png" {
|
||||
@@ -424,8 +424,8 @@ func (this *Html2Image) setImage(path string, x, y float64) {
|
||||
if err != nil {
|
||||
return
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.gc.Translate(x, y)
|
||||
this.gc.DrawImage(m1)
|
||||
this.gc.Translate(-x, -y)
|
||||
@@ -448,10 +448,10 @@ func (this *Html2Image) InsertA(text string, isNormal bool) {
|
||||
if text == "" {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
this.SetAColor()
|
||||
this.InsertText(text, true, "")
|
||||
|
||||
|
||||
// 还原
|
||||
if isNormal {
|
||||
this.SetNormalFont()
|
||||
@@ -464,17 +464,17 @@ func (this *Html2Image) InsertA(text string, isNormal bool) {
|
||||
func (this *Html2Image) InsertTitle(title string) {
|
||||
oldX := this.x
|
||||
oldY := this.y - 35
|
||||
|
||||
|
||||
// 插入之
|
||||
this.SetTitleFont()
|
||||
|
||||
|
||||
this.InsertText(title, true, " ")
|
||||
|
||||
|
||||
// 还原字体大小
|
||||
this.SetNormalFont()
|
||||
|
||||
|
||||
this.NewBr()
|
||||
|
||||
|
||||
this.gc.MoveTo(oldX, oldY)
|
||||
this.gc.LineTo(this.x, this.y - 10)
|
||||
this.gc.SetStrokeColor(color.NRGBA{200, 0, 0, 255})
|
||||
@@ -512,7 +512,7 @@ func (this *Html2Image) InsertCode(n *html.Node) {
|
||||
}
|
||||
}
|
||||
this.NewBr()
|
||||
|
||||
|
||||
this.gc.MoveTo(oldX, oldY)
|
||||
this.gc.LineTo(this.x, this.y - 20)
|
||||
this.gc.SetStrokeColor(color.NRGBA{0, 200, 0, 255})
|
||||
@@ -521,14 +521,14 @@ func (this *Html2Image) InsertCode(n *html.Node) {
|
||||
}
|
||||
|
||||
// 插入图片
|
||||
// 这个path应该是url,
|
||||
// 这个path应该是url,
|
||||
// http://abc.com/a.gif 需要先下载
|
||||
// 或 /upload/a.gif
|
||||
func (this *Html2Image) InsertImage(path string, needTrans bool, width uint) {
|
||||
if path == "" {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 是url, 那么取网络图片之
|
||||
var ok bool
|
||||
if strings.HasPrefix(path, "http") || strings.HasPrefix(path, "//") {
|
||||
@@ -539,7 +539,7 @@ func (this *Html2Image) InsertImage(path string, needTrans bool, width uint) {
|
||||
} else {
|
||||
path = revel.BasePath + "/public/" + path
|
||||
}
|
||||
|
||||
|
||||
// 需要转换, logo不需要转换
|
||||
if(needTrans) {
|
||||
painWidth := uint(this.painWidth - 10)
|
||||
@@ -557,7 +557,7 @@ func (this *Html2Image) InsertImage(path string, needTrans bool, width uint) {
|
||||
return;
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
var m1 image.Image
|
||||
_, ext := lea.SplitFilename(path)
|
||||
if ext == ".png" {
|
||||
@@ -568,8 +568,8 @@ func (this *Html2Image) InsertImage(path string, needTrans bool, width uint) {
|
||||
if err != nil {
|
||||
return
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 如果之前是p, 那么不要有<br>
|
||||
if this.preTag.Data != "p" {
|
||||
this.NewBr()
|
||||
@@ -580,9 +580,9 @@ func (this *Html2Image) InsertImage(path string, needTrans bool, width uint) {
|
||||
this.gc.Translate(-this.x, -this.y) // 这个有用些
|
||||
this.y += float64(m1.Bounds().Dy()) - 20
|
||||
this.NewP()
|
||||
|
||||
|
||||
os.Remove(path)
|
||||
|
||||
|
||||
// 如果图片是文章第一个的话, 之后的需要p
|
||||
this.isFirstP = false
|
||||
}
|
||||
@@ -605,7 +605,7 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
this.preTag = n
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
// 标签
|
||||
if n.Type == html.ElementNode {
|
||||
if n.Data == "p" {
|
||||
@@ -616,7 +616,7 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 也是一个段落, 只是要缩进
|
||||
if n.Data == "ul" || n.Data == "ol" {
|
||||
this.NewP()
|
||||
@@ -637,7 +637,7 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
} else {
|
||||
f(c, n, "")
|
||||
}
|
||||
|
||||
|
||||
if c.Type == html.ElementNode {
|
||||
if c.Data == "br" || c.Data == "p" {
|
||||
needPrefix = true
|
||||
@@ -650,19 +650,19 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
this.NewBr()
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 标题
|
||||
if n.Data == "h1" || n.Data == "h2" || n.Data == "h3" || n.Data == "h4" {
|
||||
this.InsertHead(n)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if n.Data == "pre" {
|
||||
// 把之后的全拿过来
|
||||
this.InsertCode(n)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 图片
|
||||
// 得到src
|
||||
if n.Data == "img" {
|
||||
@@ -680,22 +680,22 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 链接
|
||||
// 如果链接里只有文本, 那么单独处理, 如果还有其它的, 不作链接处理
|
||||
if n.Data == "a" {
|
||||
if n.FirstChild == n.LastChild {
|
||||
this.InsertA(n.FirstChild.Data, true)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 空行
|
||||
if n.Data == "br" { // || n.Data == "div"
|
||||
this.NewBr()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 是文本, 输出之
|
||||
if n.Type == html.TextNode {
|
||||
data := strings.TrimSpace(n.Data);
|
||||
@@ -705,36 +705,36 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 其余的
|
||||
|
||||
|
||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||
f(c, n, prefix)
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
f(doc, nil, "")
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 主函数
|
||||
func ToImage(uid, username, noteId, title, htmlStr, toPath string) (ok bool) {
|
||||
h := NewHtml2Image()
|
||||
|
||||
|
||||
// 标题
|
||||
h.InsertTitle(title)
|
||||
|
||||
|
||||
// 主体
|
||||
ok = h.InsertBody(htmlStr)
|
||||
if(!ok) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 页眉与页脚
|
||||
h.SetBottom(username, "")
|
||||
|
||||
|
||||
// 保存成png图片
|
||||
ok = h.SaveToPngFile(toPath)
|
||||
return
|
||||
@@ -757,4 +757,4 @@ func TestFillString() {
|
||||
|
||||
func ToImage(uid, username, noteId, title, htmlStr, toPath string) (ok bool) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,4 +7,3 @@ import (
|
||||
func Html2Image(userInfo info.User, note info.Note, content, toPath string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"os"
|
||||
// "path/filepath"
|
||||
"strings"
|
||||
// "path/filepath"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
)
|
||||
|
||||
// net的util
|
||||
@@ -16,33 +17,33 @@ import (
|
||||
// 返回文件的完整目录
|
||||
func WriteUrl(url string, toPath string) (length int64, newFilename, path string, ok bool) {
|
||||
if url == "" {
|
||||
return;
|
||||
return
|
||||
}
|
||||
content, err := GetContent(url)
|
||||
if err != nil {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
length = int64(len(content))
|
||||
|
||||
|
||||
// a.html?a=a11&xxx
|
||||
url = trimQueryParams(url)
|
||||
_, ext := SplitFilename(url)
|
||||
if toPath == "" {
|
||||
toPath = "/tmp"
|
||||
}
|
||||
// dir := filepath.Dir(toPath)
|
||||
// dir := filepath.Dir(toPath)
|
||||
newFilename = NewGuid() + ext
|
||||
fullPath := toPath + "/" + newFilename
|
||||
|
||||
|
||||
// 写到文件中
|
||||
file, err := os.Create(fullPath)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
return
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
file.Write(content)
|
||||
|
||||
|
||||
path = fullPath
|
||||
ok = true
|
||||
return
|
||||
@@ -53,43 +54,43 @@ func GetContent(url string) (content []byte, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = http.Get(url)
|
||||
Log(err)
|
||||
if(resp != nil && resp.Body != nil) {
|
||||
if resp != nil && resp.Body != nil {
|
||||
defer resp.Body.Close()
|
||||
} else {
|
||||
}
|
||||
if resp == nil || resp.Body == nil || err != nil || resp.StatusCode != http.StatusOK {
|
||||
return
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
buf, err = ioutil.ReadAll(resp.Body)
|
||||
if(err != nil) {
|
||||
Log(err)
|
||||
if resp == nil || resp.Body == nil || err != nil || resp.StatusCode != http.StatusOK {
|
||||
return
|
||||
}
|
||||
|
||||
content = buf;
|
||||
err = nil
|
||||
return
|
||||
|
||||
var buf []byte
|
||||
buf, err = ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
Log(err)
|
||||
return
|
||||
}
|
||||
|
||||
content = buf
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
// 将url ?, #后面的字符串去掉
|
||||
func trimQueryParams(url string) string {
|
||||
pos := strings.Index(url, "?");
|
||||
pos := strings.Index(url, "?")
|
||||
if pos != -1 {
|
||||
url = Substr(url, 0, pos);
|
||||
url = Substr(url, 0, pos)
|
||||
}
|
||||
|
||||
pos = strings.Index(url, "#");
|
||||
|
||||
pos = strings.Index(url, "#")
|
||||
if pos != -1 {
|
||||
url = Substr(url, 0, pos);
|
||||
url = Substr(url, 0, pos)
|
||||
}
|
||||
|
||||
pos = strings.Index(url, "!");
|
||||
|
||||
pos = strings.Index(url, "!")
|
||||
if pos != -1 {
|
||||
url = Substr(url, 0, pos);
|
||||
url = Substr(url, 0, pos)
|
||||
}
|
||||
return url;
|
||||
return url
|
||||
}
|
||||
|
||||
// 通过domain得到ip
|
||||
@@ -99,4 +100,4 @@ func GetIpFromDomain(domain string) string {
|
||||
return ip[0].String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
@@ -11,10 +11,11 @@ import (
|
||||
// overwite revel RouterFilter
|
||||
// /api/user/Info => ApiUser.Info()
|
||||
var staticPrefix = []string{"/public", "/favicon.ico", "/css", "/js", "/images", "/tinymce", "/upload", "/fonts"}
|
||||
|
||||
func RouterFilter(c *revel.Controller, fc []revel.Filter) {
|
||||
// 补全controller部分
|
||||
path := c.Request.Request.URL.Path
|
||||
|
||||
|
||||
// Figure out the Controller/Action
|
||||
var route *revel.RouteMatch = revel.MainRouter.Route(c.Request.Request)
|
||||
if route == nil {
|
||||
@@ -27,29 +28,29 @@ func RouterFilter(c *revel.Controller, fc []revel.Filter) {
|
||||
c.Result = c.NotFound("(intentionally)")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
//----------
|
||||
// life start
|
||||
/*
|
||||
type URL struct {
|
||||
Scheme string
|
||||
Opaque string // encoded opaque data
|
||||
User *Userinfo // username and password information
|
||||
Host string // host or host:port
|
||||
Path string
|
||||
RawQuery string // encoded query values, without '?'
|
||||
Fragment string // fragment for references, without '#'
|
||||
}
|
||||
type URL struct {
|
||||
Scheme string
|
||||
Opaque string // encoded opaque data
|
||||
User *Userinfo // username and password information
|
||||
Host string // host or host:port
|
||||
Path string
|
||||
RawQuery string // encoded query values, without '?'
|
||||
Fragment string // fragment for references, without '#'
|
||||
}
|
||||
*/
|
||||
if route.ControllerName != "Static" {
|
||||
|
||||
// 检查mongodb 是否lost
|
||||
db.CheckMongoSessionLost()
|
||||
|
||||
|
||||
// api设置
|
||||
// leanote.com/api/user/get => ApiUser::Get
|
||||
//* /api/login ApiAuth.Login, 这里的设置, 其实已经转成了ApiAuth了
|
||||
if strings.HasPrefix(path, "/api") && !strings.HasPrefix(route.ControllerName, "Api"){
|
||||
if strings.HasPrefix(path, "/api") && !strings.HasPrefix(route.ControllerName, "Api") {
|
||||
route.ControllerName = "Api" + route.ControllerName
|
||||
} else if strings.HasPrefix(path, "/member") && !strings.HasPrefix(route.ControllerName, "Member") {
|
||||
// member设置
|
||||
@@ -57,7 +58,7 @@ func RouterFilter(c *revel.Controller, fc []revel.Filter) {
|
||||
}
|
||||
// end
|
||||
}
|
||||
|
||||
|
||||
// Set the action.
|
||||
if err := c.SetAction(route.ControllerName, route.MethodName); err != nil {
|
||||
c.Result = c.NotFound(err.Error())
|
||||
@@ -84,4 +85,3 @@ func RouterFilter(c *revel.Controller, fc []revel.Filter) {
|
||||
|
||||
fc[0](c, fc[1:])
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
// "time"
|
||||
// "time"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -31,10 +31,10 @@ import (
|
||||
*/
|
||||
|
||||
//var jss = []string{"js/jquery-cookie", "js/bootstrap"}
|
||||
var jss = []string{"js/jquery-cookie", "js/bootstrap",
|
||||
"js/common", "js/app/note", "js/app/tag", "js/app/notebook", "js/app/share",
|
||||
var jss = []string{"js/jquery-cookie", "js/bootstrap",
|
||||
"js/common", "js/app/note", "js/app/tag", "js/app/notebook", "js/app/share",
|
||||
"js/object_id", "js/ZeroClipboard/ZeroClipboard"}
|
||||
|
||||
|
||||
var base1 = "/Users/life/Documents/Go/package2/src/github.com/leanote/leanote/"
|
||||
var base = "/Users/life/Documents/Go/package2/src/github.com/leanote/leanote/public/"
|
||||
var cmdPath = "/usr/local/bin/uglifyjs"
|
||||
@@ -54,26 +54,26 @@ func compressJs(filename string) {
|
||||
to := base + filename + "-min.js"
|
||||
cmd := exec.Command(cmdPath, source, "-o", to)
|
||||
_, err := cmd.CombinedOutput()
|
||||
fmt.Println(source);
|
||||
fmt.Println(source)
|
||||
cmdError(err)
|
||||
}
|
||||
|
||||
|
||||
func combineJs() {
|
||||
// 生成一个总文件
|
||||
cmd := exec.Command("rm", base + "js/all.js")
|
||||
cmd := exec.Command("rm", base+"js/all.js")
|
||||
_, err := cmd.CombinedOutput()
|
||||
cmdError(err)
|
||||
|
||||
|
||||
for _, js := range jss {
|
||||
to := base + js + "-min.js"
|
||||
fmt.Println(to)
|
||||
compressJs(js)
|
||||
|
||||
|
||||
// 每个压缩后的文件放入之
|
||||
cmd2 := exec.Command("/bin/sh", "-c", "cat " + to + " >> " + base + "js/all.js")
|
||||
cmd2 := exec.Command("/bin/sh", "-c", "cat "+to+" >> "+base+"js/all.js")
|
||||
_, err := cmd2.CombinedOutput()
|
||||
cmdError(err)
|
||||
cmd2 = exec.Command("/bin/sh", "-c", "cat \n >> " + base + "js/all.js")
|
||||
cmd2 = exec.Command("/bin/sh", "-c", "cat \n >> "+base+"js/all.js")
|
||||
_, err = cmd2.CombinedOutput()
|
||||
cmdError(err)
|
||||
}
|
||||
@@ -82,57 +82,57 @@ func combineJs() {
|
||||
// 改note-dev->note
|
||||
func dev() {
|
||||
// 即替换note.js->note-min.js
|
||||
m := map[string]string{"tinymce.dev.js": "tinymce.min.js",
|
||||
"tinymce.js": "tinymce.min.js",
|
||||
"jquery.ztree.all-3.5.js": "jquery.ztree.all-3.5-min.js",
|
||||
"note.js": "note-min.js",
|
||||
"app.js": "app-min.js",
|
||||
"page.js": "page-min.js",
|
||||
"common.js": "common-min.js",
|
||||
"notebook.js": "notebook-min.js",
|
||||
"share.js": "share-min.js",
|
||||
"tag.js": "tag-min.js",
|
||||
"jquery.slimscroll.js": "jquery.slimscroll-min.js",
|
||||
"jquery.contextmenu.js": "jquery.contextmenu-min.js",
|
||||
"editor/editor.js": "editor/editor-min.js",
|
||||
m := map[string]string{"tinymce.dev.js": "tinymce.min.js",
|
||||
"tinymce.js": "tinymce.min.js",
|
||||
"jquery.ztree.all-3.5.js": "jquery.ztree.all-3.5-min.js",
|
||||
"note.js": "note-min.js",
|
||||
"app.js": "app-min.js",
|
||||
"page.js": "page-min.js",
|
||||
"common.js": "common-min.js",
|
||||
"notebook.js": "notebook-min.js",
|
||||
"share.js": "share-min.js",
|
||||
"tag.js": "tag-min.js",
|
||||
"jquery.slimscroll.js": "jquery.slimscroll-min.js",
|
||||
"jquery.contextmenu.js": "jquery.contextmenu-min.js",
|
||||
"editor/editor.js": "editor/editor-min.js",
|
||||
"/public/mdeditor/editor/scrollLink.js": "/public/mdeditor/editor/scrollLink-min.js",
|
||||
"console.log(o);": "",
|
||||
}
|
||||
"console.log(o);": "",
|
||||
}
|
||||
path := base1 + "/src/views/note/note-dev.html"
|
||||
target := base1 + "/src/views/note/note.html"
|
||||
|
||||
|
||||
bs, _ := ioutil.ReadFile(path)
|
||||
content := string(bs)
|
||||
print(content)
|
||||
for key, value := range m {
|
||||
content = strings.Replace(content, key, value, -1)
|
||||
}
|
||||
|
||||
// var time = time.Now().Unix() % 1000
|
||||
|
||||
// content = strings.Replace(content, "-min.js", fmt.Sprintf("-min.js?r=%d", time), -1)
|
||||
// content = strings.Replace(content, "default{{end}}.css", fmt.Sprintf("default{{end}}.css?r=%d", time), 1)
|
||||
// content = strings.Replace(content, "writting-overwrite.css", fmt.Sprintf("writting-overwrite.css?r=%d", time), 1)
|
||||
|
||||
|
||||
// var time = time.Now().Unix() % 1000
|
||||
|
||||
// content = strings.Replace(content, "-min.js", fmt.Sprintf("-min.js?r=%d", time), -1)
|
||||
// content = strings.Replace(content, "default{{end}}.css", fmt.Sprintf("default{{end}}.css?r=%d", time), 1)
|
||||
// content = strings.Replace(content, "writting-overwrite.css", fmt.Sprintf("writting-overwrite.css?r=%d", time), 1)
|
||||
|
||||
ioutil.WriteFile(target, []byte(content), os.ModeAppend)
|
||||
}
|
||||
|
||||
// 压缩js成一块
|
||||
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]"
|
||||
// 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");
|
||||
// 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("/bin/sh", "-c", "grunt minify")
|
||||
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")
|
||||
cmd2.CombinedOutput()
|
||||
cmd2 = exec.Command("/bin/sh", "-c", "rm " + cmd.Dir + "/js/tinymce/tinymce.jquery.dev.js")
|
||||
cmd2 = exec.Command("/bin/sh", "-c", "rm "+cmd.Dir+"/js/tinymce/tinymce.jquery.dev.js")
|
||||
c, _ := cmd2.CombinedOutput()
|
||||
fmt.Println(string(c))
|
||||
|
||||
|
||||
c, _ = cmd.CombinedOutput()
|
||||
fmt.Println(string(c))
|
||||
}
|
||||
@@ -140,19 +140,19 @@ func tinymce() {
|
||||
func main() {
|
||||
// 压缩tinymce
|
||||
// tinymce()
|
||||
|
||||
dev();
|
||||
|
||||
|
||||
dev()
|
||||
|
||||
// 其它零散的需要压缩的js
|
||||
otherJss := []string{"js/main", "js/app/page", "js/contextmenu/jquery.contextmenu",
|
||||
otherJss := []string{"js/main", "js/app/page", "js/contextmenu/jquery.contextmenu",
|
||||
"js/jquery.ztree.all-3.5",
|
||||
"js/jQuery-slimScroll-1.3.0/jquery.slimscroll",
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for _, js := range otherJss {
|
||||
compressJs(js)
|
||||
}
|
||||
|
||||
|
||||
// 先压缩后合并
|
||||
combineJs()
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"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"
|
||||
"time"
|
||||
@@ -30,9 +30,9 @@ func (this *AlbumService) GetAlbums(userId string) []info.Album {
|
||||
// delete album
|
||||
// presupposition: has no images under this ablum
|
||||
func (this *AlbumService) DeleteAlbum(userId, albumId string) (bool, string) {
|
||||
if db.Count(db.Files, bson.M{"AlbumId": bson.ObjectIdHex(albumId),
|
||||
if db.Count(db.Files, bson.M{"AlbumId": bson.ObjectIdHex(albumId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
}) == 0 {
|
||||
}) == 0 {
|
||||
return db.DeleteByIdAndUserId(db.Albums, albumId, userId), ""
|
||||
}
|
||||
return false, "has images"
|
||||
@@ -41,4 +41,4 @@ func (this *AlbumService) DeleteAlbum(userId, albumId string) (bool, string) {
|
||||
// update album name
|
||||
func (this *AlbumService) UpdateAlbum(albumId, userId, name string) bool {
|
||||
return db.UpdateByIdAndUserIdField(db.Albums, albumId, userId, "Name", name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ type AttachService struct {
|
||||
func (this *AttachService) AddAttach(attach info.Attach, fromApi bool) (ok bool, msg string) {
|
||||
attach.CreatedTime = time.Now()
|
||||
ok = db.Insert(db.Attachs, attach)
|
||||
|
||||
|
||||
note := noteService.GetNoteById(attach.NoteId.Hex())
|
||||
|
||||
|
||||
// api调用时, 添加attach之前是没有note的
|
||||
var userId string
|
||||
if note.NoteId != "" {
|
||||
@@ -35,13 +35,13 @@ func (this *AttachService) AddAttach(attach info.Attach, fromApi bool) (ok bool,
|
||||
// 更新笔记的attachs num
|
||||
this.updateNoteAttachNum(attach.NoteId, 1)
|
||||
}
|
||||
|
||||
|
||||
if !fromApi {
|
||||
// 增长note's usn
|
||||
noteService.IncrNoteUsn(attach.NoteId.Hex(), userId)
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 更新笔记的附件个数
|
||||
@@ -49,13 +49,13 @@ func (this *AttachService) AddAttach(attach info.Attach, fromApi bool) (ok bool,
|
||||
func (this *AttachService) updateNoteAttachNum(noteId bson.ObjectId, addNum int) bool {
|
||||
num := db.Count(db.Attachs, bson.M{"NoteId": noteId})
|
||||
/*
|
||||
note := info.Note{}
|
||||
note = noteService.GetNoteById(noteId.Hex())
|
||||
note.AttachNum += addNum
|
||||
if note.AttachNum < 0 {
|
||||
note.AttachNum = 0
|
||||
}
|
||||
Log(note.AttachNum)
|
||||
note := info.Note{}
|
||||
note = noteService.GetNoteById(noteId.Hex())
|
||||
note.AttachNum += addNum
|
||||
if note.AttachNum < 0 {
|
||||
note.AttachNum = 0
|
||||
}
|
||||
Log(note.AttachNum)
|
||||
*/
|
||||
return db.UpdateByQField(db.Notes, bson.M{"_id": noteId}, "AttachNum", num)
|
||||
}
|
||||
@@ -63,18 +63,18 @@ func (this *AttachService) updateNoteAttachNum(noteId bson.ObjectId, addNum int)
|
||||
// list attachs
|
||||
func (this *AttachService) ListAttachs(noteId, userId string) []info.Attach {
|
||||
attachs := []info.Attach{}
|
||||
|
||||
|
||||
// 判断是否有权限为笔记添加附件, userId为空时表示是分享笔记的附件
|
||||
if userId != "" && !shareService.HasUpdateNotePerm(noteId, userId) {
|
||||
return attachs
|
||||
}
|
||||
|
||||
|
||||
// 笔记是否是自己的
|
||||
note := noteService.GetNoteByIdAndUserId(noteId, userId)
|
||||
if note.NoteId == "" {
|
||||
return attachs
|
||||
}
|
||||
|
||||
|
||||
// TODO 这里, 优化权限控制
|
||||
|
||||
db.ListByQ(db.Attachs, bson.M{"NoteId": bson.ObjectIdHex(noteId)}, &attachs)
|
||||
@@ -122,13 +122,13 @@ func (this *AttachService) DeleteAllAttachs(noteId, userId string) bool {
|
||||
func (this *AttachService) DeleteAttach(attachId, userId string) (bool, string) {
|
||||
attach := info.Attach{}
|
||||
db.Get(db.Attachs, attachId, &attach)
|
||||
|
||||
if(attach.AttachId != "") {
|
||||
|
||||
if attach.AttachId != "" {
|
||||
// 判断是否有权限为笔记添加附件
|
||||
if !shareService.HasUpdateNotePerm(attach.NoteId.Hex(), userId) {
|
||||
return false, "No Perm"
|
||||
}
|
||||
|
||||
|
||||
if db.Delete(db.Attachs, bson.M{"_id": bson.ObjectIdHex(attachId)}) {
|
||||
this.updateNoteAttachNum(attach.NoteId, -1)
|
||||
attach.Path = strings.TrimLeft(attach.Path, "/")
|
||||
@@ -137,7 +137,7 @@ func (this *AttachService) DeleteAttach(attachId, userId string) (bool, string)
|
||||
// userService.UpdateAttachSize(note.UserId.Hex(), -attach.Size)
|
||||
// 修改note Usn
|
||||
noteService.IncrNoteUsn(attach.NoteId.Hex(), userId)
|
||||
|
||||
|
||||
return true, "delete file success"
|
||||
}
|
||||
return false, "delete file error"
|
||||
|
||||
@@ -421,7 +421,7 @@ func (this *BlogService) PreNextBlog(userId string, sorterField string, isAsc bo
|
||||
// Log(sortFieldR2)
|
||||
q = db.Notes.Find(query)
|
||||
q.Sort(sortFieldR2).Limit(1).One(¬e2)
|
||||
|
||||
|
||||
return this.FixNote(note), this.FixNote(note2)
|
||||
}
|
||||
|
||||
@@ -919,7 +919,7 @@ func (this *BlogService) UpateCateUrlTitle(userId string, cateId, urlTitle strin
|
||||
"UrlTitle": "",
|
||||
})
|
||||
*/
|
||||
url = GetUrTitle(userId, urlTitle, "notebook")
|
||||
url = GetUrTitle(userId, urlTitle, "notebook", cateId)
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notebooks, cateId, userId, bson.M{
|
||||
"UrlTitle": url,
|
||||
})
|
||||
@@ -935,7 +935,7 @@ func (this *BlogService) UpateBlogUrlTitle(userId string, noteId, urlTitle strin
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, bson.M{
|
||||
"UrlTitle": "",
|
||||
})
|
||||
url = GetUrTitle(userId, urlTitle, "note")
|
||||
url = GetUrTitle(userId, urlTitle, "note", noteId)
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, bson.M{
|
||||
"UrlTitle": url,
|
||||
})
|
||||
@@ -1036,7 +1036,7 @@ func (this *BlogService) UpdateSingleUrlTitle(userId, singleId, urlTitle string)
|
||||
"UrlTitle": "",
|
||||
})
|
||||
*/
|
||||
url = GetUrTitle(userId, urlTitle, "single")
|
||||
url = GetUrTitle(userId, urlTitle, "single", singleId)
|
||||
ok = db.UpdateByIdAndUserIdMap(db.BlogSingles, singleId, userId, bson.M{
|
||||
"UrlTitle": url,
|
||||
})
|
||||
@@ -1070,7 +1070,7 @@ func (this *BlogService) AddOrUpdateSingle(userId, singleId, title, content stri
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
Title: title,
|
||||
Content: content,
|
||||
UrlTitle: GetUrTitle(userId, title, "single"),
|
||||
UrlTitle: GetUrTitle(userId, title, "single", singleId),
|
||||
CreatedTime: time.Now(),
|
||||
}
|
||||
page.UpdatedTime = page.CreatedTime
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"github.com/revel/revel"
|
||||
"time"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"os"
|
||||
"os/exec"
|
||||
"fmt"
|
||||
"strings"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 配置服务
|
||||
// 只是全局的, 用户的配置没有
|
||||
type ConfigService struct {
|
||||
adminUserId string
|
||||
siteUrl string
|
||||
adminUserId string
|
||||
siteUrl string
|
||||
adminUsername string
|
||||
// 全局的
|
||||
GlobalAllConfigs map[string]interface{}
|
||||
GlobalAllConfigs map[string]interface{}
|
||||
GlobalStringConfigs map[string]string
|
||||
GlobalArrayConfigs map[string][]string
|
||||
GlobalMapConfigs map[string]map[string]string
|
||||
GlobalArrayConfigs map[string][]string
|
||||
GlobalMapConfigs map[string]map[string]string
|
||||
GlobalArrMapConfigs map[string][]map[string]string
|
||||
}
|
||||
|
||||
// appStart时 将全局的配置从数据库中得到作为全局
|
||||
func (this *ConfigService) InitGlobalConfigs() bool {
|
||||
this.GlobalAllConfigs = map[string]interface{}{}
|
||||
@@ -34,22 +35,22 @@ func (this *ConfigService) InitGlobalConfigs() bool {
|
||||
this.GlobalArrayConfigs = map[string][]string{}
|
||||
this.GlobalMapConfigs = map[string]map[string]string{}
|
||||
this.GlobalArrMapConfigs = map[string][]map[string]string{}
|
||||
|
||||
|
||||
this.adminUsername, _ = revel.Config.String("adminUsername")
|
||||
if this.adminUsername == "" {
|
||||
this.adminUsername = "admin"
|
||||
}
|
||||
this.siteUrl, _ = revel.Config.String("site.url")
|
||||
|
||||
|
||||
userInfo := userService.GetUserInfoByAny(this.adminUsername)
|
||||
if userInfo.UserId == "" {
|
||||
return false
|
||||
}
|
||||
this.adminUserId = userInfo.UserId.Hex()
|
||||
|
||||
|
||||
configs := []info.Config{}
|
||||
db.ListByQ(db.Configs, bson.M{"UserId": userInfo.UserId}, &configs)
|
||||
|
||||
|
||||
for _, config := range configs {
|
||||
if config.IsArr {
|
||||
this.GlobalArrayConfigs[config.Key] = config.ValueArr
|
||||
@@ -65,12 +66,12 @@ func (this *ConfigService) InitGlobalConfigs() bool {
|
||||
this.GlobalAllConfigs[config.Key] = config.ValueStr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *ConfigService) GetSiteUrl() string {
|
||||
return this.siteUrl;
|
||||
return this.siteUrl
|
||||
}
|
||||
func (this *ConfigService) GetAdminUsername() string {
|
||||
return this.adminUsername
|
||||
@@ -84,15 +85,15 @@ func (this *ConfigService) updateGlobalConfig(userId, key string, value interfac
|
||||
// 判断是否存在
|
||||
if _, ok := this.GlobalAllConfigs[key]; !ok {
|
||||
// 需要添加
|
||||
config := info.Config{ConfigId: bson.NewObjectId(),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
Key: key,
|
||||
IsArr: isArr,
|
||||
IsMap: isMap,
|
||||
IsArrMap: isArrMap,
|
||||
config := info.Config{ConfigId: bson.NewObjectId(),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
Key: key,
|
||||
IsArr: isArr,
|
||||
IsMap: isMap,
|
||||
IsArrMap: isArrMap,
|
||||
UpdatedTime: time.Now(),
|
||||
}
|
||||
if(isArr) {
|
||||
if isArr {
|
||||
v, _ := value.([]string)
|
||||
config.ValueArr = v
|
||||
this.GlobalArrayConfigs[key] = v
|
||||
@@ -113,7 +114,7 @@ func (this *ConfigService) updateGlobalConfig(userId, key string, value interfac
|
||||
} else {
|
||||
i := bson.M{"UpdatedTime": time.Now()}
|
||||
this.GlobalAllConfigs[key] = value
|
||||
if(isArr) {
|
||||
if isArr {
|
||||
v, _ := value.([]string)
|
||||
i["ValueArr"] = v
|
||||
this.GlobalArrayConfigs[key] = v
|
||||
@@ -177,25 +178,26 @@ func (this *ConfigService) GetGlobalArrMapConfig(key string) []map[string]string
|
||||
func (this *ConfigService) IsOpenRegister() bool {
|
||||
return this.GetGlobalStringConfig("openRegister") != ""
|
||||
}
|
||||
|
||||
//-------
|
||||
// 修改共享笔记的配置
|
||||
func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
registerSharedNotebookPerms, registerSharedNotePerms []int,
|
||||
func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
registerSharedNotebookPerms, registerSharedNotePerms []int,
|
||||
registerSharedNotebookIds, registerSharedNoteIds, registerCopyNoteIds []string) (ok bool, msg string) {
|
||||
|
||||
defer func() {
|
||||
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
msg = fmt.Sprint(err)
|
||||
}
|
||||
}();
|
||||
|
||||
}()
|
||||
|
||||
// 用户是否存在?
|
||||
if registerSharedUserId == "" {
|
||||
ok = true
|
||||
msg = "share userId is blank, So it share nothing to register"
|
||||
this.UpdateGlobalStringConfig(this.adminUserId, "registerSharedUserId", "")
|
||||
return
|
||||
return
|
||||
} else {
|
||||
user := userService.GetUserInfo(registerSharedUserId)
|
||||
if user.UserId == "" {
|
||||
@@ -206,7 +208,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
this.UpdateGlobalStringConfig(this.adminUserId, "registerSharedUserId", registerSharedUserId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
notebooks := []map[string]string{}
|
||||
// 共享笔记本
|
||||
if len(registerSharedNotebookIds) > 0 {
|
||||
@@ -222,7 +224,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
msg = "The user has no such notebook: " + notebookId
|
||||
return
|
||||
} else {
|
||||
perm := "0";
|
||||
perm := "0"
|
||||
if registerSharedNotebookPerms[i] == 1 {
|
||||
perm = "1"
|
||||
}
|
||||
@@ -231,7 +233,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
}
|
||||
}
|
||||
this.UpdateGlobalArrMapConfig(this.adminUserId, "registerSharedNotebooks", notebooks)
|
||||
|
||||
|
||||
notes := []map[string]string{}
|
||||
// 共享笔记
|
||||
if len(registerSharedNoteIds) > 0 {
|
||||
@@ -247,7 +249,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
msg = "The user has no such note: " + noteId
|
||||
return
|
||||
} else {
|
||||
perm := "0";
|
||||
perm := "0"
|
||||
if registerSharedNotePerms[i] == 1 {
|
||||
perm = "1"
|
||||
}
|
||||
@@ -256,7 +258,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
}
|
||||
}
|
||||
this.UpdateGlobalArrMapConfig(this.adminUserId, "registerSharedNotes", notes)
|
||||
|
||||
|
||||
// 复制
|
||||
noteIds := []string{}
|
||||
if len(registerCopyNoteIds) > 0 {
|
||||
@@ -277,7 +279,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
}
|
||||
}
|
||||
this.UpdateGlobalArrayConfig(this.adminUserId, "registerCopyNoteIds", noteIds)
|
||||
|
||||
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
@@ -298,7 +300,7 @@ func (this *ConfigService) getBackupDirname() string {
|
||||
}
|
||||
func (this *ConfigService) Backup(remark string) (ok bool, msg string) {
|
||||
binPath := configService.GetGlobalStringConfig("mongodumpPath")
|
||||
config := revel.Config;
|
||||
config := revel.Config
|
||||
dbname, _ := config.String("db.dbname")
|
||||
host, _ := revel.Config.String("db.host")
|
||||
port, _ := revel.Config.String("db.port")
|
||||
@@ -318,20 +320,21 @@ func (this *ConfigService) Backup(remark string) (ok bool, msg string) {
|
||||
msg = fmt.Sprintf("%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
cmd := exec.Command("/bin/sh", "-c", binPath)
|
||||
Log(binPath);
|
||||
Log(binPath)
|
||||
b, err := cmd.Output()
|
||||
if err != nil {
|
||||
msg = fmt.Sprintf("%v", err)
|
||||
if err != nil {
|
||||
msg = fmt.Sprintf("%v", err)
|
||||
ok = false
|
||||
Log("error:......")
|
||||
Log(string(b))
|
||||
return
|
||||
}
|
||||
Log("error:......")
|
||||
Log(string(b))
|
||||
return
|
||||
}
|
||||
ok = configService.AddBackup(dir, remark)
|
||||
return ok, msg
|
||||
return ok, msg
|
||||
}
|
||||
|
||||
// 还原
|
||||
func (this *ConfigService) Restore(createdTime string) (ok bool, msg string) {
|
||||
backups := this.GetGlobalArrMapConfig("backups") // [{}, {}]
|
||||
@@ -339,22 +342,22 @@ func (this *ConfigService) Restore(createdTime string) (ok bool, msg string) {
|
||||
var backup map[string]string
|
||||
for i, backup = range backups {
|
||||
if backup["createdTime"] == createdTime {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
if i == len(backups) {
|
||||
return false, "Backup Not Found"
|
||||
}
|
||||
|
||||
|
||||
// 先备份当前
|
||||
ok, msg = this.Backup("Auto backup when restore from " + backup["createdTime"] )
|
||||
ok, msg = this.Backup("Auto backup when restore from " + backup["createdTime"])
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// mongorestore -h localhost -d leanote --directoryperdb /home/user1/gopackage/src/github.com/leanote/leanote/mongodb_backup/leanote_install_data/
|
||||
binPath := configService.GetGlobalStringConfig("mongorestorePath")
|
||||
config := revel.Config;
|
||||
config := revel.Config
|
||||
dbname, _ := config.String("db.dbname")
|
||||
host, _ := revel.Config.String("db.host")
|
||||
port, _ := revel.Config.String("db.port")
|
||||
@@ -365,26 +368,26 @@ func (this *ConfigService) Restore(createdTime string) (ok bool, msg string) {
|
||||
if username != "" {
|
||||
binPath += " -u " + username + " -p " + password
|
||||
}
|
||||
|
||||
|
||||
path := backup["path"] + "/" + dbname
|
||||
// 判断路径是否存在
|
||||
if !IsDirExists(path) {
|
||||
return false, path + " Is Not Exists"
|
||||
}
|
||||
|
||||
|
||||
binPath += " " + path
|
||||
|
||||
|
||||
cmd := exec.Command("/bin/sh", "-c", binPath)
|
||||
Log(binPath);
|
||||
Log(binPath)
|
||||
b, err := cmd.Output()
|
||||
if err != nil {
|
||||
msg = fmt.Sprintf("%v", err)
|
||||
if err != nil {
|
||||
msg = fmt.Sprintf("%v", err)
|
||||
ok = false
|
||||
Log("error:......")
|
||||
Log(string(b))
|
||||
return
|
||||
}
|
||||
|
||||
Log("error:......")
|
||||
Log(string(b))
|
||||
return
|
||||
}
|
||||
|
||||
return true, ""
|
||||
}
|
||||
func (this *ConfigService) DeleteBackup(createdTime string) (bool, string) {
|
||||
@@ -393,22 +396,22 @@ func (this *ConfigService) DeleteBackup(createdTime string) (bool, string) {
|
||||
var backup map[string]string
|
||||
for i, backup = range backups {
|
||||
if backup["createdTime"] == createdTime {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
if i == len(backups) {
|
||||
return false, "Backup Not Found"
|
||||
}
|
||||
|
||||
|
||||
// 删除文件夹之
|
||||
err := os.RemoveAll(backups[i]["path"])
|
||||
if err != nil {
|
||||
return false, fmt.Sprintf("%v", err)
|
||||
}
|
||||
|
||||
|
||||
// 删除之
|
||||
backups = append(backups[0:i], backups[i+1:]...)
|
||||
|
||||
|
||||
ok := this.UpdateGlobalArrMapConfig(this.adminUserId, "backups", backups)
|
||||
return ok, ""
|
||||
}
|
||||
@@ -419,14 +422,14 @@ func (this *ConfigService) UpdateBackupRemark(createdTime, remark string) (bool,
|
||||
var backup map[string]string
|
||||
for i, backup = range backups {
|
||||
if backup["createdTime"] == createdTime {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
if i == len(backups) {
|
||||
return false, "Backup Not Found"
|
||||
}
|
||||
backup["remark"] = remark;
|
||||
|
||||
backup["remark"] = remark
|
||||
|
||||
ok := this.UpdateGlobalArrMapConfig(this.adminUserId, "backups", backups)
|
||||
return ok, ""
|
||||
}
|
||||
@@ -438,7 +441,7 @@ func (this *ConfigService) GetBackup(createdTime string) (map[string]string, boo
|
||||
var backup map[string]string
|
||||
for i, backup = range backups {
|
||||
if backup["createdTime"] == createdTime {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
if i == len(backups) {
|
||||
@@ -456,15 +459,15 @@ var port string
|
||||
func init() {
|
||||
revel.OnAppStart(func() {
|
||||
/*
|
||||
不用配置的, 因为最终通过命令可以改, 而且有的使用nginx代理
|
||||
port = strconv.Itoa(revel.HttpPort)
|
||||
if port != "80" {
|
||||
port = ":" + port
|
||||
} else {
|
||||
port = "";
|
||||
}
|
||||
不用配置的, 因为最终通过命令可以改, 而且有的使用nginx代理
|
||||
port = strconv.Itoa(revel.HttpPort)
|
||||
if port != "80" {
|
||||
port = ":" + port
|
||||
} else {
|
||||
port = "";
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
siteUrl, _ := revel.Config.String("site.url") // 已包含:9000, http, 去掉成 leanote.com
|
||||
if strings.HasPrefix(siteUrl, "http://") {
|
||||
defaultDomain = siteUrl[len("http://"):]
|
||||
@@ -472,7 +475,7 @@ func init() {
|
||||
defaultDomain = siteUrl[len("https://"):]
|
||||
schema = "https://"
|
||||
}
|
||||
|
||||
|
||||
// port localhost:9000
|
||||
ports := strings.Split(defaultDomain, ":")
|
||||
if len(ports) == 2 {
|
||||
@@ -487,49 +490,53 @@ func init() {
|
||||
}
|
||||
|
||||
func (this *ConfigService) GetSchema() string {
|
||||
return schema;
|
||||
return schema
|
||||
}
|
||||
|
||||
// 默认
|
||||
func (this *ConfigService) GetDefaultDomain() string {
|
||||
return defaultDomain
|
||||
}
|
||||
|
||||
// 包含http://
|
||||
func (this *ConfigService) GetDefaultUrl() string {
|
||||
return schema + defaultDomain
|
||||
}
|
||||
|
||||
// note
|
||||
func (this *ConfigService) GetNoteDomain() string {
|
||||
subDomain := this.GetGlobalStringConfig("noteSubDomain");
|
||||
subDomain := this.GetGlobalStringConfig("noteSubDomain")
|
||||
if subDomain != "" {
|
||||
return subDomain + port
|
||||
}
|
||||
return this.GetDefaultDomain() + "/note"
|
||||
}
|
||||
func (this *ConfigService) GetNoteUrl() string {
|
||||
return schema + this.GetNoteDomain();
|
||||
return schema + this.GetNoteDomain()
|
||||
}
|
||||
|
||||
// blog
|
||||
func (this *ConfigService) GetBlogDomain() string {
|
||||
subDomain := this.GetGlobalStringConfig("blogSubDomain");
|
||||
subDomain := this.GetGlobalStringConfig("blogSubDomain")
|
||||
if subDomain != "" {
|
||||
return subDomain + port
|
||||
}
|
||||
return this.GetDefaultDomain() + "/blog"
|
||||
}
|
||||
func (this *ConfigService) GetBlogUrl() string {
|
||||
return schema + this.GetBlogDomain();
|
||||
return schema + this.GetBlogDomain()
|
||||
}
|
||||
|
||||
// lea
|
||||
func (this *ConfigService) GetLeaDomain() string {
|
||||
subDomain := this.GetGlobalStringConfig("leaSubDomain");
|
||||
subDomain := this.GetGlobalStringConfig("leaSubDomain")
|
||||
if subDomain != "" {
|
||||
return subDomain + port
|
||||
}
|
||||
return this.GetDefaultDomain() + "/lea"
|
||||
}
|
||||
func (this *ConfigService) GetLeaUrl() string {
|
||||
return schema + this.GetLeaDomain();
|
||||
return schema + this.GetLeaDomain()
|
||||
}
|
||||
|
||||
func (this *ConfigService) GetUserUrl(domain string) string {
|
||||
@@ -543,6 +550,7 @@ func (this *ConfigService) GetUserSubUrl(subDomain string) string {
|
||||
func (this *ConfigService) AllowCustomDomain() bool {
|
||||
return configService.GetGlobalStringConfig("allowCustomDomain") != ""
|
||||
}
|
||||
|
||||
// 是否是好的自定义域名
|
||||
func (this *ConfigService) IsGoodCustomDomain(domain string) bool {
|
||||
blacks := this.GetGlobalArrayConfig("blackCustomDomains")
|
||||
@@ -567,20 +575,29 @@ func (this *ConfigService) IsGoodSubDomain(domain string) bool {
|
||||
// 上传大小
|
||||
func (this *ConfigService) GetUploadSize(key string) float64 {
|
||||
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 {
|
||||
return map[string]float64{
|
||||
"uploadImageSize": this.GetUploadSize("uploadImageSize"),
|
||||
"uploadBlogLogoSize":this.GetUploadSize("uploadBlogLogoSize"),
|
||||
"uploadAttachSize":this.GetUploadSize("uploadAttachSize"),
|
||||
"uploadAvatarSize":this.GetUploadSize("uploadAvatarSize"),
|
||||
"uploadImageSize": this.GetUploadSize("uploadImageSize"),
|
||||
"uploadBlogLogoSize": this.GetUploadSize("uploadBlogLogoSize"),
|
||||
"uploadAttachSize": this.GetUploadSize("uploadAttachSize"),
|
||||
"uploadAvatarSize": this.GetUploadSize("uploadAvatarSize"),
|
||||
}
|
||||
}
|
||||
|
||||
// 为用户得到全局的配置
|
||||
// NoteController调用
|
||||
func (this *ConfigService) GetGlobalConfigForUser() map[string]interface{} {
|
||||
uploadSizeConfigs := this.GetUploadSizeLimit();
|
||||
uploadSizeConfigs := this.GetUploadSizeLimit()
|
||||
config := map[string]interface{}{}
|
||||
for k, v := range uploadSizeConfigs {
|
||||
config[k] = v
|
||||
@@ -594,5 +611,5 @@ func (this *ConfigService) HomePageIsAdminsBlog() bool {
|
||||
}
|
||||
|
||||
func (this *ConfigService) GetVersion() string {
|
||||
return "1.1"
|
||||
return "1.4.1"
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"strings"
|
||||
"html/template"
|
||||
"net/smtp"
|
||||
"strconv"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"bytes"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 发送邮件
|
||||
@@ -20,7 +20,7 @@ type EmailService struct {
|
||||
tpls map[string]*template.Template
|
||||
}
|
||||
|
||||
func NewEmailService() (*EmailService) {
|
||||
func NewEmailService() *EmailService {
|
||||
return &EmailService{tpls: map[string]*template.Template{}}
|
||||
}
|
||||
|
||||
@@ -39,32 +39,32 @@ func InitEmailFromDb() {
|
||||
|
||||
func (this *EmailService) SendEmail(to, subject, body string) (ok bool, e string) {
|
||||
InitEmailFromDb()
|
||||
|
||||
|
||||
if host == "" || emailPort == "" || username == "" || password == "" {
|
||||
return
|
||||
return
|
||||
}
|
||||
hp := strings.Split(host, ":")
|
||||
auth := smtp.PlainAuth("", username, password, hp[0])
|
||||
|
||||
|
||||
var content_type string
|
||||
|
||||
|
||||
mailtype := "html"
|
||||
if mailtype == "html" {
|
||||
content_type = "Content-Type: text/"+ mailtype + "; charset=UTF-8"
|
||||
} else{
|
||||
content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
|
||||
} else {
|
||||
content_type = "Content-Type: text/plain" + "; charset=UTF-8"
|
||||
}
|
||||
|
||||
msg := []byte("To: " + to + "\r\nFrom: " + username + "<"+ username +">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
|
||||
|
||||
msg := []byte("To: " + to + "\r\nFrom: " + username + "<" + username + ">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
|
||||
send_to := strings.Split(to, ";")
|
||||
err := smtp.SendMail(host+":"+emailPort, auth, username, send_to, msg)
|
||||
|
||||
|
||||
if err != nil {
|
||||
e = fmt.Sprint(err)
|
||||
return
|
||||
return
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// AddUser调用
|
||||
@@ -74,20 +74,20 @@ func (this *EmailService) RegisterSendActiveEmail(userInfo info.User, email stri
|
||||
if token == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateRegisterSubject");
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateRegister");
|
||||
|
||||
if(tpl == "") {
|
||||
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateRegisterSubject")
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateRegister")
|
||||
|
||||
if tpl == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
tokenUrl := configService.GetSiteUrl() + "/user/activeEmail?token=" + token
|
||||
// {siteUrl} {tokenUrl} {token} {tokenTimeout} {user.id} {user.email} {user.username}
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "tokenUrl": tokenUrl, "token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail))),
|
||||
"user": map[string]interface{}{
|
||||
"userId": userInfo.UserId.Hex(),
|
||||
"email": userInfo.Email,
|
||||
"userId": userInfo.UserId.Hex(),
|
||||
"email": userInfo.Email,
|
||||
"username": userInfo.Username,
|
||||
},
|
||||
}
|
||||
@@ -97,7 +97,7 @@ func (this *EmailService) RegisterSendActiveEmail(userInfo info.User, email stri
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// 发送邮件
|
||||
ok, _ = this.SendEmail(email, subject, tpl)
|
||||
return ok
|
||||
@@ -113,66 +113,66 @@ func (this *EmailService) UpdateEmailSendActiveEmail(userInfo info.User, email s
|
||||
}
|
||||
|
||||
token := tokenService.NewToken(userInfo.UserId.Hex(), email, info.TokenUpdateEmail)
|
||||
|
||||
|
||||
if token == "" {
|
||||
return
|
||||
}
|
||||
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateUpdateEmailSubject");
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateUpdateEmail");
|
||||
|
||||
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateUpdateEmailSubject")
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateUpdateEmail")
|
||||
|
||||
// 发送邮件
|
||||
tokenUrl := configService.GetSiteUrl() + "/user/updateEmail?token=" + token
|
||||
// {siteUrl} {tokenUrl} {token} {tokenTimeout} {user.userId} {user.email} {user.username}
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "tokenUrl": tokenUrl, "token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail))),
|
||||
"newEmail": email,
|
||||
"user": map[string]interface{}{
|
||||
"userId": userInfo.UserId.Hex(),
|
||||
"email": userInfo.Email,
|
||||
"userId": userInfo.UserId.Hex(),
|
||||
"email": userInfo.Email,
|
||||
"username": userInfo.Username,
|
||||
},
|
||||
}
|
||||
|
||||
ok, msg, subject, tpl = this.renderEmail(subject, tpl, token2Value)
|
||||
if !ok {
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 发送邮件
|
||||
ok, msg = this.SendEmail(email, subject, tpl)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *EmailService) FindPwdSendEmail(token, email string) (ok bool, msg string) {
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateFindPasswordSubject");
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateFindPassword");
|
||||
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateFindPasswordSubject")
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateFindPassword")
|
||||
|
||||
// 发送邮件
|
||||
tokenUrl := configService.GetSiteUrl() + "/findPassword/" + token
|
||||
// {siteUrl} {tokenUrl} {token} {tokenTimeout} {user.id} {user.email} {user.username}
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "tokenUrl": tokenUrl,
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "tokenUrl": tokenUrl,
|
||||
"token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail)))}
|
||||
|
||||
|
||||
ok, msg, subject, tpl = this.renderEmail(subject, tpl, token2Value)
|
||||
if !ok {
|
||||
return
|
||||
return
|
||||
}
|
||||
// 发送邮件
|
||||
ok, msg = this.SendEmail(email, subject, tpl)
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// 发送邀请链接
|
||||
func (this *EmailService) SendInviteEmail(userInfo info.User, email, content string) bool {
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateInviteSubject");
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateInvite");
|
||||
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateInviteSubject")
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateInvite")
|
||||
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(),
|
||||
"registerUrl": configService.GetSiteUrl() + "/register?from=" + userInfo.Username,
|
||||
"content": content,
|
||||
"content": content,
|
||||
"user": map[string]interface{}{
|
||||
"username": userInfo.Username,
|
||||
"email": userInfo.Email,
|
||||
"email": userInfo.Email,
|
||||
},
|
||||
}
|
||||
var ok bool
|
||||
@@ -187,32 +187,32 @@ func (this *EmailService) SendInviteEmail(userInfo info.User, email, content str
|
||||
|
||||
// 发送评论
|
||||
func (this *EmailService) SendCommentEmail(note info.Note, comment info.BlogComment, userId, content string) bool {
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateCommentSubject");
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateComment");
|
||||
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateCommentSubject")
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateComment")
|
||||
|
||||
// title := "评论提醒"
|
||||
|
||||
|
||||
/*
|
||||
toUserId := note.UserId.Hex()
|
||||
// title := "评论提醒"
|
||||
|
||||
// 表示回复回复的内容, 那么发送给之前回复的
|
||||
if comment.CommentId != "" {
|
||||
toUserId = comment.UserId.Hex()
|
||||
}
|
||||
toUserInfo := userService.GetUserInfo(toUserId)
|
||||
sendUserInfo := userService.GetUserInfo(userId)
|
||||
|
||||
subject := note.Title + " 收到 " + sendUserInfo.Username + " 的评论";
|
||||
if comment.CommentId != "" {
|
||||
subject = "您在 " + note.Title + " 发表的评论收到 " + sendUserInfo.Username;
|
||||
if userId == note.UserId.Hex() {
|
||||
subject += "(作者)";
|
||||
toUserId := note.UserId.Hex()
|
||||
// title := "评论提醒"
|
||||
|
||||
// 表示回复回复的内容, 那么发送给之前回复的
|
||||
if comment.CommentId != "" {
|
||||
toUserId = comment.UserId.Hex()
|
||||
}
|
||||
toUserInfo := userService.GetUserInfo(toUserId)
|
||||
sendUserInfo := userService.GetUserInfo(userId)
|
||||
|
||||
subject := note.Title + " 收到 " + sendUserInfo.Username + " 的评论";
|
||||
if comment.CommentId != "" {
|
||||
subject = "您在 " + note.Title + " 发表的评论收到 " + sendUserInfo.Username;
|
||||
if userId == note.UserId.Hex() {
|
||||
subject += "(作者)";
|
||||
}
|
||||
subject += " 的评论";
|
||||
}
|
||||
subject += " 的评论";
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
toUserId := note.UserId.Hex()
|
||||
// 表示回复回复的内容, 那么发送给之前回复的
|
||||
if comment.CommentId != "" {
|
||||
@@ -220,28 +220,28 @@ func (this *EmailService) SendCommentEmail(note info.Note, comment info.BlogComm
|
||||
}
|
||||
toUserInfo := userService.GetUserInfo(toUserId) // 被评论者
|
||||
sendUserInfo := userService.GetUserInfo(userId) // 评论者
|
||||
|
||||
// {siteUrl} {blogUrl}
|
||||
|
||||
// {siteUrl} {blogUrl}
|
||||
// {blog.id} {blog.title} {blog.url}
|
||||
// {commentUser.userId} {commentUser.username} {commentUser.email}
|
||||
// {commentUser.userId} {commentUser.username} {commentUser.email}
|
||||
// {commentedUser.userId} {commentedUser.username} {commentedUser.email}
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "blogUrl": configService.GetBlogUrl(),
|
||||
"blog": map[string]string{
|
||||
"id": note.NoteId.Hex(),
|
||||
"id": note.NoteId.Hex(),
|
||||
"title": note.Title,
|
||||
"url": configService.GetBlogUrl() + "/view/" + note.NoteId.Hex(),
|
||||
"url": configService.GetBlogUrl() + "/view/" + note.NoteId.Hex(),
|
||||
},
|
||||
"commentContent": content,
|
||||
// 评论者信息
|
||||
"commentUser": map[string]interface{}{"userId": sendUserInfo.UserId.Hex(),
|
||||
"username": sendUserInfo.Username,
|
||||
"email": sendUserInfo.Email,
|
||||
"commentUser": map[string]interface{}{"userId": sendUserInfo.UserId.Hex(),
|
||||
"username": sendUserInfo.Username,
|
||||
"email": sendUserInfo.Email,
|
||||
"isBlogAuthor": userId == note.UserId.Hex(),
|
||||
},
|
||||
// 被评论者信息
|
||||
"commentedUser": map[string]interface{}{"userId": toUserId,
|
||||
"username": toUserInfo.Username,
|
||||
"email": toUserInfo.Email,
|
||||
"username": toUserInfo.Username,
|
||||
"email": toUserInfo.Email,
|
||||
"isBlogAuthor": toUserId == note.UserId.Hex(),
|
||||
},
|
||||
}
|
||||
@@ -251,53 +251,52 @@ func (this *EmailService) SendCommentEmail(note info.Note, comment info.BlogComm
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// 发送邮件
|
||||
ok, _ = this.SendEmail(toUserInfo.Email, subject, tpl)
|
||||
return ok
|
||||
}
|
||||
|
||||
|
||||
// 验证模板是否正确
|
||||
func (this *EmailService) ValidTpl(str string) (ok bool, msg string){
|
||||
defer func() {
|
||||
func (this *EmailService) ValidTpl(str string) (ok bool, msg string) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
msg = fmt.Sprint(err)
|
||||
}
|
||||
}();
|
||||
header := configService.GetGlobalStringConfig("emailTemplateHeader");
|
||||
footer := configService.GetGlobalStringConfig("emailTemplateFooter");
|
||||
}()
|
||||
header := configService.GetGlobalStringConfig("emailTemplateHeader")
|
||||
footer := configService.GetGlobalStringConfig("emailTemplateFooter")
|
||||
str = strings.Replace(str, "{{header}}", header, -1)
|
||||
str = strings.Replace(str, "{{footer}}", footer, -1)
|
||||
_, err := template.New("tpl name").Parse(str)
|
||||
if err != nil {
|
||||
if err != nil {
|
||||
msg = fmt.Sprint(err)
|
||||
return
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// ok, msg, subject, tpl
|
||||
func (this *EmailService) getTpl(str string) (ok bool, msg string, tpl *template.Template){
|
||||
defer func() {
|
||||
func (this *EmailService) getTpl(str string) (ok bool, msg string, tpl *template.Template) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
msg = fmt.Sprint(err)
|
||||
}
|
||||
}();
|
||||
|
||||
}()
|
||||
|
||||
var err error
|
||||
var has bool
|
||||
|
||||
|
||||
if tpl, has = this.tpls[str]; !has {
|
||||
tpl, err = template.New("tpl name").Parse(str)
|
||||
if err != nil {
|
||||
tpl, err = template.New("tpl name").Parse(str)
|
||||
if err != nil {
|
||||
msg = fmt.Sprint(err)
|
||||
return
|
||||
}
|
||||
this.tpls[str] = tpl
|
||||
return
|
||||
}
|
||||
this.tpls[str] = tpl
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
@@ -310,67 +309,67 @@ func (this *EmailService) renderEmail(subject, body string, values map[string]in
|
||||
defer func() { // 必须要先声明defer,否则不能捕获到panic异常
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
msg = fmt.Sprint(err) // 这里的err其实就是panic传入的内容,
|
||||
msg = fmt.Sprint(err) // 这里的err其实就是panic传入的内容,
|
||||
}
|
||||
}();
|
||||
|
||||
}()
|
||||
|
||||
var tpl *template.Template
|
||||
|
||||
values["siteUrl"] = configService.GetSiteUrl();
|
||||
|
||||
|
||||
values["siteUrl"] = configService.GetSiteUrl()
|
||||
|
||||
// subject
|
||||
if subject != "" {
|
||||
ok, msg, tpl = this.getTpl(subject)
|
||||
if(!ok) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
err := tpl.Execute(&buffer, values)
|
||||
if err != nil {
|
||||
err := tpl.Execute(&buffer, values)
|
||||
if err != nil {
|
||||
msg = fmt.Sprint(err)
|
||||
return
|
||||
}
|
||||
o = buffer.String()
|
||||
} else {
|
||||
o = ""
|
||||
}
|
||||
|
||||
// content
|
||||
header := configService.GetGlobalStringConfig("emailTemplateHeader");
|
||||
footer := configService.GetGlobalStringConfig("emailTemplateFooter");
|
||||
}
|
||||
o = buffer.String()
|
||||
} else {
|
||||
o = ""
|
||||
}
|
||||
|
||||
// content
|
||||
header := configService.GetGlobalStringConfig("emailTemplateHeader")
|
||||
footer := configService.GetGlobalStringConfig("emailTemplateFooter")
|
||||
body = strings.Replace(body, "{{header}}", header, -1)
|
||||
body = strings.Replace(body, "{{footer}}", footer, -1)
|
||||
values["subject"] = o
|
||||
ok, msg, tpl = this.getTpl(body)
|
||||
if(!ok) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var buffer2 bytes.Buffer
|
||||
err := tpl.Execute(&buffer2, values)
|
||||
if err != nil {
|
||||
err := tpl.Execute(&buffer2, values)
|
||||
if err != nil {
|
||||
msg = fmt.Sprint(err)
|
||||
return
|
||||
}
|
||||
b = buffer2.String()
|
||||
|
||||
return
|
||||
}
|
||||
b = buffer2.String()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 发送email给用户
|
||||
// 需要记录
|
||||
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"
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 尝试renderHtml
|
||||
ok, msg, _, _ = this.renderEmail(subject, body, map[string]interface{}{})
|
||||
if(!ok) {
|
||||
if !ok {
|
||||
Log(msg)
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
go func() {
|
||||
for _, user := range users {
|
||||
LogJ(user)
|
||||
@@ -381,8 +380,8 @@ func (this *EmailService) SendEmailToUsers(users []info.User, subject, body stri
|
||||
ok2, msg2, subject2, body2 := this.renderEmail(subject, body, m)
|
||||
ok = ok2
|
||||
msg = msg2
|
||||
if(ok2) {
|
||||
sendOk, msg := this.SendEmail(user.Email, subject2, body2);
|
||||
if ok2 {
|
||||
sendOk, msg := this.SendEmail(user.Email, subject2, body2)
|
||||
this.AddEmailLog(user.Email, subject, body, sendOk, msg) // 把模板记录下
|
||||
// 记录到Email Log
|
||||
if sendOk {
|
||||
@@ -395,47 +394,47 @@ func (this *EmailService) SendEmailToUsers(users []info.User, subject, body stri
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
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"
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 尝试renderHtml
|
||||
ok, msg, _, _ = this.renderEmail(subject, body, map[string]interface{}{})
|
||||
if(!ok) {
|
||||
if !ok {
|
||||
Log(msg)
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// go func() {
|
||||
for _, email := range emails {
|
||||
if email == "" {
|
||||
continue
|
||||
}
|
||||
m := map[string]interface{}{}
|
||||
m["email"] = email
|
||||
ok, msg, subject, body = this.renderEmail(subject, body, m)
|
||||
if(ok) {
|
||||
sendOk, msg := this.SendEmail(email, subject, body);
|
||||
this.AddEmailLog(email, subject, body, sendOk, msg)
|
||||
// 记录到Email Log
|
||||
if sendOk {
|
||||
Log("ok " + email)
|
||||
} else {
|
||||
Log("no " + email)
|
||||
}
|
||||
} else {
|
||||
Log(msg);
|
||||
}
|
||||
|
||||
// go func() {
|
||||
for _, email := range emails {
|
||||
if email == "" {
|
||||
continue
|
||||
}
|
||||
// }()
|
||||
|
||||
return
|
||||
m := map[string]interface{}{}
|
||||
m["email"] = email
|
||||
ok, msg, subject, body = this.renderEmail(subject, body, m)
|
||||
if ok {
|
||||
sendOk, msg := this.SendEmail(email, subject, body)
|
||||
this.AddEmailLog(email, subject, body, sendOk, msg)
|
||||
// 记录到Email Log
|
||||
if sendOk {
|
||||
Log("ok " + email)
|
||||
} else {
|
||||
Log("no " + email)
|
||||
}
|
||||
} else {
|
||||
Log(msg)
|
||||
}
|
||||
}
|
||||
// }()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 添加邮件日志
|
||||
@@ -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()}
|
||||
db.Insert(db.EmailLogs, log)
|
||||
}
|
||||
|
||||
// 展示邮件日志
|
||||
|
||||
func (this *EmailService) DeleteEmails(ids []string) bool {
|
||||
@@ -451,7 +451,7 @@ func (this *EmailService) DeleteEmails(ids []string) bool {
|
||||
idsO[i] = bson.ObjectIdHex(id)
|
||||
}
|
||||
db.DeleteAll(db.EmailLogs, bson.M{"_id": bson.M{"$in": idsO}})
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
func (this *EmailService) ListEmailLogs(pageNumber, pageSize int, sortField string, isAsc bool, email string) (page info.Page, emailLogs []info.EmailLog) {
|
||||
@@ -461,7 +461,7 @@ func (this *EmailService) ListEmailLogs(pageNumber, pageSize int, sortField stri
|
||||
if email != "" {
|
||||
query["Email"] = bson.M{"$regex": bson.RegEx{".*?" + email + ".*", "i"}}
|
||||
}
|
||||
q := db.EmailLogs.Find(query);
|
||||
q := db.EmailLogs.Find(query)
|
||||
// 总记录数
|
||||
count, _ := q.Count()
|
||||
// 列表
|
||||
@@ -471,4 +471,4 @@ func (this *EmailService) ListEmailLogs(pageNumber, pageSize int, sortField stri
|
||||
All(&emailLogs)
|
||||
page = info.NewPage(pageNumber, pageSize, count, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ func (this *FileService) AddImage(image info.File, albumId, userId string, needC
|
||||
image.IsDefaultAlbum = true
|
||||
}
|
||||
image.UserId = bson.ObjectIdHex(userId)
|
||||
|
||||
|
||||
ok = db.Insert(db.Files, image)
|
||||
return
|
||||
}
|
||||
@@ -40,28 +40,28 @@ func (this *FileService) AddImage(image info.File, albumId, userId string, needC
|
||||
func (this *FileService) ListImagesWithPage(userId, albumId, key string, pageNumber, pageSize int) info.Page {
|
||||
skipNum, sortFieldR := parsePageAndSort(pageNumber, pageSize, "CreatedTime", false)
|
||||
files := []info.File{}
|
||||
|
||||
|
||||
q := bson.M{"UserId": bson.ObjectIdHex(userId), "Type": ""} // life
|
||||
if albumId != "" {
|
||||
q["AlbumId"] = bson.ObjectIdHex(albumId);
|
||||
q["AlbumId"] = bson.ObjectIdHex(albumId)
|
||||
} else {
|
||||
q["IsDefaultAlbum"] = true
|
||||
}
|
||||
if key != "" {
|
||||
q["Title"] = bson.M{"$regex": bson.RegEx{".*?" + key + ".*", "i"}}
|
||||
q["Title"] = bson.M{"$regex": bson.RegEx{".*?" + key + ".*", "i"}}
|
||||
}
|
||||
|
||||
// LogJ(q)
|
||||
|
||||
count := db.Count(db.Files, q);
|
||||
|
||||
|
||||
// LogJ(q)
|
||||
|
||||
count := db.Count(db.Files, q)
|
||||
|
||||
db.Files.
|
||||
Find(q).
|
||||
Sort(sortFieldR).
|
||||
Skip(skipNum).
|
||||
Limit(pageSize).
|
||||
All(&files)
|
||||
|
||||
|
||||
return info.Page{Count: count, List: files}
|
||||
}
|
||||
|
||||
@@ -75,12 +75,12 @@ func (this *FileService) GetAllImageNamesMap(userId string) (m map[string]bool)
|
||||
q := bson.M{"UserId": bson.ObjectIdHex(userId)}
|
||||
files := []info.File{}
|
||||
db.ListByQWithFields(db.Files, q, []string{"Name"}, &files)
|
||||
|
||||
|
||||
m = make(map[string]bool)
|
||||
if len(files) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
for _, file := range files {
|
||||
m[file.Name] = true
|
||||
}
|
||||
@@ -91,8 +91,8 @@ func (this *FileService) GetAllImageNamesMap(userId string) (m map[string]bool)
|
||||
func (this *FileService) DeleteImage(userId, fileId string) (bool, string) {
|
||||
file := info.File{}
|
||||
db.GetByIdAndUserId(db.Files, fileId, userId, &file)
|
||||
|
||||
if(file.FileId != "") {
|
||||
|
||||
if file.FileId != "" {
|
||||
if db.DeleteByIdAndUserId(db.Files, fileId, userId) {
|
||||
// delete image
|
||||
// TODO
|
||||
@@ -173,63 +173,63 @@ func (this *FileService) GetFile(userId, fileId string) string {
|
||||
if fileId == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
file := info.File{}
|
||||
db.Get(db.Files, fileId, &file)
|
||||
path := file.Path
|
||||
if path == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
// 1. 判断权限
|
||||
|
||||
|
||||
// 是否是我的文件
|
||||
if userId != "" && file.UserId.Hex() == userId {
|
||||
return path
|
||||
}
|
||||
|
||||
|
||||
// 得到使用过该fileId的所有笔记NoteId
|
||||
// 这些笔记是否有public的, 若有则ok
|
||||
// 这些笔记(笔记本)是否有共享给我的, 若有则ok
|
||||
|
||||
|
||||
noteIds := noteImageService.GetNoteIds(fileId)
|
||||
if noteIds != nil && len(noteIds) > 0 {
|
||||
// 这些笔记是否有public的
|
||||
if db.Has(db.Notes, bson.M{"_id": bson.M{"$in": noteIds}, "IsBlog": true}) {
|
||||
return path
|
||||
}
|
||||
|
||||
|
||||
// 2014/12/28 修复, 如果是分享给用户组, 那就不行, 这里可以实现
|
||||
for _, noteId := range noteIds {
|
||||
note := noteService.GetNoteById(noteId.Hex())
|
||||
if shareService.HasReadPerm(note.UserId.Hex(), userId, noteId.Hex()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// 若有共享给我的笔记?
|
||||
// 对该笔记可读?
|
||||
if db.Has(db.ShareNotes, bson.M{"ToUserId": bson.ObjectIdHex(userId), "NoteId": bson.M{"$in": noteIds}}) {
|
||||
return path
|
||||
}
|
||||
|
||||
// 笔记本是否共享给我?
|
||||
// 通过笔记得到笔记本
|
||||
notes := []info.Note{}
|
||||
db.ListByQWithFields(db.Notes, bson.M{"_id": bson.M{"$in": noteIds}}, []string{"NotebookId"}, ¬es)
|
||||
if notes != nil && len(notes) > 0 {
|
||||
notebookIds := make([]bson.ObjectId, len(notes))
|
||||
for i := 0; i < len(notes); i++ {
|
||||
notebookIds[i] = notes[i].NotebookId
|
||||
}
|
||||
|
||||
if db.Has(db.ShareNotebooks, bson.M{"ToUserId": bson.ObjectIdHex(userId), "NotebookId": bson.M{"$in": notebookIds}}) {
|
||||
return path
|
||||
}
|
||||
}
|
||||
/*
|
||||
// 若有共享给我的笔记?
|
||||
// 对该笔记可读?
|
||||
if db.Has(db.ShareNotes, bson.M{"ToUserId": bson.ObjectIdHex(userId), "NoteId": bson.M{"$in": noteIds}}) {
|
||||
return path
|
||||
}
|
||||
|
||||
// 笔记本是否共享给我?
|
||||
// 通过笔记得到笔记本
|
||||
notes := []info.Note{}
|
||||
db.ListByQWithFields(db.Notes, bson.M{"_id": bson.M{"$in": noteIds}}, []string{"NotebookId"}, ¬es)
|
||||
if notes != nil && len(notes) > 0 {
|
||||
notebookIds := make([]bson.ObjectId, len(notes))
|
||||
for i := 0; i < len(notes); i++ {
|
||||
notebookIds[i] = notes[i].NotebookId
|
||||
}
|
||||
|
||||
if db.Has(db.ShareNotebooks, bson.M{"ToUserId": bson.ObjectIdHex(userId), "NotebookId": bson.M{"$in": notebookIds}}) {
|
||||
return path
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// 可能是刚复制到owner上, 但内容又没有保存, 所以没有note->imageId的映射, 此时看是否有fromFileId
|
||||
if file.FromFileId != "" {
|
||||
fromFile := info.File{}
|
||||
@@ -238,54 +238,56 @@ func (this *FileService) GetFile(userId, fileId string) string {
|
||||
return fromFile.Path
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// 复制共享的笔记时, 复制其中的图片到我本地
|
||||
// 复制图片
|
||||
func (this *FileService) CopyImage(userId, fileId, toUserId string) (bool, string) {
|
||||
// 是否已经复制过了
|
||||
file2 := info.File{}
|
||||
db.GetByQ(db.Files, bson.M{"UserId": bson.ObjectIdHex(toUserId), "FromFileId": bson.ObjectIdHex(fileId)}, &file2)
|
||||
if file2.FileId != "" {
|
||||
return true, file2.FileId.Hex();
|
||||
return true, file2.FileId.Hex()
|
||||
}
|
||||
|
||||
// 复制之
|
||||
|
||||
file := info.File{}
|
||||
db.GetByIdAndUserId(db.Files, fileId, userId, &file)
|
||||
|
||||
|
||||
if file.FileId == "" || file.UserId.Hex() != userId {
|
||||
return false, ""
|
||||
}
|
||||
|
||||
|
||||
_, ext := SplitFilename(file.Name)
|
||||
newFilename := NewGuid() + ext
|
||||
|
||||
dir := "files/" + toUserId + "/images"
|
||||
guid := NewGuid()
|
||||
newFilename := guid + ext
|
||||
|
||||
// TODO 统一目录格式
|
||||
// dir := "files/" + toUserId + "/images"
|
||||
dir := "files/" + GetRandomFilePath(toUserId, guid) + "/images"
|
||||
filePath := dir + "/" + newFilename
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
err := os.MkdirAll(revel.BasePath+dir, 0755)
|
||||
if err != nil {
|
||||
return false, ""
|
||||
}
|
||||
|
||||
_, err = CopyFile(revel.BasePath + "/" + file.Path, revel.BasePath + "/" + filePath)
|
||||
|
||||
_, err = CopyFile(revel.BasePath+"/"+file.Path, revel.BasePath+"/"+filePath)
|
||||
if err != nil {
|
||||
Log(err)
|
||||
return false, ""
|
||||
}
|
||||
|
||||
|
||||
fileInfo := info.File{Name: newFilename,
|
||||
Title: file.Title,
|
||||
Path: filePath,
|
||||
Size: file.Size,
|
||||
Title: file.Title,
|
||||
Path: filePath,
|
||||
Size: file.Size,
|
||||
FromFileId: file.FileId}
|
||||
id := bson.NewObjectId();
|
||||
id := bson.NewObjectId()
|
||||
fileInfo.FileId = id
|
||||
fileId = id.Hex()
|
||||
Ok, _ := this.AddImage(fileInfo, "", toUserId, false)
|
||||
|
||||
|
||||
if Ok {
|
||||
return Ok, id.Hex()
|
||||
}
|
||||
@@ -296,7 +298,7 @@ func (this *FileService) CopyImage(userId, fileId, toUserId string) (bool, strin
|
||||
func (this *FileService) IsMyFile(userId, fileId string) bool {
|
||||
// 如果有问题会panic
|
||||
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)})
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
// "strings"
|
||||
// "strings"
|
||||
)
|
||||
|
||||
// 用户组, 用户组用户管理
|
||||
@@ -16,34 +16,35 @@ type GroupService struct {
|
||||
|
||||
// 添加分组
|
||||
func (this *GroupService) AddGroup(userId, title string) (bool, info.Group) {
|
||||
group := info.Group {
|
||||
GroupId: bson.NewObjectId(),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
Title: title,
|
||||
group := info.Group{
|
||||
GroupId: bson.NewObjectId(),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
Title: title,
|
||||
CreatedTime: time.Now(),
|
||||
}
|
||||
return db.Insert(db.Groups, group), group
|
||||
}
|
||||
|
||||
// 删除分组
|
||||
// 判断是否有好友
|
||||
func (this *GroupService) DeleteGroup(userId, groupId string) (ok bool, msg string) {
|
||||
/*
|
||||
if db.Has(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)}) {
|
||||
return false, "groupHasUsers"
|
||||
}
|
||||
if db.Has(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)}) {
|
||||
return false, "groupHasUsers"
|
||||
}
|
||||
*/
|
||||
if !this.isMyGroup(userId, groupId) {
|
||||
return false, "notMyGroup"
|
||||
}
|
||||
|
||||
|
||||
// 删除分组后, 需要删除所有用户分享到该组的笔记本, 笔记
|
||||
|
||||
shareService.DeleteAllShareNotebookGroup(groupId);
|
||||
shareService.DeleteAllShareNoteGroup(groupId);
|
||||
|
||||
|
||||
shareService.DeleteAllShareNotebookGroup(groupId)
|
||||
shareService.DeleteAllShareNoteGroup(groupId)
|
||||
|
||||
db.DeleteAll(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)})
|
||||
return db.DeleteByIdAndUserId(db.Groups, groupId, userId), ""
|
||||
|
||||
|
||||
// TODO 删除分组后, 在shareNote, shareNotebook中也要删除
|
||||
}
|
||||
|
||||
@@ -53,15 +54,15 @@ func (this *GroupService) UpdateGroupTitle(userId, groupId, title string) (ok bo
|
||||
}
|
||||
|
||||
// 得到用户的所有分组(包括下的所有用户)
|
||||
func (this *GroupService) GetGroupsAndUsers(userId string) ([]info.Group) {
|
||||
/*
|
||||
// 得到我的分组
|
||||
groups := []info.Group{}
|
||||
db.ListByQ(db.Groups, bson.M{"UserId": bson.ObjectIdHex(userId)}, &groups)
|
||||
*/
|
||||
func (this *GroupService) GetGroupsAndUsers(userId string) []info.Group {
|
||||
/*
|
||||
// 得到我的分组
|
||||
groups := []info.Group{}
|
||||
db.ListByQ(db.Groups, bson.M{"UserId": bson.ObjectIdHex(userId)}, &groups)
|
||||
*/
|
||||
// 我的分组, 及我所属的分组
|
||||
groups := this.GetGroupsContainOf(userId);
|
||||
|
||||
groups := this.GetGroupsContainOf(userId)
|
||||
|
||||
// 得到其下的用户
|
||||
for i, group := range groups {
|
||||
group.Users = this.GetUsers(group.GroupId.Hex())
|
||||
@@ -69,8 +70,9 @@ func (this *GroupService) GetGroupsAndUsers(userId string) ([]info.Group) {
|
||||
}
|
||||
return groups
|
||||
}
|
||||
|
||||
// 仅仅得到所有分组
|
||||
func (this *GroupService) GetGroups(userId string) ([]info.Group) {
|
||||
func (this *GroupService) GetGroups(userId string) []info.Group {
|
||||
// 得到分组s
|
||||
groups := []info.Group{}
|
||||
db.ListByQ(db.Groups, bson.M{"UserId": bson.ObjectIdHex(userId)}, &groups)
|
||||
@@ -78,24 +80,24 @@ func (this *GroupService) GetGroups(userId string) ([]info.Group) {
|
||||
}
|
||||
|
||||
// 得到我的和我所属组的ids
|
||||
func (this *GroupService) GetMineAndBelongToGroupIds(userId string) ([]bson.ObjectId) {
|
||||
func (this *GroupService) GetMineAndBelongToGroupIds(userId string) []bson.ObjectId {
|
||||
// 所属组
|
||||
groupIds := this.GetBelongToGroupIds(userId)
|
||||
|
||||
|
||||
m := map[bson.ObjectId]bool{}
|
||||
for _, groupId := range groupIds {
|
||||
m[groupId] = true
|
||||
}
|
||||
|
||||
|
||||
// 我的组
|
||||
myGroups := this.GetGroups(userId)
|
||||
|
||||
|
||||
for _, group := range myGroups {
|
||||
if !m[group.GroupId] {
|
||||
groupIds = append(groupIds, group.GroupId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return groupIds
|
||||
}
|
||||
|
||||
@@ -105,28 +107,28 @@ func (this *GroupService) GetGroupsContainOf(userId string) []info.Group {
|
||||
// 我的组
|
||||
myGroups := this.GetGroups(userId)
|
||||
myGroupMap := map[bson.ObjectId]bool{}
|
||||
|
||||
|
||||
for _, group := range myGroups {
|
||||
myGroupMap[group.GroupId] = true
|
||||
}
|
||||
|
||||
|
||||
// 所属组
|
||||
groupIds := this.GetBelongToGroupIds(userId)
|
||||
|
||||
groups := []info.Group{}
|
||||
db.ListByQ(db.Groups, bson.M{"_id": bson.M{"$in": groupIds}}, &groups)
|
||||
|
||||
|
||||
for _, group := range groups {
|
||||
if !myGroupMap[group.GroupId] {
|
||||
myGroups = append(myGroups, group)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return myGroups
|
||||
}
|
||||
|
||||
// 得到分组, shareService用
|
||||
func (this *GroupService) GetGroup(userId, groupId string) (info.Group) {
|
||||
func (this *GroupService) GetGroup(userId, groupId string) info.Group {
|
||||
// 得到分组s
|
||||
group := info.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
|
||||
groupUsers := []info.GroupUser{}
|
||||
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
|
||||
func (this *GroupService) GetBelongToGroupIds(userId string) ([]bson.ObjectId) {
|
||||
func (this *GroupService) GetBelongToGroupIds(userId string) []bson.ObjectId {
|
||||
// 得到UserIds
|
||||
groupUsers := []info.GroupUser{}
|
||||
db.ListByQWithFields(db.GroupUsers, bson.M{"UserId": bson.ObjectIdHex(userId)}, []string{"GroupId"}, &groupUsers)
|
||||
@@ -182,23 +184,23 @@ func (this *GroupService) IsExistsGroupUser(userId, groupId string) (ok bool) {
|
||||
func (this *GroupService) AddUser(ownUserId, groupId, userId string) (ok bool, msg string) {
|
||||
// groupId是否是ownUserId的?
|
||||
/*
|
||||
if !this.IsExistsGroupUser(ownUserId, groupId) {
|
||||
return false, "forbidden"
|
||||
}
|
||||
if !this.IsExistsGroupUser(ownUserId, groupId) {
|
||||
return false, "forbiddenNotMyGroup"
|
||||
}
|
||||
*/
|
||||
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)}) {
|
||||
return false, "hasUsers"
|
||||
return false, "userExistsInGroup"
|
||||
}
|
||||
|
||||
|
||||
return db.Insert(db.GroupUsers, info.GroupUser{
|
||||
GroupUserId: bson.NewObjectId(),
|
||||
GroupId: bson.ObjectIdHex(groupId),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
GroupId: bson.ObjectIdHex(groupId),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
CreatedTime: time.Now(),
|
||||
}), ""
|
||||
}
|
||||
@@ -207,17 +209,17 @@ func (this *GroupService) AddUser(ownUserId, groupId, userId string) (ok bool, m
|
||||
func (this *GroupService) DeleteUser(ownUserId, groupId, userId string) (ok bool, msg string) {
|
||||
// groupId是否是ownUserId的?
|
||||
/*
|
||||
if !this.IsExistsGroupUser(ownUserId, groupId) {
|
||||
return false, "forbidden"
|
||||
}
|
||||
if !this.IsExistsGroupUser(ownUserId, groupId) {
|
||||
return false, "forbiddenNotMyGroup"
|
||||
}
|
||||
*/
|
||||
if !this.isMyGroup(ownUserId, groupId) {
|
||||
return false, "forbidden"
|
||||
return false, "forbiddenNotMyGroup"
|
||||
}
|
||||
|
||||
|
||||
// 删除该用户分享到本组的笔记本, 笔记
|
||||
shareService.DeleteShareNotebookGroupWhenDeleteGroupUser(userId, groupId);
|
||||
shareService.DeleteShareNoteGroupWhenDeleteGroupUser(userId, groupId);
|
||||
|
||||
shareService.DeleteShareNotebookGroupWhenDeleteGroupUser(userId, groupId)
|
||||
shareService.DeleteShareNoteGroupWhenDeleteGroupUser(userId, groupId)
|
||||
|
||||
return db.Delete(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId), "UserId": bson.ObjectIdHex(userId)}), ""
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// "time"
|
||||
// "time"
|
||||
)
|
||||
|
||||
// 历史记录
|
||||
@@ -22,7 +22,7 @@ func (this *NoteContentHistoryService) AddHistory(noteId, userId string, eachHis
|
||||
if eachHistory.Content == "" {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 先查是否存在历史记录, 没有则添加之
|
||||
history := info.NoteContentHistory{}
|
||||
db.GetByIdAndUserId(db.NoteContentHistories, noteId, userId, &history)
|
||||
@@ -38,8 +38,8 @@ func (this *NoteContentHistoryService) AddHistory(noteId, userId string, eachHis
|
||||
}
|
||||
newHistory := []info.EachHistory{eachHistory}
|
||||
newHistory = append(newHistory, history.Histories...) // 在开头加了, 最近的在最前
|
||||
history.Histories = newHistory
|
||||
|
||||
history.Histories = newHistory
|
||||
|
||||
// 更新之
|
||||
db.UpdateByIdAndUserId(db.NoteContentHistories, noteId, userId, history)
|
||||
}
|
||||
@@ -48,13 +48,13 @@ func (this *NoteContentHistoryService) AddHistory(noteId, userId string, eachHis
|
||||
|
||||
// 新建历史
|
||||
func (this *NoteContentHistoryService) newHistory(noteId, userId string, eachHistory info.EachHistory) {
|
||||
history := info.NoteContentHistory{NoteId: bson.ObjectIdHex(noteId),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
history := info.NoteContentHistory{NoteId: bson.ObjectIdHex(noteId),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
Histories: []info.EachHistory{eachHistory},
|
||||
}
|
||||
|
||||
|
||||
// 保存之
|
||||
db.Insert(db.NoteContentHistories, history)
|
||||
db.Insert(db.NoteContentHistories, history)
|
||||
}
|
||||
|
||||
// 列表展示
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"regexp"
|
||||
// "time"
|
||||
// "time"
|
||||
)
|
||||
|
||||
type NoteImageService struct {
|
||||
}
|
||||
|
||||
// 通过id, userId得到noteIds
|
||||
func (this *NoteImageService) GetNoteIds(imageId string) ([]bson.ObjectId) {
|
||||
func (this *NoteImageService) GetNoteIds(imageId string) []bson.ObjectId {
|
||||
noteImages := []info.NoteImage{}
|
||||
db.ListByQWithFields(db.NoteImages, bson.M{"ImageId": bson.ObjectIdHex(imageId)}, []string{"NoteId"}, ¬eImages)
|
||||
|
||||
db.ListByQWithFields(db.NoteImages, bson.M{"ImageId": bson.ObjectIdHex(imageId)}, []string{"NoteId"}, ¬eImages)
|
||||
|
||||
if noteImages != nil && len(noteImages) > 0 {
|
||||
noteIds := make([]bson.ObjectId, len(noteImages))
|
||||
cnt := len(noteImages)
|
||||
@@ -25,7 +25,7 @@ func (this *NoteImageService) GetNoteIds(imageId string) ([]bson.ObjectId) {
|
||||
}
|
||||
return noteIds
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -67,23 +67,19 @@ func (this *NoteImageService) UpdateNoteImages(userId, noteId, imgSrc, content s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 复制图片, 把note的图片都copy给我, 且修改noteContent图片路径
|
||||
func (this *NoteImageService) CopyNoteImages(fromNoteId, fromUserId, newNoteId, content, toUserId string) string {
|
||||
/* 弃用之
|
||||
// 得到fromNoteId的noteImages, 如果为空, 则直接返回content
|
||||
noteImages := []info.NoteImage{}
|
||||
db.ListByQWithFields(db.NoteImages, bson.M{"NoteId": bson.ObjectIdHex(fromNoteId)}, []string{"ImageId"}, ¬eImages)
|
||||
|
||||
if len(noteImages) == 0 {
|
||||
return content;
|
||||
}
|
||||
|
||||
// <img src="/file/outputImage?fileId=12323232" />
|
||||
// 把fileId=1232替换成新的
|
||||
replaceMap := map[string]string{}
|
||||
for _, noteImage := range noteImages {
|
||||
imageId := noteImage.ImageId.Hex()
|
||||
ok, newImageId := fileService.CopyImage(fromUserId, imageId, toUserId)
|
||||
@@ -91,37 +87,61 @@ func (this *NoteImageService) CopyNoteImages(fromNoteId, fromUserId, newNoteId,
|
||||
replaceMap[imageId] = newImageId
|
||||
}
|
||||
}
|
||||
|
||||
if len(replaceMap) > 0 {
|
||||
// 替换之
|
||||
reg, _ := regexp.Compile("outputImage\\?fileId=([a-z0-9A-Z]{24})")
|
||||
content = reg.ReplaceAllStringFunc(content, func(each string) string {
|
||||
// each=outputImage?fileId=541bd2f599c37b4f3r000003
|
||||
fileId := each[len(each)-24:] // 得到后24位, 也即id
|
||||
if replaceFileId, ok := replaceMap[fileId]; ok {
|
||||
*/
|
||||
|
||||
// 因为很多图片上传就会删除, 所以直接从内容中查看图片id进行复制
|
||||
|
||||
// <img src="/file/outputImage?fileId=12323232" />
|
||||
// 把fileId=1232替换成新的
|
||||
replaceMap := map[string]string{}
|
||||
|
||||
reg, _ := regexp.Compile("(outputImage|getImage)\\?fileId=([a-z0-9A-Z]{24})")
|
||||
content = reg.ReplaceAllStringFunc(content, func(each string) string {
|
||||
// each = outputImage?fileId=541bd2f599c37b4f3r000003
|
||||
// each = getImage?fileId=541bd2f599c37b4f3r000003
|
||||
|
||||
fileId := each[len(each)-24:] // 得到后24位, 也即id
|
||||
|
||||
if _, ok := replaceMap[fileId]; !ok {
|
||||
if bson.IsObjectIdHex(fileId) {
|
||||
ok2, newImageId := fileService.CopyImage(fromUserId, fileId, toUserId)
|
||||
if ok2 {
|
||||
replaceMap[fileId] = newImageId
|
||||
} else {
|
||||
replaceMap[fileId] = ""
|
||||
}
|
||||
} else {
|
||||
replaceMap[fileId] = ""
|
||||
}
|
||||
}
|
||||
|
||||
replaceFileId := replaceMap[fileId]
|
||||
if replaceFileId != "" {
|
||||
if each[0] == 'o' {
|
||||
return "outputImage?fileId=" + replaceFileId
|
||||
}
|
||||
return each
|
||||
});
|
||||
}
|
||||
|
||||
return content;
|
||||
return "getImage?fileId=" + replaceFileId
|
||||
}
|
||||
return each
|
||||
})
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
func (this *NoteImageService) getImagesByNoteIds(noteIds []bson.ObjectId) map[string][]info.File {
|
||||
noteNoteImages := []info.NoteImage{}
|
||||
db.ListByQ(db.NoteImages, bson.M{"NoteId": bson.M{"$in": noteIds}}, ¬eNoteImages)
|
||||
|
||||
|
||||
// 得到imageId, 再去files表查所有的Files
|
||||
imageIds := []bson.ObjectId{}
|
||||
|
||||
|
||||
// 图片1 => N notes
|
||||
imageIdNotes := map[string][]string{} // imageId => [noteId1, noteId2, ...]
|
||||
for _, noteImage := range noteNoteImages {
|
||||
imageId := noteImage.ImageId
|
||||
imageIds = append(imageIds, imageId)
|
||||
|
||||
|
||||
imageIdHex := imageId.Hex()
|
||||
noteId := noteImage.NoteId.Hex()
|
||||
if notes, ok := imageIdNotes[imageIdHex]; ok {
|
||||
@@ -130,11 +150,11 @@ func (this *NoteImageService) getImagesByNoteIds(noteIds []bson.ObjectId) map[st
|
||||
imageIdNotes[imageIdHex] = []string{noteId}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 得到所有files
|
||||
files := []info.File{}
|
||||
db.ListByQ(db.Files, bson.M{"_id": bson.M{"$in": imageIds}}, &files)
|
||||
|
||||
|
||||
// 建立note->file关联
|
||||
noteImages := make(map[string][]info.File)
|
||||
for _, file := range files {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,15 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
// "fmt"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// "fmt"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"sort"
|
||||
"time"
|
||||
"strings"
|
||||
// "html"
|
||||
"time"
|
||||
// "html"
|
||||
)
|
||||
|
||||
// 笔记本
|
||||
@@ -42,8 +42,8 @@ func ParseAndSortNotebooks(userNotebooks []info.Notebook, noParentDelete, needSo
|
||||
for _, each := range userNotebooks {
|
||||
newNotebooks := info.Notebooks{Subs: info.SubNotebooks{}}
|
||||
newNotebooks.NotebookId = each.NotebookId
|
||||
newNotebooks.Title = each.Title;
|
||||
// newNotebooks.Title = html.EscapeString(each.Title)
|
||||
newNotebooks.Title = each.Title
|
||||
// newNotebooks.Title = html.EscapeString(each.Title)
|
||||
newNotebooks.Title = strings.Replace(strings.Replace(each.Title, "<script>", "", -1), "</script", "", -1)
|
||||
newNotebooks.Seq = each.Seq
|
||||
newNotebooks.UserId = each.UserId
|
||||
@@ -51,13 +51,13 @@ func ParseAndSortNotebooks(userNotebooks []info.Notebook, noParentDelete, needSo
|
||||
newNotebooks.NumberNotes = each.NumberNotes
|
||||
newNotebooks.IsTrash = each.IsTrash
|
||||
newNotebooks.IsBlog = each.IsBlog
|
||||
|
||||
|
||||
// 存地址
|
||||
userNotebooksMap[each.NotebookId] = &newNotebooks
|
||||
}
|
||||
|
||||
// 第二遍, 追加到父下
|
||||
|
||||
|
||||
// 需要删除的id
|
||||
needDeleteNotebookId := map[bson.ObjectId]bool{}
|
||||
for id, each := range userNotebooksMap {
|
||||
@@ -70,7 +70,7 @@ func ParseAndSortNotebooks(userNotebooks []info.Notebook, noParentDelete, needSo
|
||||
needDeleteNotebookId[id] = true
|
||||
// delete(userNotebooksMap, id)
|
||||
} else if noParentDelete {
|
||||
// 没有父, 且设置了要删除
|
||||
// 没有父, 且设置了要删除
|
||||
needDeleteNotebookId[id] = true
|
||||
// delete(userNotebooksMap, id)
|
||||
}
|
||||
@@ -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{}
|
||||
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(¬ebooks)
|
||||
return notebooks
|
||||
}
|
||||
@@ -137,7 +137,7 @@ func (this *NotebookService) GetNotebooks(userId string) info.SubNotebooks {
|
||||
if len(userNotebooks) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
return ParseAndSortNotebooks(userNotebooks, true, true)
|
||||
}
|
||||
|
||||
@@ -147,18 +147,22 @@ func (this *NotebookService) GetNotebooks(userId string) info.SubNotebooks {
|
||||
func (this *NotebookService) GetNotebooksByNotebookIds(notebookIds []bson.ObjectId) info.SubNotebooks {
|
||||
userNotebooks := []info.Notebook{}
|
||||
db.Notebooks.Find(bson.M{"_id": bson.M{"$in": notebookIds}}).All(&userNotebooks)
|
||||
|
||||
|
||||
if len(userNotebooks) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
return ParseAndSortNotebooks(userNotebooks, false, false)
|
||||
}
|
||||
|
||||
// 添加
|
||||
// [ok]
|
||||
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())
|
||||
now := time.Now()
|
||||
notebook.CreatedTime = now
|
||||
@@ -169,12 +173,13 @@ func (this *NotebookService) AddNotebook(notebook info.Notebook) (bool, info.Not
|
||||
}
|
||||
return true, notebook
|
||||
}
|
||||
|
||||
// 更新笔记, api
|
||||
func (this *NotebookService) UpdateNotebookApi(userId, notebookId, title, parentNotebookId string, seq, usn int) (bool, string, info.Notebook) {
|
||||
if notebookId == "" {
|
||||
return false, "notebookIdNotExists", info.Notebook{}
|
||||
}
|
||||
|
||||
|
||||
// 先判断usn是否和数据库的一样, 如果不一样, 则冲突, 不保存
|
||||
notebook := this.GetNotebookById(notebookId)
|
||||
// 不存在
|
||||
@@ -183,16 +188,16 @@ func (this *NotebookService) UpdateNotebookApi(userId, notebookId, title, parent
|
||||
} else if notebook.Usn != usn {
|
||||
return false, "conflict", notebook
|
||||
}
|
||||
notebook.Usn = userService.IncrUsn(userId);
|
||||
notebook.Title = title;
|
||||
|
||||
updates := bson.M{"Title": title, "Usn": notebook.Usn, "Seq": seq, "UpdatedTime": time.Now()};
|
||||
if(parentNotebookId != "" && bson.IsObjectIdHex(parentNotebookId)) {
|
||||
updates["ParentNotebookId"] = bson.ObjectIdHex(parentNotebookId);
|
||||
notebook.Usn = userService.IncrUsn(userId)
|
||||
notebook.Title = title
|
||||
|
||||
updates := bson.M{"Title": title, "Usn": notebook.Usn, "Seq": seq, "UpdatedTime": time.Now()}
|
||||
if parentNotebookId != "" && bson.IsObjectIdHex(parentNotebookId) {
|
||||
updates["ParentNotebookId"] = bson.ObjectIdHex(parentNotebookId)
|
||||
} else {
|
||||
updates["ParentNotebookId"] = "";
|
||||
updates["ParentNotebookId"] = ""
|
||||
}
|
||||
ok := db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, updates);
|
||||
ok := db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, updates)
|
||||
if ok {
|
||||
return ok, "", this.GetNotebookById(notebookId)
|
||||
}
|
||||
@@ -202,7 +207,7 @@ func (this *NotebookService) UpdateNotebookApi(userId, notebookId, title, parent
|
||||
// 判断是否是blog
|
||||
func (this *NotebookService) IsBlog(notebookId string) bool {
|
||||
notebook := info.Notebook{}
|
||||
db.GetByQWithFields(db.Notebooks, bson.M{"_id": bson.ObjectIdHex(notebookId)}, []string{"IsBlog"}, ¬ebook);
|
||||
db.GetByQWithFields(db.Notebooks, bson.M{"_id": bson.ObjectIdHex(notebookId)}, []string{"IsBlog"}, ¬ebook)
|
||||
return notebook.IsBlog
|
||||
}
|
||||
|
||||
@@ -228,20 +233,20 @@ func (this *NotebookService) UpdateNotebookTitle(notebookId, userId, title strin
|
||||
|
||||
// 更新notebook
|
||||
func (this *NotebookService) UpdateNotebook(userId, notebookId string, needUpdate bson.M) bool {
|
||||
needUpdate["UpdatedTime"] = time.Now();
|
||||
needUpdate["UpdatedTime"] = time.Now()
|
||||
needUpdate["Usn"] = userService.IncrUsn(userId)
|
||||
return db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, needUpdate)
|
||||
}
|
||||
|
||||
// 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)}
|
||||
// 笔记本
|
||||
db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, updates)
|
||||
|
||||
|
||||
// 更新笔记
|
||||
q := bson.M{"UserId": bson.ObjectIdHex(userId),
|
||||
"NotebookId": bson.ObjectIdHex(notebookId)}
|
||||
q := bson.M{"UserId": bson.ObjectIdHex(userId),
|
||||
"NotebookId": bson.ObjectIdHex(notebookId)}
|
||||
data := bson.M{"IsBlog": isBlog}
|
||||
if isBlog {
|
||||
data["PublicTime"] = time.Now()
|
||||
@@ -251,7 +256,7 @@ func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) (boo
|
||||
// usn
|
||||
data["Usn"] = userService.IncrUsn(userId)
|
||||
db.UpdateByQMap(db.Notes, q, data)
|
||||
|
||||
|
||||
// noteContents也更新, 这个就麻烦了, noteContents表没有NotebookId
|
||||
// 先查该notebook下所有notes, 得到id
|
||||
notes := []info.Note{}
|
||||
@@ -263,12 +268,12 @@ func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) (boo
|
||||
}
|
||||
db.UpdateByQMap(db.NoteContents, bson.M{"_id": bson.M{"$in": noteIds}}, bson.M{"IsBlog": isBlog})
|
||||
}
|
||||
|
||||
|
||||
// 重新计算tags
|
||||
go (func() {
|
||||
blogService.ReCountBlogTags(userId)
|
||||
})()
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -276,18 +281,18 @@ func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) (boo
|
||||
// 先查看该notebookId下是否有notes, 没有则删除
|
||||
func (this *NotebookService) DeleteNotebook(userId, notebookId string) (bool, string) {
|
||||
if db.Count(db.Notebooks, bson.M{
|
||||
"ParentNotebookId": bson.ObjectIdHex(notebookId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"IsDeleted": false,
|
||||
}) == 0 { // 无
|
||||
if db.Count(db.Notes, bson.M{"NotebookId": bson.ObjectIdHex(notebookId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"IsTrash": false,
|
||||
"ParentNotebookId": bson.ObjectIdHex(notebookId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"IsDeleted": false,
|
||||
}) == 0 { // 无
|
||||
if db.Count(db.Notes, bson.M{"NotebookId": bson.ObjectIdHex(notebookId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"IsTrash": false,
|
||||
"IsDeleted": false}) == 0 { // 不包含trash
|
||||
// 不是真删除 1/20, 为了同步笔记本
|
||||
ok := db.UpdateByQMap(db.Notebooks, bson.M{"_id": bson.ObjectIdHex(notebookId)}, bson.M{"IsDeleted": true, "Usn": userService.IncrUsn(userId)})
|
||||
return ok, ""
|
||||
// return db.DeleteByIdAndUserId(db.Notebooks, notebookId, userId), ""
|
||||
// return db.DeleteByIdAndUserId(db.Notebooks, notebookId, userId), ""
|
||||
}
|
||||
return false, "笔记本下有笔记"
|
||||
} else {
|
||||
@@ -321,7 +326,7 @@ func (this *NotebookService) SortNotebooks(userId string, notebookId2Seqs map[st
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -329,12 +334,12 @@ func (this *NotebookService) SortNotebooks(userId string, notebookId2Seqs map[st
|
||||
func (this *NotebookService) DragNotebooks(userId string, curNotebookId string, parentNotebookId string, siblings []string) bool {
|
||||
ok := false
|
||||
// 如果没parentNotebookId, 则parentNotebookId设空
|
||||
if(parentNotebookId == "") {
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notebooks, curNotebookId, userId, bson.M{"ParentNotebookId": "", "Usn": userService.IncrUsn(userId)});
|
||||
if parentNotebookId == "" {
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notebooks, curNotebookId, userId, bson.M{"ParentNotebookId": "", "Usn": userService.IncrUsn(userId)})
|
||||
} 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 {
|
||||
return false
|
||||
}
|
||||
@@ -345,7 +350,7 @@ func (this *NotebookService) DragNotebooks(userId string, curNotebookId string,
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -362,12 +367,12 @@ func (this *NotebookService) ReCountNotebookNumberNotes(notebookId string) bool
|
||||
|
||||
func (this *NotebookService) ReCountAll() {
|
||||
/*
|
||||
// 得到所有笔记本
|
||||
notebooks := []info.Notebook{}
|
||||
db.ListByQWithFields(db.Notebooks, bson.M{}, []string{"NotebookId"}, ¬ebooks)
|
||||
|
||||
for _, each := range notebooks {
|
||||
this.ReCountNotebookNumberNotes(each.NotebookId.Hex())
|
||||
}
|
||||
// 得到所有笔记本
|
||||
notebooks := []info.Notebook{}
|
||||
db.ListByQWithFields(db.Notebooks, bson.M{}, []string{"NotebookId"}, ¬ebooks)
|
||||
|
||||
for _, each := range notebooks {
|
||||
this.ReCountNotebookNumberNotes(each.NotebookId.Hex())
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
// 找回密码
|
||||
@@ -14,7 +14,7 @@ var overHours = 2.0 // 小时后过期
|
||||
type PwdService struct {
|
||||
}
|
||||
|
||||
// 1. 找回密码, 通过email找用户,
|
||||
// 1. 找回密码, 通过email找用户,
|
||||
// 用户存在, 生成code
|
||||
func (this *PwdService) FindPwd(email string) (ok bool, msg string) {
|
||||
ok = false
|
||||
@@ -23,38 +23,40 @@ func (this *PwdService) FindPwd(email string) (ok bool, msg string) {
|
||||
msg = "用户不存在"
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
token := tokenService.NewToken(userId, email, info.TokenPwd)
|
||||
if token == "" {
|
||||
return false, "db error"
|
||||
}
|
||||
|
||||
|
||||
// 发送邮件
|
||||
ok, msg = emailService.FindPwdSendEmail(token, email)
|
||||
return
|
||||
}
|
||||
|
||||
// 重置密码时
|
||||
// 修改密码
|
||||
// 先验证
|
||||
func (this *PwdService) UpdatePwd(token, pwd string) (bool, string) {
|
||||
var tokenInfo info.Token
|
||||
var ok bool
|
||||
var msg string
|
||||
|
||||
|
||||
// 先验证
|
||||
if ok, msg, tokenInfo = tokenService.VerifyToken(token, info.TokenPwd); !ok {
|
||||
return ok, msg
|
||||
}
|
||||
digest, err := GenerateHash(pwd)
|
||||
if err != nil {
|
||||
return false,"GenerateHash error"
|
||||
|
||||
passwd := GenPwd(pwd)
|
||||
if passwd == "" {
|
||||
return false, "GenerateHash error"
|
||||
}
|
||||
passwd := string(digest)
|
||||
|
||||
// 修改密码之
|
||||
ok = db.UpdateByQField(db.Users, bson.M{"_id": tokenInfo.UserId}, "Pwd", passwd)
|
||||
|
||||
|
||||
// 删除token
|
||||
tokenService.DeleteToken(tokenInfo.UserId.Hex(), info.TokenPwd)
|
||||
|
||||
|
||||
return ok, ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
// "strings"
|
||||
// "strings"
|
||||
)
|
||||
|
||||
// Session存储到mongodb中
|
||||
@@ -14,9 +14,10 @@ type SessionService struct {
|
||||
}
|
||||
|
||||
func (this *SessionService) Update(sessionId, key string, value interface{}) bool {
|
||||
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()})
|
||||
}
|
||||
|
||||
// 注销时清空session
|
||||
func (this *SessionService) Clear(sessionId string) bool {
|
||||
return db.Delete(db.Sessions, bson.M{"SessionId": sessionId})
|
||||
@@ -24,7 +25,7 @@ func (this *SessionService) Clear(sessionId string) bool {
|
||||
func (this *SessionService) Get(sessionId string) info.Session {
|
||||
session := info.Session{}
|
||||
db.GetByQ(db.Sessions, bson.M{"SessionId": sessionId}, &session)
|
||||
|
||||
|
||||
// 如果没有session, 那么插入一条之
|
||||
if session.Id == "" {
|
||||
session.Id = bson.NewObjectId()
|
||||
@@ -33,7 +34,7 @@ func (this *SessionService) Get(sessionId string) info.Session {
|
||||
session.UpdatedTime = session.CreatedTime
|
||||
db.Insert(db.Sessions, session)
|
||||
}
|
||||
|
||||
|
||||
return session
|
||||
}
|
||||
|
||||
@@ -45,14 +46,16 @@ func (this *SessionService) LoginTimesIsOver(sessionId string) bool {
|
||||
session := this.Get(sessionId)
|
||||
return session.LoginTimes > 5
|
||||
}
|
||||
|
||||
// 登录成功后清空错误次数
|
||||
func (this *SessionService) ClearLoginTimes(sessionId string) bool {
|
||||
return this.Update(sessionId, "LoginTimes", 0)
|
||||
}
|
||||
|
||||
// 增加错误次数
|
||||
func (this *SessionService) IncrLoginTimes(sessionId string) bool {
|
||||
session := this.Get(sessionId)
|
||||
return this.Update(sessionId, "LoginTimes", session.LoginTimes + 1)
|
||||
return this.Update(sessionId, "LoginTimes", session.LoginTimes+1)
|
||||
}
|
||||
|
||||
//----------
|
||||
@@ -75,7 +78,7 @@ func (this *SessionService) SetCaptcha(sessionId, captcha string) bool {
|
||||
func (this *SessionService) GetUserId(sessionId string) string {
|
||||
session := this.Get(sessionId)
|
||||
// 更新updateTime, 避免过期
|
||||
db.UpdateByQMap(db.Sessions, bson.M{"SessionId": sessionId},
|
||||
db.UpdateByQMap(db.Sessions, bson.M{"SessionId": sessionId},
|
||||
bson.M{"UpdatedTime": time.Now()})
|
||||
return session.UserId
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 共享Notebook, Note服务
|
||||
@@ -35,7 +35,7 @@ type ShareService struct {
|
||||
func (this *ShareService) getOrQ(userId string) bson.M {
|
||||
// 得到我和和我参与的组织
|
||||
groupIds := groupService.GetMineAndBelongToGroupIds(userId)
|
||||
|
||||
|
||||
q := bson.M{}
|
||||
if len(groupIds) > 0 {
|
||||
orQ := []bson.M{
|
||||
@@ -45,7 +45,7 @@ func (this *ShareService) getOrQ(userId string) bson.M {
|
||||
// 不是trash的
|
||||
q["$or"] = orQ
|
||||
} else {
|
||||
q["ToUserId"] = bson.ObjectIdHex(userId);
|
||||
q["ToUserId"] = bson.ObjectIdHex(userId)
|
||||
}
|
||||
return q
|
||||
}
|
||||
@@ -53,44 +53,44 @@ func (this *ShareService) getOrQ(userId string) bson.M {
|
||||
// 得到共享给我的笔记本和用户(谁共享给了我)
|
||||
func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksByUser, []info.User) {
|
||||
myUserId := userId
|
||||
|
||||
|
||||
// 得到共享给我的用户s信息
|
||||
// 得到我参与的组织
|
||||
q := this.getOrQ(userId)
|
||||
|
||||
|
||||
// 不查hasShareNotes
|
||||
// 直接查shareNotes, shareNotebooks表得到userId
|
||||
userIds1 := []bson.ObjectId{}
|
||||
db.Distinct(db.ShareNotes, q, "UserId", &userIds1)
|
||||
|
||||
|
||||
userIds2 := []bson.ObjectId{}
|
||||
db.Distinct(db.ShareNotebooks, q, "UserId", &userIds2) // BUG之前是userId1, 2014/12/29
|
||||
|
||||
|
||||
userIds := append(userIds1, userIds2...)
|
||||
|
||||
userInfos := userService.GetUserInfosOrderBySeq(userIds);
|
||||
|
||||
userInfos := userService.GetUserInfosOrderBySeq(userIds)
|
||||
// 不要我的id
|
||||
for i, userInfo := range userInfos {
|
||||
if userInfo.UserId.Hex() == myUserId {
|
||||
userInfos = append(userInfos[:i], userInfos[i+1:]...)
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------
|
||||
// 得到他们共享给我的notebooks
|
||||
|
||||
|
||||
// 这里可能会得到重复的记录
|
||||
// 权限: 笔记本分享给个人 > 笔记本分享给组织
|
||||
shareNotebooks := []info.ShareNotebook{}
|
||||
db.ShareNotebooks.Find(q).Sort("-ToUserId").All(&shareNotebooks) // 按ToUserId降序排序, 那么有ToUserId的在前面
|
||||
|
||||
|
||||
if len(shareNotebooks) == 0 {
|
||||
return nil, userInfos
|
||||
}
|
||||
|
||||
|
||||
shareNotebooksLen := len(shareNotebooks)
|
||||
|
||||
|
||||
// 找到了所有的notbookId, 那么找notebook表得到其详细信息
|
||||
notebookIds := []bson.ObjectId{}
|
||||
shareNotebooksMap := make(map[bson.ObjectId]info.ShareNotebook, shareNotebooksLen)
|
||||
@@ -102,34 +102,34 @@ func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksB
|
||||
shareNotebooksMap[each.NotebookId] = each
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 1, 2
|
||||
subNotebooks := notebookService.GetNotebooksByNotebookIds(notebookIds)
|
||||
// 填充其它信息变成SubShareNotebooks
|
||||
subShareNotebooks := this.parseToSubShareNotebooks(&subNotebooks, &shareNotebooksMap)
|
||||
|
||||
|
||||
// 3 按用户进行分组成ShareNotebooksByUser
|
||||
shareNotebooksByUsersMap := map[bson.ObjectId] []info.ShareNotebooks{}
|
||||
shareNotebooksByUsersMap := map[bson.ObjectId][]info.ShareNotebooks{}
|
||||
// 先建立userId => []
|
||||
for _, eachSub := range subShareNotebooks {
|
||||
userId := eachSub.Notebook.UserId
|
||||
// 我自己的, 算了
|
||||
if userId.Hex() == myUserId {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
if _, ok := shareNotebooksByUsersMap[userId]; ok {
|
||||
shareNotebooksByUsersMap[userId] = append(shareNotebooksByUsersMap[userId], eachSub)
|
||||
} else {
|
||||
shareNotebooksByUsersMap[userId] = []info.ShareNotebooks{eachSub}
|
||||
}
|
||||
}
|
||||
shareNotebooksByUser := info.ShareNotebooksByUser{};
|
||||
shareNotebooksByUser := info.ShareNotebooksByUser{}
|
||||
for userId, eachShareNotebooks := range shareNotebooksByUsersMap {
|
||||
// 4, 按用户排序
|
||||
shareNotebooksByUser[userId.Hex()] = sortSubShareNotebooks(eachShareNotebooks)
|
||||
}
|
||||
|
||||
|
||||
return shareNotebooksByUser, userInfos
|
||||
}
|
||||
|
||||
@@ -152,46 +152,46 @@ func (this *ShareService) parseToSubShareNotebooks(subNotebooks *info.SubNoteboo
|
||||
subShareNotebooks := info.SubShareNotebooks{}
|
||||
for _, each := range *subNotebooks {
|
||||
shareNotebooks := info.ShareNotebooks{}
|
||||
shareNotebooks.Notebook = each.Notebook // 基本信息有了
|
||||
shareNotebooks.Notebook = each.Notebook // 基本信息有了
|
||||
shareNotebooks.ShareNotebook = (*shareNotebooksMap)[each.NotebookId] // perm有了
|
||||
|
||||
|
||||
// 公用的, 单独赋值
|
||||
shareNotebooks.Seq = shareNotebooks.ShareNotebook.Seq
|
||||
shareNotebooks.NotebookId = shareNotebooks.ShareNotebook.NotebookId
|
||||
|
||||
|
||||
// 还有其子, 递归解析之
|
||||
if each.Subs != nil && len(each.Subs) > 0 {
|
||||
shareNotebooks.Subs = this.parseToSubShareNotebooks(&each.Subs, shareNotebooksMap)
|
||||
}
|
||||
subShareNotebooks = append(subShareNotebooks, shareNotebooks)
|
||||
}
|
||||
|
||||
|
||||
return subShareNotebooks
|
||||
}
|
||||
|
||||
//-------------
|
||||
|
||||
// 得到共享笔记本下的notes
|
||||
func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, sharedUserId string,
|
||||
page, pageSize int, sortField string, isAsc bool) ([]info.ShareNoteWithPerm) {
|
||||
func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, sharedUserId string,
|
||||
page, pageSize int, sortField string, isAsc bool) []info.ShareNoteWithPerm {
|
||||
// 1 首先判断是否真的sharedUserId 共享了 notebookId 给 myUserId
|
||||
q := this.getOrQ(myUserId)
|
||||
q["NotebookId"] = bson.ObjectIdHex(notebookId);
|
||||
q["UserId"] = bson.ObjectIdHex(sharedUserId);
|
||||
q["NotebookId"] = bson.ObjectIdHex(notebookId)
|
||||
q["UserId"] = bson.ObjectIdHex(sharedUserId)
|
||||
shareNotebook := info.ShareNotebook{}
|
||||
db.GetByQ(db.ShareNotebooks,
|
||||
db.GetByQ(db.ShareNotebooks,
|
||||
q,
|
||||
&shareNotebook)
|
||||
|
||||
|
||||
if shareNotebook.NotebookId == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
perm := shareNotebook.Perm
|
||||
|
||||
|
||||
// 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.1 如果该notebook自己有其它权限信息, 比如1, 那么覆盖notebook的权限信息
|
||||
noteIds := make([]bson.ObjectId, len(notes))
|
||||
@@ -201,7 +201,7 @@ func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, share
|
||||
// 笔记的权限
|
||||
shareNotes := []info.ShareNote{}
|
||||
delete(q, "NotebookId")
|
||||
q["NoteId"] = bson.M{"$in": noteIds}
|
||||
q["NoteId"] = bson.M{"$in": noteIds}
|
||||
db.ShareNotes.Find(q).Sort("-ToUserId").All(&shareNotes) // 给个的权限>给组织的权限
|
||||
notePerms := map[bson.ObjectId]int{}
|
||||
for _, each := range shareNotes {
|
||||
@@ -210,16 +210,16 @@ func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, share
|
||||
}
|
||||
}
|
||||
Log("笔记权限")
|
||||
LogJ(notePerms);
|
||||
|
||||
LogJ(notePerms)
|
||||
|
||||
// 3.2 组合
|
||||
notesWithPerm := make([]info.ShareNoteWithPerm, len(notes))
|
||||
for i, each := range notes {
|
||||
thisPerm := perm;
|
||||
thisPerm := perm
|
||||
if selfPerm, ok := notePerms[each.NoteId]; ok {
|
||||
thisPerm = selfPerm
|
||||
}
|
||||
|
||||
|
||||
notesWithPerm[i] = info.ShareNoteWithPerm{each, thisPerm}
|
||||
}
|
||||
return notesWithPerm
|
||||
@@ -228,17 +228,17 @@ func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, share
|
||||
// 得到note的perm信息
|
||||
//func (this *ShareService) getNotesPerm(noteIds []bson.ObjectId, myUserId, sharedUserId string) map[bson.ObjectId]int {
|
||||
// shareNotes := []info.ShareNote{}
|
||||
// db.ListByQ(db.ShareNotes,
|
||||
// db.ListByQ(db.ShareNotes,
|
||||
// bson.M{
|
||||
// "NoteId": bson.M{"$in": noteIds},
|
||||
// "UserId": bson.ObjectIdHex(sharedUserId),
|
||||
// "NoteId": bson.M{"$in": noteIds},
|
||||
// "UserId": bson.ObjectIdHex(sharedUserId),
|
||||
// "ToUserId": bson.ObjectIdHex(myUserId)}, &shareNotes)
|
||||
//
|
||||
//
|
||||
// notesPerm := make(map[bson.ObjectId]int, len(shareNotes))
|
||||
// for _, each := range shareNotes {
|
||||
// notesPerm[each.NoteId] = each.Perm
|
||||
// }
|
||||
//
|
||||
//
|
||||
// return notesPerm
|
||||
//}
|
||||
|
||||
@@ -246,26 +246,26 @@ func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, share
|
||||
// 如果真要支持排序, 这里得到所有共享的notes, 到noteService方再sort和limit
|
||||
// 可以这样! 到时将零散的共享noteId放在用户基本数据中
|
||||
// 这里不好排序
|
||||
func (this *ShareService) ListShareNotes(myUserId, sharedUserId string,
|
||||
pageNumber, pageSize int, sortField string, isAsc bool) ([]info.ShareNoteWithPerm) {
|
||||
|
||||
func (this *ShareService) ListShareNotes(myUserId, sharedUserId string,
|
||||
pageNumber, pageSize int, sortField string, isAsc bool) []info.ShareNoteWithPerm {
|
||||
|
||||
skipNum, _ := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
|
||||
shareNotes := []info.ShareNote{}
|
||||
|
||||
|
||||
q := this.getOrQ(myUserId)
|
||||
q["UserId"] = bson.ObjectIdHex(sharedUserId);
|
||||
|
||||
q["UserId"] = bson.ObjectIdHex(sharedUserId)
|
||||
|
||||
db.ShareNotes.
|
||||
Find(q).
|
||||
Sort("-ToUserId"). // 给个人的权限 > 给组织的权限
|
||||
Skip(skipNum).
|
||||
Limit(pageSize).
|
||||
All(&shareNotes)
|
||||
|
||||
|
||||
if len(shareNotes) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
noteIds := make([]bson.ObjectId, len(shareNotes))
|
||||
for i, each := range shareNotes {
|
||||
noteIds[i] = each.NoteId
|
||||
@@ -275,7 +275,7 @@ func (this *ShareService) ListShareNotes(myUserId, sharedUserId string,
|
||||
for _, each := range notes {
|
||||
notesMap[each.NoteId] = each
|
||||
}
|
||||
|
||||
|
||||
// 将shareNotes与notes结合起来
|
||||
notesWithPerm := []info.ShareNoteWithPerm{}
|
||||
hasAdded := map[bson.ObjectId]bool{} // 防止重复, 只要前面权限高的
|
||||
@@ -297,8 +297,8 @@ func (this *ShareService) notes2NotesWithPerm(notes []info.Note) {
|
||||
// [ok]
|
||||
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()
|
||||
return db.Insert(db.ShareNotebooks, shareNotebook)
|
||||
}
|
||||
@@ -312,22 +312,22 @@ func (this *ShareService) AddShareNotebook(notebookId string, perm int, userId,
|
||||
}
|
||||
return this.AddShareNotebookToUserId(notebookId, perm, userId, toUserId)
|
||||
}
|
||||
|
||||
|
||||
// 第三方注册时没有email
|
||||
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),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"ToUserId": bson.ObjectIdHex(toUserId),
|
||||
});
|
||||
|
||||
shareNotebook := info.ShareNotebook{NotebookId: bson.ObjectIdHex(notebookId),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
ToUserId: bson.ObjectIdHex(toUserId),
|
||||
Perm: perm,
|
||||
})
|
||||
|
||||
shareNotebook := info.ShareNotebook{NotebookId: bson.ObjectIdHex(notebookId),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
ToUserId: bson.ObjectIdHex(toUserId),
|
||||
Perm: perm,
|
||||
CreatedTime: time.Now(),
|
||||
}
|
||||
return db.Insert(db.ShareNotebooks, shareNotebook), "", toUserId
|
||||
@@ -350,27 +350,26 @@ func (this *ShareService) AddShareNote(noteId string, perm int, userId, email st
|
||||
return this.AddShareNoteToUserId(noteId, perm, userId, toUserId)
|
||||
}
|
||||
|
||||
// 第三方测试没有userId
|
||||
// 第三方测试没有userId
|
||||
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),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"ToUserId": bson.ObjectIdHex(toUserId),
|
||||
});
|
||||
|
||||
shareNote := info.ShareNote{NoteId: bson.ObjectIdHex(noteId),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
ToUserId: bson.ObjectIdHex(toUserId),
|
||||
Perm: perm,
|
||||
})
|
||||
|
||||
shareNote := info.ShareNote{NoteId: bson.ObjectIdHex(noteId),
|
||||
UserId: bson.ObjectIdHex(userId),
|
||||
ToUserId: bson.ObjectIdHex(toUserId),
|
||||
Perm: perm,
|
||||
CreatedTime: time.Now(),
|
||||
}
|
||||
return db.Insert(db.ShareNotes, shareNote), "", toUserId
|
||||
}
|
||||
|
||||
|
||||
// updatedUserId是否有查看userId noteId的权限?
|
||||
// userId是所有者
|
||||
func (this *ShareService) HasReadPerm(userId, updatedUserId, noteId string) bool {
|
||||
@@ -383,16 +382,16 @@ func (this *ShareService) HasReadPerm(userId, updatedUserId, noteId string) bool
|
||||
if notebookId.Hex() == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
delete(q, "NoteId")
|
||||
q["NotebookId"] = notebookId
|
||||
|
||||
|
||||
// 判断notebook是否被共享
|
||||
if !db.Has(db.ShareNotebooks, q) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
@@ -403,20 +402,20 @@ func (this *ShareService) HasUpdatePerm(userId, updatedUserId, noteId string) bo
|
||||
q := this.getOrQ(updatedUserId) // (toUserId == "xxx" || ToGroupId in (1, 2,3))
|
||||
q["UserId"] = bson.ObjectIdHex(userId)
|
||||
q["NoteId"] = bson.ObjectIdHex(noteId)
|
||||
|
||||
|
||||
// note的权限
|
||||
shares := []info.ShareNote{}
|
||||
db.ShareNotes.Find(q).Sort("-ToUserId").All(&shares) // 个人 > 组织
|
||||
for _, share := range shares {
|
||||
return share.Perm == 1 // 第1个权限最大
|
||||
}
|
||||
|
||||
|
||||
// notebook的权限
|
||||
notebookId := noteService.GetNotebookId(noteId)
|
||||
if notebookId.Hex() == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
delete(q, "NoteId")
|
||||
q["NotebookId"] = notebookId
|
||||
shares2 := []info.ShareNotebook{}
|
||||
@@ -443,19 +442,20 @@ func (this *ShareService) HasUpdateNotebookPerm(userId, updatedUserId, notebookI
|
||||
// 共享note, notebook时使用
|
||||
func (this *ShareService) AddHasShareNote(userId, toUserId string) bool {
|
||||
db.Insert(db.HasShareNotes, info.HasShareNote{UserId: bson.ObjectIdHex(userId), ToUserId: bson.ObjectIdHex(toUserId)})
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
// userId是否被共享了noteId
|
||||
func (this *ShareService) HasSharedNote(noteId, myUserId string) bool {
|
||||
return db.Has(db.ShareNotes, bson.M{"ToUserId": bson.ObjectIdHex(myUserId), "NoteId": bson.ObjectIdHex(noteId)})
|
||||
}
|
||||
|
||||
// noteId的notebook是否共享了给我
|
||||
func (this *ShareService) HasSharedNotebook(noteId, myUserId, sharedUserId string) bool {
|
||||
notebookId := noteService.GetNotebookId(noteId)
|
||||
if notebookId != "" {
|
||||
return db.Has(db.ShareNotebooks, bson.M{"NotebookId": notebookId,
|
||||
"UserId": bson.ObjectIdHex(sharedUserId),
|
||||
"UserId": bson.ObjectIdHex(sharedUserId),
|
||||
"ToUserId": bson.ObjectIdHex(myUserId),
|
||||
})
|
||||
}
|
||||
@@ -468,11 +468,12 @@ func (this *ShareService) GetShareNoteContent(noteId, myUserId, sharedUserId str
|
||||
noteContent = info.NoteContent{}
|
||||
// 是否单独共享了该notebook
|
||||
// 或者, 其notebook共享了我
|
||||
// Log(this.HasSharedNote(noteId, myUserId))
|
||||
// Log(this.HasSharedNotebook(noteId, myUserId, sharedUserId))
|
||||
Log(this.HasReadPerm(sharedUserId, myUserId, noteId))
|
||||
// Log(this.HasSharedNote(noteId, myUserId))
|
||||
// Log(this.HasSharedNotebook(noteId, myUserId, sharedUserId))
|
||||
// Log(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, ¬eContent)
|
||||
} else {
|
||||
}
|
||||
@@ -486,16 +487,16 @@ func (this *ShareService) GetShareNoteContent(noteId, myUserId, sharedUserId str
|
||||
func (this *ShareService) ListNoteShareUserInfo(noteId, userId string) []info.ShareUserInfo {
|
||||
// 得到shareNote信息, 得到所有的ToUserId
|
||||
shareNotes := []info.ShareNote{}
|
||||
db.ListByQLimit(db.ShareNotes,
|
||||
db.ListByQLimit(db.ShareNotes,
|
||||
bson.M{
|
||||
"NoteId": bson.ObjectIdHex(noteId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"NoteId": bson.ObjectIdHex(noteId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"ToGroupId": bson.M{"$exists": false},
|
||||
}, &shareNotes, 100)
|
||||
|
||||
// Log("<<>>>>")
|
||||
// Log(len(shareNotes))
|
||||
|
||||
|
||||
// Log("<<>>>>")
|
||||
// Log(len(shareNotes))
|
||||
|
||||
if len(shareNotes) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -504,45 +505,45 @@ func (this *ShareService) ListNoteShareUserInfo(noteId, userId string) []info.Sh
|
||||
for _, each := range shareNotes {
|
||||
shareNotesMap[each.ToUserId] = each
|
||||
}
|
||||
|
||||
|
||||
toUserIds := make([]bson.ObjectId, len(shareNotes))
|
||||
for i, eachShareNote := range shareNotes {
|
||||
toUserIds[i] = eachShareNote.ToUserId
|
||||
}
|
||||
|
||||
|
||||
note := noteService.GetNote(noteId, userId)
|
||||
if note.NoteId == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// 查看其notebook的shareNotebooks信息
|
||||
shareNotebooks := []info.ShareNotebook{}
|
||||
db.ListByQ(db.ShareNotebooks,
|
||||
bson.M{"NotebookId": note.NotebookId, "UserId": bson.ObjectIdHex(userId), "ToUserId": bson.M{"$in": toUserIds}},
|
||||
db.ListByQ(db.ShareNotebooks,
|
||||
bson.M{"NotebookId": note.NotebookId, "UserId": bson.ObjectIdHex(userId), "ToUserId": bson.M{"$in": toUserIds}},
|
||||
&shareNotebooks)
|
||||
shareNotebooksMap := make(map[bson.ObjectId]info.ShareNotebook, len(shareNotebooks))
|
||||
for _, each := range shareNotebooks {
|
||||
shareNotebooksMap[each.ToUserId] = each
|
||||
}
|
||||
|
||||
|
||||
// 得到用户信息
|
||||
userInfos := userService.ListUserInfosByUserIds(toUserIds)
|
||||
|
||||
|
||||
if len(userInfos) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
shareUserInfos := make([]info.ShareUserInfo, len(userInfos))
|
||||
|
||||
|
||||
for i, userInfo := range userInfos {
|
||||
_, hasNotebook := shareNotebooksMap[userInfo.UserId]
|
||||
shareUserInfos[i] = info.ShareUserInfo{ToUserId: userInfo.UserId,
|
||||
Email: userInfo.Email,
|
||||
Perm: shareNotesMap[userInfo.UserId].Perm,
|
||||
shareUserInfos[i] = info.ShareUserInfo{ToUserId: userInfo.UserId,
|
||||
Email: userInfo.Email,
|
||||
Perm: shareNotesMap[userInfo.UserId].Perm,
|
||||
NotebookHasShared: hasNotebook,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return shareUserInfos
|
||||
}
|
||||
|
||||
@@ -551,63 +552,62 @@ func (this *ShareService) ListNoteShareUserInfo(noteId, userId string) []info.Sh
|
||||
func (this *ShareService) ListNotebookShareUserInfo(notebookId, userId string) []info.ShareUserInfo {
|
||||
// notebook的shareNotebooks信息
|
||||
shareNotebooks := []info.ShareNotebook{}
|
||||
|
||||
db.ListByQLimit(db.ShareNotebooks,
|
||||
|
||||
db.ListByQLimit(db.ShareNotebooks,
|
||||
bson.M{
|
||||
"NotebookId": bson.ObjectIdHex(notebookId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"ToGroupId": bson.M{"$exists": false},
|
||||
},
|
||||
"NotebookId": bson.ObjectIdHex(notebookId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"ToGroupId": bson.M{"$exists": false},
|
||||
},
|
||||
&shareNotebooks, 100)
|
||||
|
||||
|
||||
if len(shareNotebooks) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// 得到用户信息
|
||||
toUserIds := make([]bson.ObjectId, len(shareNotebooks))
|
||||
for i, each := range shareNotebooks {
|
||||
toUserIds[i] = each.ToUserId
|
||||
}
|
||||
userInfos := userService.ListUserInfosByUserIds(toUserIds)
|
||||
|
||||
|
||||
if len(userInfos) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
shareNotebooksMap := make(map[bson.ObjectId]info.ShareNotebook, len(shareNotebooks))
|
||||
for _, each := range shareNotebooks {
|
||||
shareNotebooksMap[each.ToUserId] = each
|
||||
}
|
||||
|
||||
|
||||
shareUserInfos := make([]info.ShareUserInfo, len(userInfos))
|
||||
for i, userInfo := range userInfos {
|
||||
shareUserInfos[i] = info.ShareUserInfo{ToUserId: userInfo.UserId,
|
||||
shareUserInfos[i] = info.ShareUserInfo{ToUserId: userInfo.UserId,
|
||||
Email: userInfo.Email,
|
||||
Perm: shareNotebooksMap[userInfo.UserId].Perm,
|
||||
}
|
||||
Perm: shareNotebooksMap[userInfo.UserId].Perm,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return shareUserInfos
|
||||
}
|
||||
|
||||
|
||||
//----------------
|
||||
// 改变note share权限
|
||||
func (this *ShareService) UpdateShareNotePerm(noteId string, perm int, userId, toUserId string) bool {
|
||||
return db.UpdateByQField(db.ShareNotes,
|
||||
return db.UpdateByQField(db.ShareNotes,
|
||||
bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)},
|
||||
"Perm",
|
||||
"Perm",
|
||||
perm,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func (this *ShareService) UpdateShareNotebookPerm(notebookId string, perm int, userId, toUserId string) bool {
|
||||
return db.UpdateByQField(db.ShareNotebooks,
|
||||
return db.UpdateByQField(db.ShareNotebooks,
|
||||
bson.M{"NotebookId": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)},
|
||||
"Perm",
|
||||
"Perm",
|
||||
perm,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
//---------------
|
||||
@@ -622,6 +622,7 @@ func (this *ShareService) DeleteShareNoteAll(noteId string, userId string) bool
|
||||
return db.DeleteAll(db.ShareNotes,
|
||||
bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId)})
|
||||
}
|
||||
|
||||
// 删除share notebook
|
||||
func (this *ShareService) DeleteShareNotebook(notebookId string, userId, toUserId string) bool {
|
||||
return db.DeleteAll(db.ShareNotebooks,
|
||||
@@ -631,20 +632,20 @@ func (this *ShareService) DeleteShareNotebook(notebookId string, userId, toUserI
|
||||
// 删除userId分享给toUserId的所有
|
||||
func (this *ShareService) DeleteUserShareNoteAndNotebook(userId, toUserId string) bool {
|
||||
query := bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)}
|
||||
db.DeleteAll(db.ShareNotebooks, query);
|
||||
db.DeleteAll(db.ShareNotes, query);
|
||||
db.DeleteAll(db.HasShareNotes, query);
|
||||
|
||||
db.DeleteAll(db.ShareNotebooks, query)
|
||||
db.DeleteAll(db.ShareNotes, query)
|
||||
db.DeleteAll(db.HasShareNotes, query)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 用户userId是否有修改noteId的权限
|
||||
// 用户userId是否有修改noteId的权限
|
||||
func (this *ShareService) HasUpdateNotePerm(noteId, userId string) bool {
|
||||
if noteId == "" || userId == "" {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
note := noteService.GetNoteById(noteId)
|
||||
LogJ(note);
|
||||
LogJ(note)
|
||||
if note.UserId != "" {
|
||||
noteUserId := note.UserId.Hex()
|
||||
if noteUserId != userId {
|
||||
@@ -652,20 +653,20 @@ func (this *ShareService) HasUpdateNotePerm(noteId, userId string) bool {
|
||||
if this.HasUpdatePerm(noteUserId, userId, noteId) {
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 用户userId是否有查看noteId的权限
|
||||
// 用户userId是否有查看noteId的权限
|
||||
func (this *ShareService) HasReadNotePerm(noteId, userId string) bool {
|
||||
if noteId == "" || userId == "" {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
note := noteService.GetNoteById(noteId)
|
||||
if note.UserId != "" {
|
||||
@@ -675,13 +676,13 @@ func (this *ShareService) HasReadNotePerm(noteId, userId string) bool {
|
||||
if this.HasReadPerm(noteUserId, userId, noteId) {
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -691,16 +692,16 @@ func (this *ShareService) HasReadNotePerm(noteId, userId string) bool {
|
||||
// 得到笔记分享给的groups
|
||||
func (this *ShareService) GetNoteShareGroups(noteId, userId string) []info.ShareNote {
|
||||
groups := groupService.GetGroupsContainOf(userId)
|
||||
|
||||
|
||||
// 得到有分享的分组
|
||||
shares := []info.ShareNote{}
|
||||
db.ListByQ(db.ShareNotes,
|
||||
bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId), "ToGroupId": bson.M{"$exists":true}}, &shares)
|
||||
db.ListByQ(db.ShareNotes,
|
||||
bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId), "ToGroupId": bson.M{"$exists": true}}, &shares)
|
||||
mapShares := map[bson.ObjectId]info.ShareNote{}
|
||||
for _, share := range shares {
|
||||
mapShares[share.ToGroupId] = share
|
||||
mapShares[share.ToGroupId] = share
|
||||
}
|
||||
|
||||
|
||||
// 所有的groups都有share, 但没有share的group没有shareId
|
||||
shares2 := make([]info.ShareNote, len(groups))
|
||||
for i, group := range groups {
|
||||
@@ -708,26 +709,26 @@ func (this *ShareService) GetNoteShareGroups(noteId, userId string) []info.Share
|
||||
if !ok {
|
||||
share = info.ShareNote{}
|
||||
}
|
||||
share.ToGroup = group;
|
||||
share.ToGroup = group
|
||||
shares2[i] = share
|
||||
}
|
||||
|
||||
|
||||
return shares2
|
||||
}
|
||||
|
||||
// 共享笔记给分组
|
||||
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) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// 先删除之
|
||||
this.DeleteShareNoteGroup(userId, noteId, groupId)
|
||||
|
||||
shareNote := info.ShareNote{NoteId: bson.ObjectIdHex(noteId),
|
||||
UserId: bson.ObjectIdHex(userId), // 冗余字段
|
||||
ToGroupId: bson.ObjectIdHex(groupId),
|
||||
Perm: perm,
|
||||
|
||||
shareNote := info.ShareNote{NoteId: bson.ObjectIdHex(noteId),
|
||||
UserId: bson.ObjectIdHex(userId), // 冗余字段
|
||||
ToGroupId: bson.ObjectIdHex(groupId),
|
||||
Perm: perm,
|
||||
CreatedTime: time.Now(),
|
||||
}
|
||||
return db.Insert(db.ShareNotes, shareNote)
|
||||
@@ -736,27 +737,27 @@ func (this *ShareService) AddShareNoteGroup(userId, noteId, groupId string, perm
|
||||
// 删除
|
||||
func (this *ShareService) DeleteShareNoteGroup(userId, noteId, groupId string) bool {
|
||||
return db.Delete(db.ShareNotes, bson.M{"NoteId": bson.ObjectIdHex(noteId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"ToGroupId": bson.ObjectIdHex(groupId),
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
//-------
|
||||
|
||||
|
||||
// 得到笔记本分享给的groups
|
||||
func (this *ShareService) GetNotebookShareGroups(notebookId, userId string) []info.ShareNotebook {
|
||||
groups := groupService.GetGroupsContainOf(userId)
|
||||
|
||||
|
||||
// 得到有分享的分组
|
||||
shares := []info.ShareNotebook{}
|
||||
db.ListByQ(db.ShareNotebooks,
|
||||
bson.M{"NotebookId": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId), "ToGroupId": bson.M{"$exists":true}}, &shares)
|
||||
db.ListByQ(db.ShareNotebooks,
|
||||
bson.M{"NotebookId": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId), "ToGroupId": bson.M{"$exists": true}}, &shares)
|
||||
mapShares := map[bson.ObjectId]info.ShareNotebook{}
|
||||
for _, share := range shares {
|
||||
mapShares[share.ToGroupId] = share
|
||||
mapShares[share.ToGroupId] = share
|
||||
}
|
||||
LogJ(shares)
|
||||
|
||||
|
||||
// 所有的groups都有share, 但没有share的group没有shareId
|
||||
shares2 := make([]info.ShareNotebook, len(groups))
|
||||
for i, group := range groups {
|
||||
@@ -764,25 +765,26 @@ func (this *ShareService) GetNotebookShareGroups(notebookId, userId string) []in
|
||||
if !ok {
|
||||
share = info.ShareNotebook{}
|
||||
}
|
||||
share.ToGroup = group;
|
||||
share.ToGroup = group
|
||||
shares2[i] = share
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// 先删除之
|
||||
this.DeleteShareNotebookGroup(userId, notebookId, groupId)
|
||||
|
||||
shareNotebook := info.ShareNotebook{NotebookId: bson.ObjectIdHex(notebookId),
|
||||
UserId: bson.ObjectIdHex(userId), // 冗余字段
|
||||
ToGroupId: bson.ObjectIdHex(groupId),
|
||||
Perm: perm,
|
||||
|
||||
shareNotebook := info.ShareNotebook{NotebookId: bson.ObjectIdHex(notebookId),
|
||||
UserId: bson.ObjectIdHex(userId), // 冗余字段
|
||||
ToGroupId: bson.ObjectIdHex(groupId),
|
||||
Perm: perm,
|
||||
CreatedTime: time.Now(),
|
||||
}
|
||||
return db.Insert(db.ShareNotebooks, shareNotebook)
|
||||
@@ -791,9 +793,9 @@ func (this *ShareService) AddShareNotebookGroup(userId, notebookId, groupId stri
|
||||
// 删除
|
||||
func (this *ShareService) DeleteShareNotebookGroup(userId, notebookId, groupId string) bool {
|
||||
return db.Delete(db.ShareNotebooks, bson.M{"NotebookId": bson.ObjectIdHex(notebookId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"ToGroupId": bson.ObjectIdHex(groupId),
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
//--------------------
|
||||
@@ -803,12 +805,12 @@ func (this *ShareService) DeleteShareNotebookGroup(userId, notebookId, groupId s
|
||||
func (this *ShareService) DeleteAllShareNotebookGroup(groupId string) bool {
|
||||
return db.Delete(db.ShareNotebooks, bson.M{
|
||||
"ToGroupId": bson.ObjectIdHex(groupId),
|
||||
});
|
||||
})
|
||||
}
|
||||
func (this *ShareService) DeleteAllShareNoteGroup(groupId string) bool {
|
||||
return db.Delete(db.ShareNotes, bson.M{
|
||||
"ToGroupId": bson.ObjectIdHex(groupId),
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
//--------------------
|
||||
@@ -817,14 +819,14 @@ func (this *ShareService) DeleteAllShareNoteGroup(groupId string) bool {
|
||||
|
||||
func (this *ShareService) DeleteShareNotebookGroupWhenDeleteGroupUser(userId, groupId string) bool {
|
||||
return db.Delete(db.ShareNotebooks, bson.M{
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"ToGroupId": bson.ObjectIdHex(groupId),
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
func (this *ShareService) DeleteShareNoteGroupWhenDeleteGroupUser(userId, groupId string) bool {
|
||||
return db.Delete(db.ShareNotes, bson.M{
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"ToGroupId": bson.ObjectIdHex(groupId),
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// "time"
|
||||
// "sort"
|
||||
// "time"
|
||||
// "sort"
|
||||
)
|
||||
|
||||
type SuggestionService struct {
|
||||
@@ -18,4 +18,4 @@ func (this *SuggestionService) AddSuggestion(suggestion info.Suggestion) bool {
|
||||
suggestion.Id = bson.NewObjectId()
|
||||
}
|
||||
return db.Insert(db.Suggestions, suggestion)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
)
|
||||
@@ -31,8 +31,8 @@ func (this *TagService) AddTagsI(userId string, tags interface{}) bool {
|
||||
}
|
||||
func (this *TagService) AddTags(userId string, tags []string) bool {
|
||||
for _, tag := range tags {
|
||||
if !db.Upsert(db.Tags,
|
||||
bson.M{"_id": bson.ObjectIdHex(userId)},
|
||||
if !db.Upsert(db.Tags,
|
||||
bson.M{"_id": bson.ObjectIdHex(userId)},
|
||||
bson.M{"$addToSet": bson.M{"Tags": tag}}) {
|
||||
return false
|
||||
}
|
||||
@@ -53,18 +53,18 @@ func (this *TagService) AddOrUpdateTag(userId string, tag string) info.NoteTag {
|
||||
userIdO := bson.ObjectIdHex(userId)
|
||||
noteTag := info.NoteTag{}
|
||||
db.GetByQ(db.NoteTags, bson.M{"UserId": userIdO, "Tag": tag}, ¬eTag)
|
||||
|
||||
|
||||
// 存在, 则更新之
|
||||
if noteTag.TagId != "" {
|
||||
// 统计note数
|
||||
count := noteService.CountNoteByTag(userId, tag)
|
||||
noteTag.Count = count
|
||||
noteTag.UpdatedTime = time.Now()
|
||||
// noteTag.Usn = userService.IncrUsn(userId), 更新count而已
|
||||
// noteTag.Usn = userService.IncrUsn(userId), 更新count而已
|
||||
db.UpdateByIdAndUserId(db.NoteTags, noteTag.TagId.Hex(), userId, noteTag)
|
||||
return noteTag
|
||||
}
|
||||
|
||||
|
||||
// 不存在, 则创建之
|
||||
noteTag.TagId = bson.NewObjectId()
|
||||
noteTag.Count = 1
|
||||
@@ -75,7 +75,7 @@ func (this *TagService) AddOrUpdateTag(userId string, tag string) info.NoteTag {
|
||||
noteTag.Usn = userService.IncrUsn(userId)
|
||||
noteTag.IsDeleted = false
|
||||
db.Insert(db.NoteTags, noteTag)
|
||||
|
||||
|
||||
return noteTag
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ func (this *TagService) AddOrUpdateTag(userId string, tag string) info.NoteTag {
|
||||
func (this *TagService) GetTags(userId string) []info.NoteTag {
|
||||
tags := []info.NoteTag{}
|
||||
query := bson.M{"UserId": bson.ObjectIdHex(userId), "IsDeleted": false}
|
||||
q := db.NoteTags.Find(query);
|
||||
q := db.NoteTags.Find(query)
|
||||
sortFieldR := "-UpdatedTime"
|
||||
q.Sort(sortFieldR).All(&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 {
|
||||
usn := userService.IncrUsn(userId)
|
||||
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{}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ func (this *TagService) DeleteTag(userId string, tag string) map[string]int {
|
||||
func (this *TagService) DeleteTagApi(userId string, tag string, usn int) (ok bool, msg string, toUsn int) {
|
||||
noteTag := info.NoteTag{}
|
||||
db.GetByQ(db.NoteTags, bson.M{"UserId": bson.ObjectIdHex(userId), "Tag": tag}, ¬eTag)
|
||||
|
||||
|
||||
if noteTag.TagId == "" {
|
||||
return false, "notExists", 0
|
||||
}
|
||||
@@ -124,14 +124,14 @@ func (this *TagService) reCountTagCount(userId string, tags []string) {
|
||||
return
|
||||
}
|
||||
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{}
|
||||
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(¬eTags)
|
||||
return noteTags
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/lea/archive"
|
||||
"github.com/revel/revel"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"strings"
|
||||
"os"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"regexp"
|
||||
"io/ioutil"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 主题
|
||||
@@ -29,6 +29,7 @@ var fixedStyle = "blog_left_fixed"
|
||||
func (this *ThemeService) getDefaultThemeBasePath() string {
|
||||
return revel.BasePath + "/public/blog/themes"
|
||||
}
|
||||
|
||||
// 默认主题路径
|
||||
func (this *ThemeService) getDefaultThemePath(style string) string {
|
||||
if style == elegantStyle {
|
||||
@@ -39,6 +40,7 @@ func (this *ThemeService) getDefaultThemePath(style string) string {
|
||||
return this.getDefaultThemeBasePath() + "/default"
|
||||
}
|
||||
}
|
||||
|
||||
// blogService用
|
||||
func (this *ThemeService) GetDefaultThemePath(style string) string {
|
||||
if style == elegantStyle {
|
||||
@@ -51,34 +53,34 @@ func (this *ThemeService) GetDefaultThemePath(style string) string {
|
||||
}
|
||||
|
||||
// 得到默认主题
|
||||
// style是之前的值, 有3个值 blog_default, blog_daqi, blog_left_fixed
|
||||
// style是之前的值, 有3个值 blog_default, blog_daqi, blog_left_fixed
|
||||
func (this *ThemeService) getDefaultTheme(style string) info.Theme {
|
||||
if style == elegantStyle {
|
||||
return info.Theme{
|
||||
IsDefault: true,
|
||||
Path: "public/blog/themes/elegant",
|
||||
Name: "leanote elegant",
|
||||
Author: "leanote",
|
||||
Path: "public/blog/themes/elegant",
|
||||
Name: "leanote elegant",
|
||||
Author: "leanote",
|
||||
AuthorUrl: "http://leanote.com",
|
||||
Version: "1.0",
|
||||
Version: "1.0",
|
||||
}
|
||||
} else if style == fixedStyle {
|
||||
return info.Theme{
|
||||
IsDefault: true,
|
||||
Path: "public/blog/themes/nav_fixed",
|
||||
Name: "leanote nav fixed",
|
||||
Author: "leanote",
|
||||
Path: "public/blog/themes/nav_fixed",
|
||||
Name: "leanote nav fixed",
|
||||
Author: "leanote",
|
||||
AuthorUrl: "http://leanote.com",
|
||||
Version: "1.0",
|
||||
Version: "1.0",
|
||||
}
|
||||
} else { // blog default
|
||||
return info.Theme{
|
||||
IsDefault: true,
|
||||
Path: "public/blog/themes/default",
|
||||
Name: "leanote default",
|
||||
Author: "leanote",
|
||||
Path: "public/blog/themes/default",
|
||||
Name: "leanote default",
|
||||
Author: "leanote",
|
||||
AuthorUrl: "http://leanote.com",
|
||||
Version: "1.0",
|
||||
Version: "1.0",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,15 +105,15 @@ func (this *ThemeService) CopyDefaultTheme(userBlog info.UserBlog) (ok bool, the
|
||||
themePath := this.getUserThemePath(userId, themeId)
|
||||
err := os.MkdirAll(themePath, 0755)
|
||||
if err != nil {
|
||||
return
|
||||
return
|
||||
}
|
||||
// 复制默认主题
|
||||
defaultThemePath := this.getDefaultThemePath(userBlog.Style)
|
||||
err = CopyDir(defaultThemePath, themePath)
|
||||
if err != nil {
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 保存到数据库中
|
||||
theme, _ := this.getThemeConfig(themePath)
|
||||
theme.ThemeId = newThemeId
|
||||
@@ -119,7 +121,7 @@ func (this *ThemeService) CopyDefaultTheme(userBlog info.UserBlog) (ok bool, the
|
||||
theme.CreatedTime = time.Now()
|
||||
theme.UpdatedTime = theme.CreatedTime
|
||||
theme.UserId = bson.ObjectIdHex(userId)
|
||||
|
||||
|
||||
ok = db.Insert(db.Themes, theme)
|
||||
return ok, themeId
|
||||
}
|
||||
@@ -141,7 +143,7 @@ func (this *ThemeService) NewTheme(userId string) (ok bool, themeId string) {
|
||||
themeService.NewThemeForFirst(userBlog)
|
||||
}
|
||||
// 再copy一个默认主题
|
||||
userBlog.Style = "defaultStyle";
|
||||
userBlog.Style = "defaultStyle"
|
||||
ok, themeId = this.CopyDefaultTheme(userBlog)
|
||||
return
|
||||
}
|
||||
@@ -151,37 +153,37 @@ func (this *ThemeService) parseConfig(configStr string) (theme info.Theme, err e
|
||||
theme = info.Theme{}
|
||||
// 除去/**/注释
|
||||
reg, _ := regexp.Compile("/\\*[\\s\\S]*?\\*/")
|
||||
configStr = reg.ReplaceAllString(configStr, "")
|
||||
configStr = reg.ReplaceAllString(configStr, "")
|
||||
// 转成map
|
||||
config := map[string]interface{}{}
|
||||
err = json.Unmarshal([]byte(configStr), &config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 没有错, 则将Name, Version, Author, AuthorUrl
|
||||
Name := config["Name"]
|
||||
if Name != nil {
|
||||
theme.Name = Name.(string)
|
||||
}
|
||||
Version := config["Version"]
|
||||
if Version != nil {
|
||||
theme.Version = Version.(string)
|
||||
}
|
||||
Author := config["Author"]
|
||||
if Author != nil {
|
||||
theme.Author = Author.(string)
|
||||
}
|
||||
AuthorUrl := config["AuthorUrl"]
|
||||
if AuthorUrl != nil {
|
||||
theme.AuthorUrl = AuthorUrl.(string)
|
||||
}
|
||||
theme.Info = config
|
||||
|
||||
return
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 没有错, 则将Name, Version, Author, AuthorUrl
|
||||
Name := config["Name"]
|
||||
if Name != nil {
|
||||
theme.Name = Name.(string)
|
||||
}
|
||||
Version := config["Version"]
|
||||
if Version != nil {
|
||||
theme.Version = Version.(string)
|
||||
}
|
||||
Author := config["Author"]
|
||||
if Author != nil {
|
||||
theme.Author = Author.(string)
|
||||
}
|
||||
AuthorUrl := config["AuthorUrl"]
|
||||
if AuthorUrl != nil {
|
||||
theme.AuthorUrl = AuthorUrl.(string)
|
||||
}
|
||||
theme.Info = config
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 读取theme.json得到值
|
||||
func (this *ThemeService) getThemeConfig(themePath string) (theme info.Theme, err error) {
|
||||
func (this *ThemeService) getThemeConfig(themePath string) (theme info.Theme, err error) {
|
||||
theme = info.Theme{}
|
||||
configStr := GetFileStrContent(themePath + "/theme.json")
|
||||
theme, err = this.parseConfig(configStr)
|
||||
@@ -222,12 +224,12 @@ func (this *ThemeService) GetThemeInfo(themeId, style string) map[string]interfa
|
||||
func (this *ThemeService) GetUserThemes(userId string) (theme info.Theme, themes []info.Theme) {
|
||||
theme = info.Theme{}
|
||||
themes = []info.Theme{}
|
||||
|
||||
// db.ListByQ(db.Themes, bson.M{"UserId": bson.ObjectIdHex(userId)}, &themes)
|
||||
|
||||
|
||||
// db.ListByQ(db.Themes, bson.M{"UserId": bson.ObjectIdHex(userId)}, &themes)
|
||||
|
||||
// 创建时间逆序
|
||||
query := bson.M{"UserId": bson.ObjectIdHex(userId)}
|
||||
q := db.Themes.Find(query);
|
||||
q := db.Themes.Find(query)
|
||||
q.Sort("-CreatedTime").All(&themes)
|
||||
if len(themes) == 0 {
|
||||
userBlog := blogService.GetUserBlog(userId)
|
||||
@@ -285,6 +287,7 @@ func (this *ThemeService) GetThemePath(userId, themeId string) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// 更新模板内容
|
||||
func (this *ThemeService) UpdateTplContent(userId, themeId, filename, content string) (ok bool, msg string) {
|
||||
basePath := this.GetThemeAbsolutePath(userId, themeId)
|
||||
@@ -305,13 +308,13 @@ func (this *ThemeService) UpdateTplContent(userId, themeId, filename, content st
|
||||
return false, fmt.Sprintf("%v", err)
|
||||
}
|
||||
// 正确, 更新theme信息
|
||||
ok = db.UpdateByQMap(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId)},
|
||||
ok = db.UpdateByQMap(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId)},
|
||||
bson.M{
|
||||
"Name": theme.Name,
|
||||
"Version": theme.Version,
|
||||
"Author": theme.Author,
|
||||
"Name": theme.Name,
|
||||
"Version": theme.Version,
|
||||
"Author": theme.Author,
|
||||
"AuthorUrl": theme.AuthorUrl,
|
||||
"Info": theme.Info,
|
||||
"Info": theme.Info,
|
||||
})
|
||||
if ok {
|
||||
ok = PutFileStrContent(path, content)
|
||||
@@ -351,7 +354,7 @@ func (this *ThemeService) ActiveTheme(userId, themeId string) (ok bool) {
|
||||
db.UpdateByQField(db.Themes, bson.M{"UserId": bson.ObjectIdHex(userId), "IsActive": true}, "IsActive", false)
|
||||
// 现在的设为true
|
||||
db.UpdateByQField(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId)}, "IsActive", true)
|
||||
|
||||
|
||||
// UserBlog ThemeId
|
||||
db.UpdateByQField(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, "ThemeId", bson.ObjectIdHex(themeId))
|
||||
return true
|
||||
@@ -361,7 +364,7 @@ func (this *ThemeService) ActiveTheme(userId, themeId string) (ok bool) {
|
||||
|
||||
// 删除主题
|
||||
func (this *ThemeService) DeleteTheme(userId, themeId string) (ok bool) {
|
||||
return db.Delete(db.Themes,bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId), "IsActive": false})
|
||||
return db.Delete(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId), "IsActive": false})
|
||||
}
|
||||
|
||||
// 公开主题, 只有管理员才有权限, 之前没公开的变成公开
|
||||
@@ -375,37 +378,37 @@ func (this *ThemeService) PublicTheme(userId, themeId string) (ok bool) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// 导出主题
|
||||
func (this *ThemeService) ExportTheme(userId, themeId string) (ok bool, path string) {
|
||||
theme := this.GetThemeById(themeId)
|
||||
// 打包
|
||||
// 验证路径, 别把整个项目打包了
|
||||
Log(theme.Path)
|
||||
if theme.Path == "" ||
|
||||
if theme.Path == "" ||
|
||||
(!strings.HasPrefix(theme.Path, "public/upload") &&
|
||||
!strings.HasPrefix(theme.Path, "public/blog/themes")) ||
|
||||
!strings.HasPrefix(theme.Path, "public/blog/themes")) ||
|
||||
strings.Contains(theme.Path, "..") {
|
||||
return
|
||||
}
|
||||
|
||||
sourcePath := revel.BasePath + "/" + theme.Path
|
||||
|
||||
sourcePath := revel.BasePath + "/" + theme.Path
|
||||
targetPath := revel.BasePath + "/public/upload/" + userId + "/tmp"
|
||||
err := os.MkdirAll(targetPath, 0755)
|
||||
if err != nil {
|
||||
Log(err)
|
||||
return
|
||||
return
|
||||
}
|
||||
targetName := targetPath + "/" + theme.Name + ".zip"
|
||||
Log(sourcePath)
|
||||
Log(targetName)
|
||||
ok = archive.Zip(sourcePath, targetName)
|
||||
ok = archive.Zip(sourcePath, targetName)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
return true, targetName
|
||||
}
|
||||
|
||||
// 导入主题
|
||||
// path == /llllllll/..../public/upload/.../aa.zip, 绝对路径
|
||||
func (this *ThemeService) ImportTheme(userId, path string) (ok bool, msg string) {
|
||||
@@ -416,14 +419,14 @@ func (this *ThemeService) ImportTheme(userId, path string) (ok bool, msg string)
|
||||
err := os.MkdirAll(targetPath, 0755)
|
||||
if err != nil {
|
||||
msg = "error"
|
||||
return
|
||||
return
|
||||
}
|
||||
if ok, msg = archive.Unzip(path, targetPath); !ok {
|
||||
DeleteFile(targetPath)
|
||||
Log("oh no")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 主题验证
|
||||
if ok, msg = this.ValidateTheme(targetPath, "", ""); !ok {
|
||||
DeleteFile(targetPath)
|
||||
@@ -443,13 +446,13 @@ func (this *ThemeService) ImportTheme(userId, path string) (ok bool, msg string)
|
||||
theme.CreatedTime = time.Now()
|
||||
theme.UpdatedTime = theme.CreatedTime
|
||||
theme.UserId = bson.ObjectIdHex(userId)
|
||||
|
||||
|
||||
ok = db.Insert(db.Themes, theme)
|
||||
if !ok {
|
||||
DeleteFile(targetPath)
|
||||
}
|
||||
DeleteFile(path)
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// 升级用
|
||||
@@ -492,28 +495,28 @@ func (this *ThemeService) InstallTheme(userId, themeId string) (ok bool) {
|
||||
if !theme.IsDefault {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// 用户之前是否有主题?
|
||||
userBlog := blogService.GetUserBlog(userId)
|
||||
if userBlog.ThemeId == "" {
|
||||
this.NewThemeForFirst(userBlog)
|
||||
}
|
||||
|
||||
|
||||
// 生成新主题
|
||||
newThemeId := bson.NewObjectId()
|
||||
themeId = newThemeId.Hex()
|
||||
themePath := this.getUserThemePath(userId, themeId)
|
||||
err := os.MkdirAll(themePath, 0755)
|
||||
if err != nil {
|
||||
return
|
||||
return
|
||||
}
|
||||
// 复制默认主题
|
||||
sourceThemePath := revel.BasePath + "/" + theme.Path
|
||||
err = CopyDir(sourceThemePath, themePath)
|
||||
if err != nil {
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 保存到数据库中
|
||||
theme, _ = this.getThemeConfig(themePath)
|
||||
theme.ThemeId = newThemeId
|
||||
@@ -521,11 +524,11 @@ func (this *ThemeService) InstallTheme(userId, themeId string) (ok bool) {
|
||||
theme.CreatedTime = time.Now()
|
||||
theme.UpdatedTime = theme.CreatedTime
|
||||
theme.UserId = bson.ObjectIdHex(userId)
|
||||
|
||||
|
||||
ok = db.Insert(db.Themes, theme)
|
||||
|
||||
|
||||
// 激活之
|
||||
this.ActiveTheme(userId, themeId);
|
||||
this.ActiveTheme(userId, themeId)
|
||||
|
||||
return ok
|
||||
}
|
||||
@@ -535,39 +538,39 @@ func (this *ThemeService) InstallTheme(userId, themeId string) (ok bool) {
|
||||
func (this *ThemeService) ValidateTheme(path string, filename, newContent string) (ok bool, msg string) {
|
||||
Log("theme Path")
|
||||
Log(path)
|
||||
// 建立一个有向图
|
||||
// 建立一个有向图
|
||||
// 将该path下的所有文件提出, 得到文件的引用情况
|
||||
files := ListDir(path)
|
||||
LogJ(files);
|
||||
LogJ(files)
|
||||
size := len(files)
|
||||
if(size > 100) {
|
||||
ok = false;
|
||||
if size > 100 {
|
||||
ok = false
|
||||
msg = "tooManyFiles"
|
||||
return
|
||||
}
|
||||
/*
|
||||
111111111
|
||||
111000000
|
||||
111111111
|
||||
111000000
|
||||
*/
|
||||
vector := make([][]int, size)
|
||||
for i := 0; i < size; i++ {
|
||||
vector[i] = make([]int, size)
|
||||
}
|
||||
fileIndexMap := map[string]int{} // fileName => index
|
||||
fileIndexMap := map[string]int{} // fileName => index
|
||||
fileContent := map[string]string{} // fileName => content
|
||||
index := 0
|
||||
// 得到文件内容, 和建立索引, 每个文件都有一个index, 对应数组位置
|
||||
for _, t := range files {
|
||||
if !strings.Contains(t, ".html") {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
if t != filename {
|
||||
fileBytes, err := ioutil.ReadFile(path + "/" + t)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
fileIndexMap[t] = index;
|
||||
|
||||
fileIndexMap[t] = index
|
||||
// html内容
|
||||
fileStr := string(fileBytes)
|
||||
fileContent[t] = fileStr
|
||||
@@ -583,7 +586,7 @@ func (this *ThemeService) ValidateTheme(path string, filename, newContent string
|
||||
thisIndex := fileIndexMap[filename]
|
||||
finds := reg.FindAllStringSubmatch(content, -1) // 子匹配
|
||||
LogJ(finds)
|
||||
// Log(content)
|
||||
// Log(content)
|
||||
if finds != nil && len(finds) > 0 {
|
||||
for _, includes := range finds {
|
||||
include := includes[1]
|
||||
@@ -597,7 +600,7 @@ func (this *ThemeService) ValidateTheme(path string, filename, newContent string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LogJ(vector)
|
||||
LogJ(fileIndexMap)
|
||||
// 建立图后, 判断是否有环
|
||||
@@ -607,7 +610,7 @@ func (this *ThemeService) ValidateTheme(path string, filename, newContent string
|
||||
} else {
|
||||
ok = true
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// 检测有向图是否有环, DFS
|
||||
@@ -615,9 +618,7 @@ func (this *ThemeService) hasRound(vector [][]int, size int) (ok bool) {
|
||||
for i := 0; i < size; i++ {
|
||||
visited := make([]int, size)
|
||||
if this.hasRoundEach(vector, i, size, visited) {
|
||||
Log(">>")
|
||||
Log(i);
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
}
|
||||
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) {
|
||||
if visited[index] > 0 {
|
||||
Log("<")
|
||||
Log(index)
|
||||
return true
|
||||
}
|
||||
visited[index] = 1;
|
||||
visited[index] = 1
|
||||
// 遍历它的孩子
|
||||
for i := 0; i < size; i++ {
|
||||
if vector[index][i] > 0 {
|
||||
return this.hasRoundEach(vector, i, size, visited);
|
||||
return this.hasRoundEach(vector, i, size, visited)
|
||||
}
|
||||
}
|
||||
visited[index] = 0;
|
||||
return false;
|
||||
visited[index] = 0
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -18,11 +18,11 @@ type TokenService struct {
|
||||
// 生成token
|
||||
func (this *TokenService) NewToken(userId string, email string, tokenType int) string {
|
||||
token := info.Token{UserId: bson.ObjectIdHex(userId), Token: NewGuidWith(email), CreatedTime: time.Now(), Email: email, Type: tokenType}
|
||||
|
||||
|
||||
if db.Upsert(db.Tokens, bson.M{"_id": token.UserId}, token) {
|
||||
return token.Token
|
||||
}
|
||||
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -50,23 +50,23 @@ func (this *TokenService) VerifyToken(token string, tokenType int) (ok bool, msg
|
||||
msg = "不存在"
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
db.GetByQ(db.Tokens, bson.M{"Token": token}, &tokenInfo)
|
||||
|
||||
|
||||
if tokenInfo.UserId == "" {
|
||||
msg = "不存在"
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 验证是否过时
|
||||
now := time.Now()
|
||||
duration := now.Sub(tokenInfo.CreatedTime)
|
||||
|
||||
|
||||
if duration.Hours() > overHours {
|
||||
msg = "过期"
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
// 回收站
|
||||
@@ -25,6 +25,12 @@ type TrashService struct {
|
||||
// 应该放在回收站里
|
||||
// 有trashService
|
||||
func (this *TrashService) DeleteNote(noteId, userId string) bool {
|
||||
note := noteService.GetNote(noteId, userId)
|
||||
// 如果是垃圾, 则彻底删除
|
||||
if note.IsTrash {
|
||||
return this.DeleteTrash(noteId, userId)
|
||||
}
|
||||
|
||||
// 首先删除其共享
|
||||
if shareService.DeleteShareNoteAll(noteId, userId) {
|
||||
// 更新note isTrash = true
|
||||
@@ -36,13 +42,15 @@ func (this *TrashService) DeleteNote(noteId, userId string) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 删除别人共享给我的笔记
|
||||
// 先判断我是否有权限, 笔记是否是我创建的
|
||||
func (this *TrashService) DeleteSharedNote(noteId, userId, myUserId string) bool {
|
||||
note := noteService.GetNote(noteId, userId)
|
||||
func (this *TrashService) DeleteSharedNote(noteId, myUserId string) bool {
|
||||
note := noteService.GetNoteById(noteId)
|
||||
userId := note.UserId.Hex()
|
||||
if shareService.HasUpdatePerm(userId, myUserId, noteId) && note.CreatedUserId.Hex() == myUserId {
|
||||
return db.UpdateByIdAndUserId(db.Notes, noteId, userId, bson.M{"$set": bson.M{"IsTrash": true, "Usn": userService.IncrUsn(userId)}})
|
||||
}
|
||||
@@ -51,16 +59,16 @@ func (this *TrashService) DeleteSharedNote(noteId, userId, myUserId string) bool
|
||||
|
||||
// recover
|
||||
func (this *TrashService) recoverNote(noteId, notebookId, userId string) bool {
|
||||
re := db.UpdateByIdAndUserId(db.Notes, noteId, userId,
|
||||
bson.M{"$set": bson.M{"IsTrash": false,
|
||||
"Usn": userService.IncrUsn(userId),
|
||||
re := db.UpdateByIdAndUserId(db.Notes, noteId, userId,
|
||||
bson.M{"$set": bson.M{"IsTrash": false,
|
||||
"Usn": userService.IncrUsn(userId),
|
||||
"NotebookId": bson.ObjectIdHex(notebookId)}})
|
||||
return re;
|
||||
return re
|
||||
}
|
||||
|
||||
// 删除trash
|
||||
func (this *TrashService) DeleteTrash(noteId, userId string) bool {
|
||||
note := noteService.GetNote(noteId, userId);
|
||||
note := noteService.GetNote(noteId, userId)
|
||||
if note.NoteId == "" {
|
||||
return false
|
||||
}
|
||||
@@ -68,52 +76,62 @@ func (this *TrashService) DeleteTrash(noteId, userId string) bool {
|
||||
ok := attachService.DeleteAllAttachs(noteId, userId)
|
||||
|
||||
// 设置删除位
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId,
|
||||
bson.M{"IsDeleted": true,
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId,
|
||||
bson.M{"IsDeleted": true,
|
||||
"Usn": userService.IncrUsn(userId)})
|
||||
// delete note
|
||||
// ok = db.DeleteByIdAndUserId(db.Notes, noteId, userId)
|
||||
|
||||
// ok = db.DeleteByIdAndUserId(db.Notes, noteId, userId)
|
||||
|
||||
// delete content
|
||||
ok = db.DeleteByIdAndUserId(db.NoteContents, noteId, userId)
|
||||
|
||||
|
||||
// 删除content history
|
||||
ok = db.DeleteByIdAndUserId(db.NoteContentHistories, noteId, userId)
|
||||
|
||||
// 重新统计tag's count
|
||||
// TODO 这里会改变tag's Usn
|
||||
tagService.reCountTagCount(userId, note.Tags)
|
||||
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
func (this *TrashService) DeleteTrashApi(noteId, userId string, usn int) (bool, string, int) {
|
||||
note := noteService.GetNote(noteId, userId)
|
||||
|
||||
|
||||
if note.NoteId == "" || note.IsDeleted {
|
||||
return false, "notExists", 0
|
||||
}
|
||||
|
||||
|
||||
if note.Usn != usn {
|
||||
return false, "conflict", 0
|
||||
}
|
||||
|
||||
|
||||
// delete note's attachs
|
||||
ok := attachService.DeleteAllAttachs(noteId, userId)
|
||||
|
||||
// 设置删除位
|
||||
afterUsn := userService.IncrUsn(userId)
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId,
|
||||
bson.M{"IsDeleted": true,
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId,
|
||||
bson.M{"IsDeleted": true,
|
||||
"Usn": afterUsn})
|
||||
|
||||
|
||||
// delete content
|
||||
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
|
||||
}
|
||||
|
||||
// 列出note, 排序规则, 还有分页
|
||||
// CreatedTime, UpdatedTime, title 来排序
|
||||
func (this *TrashService) ListNotes(userId string,
|
||||
pageNumber, pageSize int, sortField string, isAsc bool) (notes []info.Note) {
|
||||
func (this *TrashService) ListNotes(userId string,
|
||||
pageNumber, pageSize int, sortField string, isAsc bool) (notes []info.Note) {
|
||||
_, notes = noteService.ListNotes(userId, "", true, pageNumber, pageSize, sortField, isAsc, false)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
type UpgradeService struct {
|
||||
}
|
||||
|
||||
@@ -16,7 +15,7 @@ type UpgradeService struct {
|
||||
func (this *UpgradeService) UpgradeBlog() bool {
|
||||
notes := []info.Note{}
|
||||
db.ListByQ(db.Notes, bson.M{"IsBlog": true}, ¬es)
|
||||
|
||||
|
||||
// PublicTime, RecommendTime = UpdatedTime
|
||||
for _, note := range notes {
|
||||
if note.IsBlog && note.PublicTime.Year() < 100 {
|
||||
@@ -24,7 +23,7 @@ func (this *UpgradeService) UpgradeBlog() bool {
|
||||
Log(note.NoteId.Hex())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -40,25 +39,25 @@ func (this *UpgradeService) UpgradeBetaToBeta2(userId string) (ok bool, msg stri
|
||||
if configService.GetGlobalStringConfig("UpgradeBetaToBeta2") != "" {
|
||||
return false, "Leanote have been upgraded"
|
||||
}
|
||||
|
||||
|
||||
// 1. aboutMe -> page
|
||||
userBlogs := []info.UserBlog{}
|
||||
db.ListByQ(db.UserBlogs, bson.M{}, &userBlogs)
|
||||
|
||||
|
||||
for _, userBlog := range userBlogs {
|
||||
blogService.AddOrUpdateSingle(userBlog.UserId.Hex(), "", "About Me", userBlog.AboutMe)
|
||||
}
|
||||
|
||||
|
||||
// 2. 默认主题, 给admin用户
|
||||
themeService.UpgradeThemeBeta2()
|
||||
|
||||
|
||||
// 3. UrlTitles
|
||||
|
||||
|
||||
// 3.1 note
|
||||
notes := []info.Note{}
|
||||
db.ListByQ(db.Notes, bson.M{}, ¬es)
|
||||
for _, note := range notes {
|
||||
data := bson.M{}
|
||||
data := bson.M{}
|
||||
noteId := note.NoteId.Hex()
|
||||
// PublicTime, RecommendTime = UpdatedTime
|
||||
if note.IsBlog && note.PublicTime.Year() < 100 {
|
||||
@@ -66,11 +65,11 @@ func (this *UpgradeService) UpgradeBetaToBeta2(userId string) (ok bool, msg stri
|
||||
data["RecommendTime"] = note.UpdatedTime
|
||||
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)
|
||||
Log(noteId)
|
||||
}
|
||||
|
||||
|
||||
// 3.2
|
||||
Log("notebook")
|
||||
notebooks := []info.Notebook{}
|
||||
@@ -78,28 +77,28 @@ func (this *UpgradeService) UpgradeBetaToBeta2(userId string) (ok bool, msg stri
|
||||
for _, notebook := range notebooks {
|
||||
notebookId := notebook.NotebookId.Hex()
|
||||
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)
|
||||
Log(notebookId)
|
||||
}
|
||||
|
||||
|
||||
// 3.3 single
|
||||
/*
|
||||
singles := []info.BlogSingle{}
|
||||
db.ListByQ(db.BlogSingles, bson.M{}, &singles)
|
||||
for _, single := range singles {
|
||||
singleId := single.SingleId.Hex()
|
||||
blogService.UpdateSingleUrlTitle(single.UserId.Hex(), singleId, single.Title)
|
||||
Log(singleId)
|
||||
}
|
||||
singles := []info.BlogSingle{}
|
||||
db.ListByQ(db.BlogSingles, bson.M{}, &singles)
|
||||
for _, single := range singles {
|
||||
singleId := single.SingleId.Hex()
|
||||
blogService.UpdateSingleUrlTitle(single.UserId.Hex(), singleId, single.Title)
|
||||
Log(singleId)
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// 删除索引
|
||||
db.ShareNotes.DropIndex("UserId", "ToUserId", "NoteId")
|
||||
ok = true
|
||||
msg = "success"
|
||||
configService.UpdateGlobalStringConfig(userId, "UpgradeBetaToBeta2", "1")
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -134,8 +133,8 @@ func (this *UpgradeService) moveTag() {
|
||||
func (this *UpgradeService) setNotebookUsn() {
|
||||
usnI := 1
|
||||
notebooks := []info.Notebook{}
|
||||
db.ListByQWithFields(db.Notebooks, bson.M{}, []string{"UserId"}, ¬ebooks)
|
||||
|
||||
db.ListByQWithFields(db.Notebooks, bson.M{}, []string{"UserId"}, ¬ebooks)
|
||||
|
||||
for _, notebook := range notebooks {
|
||||
db.UpdateByQField(db.Notebooks, bson.M{"_id": notebook.NotebookId}, "Usn", usnI)
|
||||
usnI++
|
||||
@@ -145,8 +144,8 @@ func (this *UpgradeService) setNotebookUsn() {
|
||||
func (this *UpgradeService) setNoteUsn() {
|
||||
usnI := 1
|
||||
notes := []info.Note{}
|
||||
db.ListByQWithFields(db.Notes, bson.M{}, []string{"UserId"}, ¬es)
|
||||
|
||||
db.ListByQWithFields(db.Notes, bson.M{}, []string{"UserId"}, ¬es)
|
||||
|
||||
for _, note := range notes {
|
||||
db.UpdateByQField(db.Notes, bson.M{"_id": note.NoteId}, "Usn", usnI)
|
||||
usnI++
|
||||
@@ -158,25 +157,25 @@ func (this *UpgradeService) Api(userId string) (ok bool, msg string) {
|
||||
if configService.GetGlobalStringConfig("UpgradeBetaToBeta4") != "" {
|
||||
return false, "Leanote have been upgraded"
|
||||
}
|
||||
|
||||
|
||||
// user
|
||||
db.UpdateByQField(db.Users, bson.M{}, "Usn", 200000)
|
||||
|
||||
// notebook
|
||||
db.UpdateByQField(db.Notebooks, bson.M{}, "IsDeleted", false)
|
||||
this.setNotebookUsn();
|
||||
|
||||
this.setNotebookUsn()
|
||||
|
||||
// note
|
||||
// 1-N
|
||||
db.UpdateByQField(db.Notes, bson.M{}, "IsDeleted", false)
|
||||
this.setNoteUsn();
|
||||
|
||||
this.setNoteUsn()
|
||||
|
||||
// tag
|
||||
// 1-N
|
||||
/// tag, 要重新插入, 将之前的Tag表迁移到NoteTag中
|
||||
this.moveTag();
|
||||
|
||||
this.moveTag()
|
||||
|
||||
configService.UpdateGlobalStringConfig(userId, "UpgradeBetaToBeta4", "1")
|
||||
|
||||
|
||||
return true, ""
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserService struct {
|
||||
@@ -23,7 +23,7 @@ func (this *UserService) IncrUsn(userId string) int {
|
||||
Log("inc Usn")
|
||||
db.UpdateByQField(db.Users, query, "Usn", usn)
|
||||
return usn
|
||||
// return db.Update(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, bson.M{"$inc": bson.M{"ReadNum": 1}})
|
||||
// return db.Update(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, bson.M{"$inc": bson.M{"ReadNum": 1}})
|
||||
}
|
||||
|
||||
func (this *UserService) GetUsn(userId string) int {
|
||||
@@ -39,18 +39,18 @@ func (this *UserService) AddUser(user info.User) bool {
|
||||
user.UserId = bson.NewObjectId()
|
||||
}
|
||||
user.CreatedTime = time.Now()
|
||||
|
||||
|
||||
if user.Email != "" {
|
||||
user.Email = strings.ToLower(user.Email)
|
||||
|
||||
|
||||
// 发送验证邮箱
|
||||
go func() {
|
||||
emailService.RegisterSendActiveEmail(user, user.Email)
|
||||
// 发送给我 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)
|
||||
}
|
||||
|
||||
@@ -94,11 +94,11 @@ func (this *UserService) GetUserInfoByAny(idEmailUsername string) info.User {
|
||||
if IsObjectId(idEmailUsername) {
|
||||
return this.GetUserInfo(idEmailUsername)
|
||||
}
|
||||
|
||||
|
||||
if strings.Contains(idEmailUsername, "@") {
|
||||
return this.GetUserInfoByEmail(idEmailUsername)
|
||||
}
|
||||
|
||||
|
||||
// username
|
||||
return this.GetUserInfoByUsername(idEmailUsername)
|
||||
}
|
||||
@@ -111,7 +111,7 @@ func (this *UserService) setUserLogo(user *info.User) {
|
||||
if user.Logo != "" && !strings.HasPrefix(user.Logo, "http") {
|
||||
user.Logo = strings.Trim(user.Logo, "/")
|
||||
user.Logo = configService.GetSiteUrl() + "/" + user.Logo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 仅得到用户
|
||||
@@ -129,6 +129,7 @@ func (this *UserService) GetUserInfo(userId string) info.User {
|
||||
this.setUserLogo(&user)
|
||||
return user
|
||||
}
|
||||
|
||||
// 得到用户信息 email
|
||||
func (this *UserService) GetUserInfoByEmail(email string) info.User {
|
||||
user := info.User{}
|
||||
@@ -137,6 +138,7 @@ func (this *UserService) GetUserInfoByEmail(email string) info.User {
|
||||
this.setUserLogo(&user)
|
||||
return user
|
||||
}
|
||||
|
||||
// 得到用户信息 username
|
||||
func (this *UserService) GetUserInfoByUsername(username string) info.User {
|
||||
user := info.User{}
|
||||
@@ -163,11 +165,12 @@ func (this *UserService) ListUserInfosByEmails(emails []string) []info.User {
|
||||
db.ListByQ(db.Users, bson.M{"Email": bson.M{"$in": emails}}, &users)
|
||||
return users
|
||||
}
|
||||
|
||||
// 用户信息即可
|
||||
func (this *UserService) MapUserInfoByUserIds(userIds []bson.ObjectId) map[bson.ObjectId]info.User {
|
||||
users := []info.User{}
|
||||
db.ListByQ(db.Users, bson.M{"_id": bson.M{"$in": userIds}}, &users)
|
||||
|
||||
|
||||
userMap := make(map[bson.ObjectId]info.User, len(users))
|
||||
for _, user := range users {
|
||||
this.setUserLogo(&user)
|
||||
@@ -175,6 +178,7 @@ func (this *UserService) MapUserInfoByUserIds(userIds []bson.ObjectId) map[bson.
|
||||
}
|
||||
return userMap
|
||||
}
|
||||
|
||||
// 用户信息和博客设置信息
|
||||
func (this *UserService) MapUserInfoAndBlogInfosByUserIds(userIds []bson.ObjectId) map[bson.ObjectId]info.User {
|
||||
return this.MapUserInfoByUserIds(userIds)
|
||||
@@ -184,33 +188,33 @@ func (this *UserService) MapUserInfoAndBlogInfosByUserIds(userIds []bson.ObjectI
|
||||
func (this *UserService) MapUserAndBlogByUserIds(userIds []bson.ObjectId) map[string]info.UserAndBlog {
|
||||
users := []info.User{}
|
||||
db.ListByQ(db.Users, bson.M{"_id": bson.M{"$in": userIds}}, &users)
|
||||
|
||||
|
||||
userBlogs := []info.UserBlog{}
|
||||
db.ListByQ(db.UserBlogs, bson.M{"_id": bson.M{"$in": userIds}}, &userBlogs)
|
||||
|
||||
|
||||
userBlogMap := make(map[bson.ObjectId]info.UserBlog, len(userBlogs))
|
||||
for _, user := range userBlogs {
|
||||
userBlogMap[user.UserId] = user
|
||||
}
|
||||
|
||||
|
||||
userAndBlogMap := make(map[string]info.UserAndBlog, len(users))
|
||||
|
||||
|
||||
for _, user := range users {
|
||||
this.setUserLogo(&user)
|
||||
|
||||
|
||||
userBlog, ok := userBlogMap[user.UserId]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
userAndBlogMap[user.UserId.Hex()] = info.UserAndBlog{
|
||||
UserId: user.UserId,
|
||||
Username: user.Username,
|
||||
Email: user.Email,
|
||||
Logo: user.Logo,
|
||||
UserId: user.UserId,
|
||||
Username: user.Username,
|
||||
Email: user.Email,
|
||||
Logo: user.Logo,
|
||||
BlogTitle: userBlog.Title,
|
||||
BlogLogo: userBlog.Logo,
|
||||
BlogUrl: blogService.GetUserBlogUrl(&userBlog, user.Username),
|
||||
BlogLogo: userBlog.Logo,
|
||||
BlogUrl: blogService.GetUserBlogUrl(&userBlog, user.Username),
|
||||
}
|
||||
}
|
||||
return userAndBlogMap
|
||||
@@ -220,11 +224,11 @@ func (this *UserService) MapUserAndBlogByUserIds(userIds []bson.ObjectId) map[st
|
||||
func (this *UserService) GetUserAndBlogUrl(userId string) info.UserAndBlogUrl {
|
||||
user := this.GetUserInfo(userId)
|
||||
userBlog := blogService.GetUserBlog(userId)
|
||||
|
||||
|
||||
blogUrls := blogService.GetBlogUrls(&userBlog, &user)
|
||||
|
||||
|
||||
return info.UserAndBlogUrl{
|
||||
User: user,
|
||||
User: user,
|
||||
BlogUrl: blogUrls.IndexUrl,
|
||||
PostUrl: blogUrls.PostUrl,
|
||||
}
|
||||
@@ -249,15 +253,15 @@ func (this *UserService) GetUserAndBlog(userId string) info.UserAndBlog {
|
||||
// 通过ids得到users, 按id的顺序组织users
|
||||
func (this *UserService) GetUserInfosOrderBySeq(userIds []bson.ObjectId) []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{}
|
||||
for _, user := range users {
|
||||
usersMap[user.UserId] = user
|
||||
}
|
||||
|
||||
|
||||
hasAppend := map[bson.ObjectId]bool{} // 为了防止userIds有重复的
|
||||
users2 := []info.User{};
|
||||
users2 := []info.User{}
|
||||
for _, userId := range userIds {
|
||||
if user, ok := usersMap[userId]; ok && !hasAppend[userId] {
|
||||
hasAppend[userId] = true
|
||||
@@ -270,7 +274,7 @@ func (this *UserService) GetUserInfosOrderBySeq(userIds []bson.ObjectId) []info.
|
||||
// 使用email(username), 得到用户信息
|
||||
func (this *UserService) GetUserInfoByName(emailOrUsername string) info.User {
|
||||
emailOrUsername = strings.ToLower(emailOrUsername)
|
||||
|
||||
|
||||
user := info.User{}
|
||||
if strings.Contains(emailOrUsername, "@") {
|
||||
db.GetByQ(db.Users, bson.M{"Email": emailOrUsername}, &user)
|
||||
@@ -288,19 +292,19 @@ func (this *UserService) UpdateUsername(userId, username string) (bool, string)
|
||||
}
|
||||
usernameRaw := username // 原先的, 可能是同一个, 但有大小写
|
||||
username = strings.ToLower(username)
|
||||
|
||||
|
||||
// 先判断是否存在
|
||||
userIdO := bson.ObjectIdHex(userId)
|
||||
if db.Has(db.Users, bson.M{"Username": username, "_id": bson.M{"$ne": userIdO}}) {
|
||||
return false, "usernameIsExisted"
|
||||
}
|
||||
|
||||
|
||||
ok := db.UpdateByQMap(db.Users, bson.M{"_id": userIdO}, bson.M{"Username": username, "UsernameRaw": usernameRaw})
|
||||
return ok, ""
|
||||
}
|
||||
|
||||
// 修改头像
|
||||
func (this *UserService) UpdateAvatar(userId, avatarPath string) (bool) {
|
||||
func (this *UserService) UpdateAvatar(userId, avatarPath string) bool {
|
||||
userIdO := bson.ObjectIdHex(userId)
|
||||
return db.UpdateByQField(db.Users, bson.M{"_id": userIdO}, "Logo", avatarPath)
|
||||
}
|
||||
@@ -327,7 +331,7 @@ func (this *UserService) ResetPwd(adminUserId, userId, pwd string) (ok bool, msg
|
||||
if configService.GetAdminUserId() != adminUserId {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
passwd := GenPwd(pwd)
|
||||
if passwd == "" {
|
||||
return false, "GenerateHash error"
|
||||
@@ -337,24 +341,24 @@ 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)
|
||||
return ok
|
||||
}
|
||||
|
||||
// 帐户类型设置
|
||||
func (this *UserService) UpdateAccount(userId, accountType string, accountStartTime, accountEndTime time.Time,
|
||||
func (this *UserService) UpdateAccount(userId, accountType string, accountStartTime, accountEndTime time.Time,
|
||||
maxImageNum, maxImageSize, maxAttachNum, maxAttachSize, maxPerAttachSize int) bool {
|
||||
return db.UpdateByQI(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, info.UserAccount{
|
||||
AccountType: accountType,
|
||||
AccountStartTime: accountStartTime,
|
||||
AccountEndTime: accountEndTime,
|
||||
MaxImageNum: maxImageNum,
|
||||
MaxImageSize: maxImageSize,
|
||||
MaxAttachNum: maxAttachNum,
|
||||
MaxAttachSize: maxAttachSize,
|
||||
MaxPerAttachSize: maxPerAttachSize,
|
||||
})
|
||||
AccountType: accountType,
|
||||
AccountStartTime: accountStartTime,
|
||||
AccountEndTime: accountEndTime,
|
||||
MaxImageNum: maxImageNum,
|
||||
MaxImageSize: maxImageSize,
|
||||
MaxAttachNum: maxAttachNum,
|
||||
MaxAttachSize: maxAttachSize,
|
||||
MaxPerAttachSize: maxPerAttachSize,
|
||||
})
|
||||
}
|
||||
|
||||
//---------------
|
||||
@@ -370,14 +374,14 @@ func (this *UserService) ActiveEmail(token string) (ok bool, msg, email string)
|
||||
if userInfo.UserId == "" {
|
||||
ok = false
|
||||
msg = "不存在该用户"
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 修改之, 并将verified = true
|
||||
ok = db.UpdateByQMap(db.Users, bson.M{"_id": userInfo.UserId}, bson.M{"Verified": true})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
ok = false
|
||||
msg = "该链接已过期"
|
||||
return
|
||||
@@ -397,47 +401,28 @@ func (this *UserService) UpdateEmail(token string) (ok bool, msg, email string)
|
||||
msg = "该邮箱已注册"
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 修改之, 并将verified = true
|
||||
ok = db.UpdateByQMap(db.Users, bson.M{"_id": tokenInfo.UserId}, bson.M{"Email": email, "Verified": true})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
ok = false
|
||||
msg = "该链接已过期"
|
||||
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
|
||||
}
|
||||
|
||||
//------------
|
||||
// 偏好设置
|
||||
|
||||
// 宽度
|
||||
func (this *UserService)UpdateColumnWidth(userId string, notebookWidth, noteListWidth, mdEditorWidth int) bool {
|
||||
return db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)},
|
||||
bson.M{"NotebookWidth": notebookWidth, "NoteListWidth": noteListWidth, "MdEditorWidth": mdEditorWidth})
|
||||
func (this *UserService) UpdateColumnWidth(userId string, notebookWidth, noteListWidth, mdEditorWidth int) bool {
|
||||
return db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)},
|
||||
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})
|
||||
}
|
||||
|
||||
@@ -454,7 +439,7 @@ func (this *UserService) ListUsers(pageNumber, pageSize int, sortField string, i
|
||||
}
|
||||
query["$or"] = orQ
|
||||
}
|
||||
q := db.Users.Find(query);
|
||||
q := db.Users.Find(query)
|
||||
// 总记录数
|
||||
count, _ := q.Count()
|
||||
// 列表
|
||||
@@ -468,44 +453,44 @@ func (this *UserService) ListUsers(pageNumber, pageSize int, sortField string, i
|
||||
|
||||
func (this *UserService) GetAllUserByFilter(userFilterEmail, userFilterWhiteList, userFilterBlackList string, verified bool) []info.User {
|
||||
query := bson.M{}
|
||||
|
||||
|
||||
if verified {
|
||||
query["Verified"] = true
|
||||
}
|
||||
|
||||
|
||||
orQ := []bson.M{}
|
||||
if userFilterEmail != "" {
|
||||
orQ = append(orQ, bson.M{"Email": bson.M{"$regex": bson.RegEx{".*?" + userFilterEmail + ".*", "i"}}},
|
||||
orQ = append(orQ, bson.M{"Email": 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)
|
||||
emails := strings.Split(userFilterWhiteList, "\n");
|
||||
emails := strings.Split(userFilterWhiteList, "\n")
|
||||
orQ = append(orQ, bson.M{"Email": bson.M{"$in": emails}})
|
||||
}
|
||||
if len(orQ) > 0 {
|
||||
query["$or"] = orQ
|
||||
}
|
||||
|
||||
|
||||
emailQ := bson.M{}
|
||||
if(userFilterBlackList != "") {
|
||||
if userFilterBlackList != "" {
|
||||
userFilterWhiteList = strings.Replace(userFilterBlackList, "\r", "", -1)
|
||||
bEmails := strings.Split(userFilterBlackList, "\n");
|
||||
bEmails := strings.Split(userFilterBlackList, "\n")
|
||||
emailQ["$nin"] = bEmails
|
||||
query["Email"] = emailQ
|
||||
}
|
||||
|
||||
LogJ(query)
|
||||
users := []info.User{}
|
||||
q := db.Users.Find(query);
|
||||
q := db.Users.Find(query)
|
||||
q.All(&users)
|
||||
Log(len(users))
|
||||
|
||||
|
||||
return users
|
||||
}
|
||||
|
||||
// 统计
|
||||
// 统计
|
||||
func (this *UserService) CountUser() int {
|
||||
return db.Count(db.Users, bson.M{})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
)
|
||||
import ()
|
||||
|
||||
// service 通用方法
|
||||
|
||||
@@ -17,4 +16,4 @@ func parsePageAndSort(pageNumber, pageSize int, sortField string, isAsc bool) (s
|
||||
sortFieldR = sortField
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user