Compare commits
79
Commits
1.0-beta.4
..
1.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e37e5a37d | ||
|
|
a60da3d592 | ||
|
|
9a88fab84e | ||
|
|
4981d6aad4 | ||
|
|
7193ac6833 | ||
|
|
3d1a32764d | ||
|
|
2b8df3ed76 | ||
|
|
e94b004a5a | ||
|
|
6cc6f26fa1 | ||
|
|
120cdd53c3 | ||
|
|
435aac4a9c | ||
|
|
f234cf285d | ||
|
|
54953b69c6 | ||
|
|
60878b7a65 | ||
|
|
dada88d8a2 | ||
|
|
7167705409 | ||
|
|
4217abca6e | ||
|
|
49a97f2285 | ||
|
|
4f2d7b8cd0 | ||
|
|
afbda7bfb2 | ||
|
|
c568756d16 | ||
|
|
5794f76b0a | ||
|
|
74a768c0fb | ||
|
|
4136060825 | ||
|
|
e249a953cd | ||
|
|
eddc2e6356 | ||
|
|
1604474d6e | ||
|
|
bbaf71481c | ||
|
|
952117818c | ||
|
|
a31432f1bf | ||
|
|
b0afe25730 | ||
|
|
024e0e9bae | ||
|
|
dbabc3a5a8 | ||
|
|
a30aec8254 | ||
|
|
7440218974 | ||
|
|
b3c771a87f | ||
|
|
8f8451cdff | ||
|
|
6d7fe83469 | ||
|
|
05a5280162 | ||
|
|
8dd55eb949 | ||
|
|
5838cc218f | ||
|
|
2e52c957e0 | ||
|
|
9486c58d78 | ||
|
|
6e7c1e0d41 | ||
|
|
6a0a60a644 | ||
|
|
94f9c2c3cb | ||
|
|
37e7ed8d14 | ||
|
|
4227c80ec7 | ||
|
|
6ec6ef698b | ||
|
|
0543dd015e | ||
|
|
b88f895acf | ||
|
|
fc517700cc | ||
|
|
b5e0cd31dd | ||
|
|
ab4b8b77a3 | ||
|
|
04c339896b | ||
|
|
e37056737d | ||
|
|
89f8bb934c | ||
|
|
b564989214 | ||
|
|
03aa8edd58 | ||
|
|
803fc90dd9 | ||
|
|
6987a38820 | ||
|
|
7e458bb433 | ||
|
|
b391375008 | ||
|
|
3f89e1cf83 | ||
|
|
9f5dc8a0e2 | ||
|
|
12ea17e89f | ||
|
|
1fd6610fa3 | ||
|
|
1ec28d80c8 | ||
|
|
fcbc23e964 | ||
|
|
6fba2a6416 | ||
|
|
0e5edb16f6 | ||
|
|
5726df1a81 | ||
|
|
f3a0a786c5 | ||
|
|
fa08b3393a | ||
|
|
5db148be9f | ||
|
|
d03cce2761 | ||
|
|
3a0bdd803d | ||
|
|
d1b6dddfd0 | ||
|
|
2676c5a85d |
No files matched your search
+3
-2
@@ -2,9 +2,9 @@
|
||||
pkg
|
||||
bin2
|
||||
bin/i18n
|
||||
bin/leanote-linux
|
||||
bin/leanote-mac
|
||||
bin/leanote*
|
||||
bin/release
|
||||
bin/test.sh
|
||||
bin/tmp
|
||||
bin/test
|
||||
bin/src
|
||||
@@ -16,3 +16,4 @@ app/tmp/main.go
|
||||
.project
|
||||
public/config.codekit
|
||||
files
|
||||
/node_modules
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
language: go
|
||||
go: 1.3
|
||||
|
||||
services:
|
||||
- mongodb # 2.4.12
|
||||
|
||||
install:
|
||||
- export PATH=$PATH:$HOME/gopath/bin
|
||||
- go get -v github.com/leanote/leanote/app
|
||||
# - go get github.com/revel/cmd/revel
|
||||
# - go install github.com/revel/cmd/revel
|
||||
|
||||
script:
|
||||
- mongo --version
|
||||
- mongorestore -h localhost -d leanote --directoryperdb ./mongodb_backup/leanote_install_data/
|
||||
- go test github.com/leanote/leanote/app/tests
|
||||
- go build -ldflags -X github.com/leanote/leanote/app
|
||||
# - revel build github.com/leanote/leanote tmp
|
||||
# OK
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
var gulp = require('gulp');
|
||||
var clean = require('gulp-clean');
|
||||
var uglify = require('gulp-uglify');
|
||||
var rename = require('gulp-rename');
|
||||
var minifyHtml = require("gulp-minify-html");
|
||||
var concat = require('gulp-concat');
|
||||
var replace = require('gulp-replace');
|
||||
var inject = require('gulp-inject');
|
||||
var gulpSequence = require('gulp-sequence');
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
var leanoteBase = './';
|
||||
var base = leanoteBase + '/public'; // public base
|
||||
var noteDev = leanoteBase + '/app/views/note/note-dev.html';
|
||||
var noteProBase = leanoteBase + '/app/views/note';
|
||||
|
||||
// 合并Js, 这些js都是不怎么修改, 且是依赖
|
||||
// 840kb, 非常耗时!!
|
||||
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', // 使用打成的包, 加载速度快
|
||||
// 'libs/ace/ace.js',
|
||||
'js/jQuery-slimScroll-1.3.0/jquery.slimscroll-min.js',
|
||||
'js/contextmenu/jquery.contextmenu-min.js',
|
||||
'js/bootstrap-min.js',
|
||||
'js/object_id-min.js',
|
||||
];
|
||||
|
||||
for(var i in jss) {
|
||||
jss[i] = base + '/' + jss[i];
|
||||
}
|
||||
|
||||
return gulp
|
||||
.src(jss)
|
||||
// .pipe(uglify()) // 压缩
|
||||
.pipe(concat('dep.min.js'))
|
||||
.pipe(gulp.dest(base + '/js'));
|
||||
});
|
||||
|
||||
// 合并app js 这些js会经常变化 90kb
|
||||
gulp.task('concatAppJs', function() {
|
||||
var jss = [
|
||||
'js/common.js',
|
||||
'js/app/note.js',
|
||||
'js/app/page.js', // 写作模式下, page依赖note
|
||||
'js/app/tag.js',
|
||||
'js/app/notebook.js',
|
||||
'js/app/share.js',
|
||||
];
|
||||
|
||||
for(var i in jss) {
|
||||
jss[i] = base + '/' + jss[i];
|
||||
}
|
||||
|
||||
return gulp
|
||||
.src(jss)
|
||||
.pipe(uglify()) // 压缩
|
||||
.pipe(concat('app.min.js'))
|
||||
.pipe(gulp.dest(base + '/js'));
|
||||
});
|
||||
|
||||
// 合并requirejs和markdown为一个文件
|
||||
gulp.task('concatMarkdownJs', function() {
|
||||
var jss = [
|
||||
'js/require.js',
|
||||
'dist/main.min.js',
|
||||
];
|
||||
|
||||
for(var i in jss) {
|
||||
jss[i] = base + '/' + jss[i];
|
||||
}
|
||||
|
||||
return gulp
|
||||
.src(jss)
|
||||
.pipe(uglify()) // 压缩
|
||||
.pipe(concat('markdown.min.js'))
|
||||
.pipe(gulp.dest(base + '/js'));
|
||||
});
|
||||
|
||||
// note-dev.html -> note.html, 替换css, js
|
||||
// TODO 加?t=2323232, 强制浏览器更新, 一般只需要把app.min.js上加
|
||||
gulp.task('devToProHtml', function() {
|
||||
return gulp
|
||||
.src(noteDev)
|
||||
.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_tinymce_init_js -->/, "var tinyMCEPreInit = {base: '/public/tinymce', suffix: '.min'};")) // 替换
|
||||
// 连续两个空行换成一个空行, 没用
|
||||
.pipe(replace(/\n\n/g, '\n'))
|
||||
.pipe(replace(/\n\n/g, '\n'))
|
||||
.pipe(replace('console.log(o);', ''))
|
||||
// .pipe(minifyHtml()) // 不行, 压缩后golang报错
|
||||
.pipe(rename('note.html'))
|
||||
.pipe(gulp.dest(noteProBase));
|
||||
});
|
||||
|
||||
// tinymce
|
||||
|
||||
var tinymceBase = base + '/tinymce_4.1.9';
|
||||
gulp.task('tinymce', function() {
|
||||
// 先清理
|
||||
fs.unlink(tinymceBase + '/js/tinymce/tinymce.dev.js');
|
||||
fs.unlink(tinymceBase + '/js/tinymce/tinymce.jquery.dev.js');
|
||||
fs.unlink(tinymceBase + '/js/tinymce/tinymce.full.js');
|
||||
fs.unlink(tinymceBase + '/js/tinymce/tinymce.full.min.js');
|
||||
|
||||
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';
|
||||
// build
|
||||
cp.exec('grunt minify', {cwd: tinymceBase}, function(err, stdout, stderr) {
|
||||
console.log('stdout: ' + stdout);
|
||||
console.log('stderr: ' + stderr);
|
||||
|
||||
// 将所有都合并成一起
|
||||
cp.exec(bundleCmd, {cwd: tinymceBase}, function(err, stdout, stderr) {
|
||||
console.log('stdout: ' + stdout);
|
||||
console.log('stderr: ' + stderr);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 合并css, 无用
|
||||
gulp.task('concatCss', function() {
|
||||
return gulp
|
||||
.src([markdownRaw + '/css/default.css', markdownRaw + '/css/md.css'])
|
||||
.pipe(concat('all.css'))
|
||||
.pipe(gulp.dest(markdownMin));
|
||||
});
|
||||
|
||||
gulp.task('concat', ['concatDepJs', 'concatAppJs', 'concatMarkdownJs']);
|
||||
gulp.task('html', ['devToProHtml']);
|
||||
gulp.task('default', ['concat', 'html']);
|
||||
@@ -1,6 +1,6 @@
|
||||
leanote - you own cloud note!
|
||||
LEANOTE - NOT JUST A NOTEPAD!
|
||||
|
||||
Copyright 2014 by the contributors
|
||||
Copyright 2014-2015 by the contributors
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -12,7 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
leanote is licensed under the GPL v2.
|
||||
Leanote is licensed under the GPL v2.
|
||||
|
||||
life(life@leanote.com, lifephp@gmail.com)
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
# Leanote
|
||||
|
||||
[](https://gitter.im/leanote/leanote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[](https://travis-ci.org/leanote/leanote)
|
||||
## 1. Introduction
|
||||
|
||||
Leanote, not just a notebook!
|
||||
Leanote, not just a notepad!
|
||||

|
||||
|
||||
**Some Features**
|
||||
@@ -26,86 +27,46 @@ 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)
|
||||
|
||||
### 3.1. Download leanote
|
||||
|
||||
Leanote V1.0.3-beta has been released. Binaries:
|
||||
|
||||
* Linux: [leanote-linux-x86_64.v1.0-beta.3.bin.tar.gz](https://github.com/leanote/leanote/releases/download/1.0-beta.3/leanote-linux-x86_64.v1.0-beta.3.bin.tar.gz)
|
||||
* MacOS X: [leanote-mac-x86_64.v1.0-beta.3.bin.tar.gz](https://github.com/leanote/leanote/releases/download/1.0-beta.3/leanote-mac-x86_64.v1.0-beta.3.bin.tar.gz)
|
||||
|
||||
Or you can clone [Leanote bin repository](https://github.com/leanote/leanote-bin) (Recommend)
|
||||
|
||||
### 3.2. Install MongoDB
|
||||
|
||||
Leanote is written in go using [revel](https://revel.github.io/) and [MongoDB](https://www.mongodb.org). Thus, you need to first install MongoDB.
|
||||
|
||||
For more tips please have a look at [our wiki](https://github.com/leanote/leanote/wiki/Install-Mongodb)
|
||||
|
||||
### 3.3. Import initial MongoDB data
|
||||
|
||||
The mongodb data is in `[PATH_TO_LEANOTE]/mongodb_backup/leanote_install_data`
|
||||
|
||||
```
|
||||
$> mongorestore -h localhost -d leanote --directoryperdb PATH_TO_LEANOTE/mongodb_backup/leanote_install_data
|
||||
```
|
||||
|
||||
The initial database contains two users:
|
||||
|
||||
```
|
||||
user2 username: admin, password: abc123 (administrator)
|
||||
user3 username: demo, password: demo@leanote.com (this user is for demo)
|
||||
```
|
||||
|
||||
### 3.4. Configuration
|
||||
|
||||
Modify `[PATH_TO_LEANOTE]/conf/app.conf`. Available configuration options are:
|
||||
|
||||
``mongodb`` **required**
|
||||
|
||||
```Shell
|
||||
db.host=localhost
|
||||
db.port=27017
|
||||
db.dbname=leanote
|
||||
db.username=
|
||||
db.password=
|
||||
```
|
||||
|
||||
``app.secret`` **required** **important**
|
||||
The secret key used for cryptographic operations (revel.Sign).
|
||||
|
||||
FOR SECURITY, YOU MUST CHANGE IT!!
|
||||
|
||||
For more infomation please see `app/app.conf` and the [revel manuals](https://revel.github.io/)
|
||||
|
||||
### 3.5. Run leanote
|
||||
|
||||
```
|
||||
$> cd PATH_TO_LEANOTE/bin
|
||||
$> sudo sh run.sh
|
||||
```
|
||||
|
||||
## 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. Contributors
|
||||
Thank you to all the [contributors](https://github.com/leanote/leanote/graphs/contributors) on
|
||||
this project. Your help is much appreciated.
|
||||
|
||||
## 6. Contributing
|
||||
|
||||
Please fork this repository and contribute back using [pull requests](https://github.com/leanote/leanote/pulls).
|
||||
|
||||
## Docs
|
||||
## 5. Docs
|
||||
* [leanote binary distribution installation tutorial](https://github.com/leanote/leanote/wiki/leanote-binary-distribution-installation-tutorial)
|
||||
* [leanote develop distribution installation tutorial](https://github.com/leanote/leanote/wiki/leanote-develop-distribution-installation-tutorial)
|
||||
* [leanote blog theme api](https://github.com/leanote/leanote/wiki/leanote-blog-theme-api_en)
|
||||
|
||||
## Discussion
|
||||
* [leanote bbs](http://bbs.leanote.com)
|
||||
* [leanote google group](https://groups.google.com/forum/#!forum/leanote)
|
||||
* QQ Group: 158716820
|
||||
More docs 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).
|
||||
|
||||
You are always welcomed!
|
||||
|
||||
## 8. Donation
|
||||
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.
|
||||
|
||||
## 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
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
[中文](README_zh.md)
|
||||
|
||||
+31
-71
@@ -1,6 +1,7 @@
|
||||
# Leanote
|
||||
|
||||
# Leanote产品
|
||||
|
||||
[](https://gitter.im/leanote/leanote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[](https://travis-ci.org/leanote/leanote)
|
||||
## 1. 介绍
|
||||
|
||||
Leanote, 不只是笔记!
|
||||
@@ -24,90 +25,49 @@ Leanote, 不只是笔记!
|
||||
leanote是一款私有云笔记, 你可以下载它安装在自己的服务器上, 当然也可以在 http://leanote.com 上注册.
|
||||
|
||||
这里详细整理了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)
|
||||
|
||||
### 3.1. 下载leanote
|
||||
|
||||
Leanote V1.0-beta.3 已发布, 二进制文件(暂时没有windows版的):
|
||||
|
||||
* Linux: [leanote-linux-x86_64.v1.0-beta.3.bin.tar.gz](https://github.com/leanote/leanote/releases/download/1.0-beta.3/leanote-linux-x86_64.v1.0-beta.3.bin.tar.gz)
|
||||
* MacOS X: [leanote-mac-x86_64.v1.0-beta.3.bin.tar.gz](https://github.com/leanote/leanote/releases/download/1.0-beta.3/leanote-mac-x86_64.v1.0-beta.3.bin.tar.gz)
|
||||
|
||||
或者直接检出[Leanote bin repository](https://github.com/leanote/leanote-bin) (推荐, 因为为最新版本)
|
||||
|
||||
### 3.2. 安装 MongodbDB
|
||||
|
||||
Leanote是由golang(使用[revel](https://revel.github.io/)框架 和 [MongoDB](https://www.mongodb.org)数据库), 你需要先安装Mongodb.
|
||||
|
||||
安装MongodbDB, 导入数据更多细节请查看: [wiki](https://github.com/leanote/leanote/wiki/Install-Mongodb)
|
||||
|
||||
### 3.3. 导入初始数据
|
||||
|
||||
MongodbDB初始数据在 `[PATH_TO_LEANOTE]/mongodb_backup/leanote_install_data`
|
||||
|
||||
```
|
||||
$> mongorestore -h localhost -d leanote --directoryperdb PATH_TO_LEANOTE/mongodb_backup/leanote_install_data
|
||||
```
|
||||
|
||||
初始数据包含两个用户:
|
||||
|
||||
```
|
||||
user2 username: admin, password: abc123 (管理员, 重要!)
|
||||
user3 username: demo@leanote.com, password: demo@leanote.com (为体验使用)
|
||||
```
|
||||
|
||||
### 3.4. 配置
|
||||
|
||||
修改 `[PATH_TO_LEANOTE]/conf/app.conf`. 有以下选项:
|
||||
|
||||
``mongodb`` **必须配置!**
|
||||
|
||||
```Shell
|
||||
db.host=localhost
|
||||
db.port=27017
|
||||
db.dbname=leanote
|
||||
db.username=
|
||||
db.password=
|
||||
```
|
||||
|
||||
``app.secret`` **重要**
|
||||
请随意修改一个, app的密钥, 不能使用默认的, 不然会有安全问题
|
||||
|
||||
更多配置请查看 `app/app.conf` 和 [revel 手册](https://revel.github.io/)
|
||||
|
||||
### 3.5. 运行leanote
|
||||
|
||||
```
|
||||
$> cd PATH_TO_LEANOTE/bin
|
||||
$> sudo sh run.sh
|
||||
```
|
||||
|
||||
## 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. 贡献者
|
||||
多谢 [贡献者](https://github.com/leanote/leanote/graphs/contributors) 的贡献, leanote因有你们而更完美!
|
||||
|
||||
## 6. 加入我们
|
||||
|
||||
欢迎提交[pull requests](https://github.com/leanote/leanote/pulls) 到leanote.
|
||||
|
||||
leanote还有很多问题, 如果你喜欢它, 欢迎加入我们一起完善leanote.
|
||||
|
||||
## 相关文档
|
||||
## 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/Dminter/leanote-android-client), 开发阶段
|
||||
|
||||
欢迎加入我们!
|
||||
|
||||
## 联系&加入我们
|
||||
* Email: leanote@leanote.com
|
||||
* [leanote 社区](http://bbs.leanote.com)
|
||||
* QQ群: 158716820
|
||||
* [leanote google group](https://groups.google.com/forum/#!forum/leanote)
|
||||
* QQ群: 158716820, 256076853
|
||||
* [Leanote Google Group](https://groups.google.com/forum/#!forum/leanote)
|
||||
|
||||
----------------------------------------------------------------
|
||||
[English](README.md)
|
||||
@@ -40,16 +40,16 @@ func (c Auth) Login(email, from string) revel.Result {
|
||||
func (c Auth) doLogin(email, pwd string) revel.Result {
|
||||
sessionId := c.Session.Id()
|
||||
var msg = ""
|
||||
|
||||
userInfo := authService.Login(email, pwd)
|
||||
if userInfo.Email != "" {
|
||||
|
||||
userInfo, err := authService.Login(email, pwd)
|
||||
if err != nil {
|
||||
// 登录错误, 则错误次数++
|
||||
msg = "wrongUsernameOrPassword"
|
||||
} else {
|
||||
c.SetSession(userInfo)
|
||||
sessionService.ClearLoginTimes(sessionId)
|
||||
return c.RenderJson(info.Re{Ok: true})
|
||||
} else {
|
||||
// 登录错误, 则错误次数++
|
||||
msg = "wrongUsernameOrPassword"
|
||||
}
|
||||
}
|
||||
|
||||
return c.RenderJson(info.Re{Ok: false, Item: sessionService.LoginTimesIsOver(sessionId) , Msg: c.Message(msg)})
|
||||
}
|
||||
@@ -61,16 +61,16 @@ func (c Auth) DoLogin(email, pwd string, captcha string) revel.Result {
|
||||
if sessionService.LoginTimesIsOver(sessionId) && sessionService.GetCaptcha(sessionId) != captcha {
|
||||
msg = "captchaError"
|
||||
} else {
|
||||
userInfo := authService.Login(email, pwd)
|
||||
if userInfo.Email != "" {
|
||||
c.SetSession(userInfo)
|
||||
sessionService.ClearLoginTimes(sessionId)
|
||||
return c.RenderJson(info.Re{Ok: true})
|
||||
} else {
|
||||
userInfo, err := authService.Login(email, pwd)
|
||||
if err != nil {
|
||||
// 登录错误, 则错误次数++
|
||||
msg = "wrongUsernameOrPassword"
|
||||
sessionService.IncrLoginTimes(sessionId)
|
||||
}
|
||||
} 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)})
|
||||
@@ -85,8 +85,16 @@ func (c Auth) Logout() revel.Result {
|
||||
|
||||
// 体验一下
|
||||
func (c Auth) Demo() revel.Result {
|
||||
c.doLogin(configService.GetGlobalStringConfig("demoUsername"), configService.GetGlobalStringConfig("demoPassword"))
|
||||
return c.Redirect("/note")
|
||||
email := configService.GetGlobalStringConfig("demoUsername")
|
||||
pwd := configService.GetGlobalStringConfig("demoPassword");
|
||||
userInfo, err := authService.Login(email, pwd)
|
||||
if err != nil {
|
||||
return c.RenderJson(info.Re{Ok: false})
|
||||
} else {
|
||||
c.SetSession(userInfo)
|
||||
return c.Redirect("/note")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------
|
||||
|
||||
@@ -824,7 +824,7 @@ func (c Blog) LikePost(noteId string, callback string) revel.Result {
|
||||
re.Ok, re.Item = blogService.LikeBlog(noteId, userId)
|
||||
return c.RenderJsonP(callback, re)
|
||||
}
|
||||
func (c Blog) GetComments(noteId string) revel.Result {
|
||||
func (c Blog) GetComments(noteId string, callback string) revel.Result {
|
||||
// 评论
|
||||
userId := c.GetUserId()
|
||||
page := c.GetPage()
|
||||
@@ -836,6 +836,10 @@ func (c Blog) GetComments(noteId string) revel.Result {
|
||||
result["comments"] = comments
|
||||
result["commentUserInfo"] = commentUserInfo
|
||||
re.Item = result
|
||||
|
||||
if callback != "" {
|
||||
return c.RenderJsonP(callback, result)
|
||||
}
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
@@ -49,10 +49,11 @@ func (c Note) Index(noteId string) revel.Result {
|
||||
hasRightNoteId := false
|
||||
if IsObjectId(noteId) {
|
||||
note := noteService.GetNoteById(noteId)
|
||||
var noteOwner = note.UserId.Hex()
|
||||
noteContent = noteService.GetNoteContent(noteId, noteOwner)
|
||||
|
||||
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()
|
||||
@@ -124,7 +125,8 @@ func (c Note) Index(noteId string) revel.Result {
|
||||
|
||||
c.RenderArgs["globalConfigs"] = configService.GetGlobalConfigForUser()
|
||||
|
||||
// return c.RenderTemplate("note/note.html")
|
||||
// return c.RenderTemplate("note/note.html")
|
||||
|
||||
if isDev, _ := revel.Config.Bool("mode.dev"); isDev {
|
||||
return c.RenderTemplate("note/note-dev.html")
|
||||
} else {
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"code.google.com/p/goauth2/oauth"
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/lea/netutil"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Oauth struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
var oauthCfg = &oauth.Config{
|
||||
ClientId: "3790fbf1fc14bc6c5d85",
|
||||
ClientSecret: "e9dadfe601c7caa6df9b33db3e7539945c60dfa2",
|
||||
AuthURL: "https://github.com/login/oauth/authorize",
|
||||
TokenURL: "https://github.com/login/oauth/access_token",
|
||||
RedirectURL: "http://leanote.com/oauth/githubCallback",
|
||||
Scope: "user",
|
||||
}
|
||||
|
||||
// 用户允许后, github返回到leanote
|
||||
// 通过code得到token
|
||||
// https://github.com/login/oauth/authorize?access_type=&approval_prompt=&client_id=3790fbf1fc14bc6c5d85&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Foauth2callback&response_type=code&scope=user&state=
|
||||
func (c Oauth) GithubCallback(code string) revel.Result {
|
||||
t := &oauth.Transport{Config: oauthCfg}
|
||||
|
||||
// Exchange the received code for a token
|
||||
tok, err := t.Exchange(code)
|
||||
token := tok.AccessToken
|
||||
if err != nil || token == "" {
|
||||
c.RenderArgs["title"] = "error"
|
||||
return c.RenderTemplate("oauth/oauth_callback_error.html")
|
||||
}
|
||||
|
||||
// 得到用户信息
|
||||
profileInfoURL := "https://api.github.com/user"
|
||||
url := fmt.Sprintf("%s?access_token=%s", profileInfoURL, token)
|
||||
content, err2 := netutil.GetContent(url)
|
||||
if err2 != nil {
|
||||
c.RenderArgs["title"] = "error"
|
||||
return c.RenderTemplate("oauth/oauth_callback_error.html")
|
||||
}
|
||||
// 转成map
|
||||
profileInfo := map[string]interface{}{}
|
||||
Log(string(content))
|
||||
err2 = json.Unmarshal(content, &profileInfo)
|
||||
if err2 != nil {
|
||||
c.RenderArgs["title"] = "error"
|
||||
return c.RenderTemplate("oauth/oauth_callback_error.html")
|
||||
}
|
||||
|
||||
usernameI := profileInfo["login"]
|
||||
|
||||
username, _ := usernameI.(string)
|
||||
userId := username
|
||||
|
||||
// 注册
|
||||
isExists, userInfo := authService.ThirdRegister("github", userId, username)
|
||||
c.RenderArgs["isExists"] = isExists
|
||||
c.RenderArgs["userInfo"] = userInfo
|
||||
|
||||
// 登录之
|
||||
c.SetSession(userInfo)
|
||||
|
||||
return c.Redirect("/note")
|
||||
}
|
||||
@@ -46,7 +46,10 @@ func (c AdminEmail) Demo() revel.Result {
|
||||
func (c AdminEmail) DoDemo(demoUsername, demoPassword string) revel.Result {
|
||||
re := info.NewRe()
|
||||
|
||||
userInfo := authService.Login(demoUsername, demoPassword)
|
||||
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";
|
||||
return c.RenderJson(re)
|
||||
|
||||
@@ -56,7 +56,11 @@ func (c AdminSetting) Demo() revel.Result {
|
||||
func (c AdminSetting) DoDemo(demoUsername, demoPassword string) revel.Result {
|
||||
re := info.NewRe()
|
||||
|
||||
userInfo := authService.Login(demoUsername, demoPassword)
|
||||
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";
|
||||
return c.RenderJson(re)
|
||||
|
||||
@@ -24,15 +24,15 @@ type ApiAuth struct {
|
||||
func (c ApiAuth) Login(email, pwd string) revel.Result {
|
||||
var msg = ""
|
||||
|
||||
userInfo := authService.Login(email, pwd)
|
||||
if userInfo.Email != "" {
|
||||
userInfo, err := authService.Login(email, pwd)
|
||||
if err != nil {
|
||||
// 登录错误, 则错误次数++
|
||||
msg = "wrongUsernameOrPassword"
|
||||
} else {
|
||||
token := bson.NewObjectId().Hex()
|
||||
sessionService.SetUserId(token, userInfo.UserId.Hex())
|
||||
return c.RenderJson(info.AuthOk{Ok: true, Token: token, UserId: userInfo.UserId, Email: userInfo.Email, Username: userInfo.Username})
|
||||
} else {
|
||||
// 登录错误, 则错误次数++
|
||||
msg = "wrongUsernameOrPassword"
|
||||
}
|
||||
}
|
||||
return c.RenderJson(info.ApiRe{Ok: false, Msg: c.Message(msg)})
|
||||
}
|
||||
|
||||
|
||||
@@ -335,8 +335,12 @@ func (c ApiNote) AddNote(noteOrContent info.ApiNote) revel.Result {
|
||||
Abstract: noteOrContent.Abstract}
|
||||
|
||||
// 通过内容得到Desc, abstract
|
||||
note.Desc = SubStringHTMLToRaw(noteContent.Content, 50)
|
||||
noteContent.Abstract = SubStringHTML(noteContent.Content, 200, "")
|
||||
if noteOrContent.Abstract == "" {
|
||||
note.Desc = SubStringHTMLToRaw(noteContent.Content, 200)
|
||||
noteContent.Abstract = SubStringHTML(noteContent.Content, 200, "")
|
||||
} else {
|
||||
note.Desc = SubStringHTMLToRaw(noteContent.Abstract, 200)
|
||||
}
|
||||
|
||||
note = noteService.AddNoteAndContentApi(note, noteContent, myUserId)
|
||||
|
||||
@@ -352,7 +356,7 @@ func (c ApiNote) AddNote(noteOrContent info.ApiNote) revel.Result {
|
||||
noteOrContent.UpdatedTime = note.UpdatedTime
|
||||
noteOrContent.UserId = c.getUserId()
|
||||
noteOrContent.IsMarkdown = note.IsMarkdown
|
||||
// 删除一些不要返回的
|
||||
// 删除一些不要返回的, 删除Desc?
|
||||
noteOrContent.Content = ""
|
||||
noteOrContent.Abstract = ""
|
||||
// apiNote := info.NoteToApiNote(note, noteOrContent.Files)
|
||||
@@ -494,8 +498,12 @@ func (c ApiNote) UpdateNote(noteOrContent info.ApiNote) revel.Result {
|
||||
}
|
||||
|
||||
if c.Has("Content") {
|
||||
// 通过内容得到Desc, abstract
|
||||
noteUpdate["Desc"] = SubStringHTMLToRaw(noteOrContent.Content, 50)
|
||||
// 通过内容得到Desc, 如果有Abstract, 则用Abstract生成Desc
|
||||
if noteOrContent.Abstract == "" {
|
||||
noteUpdate["Desc"] = SubStringHTMLToRaw(noteOrContent.Content, 200)
|
||||
} else {
|
||||
noteUpdate["Desc"] = SubStringHTMLToRaw(noteOrContent.Abstract, 200)
|
||||
}
|
||||
}
|
||||
|
||||
afterNoteUsn := 0
|
||||
@@ -570,4 +578,4 @@ func (c ApiNote) GetHistories(noteId string) revel.Result {
|
||||
}
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
*/
|
||||
*/
|
||||
@@ -460,7 +460,7 @@ func (c MemberBlog) ImportTheme() revel.Result {
|
||||
var ext string
|
||||
_, ext = SplitFilename(filename)
|
||||
if ext != ".zip" {
|
||||
re.Msg = "请上传zip文件"
|
||||
re.Msg = "Please upload zip file"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ func (c MemberBlog) ImportTheme() revel.Result {
|
||||
|
||||
// > 10M?
|
||||
if len(data) > 10*1024*1024 {
|
||||
re.Msg = "文件大于10M"
|
||||
re.Msg = "File is big than 10M"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Init mgo and the common DAO
|
||||
@@ -62,6 +63,14 @@ func Init(url, dbname string) {
|
||||
config := revel.Config
|
||||
if url == "" {
|
||||
url, ok = config.String("db.url")
|
||||
if !ok {
|
||||
url, ok = config.String("db.urlEnv")
|
||||
}
|
||||
if ok {
|
||||
// get dbname from url
|
||||
urls := strings.Split(url, "/")
|
||||
dbname = urls[len(urls)-1]
|
||||
}
|
||||
}
|
||||
if dbname == "" {
|
||||
dbname, _ = config.String("db.dbname")
|
||||
|
||||
+4
-2
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
// convert revel msg to js msg
|
||||
|
||||
var msgBasePath = "/Users/life/Documents/Go/package1/src/github.com/leanote/leanote/messages/"
|
||||
var targetBasePath = "/Users/life/Documents/Go/package1/src/github.com/leanote/leanote/public/js/i18n/"
|
||||
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)
|
||||
@@ -84,6 +84,8 @@ function getMsg(key, data) {
|
||||
func main() {
|
||||
parse("msg.en")
|
||||
parse("msg.zh")
|
||||
parse("msg.fr")
|
||||
parse("blog.zh")
|
||||
parse("blog.en")
|
||||
parse("blog.fr")
|
||||
}
|
||||
@@ -78,7 +78,7 @@ type ShareNotebook struct {
|
||||
UserId bson.ObjectId `bson:"UserId"`
|
||||
ToUserId bson.ObjectId `bson:"ToUserId,omitempty"`
|
||||
ToGroupId bson.ObjectId `bson:"ToGroupId,omitempty"` // 分享给的用户组
|
||||
ToGroup Group `ToGroup,omitempty` // 仅仅为了显示, 不存储, 分组信息
|
||||
ToGroup Group `ToGroup,omitempty` // 仅仅为了显示, 不存储, 分组信息
|
||||
NotebookId bson.ObjectId `bson:"NotebookId"`
|
||||
Seq int `bson:"Seq"` // 排序
|
||||
Perm int `bson:"Perm"` // 权限, 其下所有notes 0只读, 1可修改
|
||||
@@ -138,7 +138,7 @@ type ShareNote struct {
|
||||
UserId bson.ObjectId `bson:"UserId"`
|
||||
ToUserId bson.ObjectId `bson:"ToUserId,omitempty"`
|
||||
ToGroupId bson.ObjectId `bson:"ToGroupId,omitempty"` // 分享给的用户组
|
||||
ToGroup Group `ToGroup,omitempty` // 仅仅为了显示, 不存储, 分组信息
|
||||
ToGroup Group `ToGroup,omitempty` // 仅仅为了显示, 不存储, 分组信息
|
||||
NoteId bson.ObjectId `bson:"NoteId"`
|
||||
Perm int `bson:"Perm"` // 权限, 0只读, 1可修改
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
|
||||
@@ -14,7 +14,7 @@ type Theme struct {
|
||||
Version string `Version`
|
||||
Author string `Author`
|
||||
AuthorUrl string `AuthorUrl`
|
||||
Path string `Path` // 文件夹路径
|
||||
Path string `Path` // 文件夹路径, public/upload/54d7620d99c37b030600002c/themes/54d867c799c37b533e000001
|
||||
Info map[string]interface{} `Info` // 所有信息
|
||||
IsActive bool `IsActive` // 是否在用
|
||||
|
||||
|
||||
+47
-8
@@ -10,8 +10,8 @@ import (
|
||||
"github.com/leanote/leanote/app/controllers/admin"
|
||||
"github.com/leanote/leanote/app/controllers/member"
|
||||
_ "github.com/leanote/leanote/app/lea/binder"
|
||||
"github.com/leanote/leanote/app/lea/session"
|
||||
"github.com/leanote/leanote/app/lea/memcache"
|
||||
// "github.com/leanote/leanote/app/lea/session"
|
||||
// "github.com/leanote/leanote/app/lea/memcache"
|
||||
"github.com/leanote/leanote/app/lea/route"
|
||||
"reflect"
|
||||
"fmt"
|
||||
@@ -33,11 +33,11 @@ func init() {
|
||||
// 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.
|
||||
revel.SessionFilter, // Restore and write the session cookie.
|
||||
|
||||
// 使用SessionFilter标准版从cookie中得到sessionID, 然后通过MssessionFilter从Memcache中得到
|
||||
// session, 之后MSessionFilter将session只存sessionID然后返回给SessionFilter返回到web
|
||||
session.SessionFilter, // leanote session
|
||||
// session.SessionFilter, // leanote session
|
||||
// session.MSessionFilter, // leanote memcache session
|
||||
|
||||
revel.FlashFilter, // Restore and write the flash cookie.
|
||||
@@ -51,6 +51,18 @@ func init() {
|
||||
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;
|
||||
return fmt.Sprintf("%v", i)
|
||||
@@ -145,8 +157,33 @@ func init() {
|
||||
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"
|
||||
if InArray([]string{"red", "blue", "yellow", "green"}, tag) {
|
||||
classes += " label-" + tag
|
||||
} else {
|
||||
classes += " label-default"
|
||||
}
|
||||
|
||||
classes += " label-post"
|
||||
tagStr += "<span class=\"" + classes + "\" >" + str + "</span>";
|
||||
if i != lenTags - 1 {
|
||||
tagStr += " "
|
||||
}
|
||||
}
|
||||
return template.HTML(tagStr)
|
||||
}
|
||||
|
||||
// lea++
|
||||
revel.TemplateFuncs["blogTagsLea"] = func(renderArgs map[string]interface{}, tags []string, isRecommend bool) template.HTML {
|
||||
revel.TemplateFuncs["blogTagsLea"] = func(renderArgs map[string]interface{}, tags []string, typeStr string) template.HTML {
|
||||
if tags == nil || len(tags) == 0 {
|
||||
return ""
|
||||
}
|
||||
@@ -155,10 +192,12 @@ func init() {
|
||||
lenTags := len(tags)
|
||||
|
||||
tagPostUrl := "http://lea.leanote.com/"
|
||||
if isRecommend {
|
||||
if typeStr == "recommend" {
|
||||
tagPostUrl += "?tag=";
|
||||
} else {
|
||||
} else if typeStr == "latest" {
|
||||
tagPostUrl += "latest?tag=";
|
||||
} else {
|
||||
tagPostUrl += "subscription?tag=";
|
||||
}
|
||||
|
||||
for i, tag := range tags {
|
||||
@@ -367,7 +406,7 @@ func init() {
|
||||
// email配置
|
||||
InitEmail()
|
||||
InitVd()
|
||||
memcache.InitMemcache() // session服务
|
||||
// memcache.InitMemcache() // session服务
|
||||
// 其它service
|
||||
service.InitService()
|
||||
controllers.InitService()
|
||||
|
||||
@@ -56,6 +56,14 @@ func ClearDir(dir string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func MkdirAll(dir string) bool {
|
||||
err := os.MkdirAll(dir, 0777)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// list dir's all file, return filenames
|
||||
func ListDir(dir string) []string {
|
||||
f, err := os.Open(dir)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package lea
|
||||
|
||||
// 对比密码是否一致
|
||||
// 因为之前密码是用md5加密的, 所以通过密码长度来判断
|
||||
// rawPwd 原始, 用户输入的密码
|
||||
func ComparePwd(rawPwd, dbPwd string) bool {
|
||||
if len(dbPwd) == 32 {
|
||||
return Md5(rawPwd) == dbPwd
|
||||
}
|
||||
|
||||
hex := []byte(dbPwd)
|
||||
return CompareHash(hex, rawPwd)
|
||||
}
|
||||
|
||||
// 加密
|
||||
func GenPwd(rawPwd string) string {
|
||||
digest, err := GenerateHash(rawPwd)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(digest)
|
||||
}
|
||||
+22
-1
@@ -10,6 +10,7 @@ import (
|
||||
"io"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"strings"
|
||||
math_rand "math/rand"
|
||||
)
|
||||
|
||||
@@ -314,4 +315,24 @@ func InArray(arr []string, str string) bool {
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 将名称的特殊字符去掉
|
||||
func FixFilename(filename string) string {
|
||||
if filename != "" {
|
||||
// 把特殊字段给替换掉
|
||||
// str := `life "%&()+,/:;<>=?@\|`
|
||||
// . == \\.
|
||||
// $ === \\$
|
||||
reg, _ := regexp.Compile("\\.|/|#|\\$|!|\\^|\\*|'| |\"|%|&|\\(|\\)|\\+|\\,|/|:|;|<|>|=|\\?|@|\\||\\\\")
|
||||
filename = reg.ReplaceAllString(filename, "-")
|
||||
filename = strings.Trim(filename, "-") // 左右单独的-去掉
|
||||
// 把空格替换成-
|
||||
// filename = strings.Replace(filename, " ", "-", -1)
|
||||
for strings.Index(filename, "--") >= 0 { // 防止出现连续的--
|
||||
filename = strings.Replace(filename, "--", "-", -1)
|
||||
}
|
||||
return filename
|
||||
}
|
||||
return filename
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// contains two cryptographic functions for both storing and comparing passwords.
|
||||
package lea
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// GenerateHash generates bcrypt hash from plaintext password
|
||||
func GenerateHash(password string) ([]byte, error) {
|
||||
hex := []byte(password)
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword(hex, 10)
|
||||
if err != nil {
|
||||
return hashedPassword, err
|
||||
}
|
||||
return hashedPassword, nil
|
||||
}
|
||||
|
||||
// CompareHash compares bcrypt password with a plaintext one. Returns true if passwords match
|
||||
// and false if they do not.
|
||||
func CompareHash(digest []byte, password string) bool {
|
||||
hex := []byte(password)
|
||||
if err := bcrypt.CompareHashAndPassword(digest, hex); err == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
+16
-20
@@ -6,6 +6,7 @@ import (
|
||||
"os/exec"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
// "time"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -32,7 +33,7 @@ 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",
|
||||
"js/object_id"}
|
||||
"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/"
|
||||
@@ -91,7 +92,6 @@ func dev() {
|
||||
"notebook.js": "notebook-min.js",
|
||||
"share.js": "share-min.js",
|
||||
"tag.js": "tag-min.js",
|
||||
"main.js": "main-min.js",
|
||||
"jquery.slimscroll.js": "jquery.slimscroll-min.js",
|
||||
"jquery.contextmenu.js": "jquery.contextmenu-min.js",
|
||||
"editor/editor.js": "editor/editor-min.js",
|
||||
@@ -107,6 +107,13 @@ func dev() {
|
||||
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)
|
||||
|
||||
ioutil.WriteFile(target, []byte(content), os.ModeAppend)
|
||||
}
|
||||
|
||||
@@ -114,8 +121,10 @@ func dev() {
|
||||
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("/Users/life/Documents/eclipse-workspace/go/leanote_release/tinymce-master/node_modules/jake/bin/cli.js", "minify")
|
||||
cmd.Dir = "/Users/life/Documents/eclipse-workspace/go/leanote_release/tinymce-master"
|
||||
cmd := exec.Command("/bin/sh", "-c", "grunt minify");
|
||||
cmd.Dir = base + "/tinymce_4.1.9"
|
||||
|
||||
fmt.Println("正在build tinymce");
|
||||
|
||||
// 必须要先删除
|
||||
cmd2 := exec.Command("/bin/sh", "-c", "rm " + cmd.Dir + "/js/tinymce/tinymce.dev.js")
|
||||
@@ -123,32 +132,19 @@ func tinymce() {
|
||||
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))
|
||||
}
|
||||
|
||||
func main() {
|
||||
// 压缩tinymce
|
||||
tinymce()
|
||||
// tinymce()
|
||||
|
||||
dev();
|
||||
|
||||
// 其它零散的需要压缩的js
|
||||
otherJss := []string{"tinymce/tinymce", "js/main", "js/app/page", "js/contextmenu/jquery.contextmenu",
|
||||
"mdeditor/editor/scrollLink",
|
||||
"mdeditor/editor/editor",
|
||||
"mdeditor/editor/jquery.waitforimages",
|
||||
"mdeditor/editor/pagedown/local/Markdown.local.zh",
|
||||
"mdeditor/editor/pagedown/local/Markdown.local.en",
|
||||
"mdeditor/editor/pagedown/Markdown.Editor",
|
||||
"mdeditor/editor/pagedown/Markdown.Sanitizer",
|
||||
"mdeditor/editor/pagedown/Markdown.Converter",
|
||||
"mdeditor/editor/Markdown.Extra",
|
||||
"mdeditor/editor/underscore",
|
||||
"mdeditor/editor/mathJax",
|
||||
"js/jQuery-slimScroll-1.3.0/jquery.slimscroll",
|
||||
"js/app/editor_drop_paste",
|
||||
"js/app/attachment_upload",
|
||||
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",
|
||||
}
|
||||
|
||||
+46
-38
@@ -2,26 +2,31 @@ package service
|
||||
|
||||
import (
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// "github.com/leanote/leanote/app/db"
|
||||
// "github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// "github.com/revel/revel"
|
||||
"strings"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "github.com/revel/revel"
|
||||
"errors"
|
||||
"fmt"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 登录与权限
|
||||
// 登录与权限 Login & Register
|
||||
|
||||
type AuthService struct {
|
||||
}
|
||||
|
||||
// pwd已md5了
|
||||
func (this *AuthService) Login(emailOrUsername, pwd string) info.User {
|
||||
// 使用bcrypt认证或者Md5认证
|
||||
// Use bcrypt (Md5 depreciated)
|
||||
func (this *AuthService) Login(emailOrUsername, pwd string) (info.User, error) {
|
||||
emailOrUsername = strings.Trim(emailOrUsername, " ")
|
||||
// pwd = strings.Trim(pwd, " ")
|
||||
userInfo := userService.LoginGetUserInfo(emailOrUsername, Md5(pwd))
|
||||
return userInfo
|
||||
// pwd = strings.Trim(pwd, " ")
|
||||
userInfo := userService.GetUserInfoByName(emailOrUsername)
|
||||
if userInfo.UserId == "" || !ComparePwd(pwd, userInfo.Pwd) {
|
||||
return userInfo, errors.New("wrong username or password")
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
||||
|
||||
// 注册
|
||||
@@ -40,71 +45,74 @@ func (this *AuthService) Register(email, pwd, fromUserId string) (bool, string)
|
||||
if userService.IsExistsUser(email) {
|
||||
return false, "userHasBeenRegistered-" + email
|
||||
}
|
||||
user := info.User{UserId: bson.NewObjectId(), Email: email, Username: email, Pwd: Md5(pwd)}
|
||||
passwd := GenPwd(pwd)
|
||||
if passwd == "" {
|
||||
return false, "GenerateHash error"
|
||||
}
|
||||
user := info.User{UserId: bson.NewObjectId(), Email: email, Username: email, Pwd: passwd}
|
||||
if fromUserId != "" && IsObjectId(fromUserId) {
|
||||
user.FromUserId = bson.ObjectIdHex(fromUserId)
|
||||
}
|
||||
LogJ(user)
|
||||
return this.register(user)
|
||||
}
|
||||
|
||||
func (this *AuthService) register(user info.User) (bool, string) {
|
||||
if userService.AddUser(user) {
|
||||
// 添加笔记本, 生活, 学习, 工作
|
||||
userId := user.UserId.Hex();
|
||||
userId := user.UserId.Hex()
|
||||
notebook := info.Notebook{
|
||||
Seq: -1,
|
||||
Seq: -1,
|
||||
UserId: user.UserId}
|
||||
title2Id := map[string]bson.ObjectId{"life": bson.NewObjectId(), "study": bson.NewObjectId(), "work": bson.NewObjectId()}
|
||||
for title, objectId := range title2Id {
|
||||
notebook.Title = title
|
||||
notebook.NotebookId = objectId
|
||||
notebook.UserId = user.UserId
|
||||
notebookService.AddNotebook(notebook);
|
||||
notebookService.AddNotebook(notebook)
|
||||
}
|
||||
|
||||
|
||||
// 添加leanote -> 该用户的共享
|
||||
registerSharedUserId := configService.GetGlobalStringConfig("registerSharedUserId")
|
||||
if(registerSharedUserId != "") {
|
||||
if registerSharedUserId != "" {
|
||||
registerSharedNotebooks := configService.GetGlobalArrMapConfig("registerSharedNotebooks")
|
||||
registerSharedNotes := configService.GetGlobalArrMapConfig("registerSharedNotes")
|
||||
registerCopyNoteIds := configService.GetGlobalArrayConfig("registerCopyNoteIds")
|
||||
|
||||
|
||||
// 添加共享笔记本
|
||||
for _, notebook := range registerSharedNotebooks {
|
||||
perm, _ := strconv.Atoi(notebook["perm"])
|
||||
shareService.AddShareNotebookToUserId(notebook["notebookId"], perm, registerSharedUserId, userId);
|
||||
shareService.AddShareNotebookToUserId(notebook["notebookId"], perm, registerSharedUserId, userId)
|
||||
}
|
||||
|
||||
|
||||
// 添加共享笔记
|
||||
for _, note := range registerSharedNotes {
|
||||
perm, _ := strconv.Atoi(note["perm"])
|
||||
shareService.AddShareNoteToUserId(note["noteId"], perm, registerSharedUserId, userId);
|
||||
shareService.AddShareNoteToUserId(note["noteId"], perm, registerSharedUserId, userId)
|
||||
}
|
||||
|
||||
|
||||
// 复制笔记
|
||||
for _, noteId := range registerCopyNoteIds {
|
||||
note := noteService.CopySharedNote(noteId, title2Id["life"].Hex(), registerSharedUserId, user.UserId.Hex());
|
||||
// Log(noteId)
|
||||
// Log("Copy")
|
||||
// LogJ(note)
|
||||
note := noteService.CopySharedNote(noteId, title2Id["life"].Hex(), registerSharedUserId, user.UserId.Hex())
|
||||
// Log(noteId)
|
||||
// Log("Copy")
|
||||
// LogJ(note)
|
||||
noteUpdate := bson.M{"IsBlog": false} // 不要是博客
|
||||
noteService.UpdateNote(user.UserId.Hex(), note.NoteId.Hex(), noteUpdate, -1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------
|
||||
// 添加一条userBlog
|
||||
blogService.UpdateUserBlog(info.UserBlog{UserId: user.UserId,
|
||||
Title: user.Username + " 's Blog",
|
||||
SubTitle: "Love Leanote!",
|
||||
AboutMe: "Hello, I am (^_^)",
|
||||
blogService.UpdateUserBlog(info.UserBlog{UserId: user.UserId,
|
||||
Title: user.Username + " 's Blog",
|
||||
SubTitle: "Love Leanote!",
|
||||
AboutMe: "Hello, I am (^_^)",
|
||||
CanComment: true,
|
||||
})
|
||||
})
|
||||
// 添加一个单页面
|
||||
blogService.AddOrUpdateSingle(user.UserId.Hex(), "", "About Me", "Hello, I am (^_^)")
|
||||
}
|
||||
|
||||
|
||||
return true, ""
|
||||
}
|
||||
|
||||
@@ -115,7 +123,7 @@ func (this *AuthService) register(user info.User) (bool, string) {
|
||||
func (this *AuthService) getUsername(thirdType, thirdUsername string) (username string) {
|
||||
username = thirdType + "-" + thirdUsername
|
||||
i := 1
|
||||
for ;; {
|
||||
for {
|
||||
if !userService.IsExistsUserByUsername(username) {
|
||||
return
|
||||
}
|
||||
@@ -131,11 +139,11 @@ func (this *AuthService) ThirdRegister(thirdType, thirdUserId, thirdUsername str
|
||||
}
|
||||
|
||||
username := this.getUsername(thirdType, thirdUsername)
|
||||
userInfo = info.User{UserId: bson.NewObjectId(),
|
||||
Username: username,
|
||||
ThirdUserId: thirdUserId,
|
||||
userInfo = info.User{UserId: bson.NewObjectId(),
|
||||
Username: username,
|
||||
ThirdUserId: thirdUserId,
|
||||
ThirdUsername: thirdUsername,
|
||||
}
|
||||
}
|
||||
_, _ = this.register(userInfo)
|
||||
return
|
||||
}
|
||||
@@ -1197,6 +1197,10 @@ func (this *BlogService) FixBlog(blog info.BlogItem) info.Post {
|
||||
LikeNum: blog.LikeNum,
|
||||
IsMarkdown: blog.IsMarkdown,
|
||||
}
|
||||
if blog2.Tags != nil && len(blog2.Tags) > 0 && blog2.Tags[0] != "" {
|
||||
} else {
|
||||
blog2.Tags = nil
|
||||
}
|
||||
return blog2
|
||||
}
|
||||
|
||||
|
||||
@@ -455,12 +455,15 @@ var port string
|
||||
|
||||
func init() {
|
||||
revel.OnAppStart(func() {
|
||||
/*
|
||||
不用配置的, 因为最终通过命令可以改, 而且有的使用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://") {
|
||||
@@ -469,6 +472,17 @@ func init() {
|
||||
defaultDomain = siteUrl[len("https://"):]
|
||||
schema = "https://"
|
||||
}
|
||||
|
||||
// port localhost:9000
|
||||
ports := strings.Split(defaultDomain, ":")
|
||||
if len(ports) == 2 {
|
||||
port = ports[1]
|
||||
}
|
||||
if port == "80" {
|
||||
port = ""
|
||||
} else {
|
||||
port = ":" + port
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+84
-25
@@ -32,11 +32,21 @@ func (this *GroupService) DeleteGroup(userId, groupId string) (ok bool, msg stri
|
||||
return false, "groupHasUsers"
|
||||
}
|
||||
*/
|
||||
if !this.isMyGroup(userId, groupId) {
|
||||
return false, "notMyGroup"
|
||||
}
|
||||
|
||||
// 删除分组后, 需要删除所有用户分享到该组的笔记本, 笔记
|
||||
|
||||
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中也要删除
|
||||
}
|
||||
|
||||
// 修改group标题
|
||||
func (this *GroupService) UpdateGroupTitle(userId, groupId, title string) (ok bool) {
|
||||
return db.UpdateByIdAndUserIdField(db.Groups, groupId, userId, "Title", title)
|
||||
@@ -44,9 +54,14 @@ func (this *GroupService) UpdateGroupTitle(userId, groupId, title string) (ok bo
|
||||
|
||||
// 得到用户的所有分组(包括下的所有用户)
|
||||
func (this *GroupService) GetGroupsAndUsers(userId string) ([]info.Group) {
|
||||
// 得到分组s
|
||||
/*
|
||||
// 得到我的分组
|
||||
groups := []info.Group{}
|
||||
db.ListByQ(db.Groups, bson.M{"UserId": bson.ObjectIdHex(userId)}, &groups)
|
||||
*/
|
||||
// 我的分组, 及我所属的分组
|
||||
groups := this.GetGroupsContainOf(userId);
|
||||
|
||||
// 得到其下的用户
|
||||
for i, group := range groups {
|
||||
group.Users = this.GetUsers(group.GroupId.Hex())
|
||||
@@ -62,29 +77,52 @@ func (this *GroupService) GetGroups(userId string) ([]info.Group) {
|
||||
return groups
|
||||
}
|
||||
|
||||
|
||||
// 获取包含此用户的组对象数组
|
||||
func (this *GroupService) GetGroupsContainOf(userId string) []info.Group {
|
||||
groupIds := this.GetGroupIdsContainOf(userId)
|
||||
groups := []info.Group{}
|
||||
db.ListByQ(db.Groups, bson.M{"_id": bson.M{"$in": groupIds}}, &groups)
|
||||
return groups
|
||||
// 得到我的和我所属组的ids
|
||||
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
|
||||
}
|
||||
|
||||
// 获取包含此用户的组Id数组
|
||||
func (this *GroupService) GetGroupIdsContainOf(userId string) []bson.ObjectId {
|
||||
groupUsers := []info.GroupUser{}
|
||||
db.ListByQWithFields(db.GroupUsers, bson.M{"UserId": bson.ObjectIdHex(userId)}, []string{"GroupId"}, &groupUsers)
|
||||
if len(groupUsers) == 0 {
|
||||
return nil
|
||||
// 获取包含此用户的组对象数组
|
||||
// 获取该用户所属组, 和我的组
|
||||
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)
|
||||
|
||||
groupIds := make([]bson.ObjectId, len(groupUsers))
|
||||
for i, each := range groupUsers {
|
||||
groupIds[i] = each.GroupId
|
||||
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 groupIds
|
||||
|
||||
return myGroups
|
||||
}
|
||||
|
||||
// 得到分组, shareService用
|
||||
@@ -128,11 +166,26 @@ func (this *GroupService) GetBelongToGroupIds(userId string) ([]bson.ObjectId) {
|
||||
|
||||
func (this *GroupService) isMyGroup(ownUserId, groupId string) (ok bool) {
|
||||
return db.Has(db.Groups, bson.M{"_id": bson.ObjectIdHex(groupId), "UserId": bson.ObjectIdHex(ownUserId)})
|
||||
}
|
||||
}
|
||||
|
||||
// 判断组中是否包含指定用户
|
||||
func (this *GroupService) IsExistsGroupUser(userId, groupId string) (ok bool) {
|
||||
// 如果我拥有这个组, 那也行
|
||||
if this.isMyGroup(userId, groupId) {
|
||||
return true
|
||||
}
|
||||
return db.Has(db.GroupUsers, bson.M{"UserId": bson.ObjectIdHex(userId), "GroupId": bson.ObjectIdHex(groupId)})
|
||||
}
|
||||
|
||||
// 为group添加用户
|
||||
// 用户是否已存在?
|
||||
func (this *GroupService) AddUser(ownUserId, groupId, userId string) (ok bool, msg string) {
|
||||
// groupId是否是ownUserId的?
|
||||
/*
|
||||
if !this.IsExistsGroupUser(ownUserId, groupId) {
|
||||
return false, "forbidden"
|
||||
}
|
||||
*/
|
||||
if !this.isMyGroup(ownUserId, groupId) {
|
||||
return false, "forbidden"
|
||||
}
|
||||
@@ -149,16 +202,22 @@ func (this *GroupService) AddUser(ownUserId, groupId, userId string) (ok bool, m
|
||||
CreatedTime: time.Now(),
|
||||
}), ""
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
func (this *GroupService) DeleteUser(ownUserId, groupId, userId string) (ok bool, msg string) {
|
||||
// groupId是否是ownUserId的?
|
||||
/*
|
||||
if !this.IsExistsGroupUser(ownUserId, groupId) {
|
||||
return false, "forbidden"
|
||||
}
|
||||
*/
|
||||
if !this.isMyGroup(ownUserId, groupId) {
|
||||
return false, "forbidden"
|
||||
}
|
||||
|
||||
// 删除该用户分享到本组的笔记本, 笔记
|
||||
shareService.DeleteShareNotebookGroupWhenDeleteGroupUser(userId, groupId);
|
||||
shareService.DeleteShareNoteGroupWhenDeleteGroupUser(userId, groupId);
|
||||
|
||||
return db.Delete(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId), "UserId": bson.ObjectIdHex(userId)}), ""
|
||||
}
|
||||
|
||||
// 判断组中是否包含指定用户
|
||||
func (this *GroupService) IsExistsGroupUser(userId, groupId string) (ok bool) {
|
||||
return db.Has(db.GroupUsers, bson.M{"UserId": bson.ObjectIdHex(userId), "GroupId": bson.ObjectIdHex(groupId)})
|
||||
}
|
||||
@@ -18,9 +18,10 @@ func (this *NoteService) GetNote(noteId, userId string) (note info.Note) {
|
||||
return
|
||||
}
|
||||
// fileService调用
|
||||
// 不能是已经删除了的, life bug, 客户端删除后, 竟然还能在web上打开
|
||||
func (this *NoteService) GetNoteById(noteId string) (note info.Note) {
|
||||
note = info.Note{}
|
||||
db.Get(db.Notes, noteId, ¬e)
|
||||
db.GetByQ(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId), "IsDeleted": false}, ¬e)
|
||||
return
|
||||
}
|
||||
// 得到blog, blogService用
|
||||
@@ -238,7 +239,6 @@ func (this *NoteService) AddNote(note info.Note, fromApi bool) info.Note {
|
||||
|
||||
// api会传IsBlog, web不会传
|
||||
if !fromApi {
|
||||
note.PublicTime = note.UpdatedTime
|
||||
// 设为blog
|
||||
note.IsBlog = notebookService.IsBlog(notebookId)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"sort"
|
||||
"time"
|
||||
"strings"
|
||||
// "html"
|
||||
)
|
||||
|
||||
// 笔记本
|
||||
@@ -40,7 +42,9 @@ 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 = 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
|
||||
newNotebooks.ParentNotebookId = each.ParentNotebookId
|
||||
@@ -271,11 +275,15 @@ func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) (boo
|
||||
// 查看是否有子notebook
|
||||
// 先查看该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)}) == 0 { // 无
|
||||
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}) == 0 { // 不包含trash
|
||||
"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, ""
|
||||
|
||||
@@ -45,9 +45,13 @@ func (this *PwdService) UpdatePwd(token, pwd string) (bool, 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 := string(digest)
|
||||
// 修改密码之
|
||||
ok = db.UpdateByQField(db.Users, bson.M{"_id": tokenInfo.UserId}, "Pwd", Md5(pwd))
|
||||
ok = db.UpdateByQField(db.Users, bson.M{"_id": tokenInfo.UserId}, "Pwd", passwd)
|
||||
|
||||
// 删除token
|
||||
tokenService.DeleteToken(tokenInfo.UserId.Hex(), info.TokenPwd)
|
||||
|
||||
@@ -33,8 +33,9 @@ type ShareService struct {
|
||||
|
||||
// 谁共享给了我的Query
|
||||
func (this *ShareService) getOrQ(userId string) bson.M {
|
||||
// 得到我参与的组织
|
||||
groupIds := groupService.GetBelongToGroupIds(userId)
|
||||
// 得到我和和我参与的组织
|
||||
groupIds := groupService.GetMineAndBelongToGroupIds(userId)
|
||||
|
||||
q := bson.M{}
|
||||
if len(groupIds) > 0 {
|
||||
orQ := []bson.M{
|
||||
@@ -51,6 +52,8 @@ 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)
|
||||
@@ -64,7 +67,15 @@ func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksB
|
||||
db.Distinct(db.ShareNotebooks, q, "UserId", &userIds2) // BUG之前是userId1, 2014/12/29
|
||||
|
||||
userIds := append(userIds1, userIds2...)
|
||||
|
||||
userInfos := userService.GetUserInfosOrderBySeq(userIds);
|
||||
// 不要我的id
|
||||
for i, userInfo := range userInfos {
|
||||
if userInfo.UserId.Hex() == myUserId {
|
||||
userInfos = append(userInfos[:i], userInfos[i+1:]...)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// 得到他们共享给我的notebooks
|
||||
@@ -102,6 +113,11 @@ func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksB
|
||||
// 先建立userId => []
|
||||
for _, eachSub := range subShareNotebooks {
|
||||
userId := eachSub.Notebook.UserId
|
||||
// 我自己的, 算了
|
||||
if userId.Hex() == myUserId {
|
||||
continue;
|
||||
}
|
||||
|
||||
if _, ok := shareNotebooksByUsersMap[userId]; ok {
|
||||
shareNotebooksByUsersMap[userId] = append(shareNotebooksByUsersMap[userId], eachSub)
|
||||
} else {
|
||||
@@ -779,3 +795,36 @@ func (this *ShareService) DeleteShareNotebookGroup(userId, notebookId, groupId s
|
||||
"ToGroupId": bson.ObjectIdHex(groupId),
|
||||
});
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// 删除组时, 删除所有的
|
||||
//--------------------
|
||||
|
||||
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),
|
||||
});
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// 删除组内用户时, 删除其分享的
|
||||
//--------------------
|
||||
|
||||
func (this *ShareService) DeleteShareNotebookGroupWhenDeleteGroupUser(userId, groupId string) bool {
|
||||
return db.Delete(db.ShareNotebooks, bson.M{
|
||||
"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),
|
||||
"ToGroupId": bson.ObjectIdHex(groupId),
|
||||
});
|
||||
}
|
||||
@@ -239,15 +239,15 @@ func (this *UserService) GetUserInfosOrderBySeq(userIds []bson.ObjectId) []info.
|
||||
return users2
|
||||
}
|
||||
|
||||
// 使用email(username), pwd得到用户信息
|
||||
func (this *UserService) LoginGetUserInfo(emailOrUsername, md5Pwd string) info.User {
|
||||
// 使用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, "Pwd": md5Pwd}, &user)
|
||||
db.GetByQ(db.Users, bson.M{"Email": emailOrUsername}, &user)
|
||||
} else {
|
||||
db.GetByQ(db.Users, bson.M{"Username": emailOrUsername, "Pwd": md5Pwd}, &user)
|
||||
db.GetByQ(db.Users, bson.M{"Username": emailOrUsername}, &user)
|
||||
}
|
||||
this.setUserLogo(&user)
|
||||
return user
|
||||
@@ -281,10 +281,16 @@ func (this *UserService) UpdateAvatar(userId, avatarPath string) (bool) {
|
||||
// 已经登录了的用户修改密码
|
||||
func (this *UserService) UpdatePwd(userId, oldPwd, pwd string) (bool, string) {
|
||||
userInfo := this.GetUserInfo(userId)
|
||||
if userInfo.Pwd != Md5(oldPwd) {
|
||||
if !ComparePwd(oldPwd, userInfo.Pwd) {
|
||||
return false, "oldPasswordError"
|
||||
}
|
||||
ok := db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Pwd", Md5(pwd))
|
||||
|
||||
passwd := GenPwd(pwd)
|
||||
if passwd == "" {
|
||||
return false, "GenerateHash error"
|
||||
}
|
||||
|
||||
ok := db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Pwd", passwd)
|
||||
return ok, ""
|
||||
}
|
||||
|
||||
@@ -293,7 +299,12 @@ func (this *UserService) ResetPwd(adminUserId, userId, pwd string) (ok bool, msg
|
||||
if configService.GetAdminUserId() != adminUserId {
|
||||
return
|
||||
}
|
||||
ok = db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Pwd", Md5(pwd))
|
||||
|
||||
passwd := GenPwd(pwd)
|
||||
if passwd == "" {
|
||||
return false, "GenerateHash error"
|
||||
}
|
||||
ok = db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Pwd", passwd)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/robfig/revel"
|
||||
|
||||
"github.com/leanote/leanote/app/service"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "github.com/leanote/leanote/app/lea/memcache"
|
||||
// "github.com/leanote/leanote/app/lea/netutil"
|
||||
"github.com/leanote/leanote/app/lea/html2image"
|
||||
"time"
|
||||
"fmt"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// "gopkg.in/mgo.v2"
|
||||
// "encoding/json"
|
||||
// "strings"
|
||||
)
|
||||
|
||||
var userId = "5295d4c95b1dd58edb4a7f4f"
|
||||
var userIdO = bson.ObjectIdHex(userId)
|
||||
|
||||
var userId3 = "52b43ae4cfeeae33ef073b2b"
|
||||
var userId3O = bson.ObjectIdHex(userId3)
|
||||
|
||||
var toUserId = "52b4376bcfeeae33ef073b21"
|
||||
var toUserIdO = bson.ObjectIdHex(toUserId)
|
||||
|
||||
var notebookId = "52b2d051ea3ba3d3fb35910c"
|
||||
var notebookIdO = bson.ObjectIdHex(notebookId)
|
||||
var notebookId2O = bson.ObjectIdHex("52b2d051ea3ba3d3fb35910b")
|
||||
|
||||
var noteId = "52b2dd34ea3ba3d3fb35910d"
|
||||
var noteIdO = bson.ObjectIdHex(noteId)
|
||||
|
||||
func testNoteService() {
|
||||
println("testNoteService")
|
||||
noteService := &service.NoteService{}
|
||||
note := noteService.GetBlogNote("535f9e6b19807a4c8d000000")
|
||||
LogJ(note)
|
||||
/*
|
||||
_, notes := noteService.SearchNote("go", "52d3e8ac99c37b7f0d000001", 1, 30, "", false, true);
|
||||
LogJ(notes)
|
||||
*/
|
||||
return;
|
||||
|
||||
/*
|
||||
noteService.AddNote(info.Note{UserId: userIdO,
|
||||
NotebookId: notebookIdO,
|
||||
Title: "life you", Tags: []string{"red", "yellow"}})
|
||||
*/
|
||||
|
||||
noteService.AddNoteContent(info.NoteContent{UserId: userIdO,
|
||||
NoteId: bson.ObjectIdHex("52b4531dcfeeae33ef073b33"),
|
||||
Content:"xxxxxxxxxxxxxxxxxxxxlifeyou can m<div><p></p></div>"})
|
||||
|
||||
// noteService.UpdateNoteContent(userId, userId, "52b2dd34ea3ba3d3fb35910d", "life2---------")
|
||||
|
||||
// noteService.AddNote(info.Note{Title: "life", Tags: []string{"life", "life2"}})
|
||||
|
||||
// println(bson.IsObjectIdHex(id))
|
||||
|
||||
// note := noteService.Get(id)
|
||||
// fmt.Println(note)
|
||||
|
||||
// noteService.UpdateTags(id, []string{"lifedd", "life2"});
|
||||
}
|
||||
|
||||
func testNotebookService() {
|
||||
service := &service.NotebookService{}
|
||||
Log(service.IsBlog("52ccb959bcbf21610d000001"))
|
||||
|
||||
return;
|
||||
|
||||
notebooks := service.GetNotebooks(userId3)
|
||||
LogJ(notebooks)
|
||||
|
||||
// b, _ := json.MarshalIndent(notebooks, "", " ")
|
||||
// fmt.Println(string(b))
|
||||
|
||||
// service.UpdateNotebookTitle("52b2cf9eea3ba3d3fb359108", userId, "JS")
|
||||
|
||||
// service.SortNotebooks(userId, map[string]int{"52b2d051ea3ba3d3fb35910c": 4, "52b2d051ea3ba3d3fb35910b": 3})
|
||||
|
||||
/*
|
||||
service.AddNotebook(info.Notebook{UserId: userId3O,
|
||||
ParentNotebookId: bson.ObjectIdHex("52b43c1fcfeeae33ef073b2e"),
|
||||
Title: "Mac-life",
|
||||
Seq: 0})
|
||||
*/
|
||||
|
||||
println("xxx")
|
||||
}
|
||||
|
||||
func testShareService() {
|
||||
service := &service.ShareService{}
|
||||
|
||||
// service.AddShareNote("52bd127dbcbf216d0b000000", 1, "5295d4c95b1dd58edb4a7f4f", "c@a.com")
|
||||
LogJ(service.ListNoteShareUserInfo("52cd11a1bcbf215680000000", "5295d4c95b1dd58edb4a7f4f"))
|
||||
return;
|
||||
|
||||
/*
|
||||
service.AddShareNotebook(info.ShareNotebook{UserId: userId3O, ToUserId: userIdO,
|
||||
NotebookId: bson.ObjectIdHex("52b43c38cfeeae33ef073b30")})
|
||||
*/
|
||||
|
||||
notebooks,_ := service.GetShareNotebooks(userId)
|
||||
LogJ(notebooks)
|
||||
|
||||
// noteService.AddNoteContent(info.NoteContent{UserId: userIdO,
|
||||
// NoteId: bson.ObjectIdHex("52b2dd34ea3ba3d3fb35910d"), Content:"xxxxxxxxxxxxxxxxxxxxlifeyou can m<div><p></p></div>"})
|
||||
|
||||
|
||||
// noteService.AddNote(info.Note{Title: "life", Tags: []string{"life", "life2"}})
|
||||
|
||||
// println(bson.IsObjectIdHex(id))
|
||||
|
||||
// note := noteService.Get(id)
|
||||
// fmt.Println(note)
|
||||
|
||||
// noteService.UpdateTags(id, []string{"lifedd", "life2"});
|
||||
}
|
||||
|
||||
|
||||
func testAuthService() {
|
||||
userService := &service.UserService{}
|
||||
LogJ(userService.GetUserInfo("52d26b4e99c37b609a000001"))
|
||||
// userService.AddUser(info.User{UserId: bson.ObjectIdHex("52d26b4e99c37b609a000001"), Email: "leanote@leanote.com", Pwd:"abc"})
|
||||
return;
|
||||
|
||||
authService := &service.AuthService{}
|
||||
authService.Register("f@a.com", "abc")
|
||||
|
||||
// fmt.Println(authService.LogonGetUserInfo("a@a.com", "abc"))
|
||||
|
||||
// noteService.AddNoteContent(info.NoteContent{UserId: userIdO,
|
||||
// NoteId: bson.ObjectIdHex("52b2dd34ea3ba3d3fb35910d"), Content:"xxxxxxxxxxxxxxxxxxxxlifeyou can m<div><p></p></div>"})
|
||||
|
||||
// noteService.AddNote(info.Note{Title: "life", Tags: []string{"life", "life2"}})
|
||||
|
||||
// println(bson.IsObjectIdHex(id))
|
||||
|
||||
// note := noteService.Get(id)
|
||||
// fmt.Println(note)
|
||||
|
||||
// noteService.UpdateTags(id, []string{"lifedd", "life2"});
|
||||
}
|
||||
|
||||
func testTagService() {
|
||||
service := &service.TagService{}
|
||||
// service.AddTags("5295d4c95b1dd58edb4a7f4f", []string{"life", "blue", "yellow"})
|
||||
// service.AddTags("5295d4c95b1dd58edb4a7f4f", []string{"what", "can", "make"})
|
||||
LogJ(service.GetTags("5295d4c95b1dd58edb4a7f4f"))
|
||||
}
|
||||
|
||||
func testHtml2Image() {
|
||||
start := time.Now()
|
||||
Log("start...")
|
||||
// TestFillString()
|
||||
|
||||
|
||||
html2image.ToImage("uid", "username", "noteId", "开发一款属于自己的编程语言,开发一款属于自己的编程语言听起来是不是很酷?", `
|
||||
<div class="each-post">
|
||||
<p>
|
||||
一个合格的 Techspace 需要有足够专业的器材、场地和资源,你可以和你的团队在里面进行激光切割、快速贴片甚至加工木材等操作,在相对独立的空间内又能同周围的同道友人互相激发切磋。国内现有的 Techspace 没几家,不久前我去深圳特地拜访了当地的 Techspace,很喜欢那里的氛围,希望国内其他地方也能有更多这类空间供创客发挥。
|
||||
假如你有一个比较成型的想法,想在硬件领域做点事情,核心团队也基本组好,硬件软件交互基本都有专人了。</p>
|
||||
<p><a>这时候你的首要目标</a>,就是找个地方,按照你的计划,尽早做出一个可用的原型。Techspace可能是一个合适的地方。
|
||||
一个合格的 Techspace 需要有足够专业的器材、场地和资源,你可以和你的团队在里面进行激光切割、快速贴片甚至加工木材等操作,在相对独立的空间内又能同周围的同道友人互相激发切磋。国内现有的 Techspace 没几家,不久前我去深圳特地拜访了当地的 Techspace,很喜欢那里的氛围,希望国内其他地方也能有更多这类空间供创客发挥。
|
||||
深圳 Techspace 位于工业区,园区内有奥迪、BMW 等企业的厂房,在大门口我停下来问保安,M10 栋在哪里?保安答,去 Techspace?最里面靠右手那栋。惊叹于保安的机智,我也在想,莫非有许多朋友都慕名来到这巨大园区寻访 Techspace?
|
||||
穿过一片工业区里的高楼和各种建筑材料
|
||||
</p>
|
||||
<!--
|
||||
<pre class="">cd jpeg-9a/<br>./configure --enable-shared --enable-static
|
||||
make<br>make --- install</pre>
|
||||
<p>
|
||||
life you can, !!@kk
|
||||
</p>
|
||||
|
||||
-->
|
||||
</div>
|
||||
`, "/Users/life/Desktop/a.png")
|
||||
fmt.Printf("time cost %v\n", time.Now().Sub(start))
|
||||
}
|
||||
|
||||
func testLea() {
|
||||
names := ListDir("/Users/life/Documents/Go/package/src/leanote")
|
||||
fmt.Println(names);
|
||||
}
|
||||
|
||||
func main() {
|
||||
revel.BasePath = "/Users/life/Documents/Go/package/src/leanote"
|
||||
// testLea();
|
||||
|
||||
// a, b := SplitFilename("http://ab/c/a.gif#??")
|
||||
// println(a)
|
||||
// println(b)
|
||||
|
||||
// path, ok := netutil.WriteUrl("http://a.36krcnd.com/photo/2014/9bd1a07c0973d79ca05ad13c3c2e16b8.png!slider", "/tmp")
|
||||
// println(path)
|
||||
// testHtml2Image();
|
||||
|
||||
// println(IsObjectId("52d26b4e99c37b609a000001"))
|
||||
|
||||
// b := `请点击链接验证邮箱: <a href="">http://leanote.com/user/activeEmail?token=d8ca086cce5550a6227f9dc84dbac09d</a>. 48小时后过期.`
|
||||
// SendEmail("lifephp@gmail.com", "leanote-验证邮箱", "验证邮", b)
|
||||
|
||||
//_, err := mgo.Dial("mongodb://leanote:nKFAkxKnWkEQy8Vv2LlM@115.28.133.226:27017/leanote")
|
||||
|
||||
// testNotebookService();
|
||||
// testNoteService();
|
||||
// testShareService()
|
||||
// testAuthService()
|
||||
|
||||
// testTagService();
|
||||
/*
|
||||
filename := "你好59.26.png"
|
||||
ext := SubstringByte(filename, strings.LastIndex(filename, "."))
|
||||
ext = strings.ToLower(ext)
|
||||
print(ext)
|
||||
52d26ab199c37b5f80000001
|
||||
|
||||
Log(bson.NewObjectId())
|
||||
Log(bson.NewObjectId())
|
||||
Log(bson.NewObjectId())
|
||||
|
||||
*/
|
||||
// Log(TransferExt("/你好a/b/a.gif", ".jpg"))
|
||||
// TransToGif("/Users/life/Desktop/a2.png", 0, false)
|
||||
|
||||
// Log(IsUsername("xx**x"))
|
||||
|
||||
/*
|
||||
memcache.Set("xx", map[string]string{"A":"you"}, 0)
|
||||
a := memcache.Get("xx")
|
||||
Log(a)
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/service"
|
||||
// "gopkg.in/mgo.v2"
|
||||
// "fmt"
|
||||
)
|
||||
|
||||
func init() {
|
||||
db.Init("mongodb://localhost:27017/leanote", "leanote")
|
||||
service.InitService()
|
||||
}
|
||||
|
||||
// 测试登录
|
||||
func TestAuth(t *testing.T) {
|
||||
_, err := service.AuthS.Login("admin", "abc123")
|
||||
if err != nil {
|
||||
t.Error("Admin User Auth Error")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "github.com/leanote/leanote/app/service"
|
||||
// "gopkg.in/mgo.v2"
|
||||
// "fmt"
|
||||
)
|
||||
|
||||
func TestDBConnect(t *testing.T) {
|
||||
db.Init("mongodb://localhost:27017/leanote", "leanote")
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package tests
|
||||
func a() {
|
||||
}
|
||||
@@ -11,20 +11,3 @@
|
||||
<script src="/public/admin/js/artDialog/jquery.artDialog.js?skin=default"></script>
|
||||
<script src="/public/js/common.js"></script>
|
||||
<script src="/public/admin/js/admin.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
var pathname = location.pathname; // admin/t
|
||||
var search = location.search; // ?t=xxx, 如果有?page呢
|
||||
var fullPath = pathname;
|
||||
if(search.indexOf("?t=") >= 0) {
|
||||
var fullPath = pathname + search; // /admin/t?t=xxx
|
||||
}
|
||||
|
||||
$("#nav > li").removeClass("active");
|
||||
// 自己
|
||||
var $thisLi = $('#nav a[href^="' + fullPath + '"]').parent();
|
||||
$thisLi.addClass("active");
|
||||
// 父也active
|
||||
$thisLi.parent().parent().addClass('active');
|
||||
});
|
||||
</script>
|
||||
@@ -232,6 +232,8 @@
|
||||
v1.0-beta to v1.0-beta.2
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/admin/t?t=upgrade/beta3">
|
||||
<span>
|
||||
v1.0-beta.2/3 to v1.0-beta.4
|
||||
@@ -241,4 +243,4 @@
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</nav>
|
||||
@@ -27,7 +27,7 @@
|
||||
<a href="/index">{{msg . "home"}}</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="/index">leanote</a> © 2014
|
||||
<a href="/index">leanote</a> © 2014-2015
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<a href="/index">{{msg . "home"}}</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="/index">leanote</a> © 2014
|
||||
<a href="/index">leanote</a> © 2014-2015
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<a href="/index">{{msg . "home"}}</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="/index">leanote</a> © 2014
|
||||
<a href="/index">leanote</a> © 2014-2015
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
<a href="http://weibo.com/leanotecom" target="_blank"><i class="fa fa-weibo"></i></a>
|
||||
<br />
|
||||
leanote@leanote.com
|
||||
<div id="beian">
|
||||
<a href="http://www.miibeian.gov.cn" target="_blank">沪ICP备14006011号</a>
|
||||
</div>
|
||||
<br />
|
||||
Copyright © 2014-2015 <a href="http://leanote.com">Leanote</a>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<i class="fa fa-globe fa-3x icon-muted"></i>
|
||||
|
||||
+30
-26
@@ -5,8 +5,9 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="keywords" content="leanote,leanote.com">
|
||||
<meta name="description" content="leanote, {{msg $ "moto"}}">
|
||||
<meta name="author" content="leanote">
|
||||
<meta name="description" content="Leanote, {{msg $ "moto"}}">
|
||||
<meta property="qc:admins" content="2451332115167456375" />
|
||||
<meta name="author" content="leanote">
|
||||
<title>{{.title}}</title>
|
||||
|
||||
<link href="/css/bootstrap.css" rel="stylesheet">
|
||||
@@ -37,31 +38,33 @@ function log(o) {
|
||||
</div>
|
||||
|
||||
<div id="navbar" class="navbar-collapse collapse">
|
||||
<div id="lang">
|
||||
<a data-lang="en-us">English</a>
|
||||
<a data-lang="fr-fr">Français</a>
|
||||
<a data-lang="zh-cn">简体中文</a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-left">
|
||||
<li><a href="/index#" target="body" class="smooth-scroll">{{msg . "home"}}</a></li>
|
||||
<!--
|
||||
<li><a href="/index#aboutLeanote" target="#aboutLeanote" class="smooth-scroll">{{msg . "aboutLeanote"}}</a> </li>
|
||||
-->
|
||||
<li><a href="/index#download" target="#download" class="smooth-scroll">{{msg . "download"}}</a> </li>
|
||||
<li><a href="/index#donate" target="#donate" class="smooth-scroll">{{msg . "donate"}}</a> </li>
|
||||
<li><a id="leanoteBlog" href="{{.leaUrl}}/index" target="_blank" title="lea++, leanote博客平台" class="">lea++</a></li>
|
||||
<li style="position: relative; margin-right: 3px;">
|
||||
<a href="http://bbs.leanote.com" target="_blank" class="">{{msg . "discussion"}}</a>
|
||||
<li><a href="/index#" data-target="body" class="smooth-scroll">{{msg . "home"}}</a></li>
|
||||
<li style="position: relative;">
|
||||
<a id="" href="http://leanote.com/service" title="" class="">{{msg . "service"}}</a>
|
||||
<div class="red-circle" style=""></div>
|
||||
</li>
|
||||
|
||||
<li id="loginBtns">
|
||||
{{if .userInfo.Email}}
|
||||
{{msg . "hi"}}, {{.userInfo.Username}}
|
||||
<a href="{{$.noteUrl}}">{{msg . "myNote"}}</a>
|
||||
<a href="/logout">{{msg . "logout"}}</a>
|
||||
{{else}}
|
||||
<a href="/login">{{msg . "login"}}</a>
|
||||
{{if .openRegister}}
|
||||
<a href="/register" class="btn-register">{{msg . "register"}}</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<li style="position: relative; margin-right: 3px;">
|
||||
<a href="http://bbs.leanote.com" target="_blank" class="">{{msg . "discussion"}}</a>
|
||||
</li>
|
||||
<li><a id="leanoteBlog" href="http://lea.leanote.com" target="_blank" title="lea++, leanote blog platform" class="">lea++</a></li>
|
||||
<li><a id="leanoteApp" href="http://app.leanote.com" target="_blank" title="Leanote App" class="">{{msg . "desktopApp"}}</a></li>
|
||||
<li><a href="http://leanote.org" target="_blank" title="leanote.org" class="">leanote.org</a></li>
|
||||
|
||||
{{if .userInfo.Email}}
|
||||
<li id="loginBtns">
|
||||
{{msg . "hi"}}, {{.userInfo.Username}}
|
||||
<a href="{{$.noteUrl}}">{{msg . "myNote"}}</a>
|
||||
<a href="/logout">{{msg . "logout"}}</a>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,10 +94,11 @@ function log(o) {
|
||||
</div>
|
||||
|
||||
<ul id="blogNav" class="pull-right">
|
||||
<li><a href="/index#" target="body" class="smooth-scroll">{{msg . "home"}}</a></li>
|
||||
<li><a href="/index#download" target="#download" class="smooth-scroll">{{msg . "download"}}</a> </li>
|
||||
<li><a href="/index#donate" target="#donate" class="smooth-scroll">{{msg . "donate"}}</a> </li>
|
||||
<li><a href="#" target="body" class="smooth-scroll">{{msg . "home"}}</a></li>
|
||||
<li><a href="#download" target="#download" class="smooth-scroll">{{msg . "download"}}</a> </li>
|
||||
<li><a href="#donate" target="#donate" class="smooth-scroll">{{msg . "donate"}}</a> </li>
|
||||
<li><a id="leanoteBlog" href="{{.leaUrl}}/index" target="_blank" title="lea++, leanote博客平台" class="">lea++</a></li>
|
||||
|
||||
<li style="position: relative; margin-right: 3px;">
|
||||
<a href="http://bbs.leanote.com" target="_blank" class="">{{msg . "discussion"}}</a>
|
||||
<div style="position: absolute;
|
||||
@@ -108,4 +112,4 @@ function log(o) {
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
-->
|
||||
@@ -4,23 +4,22 @@
|
||||
</style>
|
||||
<section>
|
||||
<div class="header">
|
||||
<h2>leanote, {{msg . "moto"}}</h2>
|
||||
<h2>Leanote, {{msg . "moto"}}</h2>
|
||||
<p>{{msg . "moto3"}}</p>
|
||||
<p>
|
||||
Knowledge, Blog, Sharing, Cooperation... all in leanote
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<a class="btn btn-primary" href="https://github.com/leanote/leanote">{{msg . "fork github"}}</a>
|
||||
|
||||
|
||||
<a class="btn btn-default" href="/demo">{{msg . "try"}}</a>
|
||||
|
||||
|
||||
<a class="btn btn-default" href="/login">{{msg . "login"}}</a>
|
||||
{{if .openRegister}}
|
||||
|
||||
|
||||
OR
|
||||
|
||||
|
||||
<a class="btn btn-default" href="/register">{{msg . "register"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
@@ -66,20 +65,6 @@
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="container" id="download">
|
||||
<h2 style="margin: 20px 0;text-align: center;">{{msg . "download"}}</h2>
|
||||
<div class="row">
|
||||
<div style="width:300px; margin:auto; padding: 10px;">
|
||||
Linux : <a href="https://github.com/leanote/leanote/releases/download/0.4/leanote-linux-v0.4.bin.tar.gz">leanote-linux-v0.4.bin.tar.gz</a> <br />
|
||||
MacOS X : <a href="https://github.com/leanote/leanote/releases/download/0.4/leanote-mac-v0.4.bin.tar.gz">leanote-mac-v0.4.bin.tar.gz</a> <br />
|
||||
<br />
|
||||
<a href="https://github.com/leanote/leanote#3-how-to-install-leanote">{{msg . "howToInstallLeanote"}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="container" id="donate">
|
||||
<h2 style="margin: 20px 0;text-align: center;">{{msg . "donate"}}</h2>
|
||||
<div class="row">
|
||||
@@ -134,6 +119,19 @@ $(function() {
|
||||
var targetOffset = $(t).offset().top - 80;
|
||||
$('html,body').animate({scrollTop: targetOffset}, 300);
|
||||
});
|
||||
|
||||
function setCookie(name, value) {
|
||||
var Days = 10*365;
|
||||
var exp = new Date();
|
||||
exp.setTime(exp.getTime() + Days*24*60*60*1000);
|
||||
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
|
||||
}
|
||||
|
||||
$('#lang a').click(function() {
|
||||
var lang = $(this).data('lang');
|
||||
setCookie('LEANOTE_LANG', lang);
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</style>
|
||||
<section>
|
||||
<div class="header">
|
||||
<h2>leanote, {{msg . "moto"}}</h2>
|
||||
<h2>Leanote, {{msg . "moto"}}</h2>
|
||||
<p>{{msg . "moto3"}}</p>
|
||||
<p>{{msg . "moto2"}}</p>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
|
||||
|
||||
<a class="btn btn-default" href="/demo">{{msg . "try"}}</a>
|
||||
|
||||
|
||||
<a class="btn btn-default" href="/login">{{msg . "login"}}</a>
|
||||
{{if .openRegister}}
|
||||
|
||||
|
||||
OR
|
||||
|
||||
|
||||
<a class="btn btn-default" href="/register">{{msg . "register"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
@@ -64,20 +64,6 @@
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="container" id="download">
|
||||
<h2 style="margin: 20px 0;text-align: center;">{{msg . "download"}}</h2>
|
||||
<div class="row">
|
||||
<div style="width:300px; margin:auto; padding: 10px;">
|
||||
Linux : <a href="https://github.com/leanote/leanote/releases/download/0.4/leanote-linux-v0.4.bin.tar.gz">leanote-linux-v0.4.bin.tar.gz</a> <br />
|
||||
MacOS X : <a href="https://github.com/leanote/leanote/releases/download/0.4/leanote-mac-v0.4.bin.tar.gz">leanote-mac-v0.4.bin.tar.gz</a> <br />
|
||||
<br />
|
||||
<a href="https://github.com/leanote/leanote#3-how-to-install-leanote">{{msg . "howToInstallLeanote"}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="container" id="donate">
|
||||
<h2 style="margin: 20px 0;text-align: center;">{{msg . "donate"}}</h2>
|
||||
<div class="row">
|
||||
@@ -133,6 +119,19 @@ $(function() {
|
||||
var targetOffset = $(t).offset().top - 80;
|
||||
$('html,body').animate({scrollTop: targetOffset}, 300);
|
||||
});
|
||||
|
||||
function setCookie(name, value) {
|
||||
var Days = 10*365;
|
||||
var exp = new Date();
|
||||
exp.setTime(exp.getTime() + Days*24*60*60*1000);
|
||||
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
|
||||
}
|
||||
|
||||
$('#lang a').click(function() {
|
||||
var lang = $(this).data('lang');
|
||||
setCookie('LEANOTE_LANG', lang);
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<a href="/index">{{msg . "home"}}</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="/index">leanote</a> © 2014
|
||||
<a href="/index">leanote</a> © 2014-2015
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<a href="/index">{{msg . "home"}}</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="/index">leanote</a> © 2014
|
||||
<a href="/index">leanote</a> © 2014-2015
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="keywords" content="leanote,leanote.com">
|
||||
<meta name="description" content="leanote, {{msg $ "moto"}}">
|
||||
<meta name="author" content="leanote">
|
||||
|
||||
<title>{{.title}}</title>
|
||||
<link href="{{.siteUrl}}/css/bootstrap.css" rel="stylesheet">
|
||||
<link id="styleLink" href="{{.siteUrl}}/css/toImage.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<h1 class="title">
|
||||
{{.blog.Title}}
|
||||
</h1>
|
||||
<div class="created-time">
|
||||
{{ if .userBlog.Logo}}
|
||||
<img src="{{.userBlog.Logo}}" id="logo">
|
||||
{{else}}
|
||||
<img src="{{$.siteUrl}}/images/blog/default_avatar.png" id="logo">
|
||||
{{end}}
|
||||
{{.userInfo.Username}}
|
||||
|
||||
{{if .blog.Tags}}
|
||||
<img src="{{$.siteUrl}}/images/blog/tag.png" id="tag">
|
||||
{{blogTags .blog.Tags}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div class="desc">
|
||||
{{if .blog.IsMarkdown }}
|
||||
<div id="markdownContent" style="display: none">
|
||||
<!-- 用textarea装html, 防止得到的值失真 -->
|
||||
<textarea>
|
||||
{{.content | raw}}
|
||||
</textarea>
|
||||
</div>
|
||||
<div id="parsedContent">
|
||||
</div>
|
||||
{{else}}
|
||||
{{.content | raw}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<p>
|
||||
{{ if .userBlog.Logo}}
|
||||
<img src="{{.userBlog.Logo}}" id="logo">
|
||||
{{else}}
|
||||
<img src="{{$.siteUrl}}/images/blog/default_avatar.png" id="logo">
|
||||
{{end}}
|
||||
(<a href="#">http://blog.leanote.com/{{.userInfo.Username}}</a>)
|
||||
</p>
|
||||
|
||||
<img src="{{.siteUrl}}/images/logo/leanote_white.png" id="leanote_logo"/>
|
||||
<p>
|
||||
leanote, {{msg $ "moto"}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script src="{{.siteUrl}}/js/jquery-1.9.0.min.js"></script>
|
||||
<script src="{{.siteUrl}}/js/bootstrap-min.js"></script>
|
||||
|
||||
<link href="{{.siteUrl}}/public/mdeditor/editor/google-code-prettify/prettify.css" type="text/css" rel="stylesheet">
|
||||
<script src="{{.siteUrl}}/public/mdeditor/editor/google-code-prettify/prettify.js"></script>
|
||||
<script>
|
||||
$("pre").addClass("prettyprint linenums");
|
||||
prettyPrint();
|
||||
</script>
|
||||
|
||||
{{if .blog.IsMarkdown }}
|
||||
<script src="{{.siteUrl}}/public/mdeditor/editor/google-code-prettify/prettify.js"></script>
|
||||
<script src="{{.siteUrl}}/public/mdeditor/editor/pagedown/Markdown.Converter.js"></script>
|
||||
<script src="{{.siteUrl}}/public/mdeditor/editor/pagedown/Markdown.Sanitizer.js"></script>
|
||||
<script src="{{.siteUrl}}/public/mdeditor/editor/pagedown/Markdown.Editor.js"></script>
|
||||
<script src="{{.siteUrl}}/public/mdeditor/editor/pagedown/local/Markdown.local.zh.js"></script>
|
||||
<script src="{{.siteUrl}}/public/mdeditor/editor/Markdown.Extra.js"></script>
|
||||
|
||||
<!--mathjax-->
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({ tex2jax: { inlineMath: [['$','$'], ["\\(","\\)"]], processEscapes: true }, messageStyle: "none"});
|
||||
</script>
|
||||
<script src="{{.siteUrl}}/public/mdeditor/editor/mathJax.js"></script>
|
||||
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
<script>
|
||||
var content = $.trim($("#markdownContent textarea").val());
|
||||
var converter = Markdown.getSanitizingConverter();
|
||||
Markdown.Extra.init(converter, {extensions: ["tables", "fenced_code_gfm", "def_list"]});
|
||||
var html = converter.makeHtml(content);
|
||||
$("#parsedContent").html(html);
|
||||
$("pre").addClass("prettyprint linenums");
|
||||
prettyPrint();
|
||||
MathJax.Hub.Queue(["Typeset",MathJax.Hub,"wmd-preview"]);
|
||||
</script>
|
||||
{{end}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +0,0 @@
|
||||
lif------------
|
||||
e
|
||||
|
||||
you can
|
||||
@@ -40,23 +40,32 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<style>
|
||||
.mce-btn.mce-active, .mce-btn.mce-active:hover {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
.mce-btn {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
{{template "member/footer.html" .}}
|
||||
<script type="text/javascript" src="/tinymce/tinymce.js"></script>
|
||||
<script>
|
||||
var urlPrefix = "{{.siteUrl}}";
|
||||
var LeaAce = {nowIsInAce: function() {return false;}};
|
||||
$(function() {
|
||||
tinymce.init({
|
||||
selector : "#content1",
|
||||
content_css : [ "/css/bootstrap.css", "/css/editor/editor.css" ],
|
||||
skin : "custom",
|
||||
content_css : ["/css/editor/editor.css" ],
|
||||
theme : "leanote",
|
||||
language : "{{.locale}}",
|
||||
height : 300,
|
||||
width : "100%",
|
||||
skin : "custom",
|
||||
// skin : "custom",
|
||||
plugins : [
|
||||
"advlist autolink link leanote_image lists charmap hr ",
|
||||
"advlist autolink link lists charmap hr ",
|
||||
"searchreplace visualblocks visualchars tabfocus",
|
||||
"table contextmenu directionality textcolor paste fullpage textcolor"],
|
||||
"table contextmenu directionality textcolor fullpage textcolor"],
|
||||
toolbar1 : "formatselect |fontselect fontsizeselect| forecolor backcolor | bold italic underline strikethrough | bullist numlist |",
|
||||
menubar : false,
|
||||
statusbar : false,
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
{{range .myTpls}}
|
||||
<a href="#" class="list-group-item " data-file="{{.}}">
|
||||
<i class="fa fa-remove icon-muted remove-file" title="delete file" ></i>
|
||||
{{.}}
|
||||
<span class="filename" data-filename="{{.}}">{{.}}</span>
|
||||
<span class="badge"></span>
|
||||
</a>
|
||||
{{end}}
|
||||
@@ -123,7 +123,7 @@ var theme = {
|
||||
saveBtnO: $("#saveBtn"),
|
||||
newFileO: $("#newFile"),
|
||||
curTpl: "",
|
||||
tplInfos: {"header.html": "{{msg . "header"}}", "footer.html": "{{msg . "footer"}}", "index.html": "{{msg . "header"}}", "cate.html": "{{msg . "cate"}}", "search.html": "{{msg . "search"}}", "single.html": "{{msg . "single"}}", "archive.html": "{{msg . "archive"}}", "post.html": "{{msg . "post"}}", "tags.html": "{{msg . "tags"}}", "tag_posts.html": "{{msg . "tag_posts"}}", "share_comment.html": "{{msg . "share_comment"}}", "404.html":"404", "theme.json": "{{msg . "themeJson"}}", "paging.html": "{{msg . "paging"}}", "highlight.html": "{{msg . "highlight"}}"},
|
||||
tplInfos: {"header.html": "{{msg . "header"}}", "footer.html": "{{msg . "footer"}}", "index.html": "{{msg . "index"}}", "cate.html": "{{msg . "cate"}}", "search.html": "{{msg . "search"}}", "single.html": "{{msg . "single"}}", "archive.html": "{{msg . "archive"}}", "post.html": "{{msg . "post"}}", "tags.html": "{{msg . "tags"}}", "tag_posts.html": "{{msg . "tag_posts"}}", "share_comment.html": "{{msg . "share_comment"}}", "404.html":"404", "theme.json": "{{msg . "themeJson"}}", "paging.html": "{{msg . "paging"}}", "highlight.html": "{{msg . "highlight"}}"},
|
||||
init: function() {
|
||||
var self = this;
|
||||
self.showTplInfo();
|
||||
@@ -171,12 +171,22 @@ var theme = {
|
||||
newFile: function() {
|
||||
var self = this;
|
||||
self.newFileO.click(function() {
|
||||
art.prompt("文件名", function(file){
|
||||
// 文件是否存在?
|
||||
|
||||
|
||||
art.prompt("Filename", function(file) {
|
||||
if(!file) {
|
||||
return;
|
||||
}
|
||||
var t = '<a href="#" class="list-group-item " data-file="' + file + '"> <i class="fa fa-remove icon-muted remove-file" title="delete file" ></i> ' + file + '<span class="badge"></span></a>';
|
||||
if($('[data-filename="' + file + '"]').length > 0) {
|
||||
art.alert('File exists');
|
||||
return;
|
||||
}
|
||||
var t = $('<a href="#" class="list-group-item " data-file="' + file + '"> <i class="fa fa-remove icon-muted remove-file" title="delete file" ></i> <span class="filename" data-filename="' + file + '">' + file + '</span><span class="badge"></span></a>');
|
||||
$(".file-list").append(t);
|
||||
self.cache[file] = "";
|
||||
// trigger click, 选中之
|
||||
t.click();
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -206,6 +216,9 @@ var theme = {
|
||||
var content = editor.getValue()
|
||||
|
||||
var filename = self.curTpl;
|
||||
if(!filename) {
|
||||
return;
|
||||
}
|
||||
// 之前的内容是否有改动
|
||||
if(self.cache[filename] == content) {
|
||||
return;
|
||||
@@ -234,7 +247,7 @@ var theme = {
|
||||
renderContent: function(name, content) {
|
||||
var self = this;
|
||||
self.curTplO.html(name);
|
||||
self.curTpl = name; // 这里设计
|
||||
self.curTpl = name; // 这里才设置
|
||||
var lang = "html";
|
||||
if(name.indexOf(".js") > 0 || name.indexOf(".json") > 0) {
|
||||
lang = "javascript";
|
||||
@@ -251,8 +264,8 @@ var theme = {
|
||||
renderTpl: function(name) {
|
||||
var self = this;
|
||||
var content = "";
|
||||
self.curTpl = name; // 这里设置
|
||||
if(self.cache[name]) {
|
||||
self.curTpl = ""; // 这里设置为空
|
||||
if(self.cache[name] != undefined) {
|
||||
content = self.cache[name];
|
||||
self.renderContent(name, content);
|
||||
return;
|
||||
@@ -264,6 +277,7 @@ var theme = {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//-----------------
|
||||
// theme images
|
||||
imageListO: $("#imageList"),
|
||||
|
||||
+130
-109
@@ -7,8 +7,8 @@
|
||||
<meta name="apple-touch-fullscreen" content="yes">
|
||||
<meta name=”apple-mobile-web-app-capable” content=”yes” />
|
||||
<meta name="keywords" content="leanote,leanote.com">
|
||||
<meta name="description" content="leanote, Not Just A Notebook">
|
||||
<title>leanote, Not Just A Notebook</title>
|
||||
<meta name="description" content="Leanote, {{msg $ "moto"}}">
|
||||
<title>Leanote, {{msg $ "moto"}}</title>
|
||||
|
||||
<link href="/css/bootstrap.css" rel="stylesheet" />
|
||||
<!-- 先加载, 没有样式, 宽度不定 -->
|
||||
@@ -18,13 +18,15 @@
|
||||
<link href="/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" />
|
||||
<!-- mdeditor -->
|
||||
<link href="/public/dist/themes/default.css" rel="stylesheet" />
|
||||
<!-- context-menu -->
|
||||
<link rel="stylesheet" href="/js/contextmenu/css/contextmenu.css" type="text/css" />
|
||||
|
||||
<script>
|
||||
var hash = location.hash;
|
||||
if(hash.indexOf("writing") >= 0) {
|
||||
var files = '<link rel="stylesheet" href="/css/theme/writting-overwrite.css" type="text/css" id="themeLink" />';
|
||||
} else {
|
||||
var files ='<link rel="stylesheet" href="/css/theme/{{if .userInfo.Theme}}{{.userInfo.Theme}}{{else}}default{{end}}.css" type="text/css" id="themeLink" />';
|
||||
var files ='<link rel="stylesheet" href="/css/theme/{{if .userInfo.Theme}}{{.userInfo.Theme}}{{else}}default{{end}}.css?t=3" type="text/css" id="themeLink" />';
|
||||
}
|
||||
document.write(files);
|
||||
</script>
|
||||
@@ -60,7 +62,7 @@ function log(o) {
|
||||
<!-- search -->
|
||||
<div class="pull-left" id="searchWrap">
|
||||
<form class="navbar-form form-inline col-lg-2" id="searchNote">
|
||||
<input class="form-control" placeholder="Search" type="text" id="searchNoteInput">
|
||||
<input class="form-control" placeholder="{{msg . "SearchNote"}}" type="text" id="searchNoteInput">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -68,14 +70,15 @@ function log(o) {
|
||||
<div class="pull-left" style="" id="newNoteWrap">
|
||||
<!-- 新建笔记 -->
|
||||
<div id="newMyNote">
|
||||
<a id="newNoteBtn" title="{{msg . "newNote"}}">
|
||||
<i class="fa fa-file-o"></i>
|
||||
<a class="new-note" id="newNoteBtn" title="{{msg . "newNote"}}">
|
||||
<!--<i class="fa fa-file-o"></i>-->
|
||||
<span class="new-note-text">{{msg . "newNote"}}</span>
|
||||
<span class="new-note-text-abbr">{{msg . "new"}}</span>
|
||||
</a>
|
||||
<span class="new-split">|</span>
|
||||
<a id="newNoteMarkdownBtn" title="{{msg . "newMarkdown"}}">
|
||||
<span class="new-markdown-text">Markdown</span>
|
||||
<a class="new-note new-markdown" id="newNoteMarkdownBtn" title="{{msg . "newMarkdown"}}">
|
||||
<!-- <i class="lea-icon icon-markdown"></i> -->
|
||||
<span class="new-markdown-text">{{msg . "newMarkdown"}}</span>
|
||||
<span class="new-markdown-text-abbr">Md</span>
|
||||
</a>
|
||||
<span class="for-split"> - </span>
|
||||
@@ -86,7 +89,7 @@ function log(o) {
|
||||
<i class="fa fa-angle-down"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-list" id="searchNotebookForAddDropdownList">
|
||||
<input type="text" placeholder="Search notebook" class="form-control" id="searchNotebookForAdd"/>
|
||||
<input type="text" placeholder="{{msg . "SearchNotebook"}}" class="form-control" id="searchNotebookForAdd"/>
|
||||
<ul class="clearfix" role="menu" aria-labelledby="listNotebookDropdownMenu" id="notebookNavForNewNote">
|
||||
</ul>
|
||||
</div>
|
||||
@@ -95,14 +98,14 @@ function log(o) {
|
||||
|
||||
<!-- 只为新建别人的笔记 -->
|
||||
<div id="newSharedNote" style="display: none">
|
||||
<a id="newSharedNoteBtn">
|
||||
<i class="fa fa-file-o"></i>
|
||||
<a id="newSharedNoteBtn" class="new-note">
|
||||
<!--<i class="fa fa-file-o"></i> -->
|
||||
<span class="new-note-text">{{msg . "newNote"}}</span>
|
||||
<span class="new-note-text-abbr">{{msg . "new"}}</span>
|
||||
</a>
|
||||
<span class="new-split">|</span>
|
||||
<a id="newShareNoteMarkdownBtn" title="{{msg . "newMarkdown"}}">
|
||||
<span class="new-markdown-text">Markdown</span>
|
||||
<a id="newShareNoteMarkdownBtn" class="new-note" title="{{msg . "newMarkdown"}}">
|
||||
<span class="new-markdown-text">{{msg . "newMarkdown"}}</span>
|
||||
<span class="new-markdown-text-abbr">Md</span>
|
||||
</a>
|
||||
<span class="for-split"> - </span>
|
||||
@@ -186,13 +189,11 @@ function log(o) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="pull-right top-nav writting-hide lea-blog">
|
||||
<a target="_blank" href="http://lea.leanote.com">
|
||||
lea++
|
||||
</a>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="pull-right top-nav writting-hide" id="myBlog">
|
||||
<a target="_blank" href="{{$.blogUrl}}/{{.userInfo.Username}}">
|
||||
@@ -269,7 +270,7 @@ function log(o) {
|
||||
</div>
|
||||
|
||||
<div class="folderBody">
|
||||
<input type="text" class="form-control" id="searchNotebookForList" placeholder="Search notebook"/>
|
||||
<input type="text" class="form-control" id="searchNotebookForList" placeholder="{{msg . "SearchNotebook"}}"/>
|
||||
<ul class="ztree" id="notebookList"></ul>
|
||||
<ul class="ztree" id="notebookListForSearch"></ul>
|
||||
</div>
|
||||
@@ -416,29 +417,7 @@ function log(o) {
|
||||
<div class="noteSplit" id="noteSplitter"></div>
|
||||
|
||||
<div id="note">
|
||||
<!-- 只读模式 -->
|
||||
<div id="noteRead">
|
||||
<div id="noteReadContainer">
|
||||
<div id="noteReadTop">
|
||||
<h2 id="noteReadTitle"></h2>
|
||||
<div class="clearfix" id="noteReadInfo">
|
||||
<i class="fa fa-bookmark-o"></i>
|
||||
<span id="noteReadTags"></span>
|
||||
|
||||
<!-- 修改时间 -->
|
||||
<i class="fa fa-clock-o"></i>{{msg . "update"}}
|
||||
<span id="noteReadUpdatedTime"></span>
|
||||
|
||||
<!-- 修改时间 -->
|
||||
<i class="fa fa-clock-o"></i>{{msg . "create"}}
|
||||
<span id="noteReadCreatedTime"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="noteReadContent">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 遮罩, 为了resize3Columns用 -->
|
||||
<div id="noteMask" class="note-mask"></div>
|
||||
<div id="noteMaskForLoading" class="note-mask">
|
||||
@@ -546,17 +525,38 @@ function log(o) {
|
||||
<div id="noteTitleDiv">
|
||||
<input name="noteTitle" id="noteTitle" value="" placeholder="{{msg . "unTitled"}}" tabindex="1" />
|
||||
</div>
|
||||
|
||||
<!-- 只读时 -->
|
||||
<div id="noteReadTop">
|
||||
<h2 id="noteReadTitle"></h2>
|
||||
<div class="clearfix" id="noteReadInfo">
|
||||
<i class="fa fa-bookmark-o"></i>
|
||||
<span id="noteReadTags"></span>
|
||||
|
||||
<!-- 修改时间 -->
|
||||
<i class="fa fa-clock-o"></i> {{msg . "update"}}
|
||||
<span id="noteReadUpdatedTime"></span>
|
||||
|
||||
<!-- 修改时间 -->
|
||||
<i class="fa fa-clock-o"></i> {{msg . "create"}}
|
||||
<span id="noteReadCreatedTime"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="editor">
|
||||
<div id="editor" class="read-only">
|
||||
<!-- 编辑器 -->
|
||||
<div id="mceToolbar">
|
||||
<div id="popularToolbar"
|
||||
style="position: absolute; right: 30px; left: 0"></div>
|
||||
<a
|
||||
style="dispaly: block; position: absolute; cursor: pointer; right: 10px; padding: 3px 10px"
|
||||
id="moreBtn"> <i class="fa fa-angle-down"></i>
|
||||
</a>
|
||||
<div id="mceToolbarContainer">
|
||||
<div id="popularToolbar" style="position: absolute; right: 30px; left: 0"></div>
|
||||
<a id="moreBtn"> <i class="fa more-fa"></i></a>
|
||||
</div>
|
||||
<!-- 查看信息 -->
|
||||
<div id="infoToolbar" class="info-toolbar invisible">
|
||||
<a class="toolbar-update"><i class="fa fa-pencil"></i> <span class="lang">{{msg . "modify"}}</span></a>
|
||||
<span class="lang">{{msg . "created"}}</span>: <span class="created-time"></span>
|
||||
<span class="lang">{{msg . "updated"}}</span>: <span class="updated-time"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editorBg"></div>
|
||||
<div id="leanoteNav" class="leanoteNav">
|
||||
@@ -584,50 +584,56 @@ function log(o) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="mdEditor">
|
||||
|
||||
|
||||
<div id="mdEditor" class="read-only">
|
||||
<div class="layout-wrapper-l1">
|
||||
<div class="layout-wrapper-l2">
|
||||
<div class="navbar navbar-default">
|
||||
<div class="navbar-inner" id="wmd-button-bar">
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group1 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group2 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group3 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group5 btn-group"></li>
|
||||
</ul>
|
||||
<!-- 帮助 -->
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group6 btn-group">
|
||||
<li class="wmd-button btn btn-success" id="wmd-help-button" title="Markdown syntax" style="left: 0px; display: none;"><span style="display: none; background-position: 0px 0px;"></span><i class="fa fa-question-circle"></i></li>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
<ul class="nav pull-right right-buttons">
|
||||
<li class="offline-status hide">
|
||||
<div class="text-danger">
|
||||
<i class="icon-attention-circled"></i>offline
|
||||
</div>
|
||||
</li>
|
||||
<li class="extension-buttons"></li>
|
||||
</ul>
|
||||
<ul class="nav pull-right title-container">
|
||||
<li><div class="working-indicator"></div></li>
|
||||
<li><a class="btn btn-success file-title-navbar" href="#"
|
||||
title="Rename document"> </a></li>
|
||||
<li><div class="input-file-title-container"><input type="text"
|
||||
class="col-sm-4 form-control hide input-file-title"
|
||||
placeholder="Document title" /></div></li>
|
||||
</ul>
|
||||
-->
|
||||
<div id="mdInfoToolbar" class="info-toolbar invisible">
|
||||
<a class="toolbar-update"><i class="fa fa-pencil"></i> <span class="lang">{{msg . "modify"}}</span></a>
|
||||
<span class="lang">{{msg . "created"}}</span>: <span class="created-time"></span>
|
||||
<span class="lang">{{msg . "updated"}}</span>: <span class="updated-time"></span>
|
||||
</div>
|
||||
|
||||
<div class="wmd-button-bar-inner">
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group1 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group2 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group3 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group5 btn-group"></li>
|
||||
</ul>
|
||||
<!-- 帮助 -->
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group6 btn-group">
|
||||
<li class="wmd-button btn btn-success" id="wmd-help-button" title="Markdown syntax" style="left: 0px; display: none;"><span style="display: none; background-position: 0px 0px;"></span><i class="fa fa-question-circle"></i></li>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
<ul class="nav pull-right right-buttons">
|
||||
<li class="offline-status hide">
|
||||
<div class="text-danger">
|
||||
<i class="icon-attention-circled"></i>offline
|
||||
</div>
|
||||
</li>
|
||||
<li class="extension-buttons"></li>
|
||||
</ul>
|
||||
<ul class="nav pull-right title-container">
|
||||
<li><div class="working-indicator"></div></li>
|
||||
<li><a class="btn btn-success file-title-navbar" href="#"
|
||||
title="Rename document"> </a></li>
|
||||
<li><div class="input-file-title-container"><input type="text"
|
||||
class="col-sm-4 form-control hide input-file-title"
|
||||
placeholder="Document title" /></div></li>
|
||||
</ul>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="editorBg"></div>
|
||||
</div>
|
||||
@@ -876,12 +882,12 @@ function log(o) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/jquery-1.9.0.min.js"></script>
|
||||
<script src="/js/jquery.ztree.all-3.5.js"></script>
|
||||
<script src="/js/i18n/msg.{{.locale}}.js"></script>
|
||||
<script src="/js/common.js"></script>
|
||||
|
||||
<script>
|
||||
var UrlPrefix = '{{.siteUrl}}'; // 为了发weibo
|
||||
var LEA = {};
|
||||
LEA.s1 = new Date();
|
||||
LEA.locale = "{{.locale}}";
|
||||
var UrlPrefix = '{{.siteUrl}}';
|
||||
var UserInfo = {{.userInfo|jsonJs}};
|
||||
var notebooks = {{.notebooks|jsonJs}};
|
||||
var shareNotebooks = {{.shareNotebooks|jsonJs}};
|
||||
@@ -894,38 +900,53 @@ var notes = {{.notes|jsonJs}};
|
||||
var latestNotes = {{if .latestNotes}}{{.latestNotes|jsonJs}}{{else}}[]{{end}};
|
||||
var noteContentJson = {{.noteContentJson|jsonJs}};
|
||||
var tagsJson = {{.tags|jsonJs}};
|
||||
LEA.locale = "{{.locale}}";
|
||||
var GlobalConfigs = {{.globalConfigs|jsonJs}}; // 2014/11/9 beta2
|
||||
var GlobalConfigs = {{.globalConfigs|jsonJs}};
|
||||
<!-- pro_tinymce_init_js -->
|
||||
</script>
|
||||
|
||||
<!-- 渲染view -->
|
||||
<script src="/tinymce/tinymce.js"></script>
|
||||
<script src="/js/i18n/msg.{{.locale}}.js"></script>
|
||||
|
||||
<!-- pro_dep_js -->
|
||||
|
||||
<!-- dev -->
|
||||
<script src="/js/jquery-1.9.0.min.js"></script>
|
||||
<script src="/js/jquery.ztree.all-3.5.js"></script>
|
||||
<script src="/js/object_id-min.js"></script>
|
||||
<script src="/public/tinymce/tinymce.js"></script>
|
||||
<!-- /dev -->
|
||||
|
||||
<script src="/public/libs/ace/ace.js"></script>
|
||||
<script src="/js/app/page.js"></script>
|
||||
|
||||
<!-- dev -->
|
||||
<script src="/js/jQuery-slimScroll-1.3.0/jquery.slimscroll.js"></script>
|
||||
<script src="/js/contextmenu/jquery.contextmenu.js"></script>
|
||||
<script src="/js/common.js"></script>
|
||||
<script src="/js/bootstrap-min.js"></script>
|
||||
<script src="/js/app/note.js"></script>
|
||||
<script src="/js/app/tag.js"></script>
|
||||
<script src="/js/app/notebook.js"></script>
|
||||
<script src="/js/app/share.js"></script>
|
||||
<script src="/js/object_id-min.js"></script>
|
||||
<script src="/js/app/page.js?t=1"></script>
|
||||
<!-- /dev -->
|
||||
|
||||
<!-- pro_app_js -->
|
||||
|
||||
<script>
|
||||
initPage();
|
||||
</script>
|
||||
|
||||
<!-- context-menu -->
|
||||
<link rel="stylesheet" href="/js/contextmenu/css/contextmenu.css" type="text/css" />
|
||||
|
||||
<!-- v2 use require.js, mdeditor -->
|
||||
<script>
|
||||
window.baseDir = '/public/dist';
|
||||
// 当tinymce.dev.js时, 请注释require
|
||||
window.require = {
|
||||
baseUrl: window.baseDir,
|
||||
deps: ['main']
|
||||
baseUrl: '/public',
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- pro_markdown_js -->
|
||||
|
||||
<!-- dev -->
|
||||
<script src="/js/require.js"></script>
|
||||
</script>
|
||||
<script src="/public/dist/main.min.js"></script>
|
||||
<!-- /dev -->
|
||||
|
||||
<script src="/public/js/upload_paste/main.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
+120
-117
@@ -7,8 +7,8 @@
|
||||
<meta name="apple-touch-fullscreen" content="yes">
|
||||
<meta name=”apple-mobile-web-app-capable” content=”yes” />
|
||||
<meta name="keywords" content="leanote,leanote.com">
|
||||
<meta name="description" content="leanote, Not Just A Notebook">
|
||||
<title>leanote, Not Just A Notebook</title>
|
||||
<meta name="description" content="Leanote, {{msg $ "moto"}}">
|
||||
<title>Leanote, {{msg $ "moto"}}</title>
|
||||
|
||||
<link href="/css/bootstrap.css" rel="stylesheet" />
|
||||
<!-- 先加载, 没有样式, 宽度不定 -->
|
||||
@@ -18,13 +18,15 @@
|
||||
<link href="/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" />
|
||||
<!-- mdeditor -->
|
||||
<link href="/public/dist/themes/default.css" rel="stylesheet" />
|
||||
<!-- context-menu -->
|
||||
<link rel="stylesheet" href="/js/contextmenu/css/contextmenu.css" type="text/css" />
|
||||
|
||||
<script>
|
||||
var hash = location.hash;
|
||||
if(hash.indexOf("writing") >= 0) {
|
||||
var files = '<link rel="stylesheet" href="/css/theme/writting-overwrite.css" type="text/css" id="themeLink" />';
|
||||
} else {
|
||||
var files ='<link rel="stylesheet" href="/css/theme/{{if .userInfo.Theme}}{{.userInfo.Theme}}{{else}}default{{end}}.css" type="text/css" id="themeLink" />';
|
||||
var files ='<link rel="stylesheet" href="/css/theme/{{if .userInfo.Theme}}{{.userInfo.Theme}}{{else}}default{{end}}.css?t=3" type="text/css" id="themeLink" />';
|
||||
}
|
||||
document.write(files);
|
||||
</script>
|
||||
@@ -60,7 +62,7 @@ function log(o) {
|
||||
<!-- search -->
|
||||
<div class="pull-left" id="searchWrap">
|
||||
<form class="navbar-form form-inline col-lg-2" id="searchNote">
|
||||
<input class="form-control" placeholder="Search" type="text" id="searchNoteInput">
|
||||
<input class="form-control" placeholder="{{msg . "SearchNote"}}" type="text" id="searchNoteInput">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -68,14 +70,15 @@ function log(o) {
|
||||
<div class="pull-left" style="" id="newNoteWrap">
|
||||
<!-- 新建笔记 -->
|
||||
<div id="newMyNote">
|
||||
<a id="newNoteBtn" title="{{msg . "newNote"}}">
|
||||
<i class="fa fa-file-o"></i>
|
||||
<a class="new-note" id="newNoteBtn" title="{{msg . "newNote"}}">
|
||||
<!--<i class="fa fa-file-o"></i>-->
|
||||
<span class="new-note-text">{{msg . "newNote"}}</span>
|
||||
<span class="new-note-text-abbr">{{msg . "new"}}</span>
|
||||
</a>
|
||||
<span class="new-split">|</span>
|
||||
<a id="newNoteMarkdownBtn" title="{{msg . "newMarkdown"}}">
|
||||
<span class="new-markdown-text">Markdown</span>
|
||||
<a class="new-note new-markdown" id="newNoteMarkdownBtn" title="{{msg . "newMarkdown"}}">
|
||||
<!-- <i class="lea-icon icon-markdown"></i> -->
|
||||
<span class="new-markdown-text">{{msg . "newMarkdown"}}</span>
|
||||
<span class="new-markdown-text-abbr">Md</span>
|
||||
</a>
|
||||
<span class="for-split"> - </span>
|
||||
@@ -86,7 +89,7 @@ function log(o) {
|
||||
<i class="fa fa-angle-down"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-list" id="searchNotebookForAddDropdownList">
|
||||
<input type="text" placeholder="Search notebook" class="form-control" id="searchNotebookForAdd"/>
|
||||
<input type="text" placeholder="{{msg . "SearchNotebook"}}" class="form-control" id="searchNotebookForAdd"/>
|
||||
<ul class="clearfix" role="menu" aria-labelledby="listNotebookDropdownMenu" id="notebookNavForNewNote">
|
||||
</ul>
|
||||
</div>
|
||||
@@ -95,14 +98,14 @@ function log(o) {
|
||||
|
||||
<!-- 只为新建别人的笔记 -->
|
||||
<div id="newSharedNote" style="display: none">
|
||||
<a id="newSharedNoteBtn">
|
||||
<i class="fa fa-file-o"></i>
|
||||
<a id="newSharedNoteBtn" class="new-note">
|
||||
<!--<i class="fa fa-file-o"></i> -->
|
||||
<span class="new-note-text">{{msg . "newNote"}}</span>
|
||||
<span class="new-note-text-abbr">{{msg . "new"}}</span>
|
||||
</a>
|
||||
<span class="new-split">|</span>
|
||||
<a id="newShareNoteMarkdownBtn" title="{{msg . "newMarkdown"}}">
|
||||
<span class="new-markdown-text">Markdown</span>
|
||||
<a id="newShareNoteMarkdownBtn" class="new-note" title="{{msg . "newMarkdown"}}">
|
||||
<span class="new-markdown-text">{{msg . "newMarkdown"}}</span>
|
||||
<span class="new-markdown-text-abbr">Md</span>
|
||||
</a>
|
||||
<span class="for-split"> - </span>
|
||||
@@ -186,13 +189,11 @@ function log(o) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="pull-right top-nav writting-hide lea-blog">
|
||||
<a target="_blank" href="http://lea.leanote.com">
|
||||
lea++
|
||||
</a>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="pull-right top-nav writting-hide" id="myBlog">
|
||||
<a target="_blank" href="{{$.blogUrl}}/{{.userInfo.Username}}">
|
||||
@@ -269,7 +270,7 @@ function log(o) {
|
||||
</div>
|
||||
|
||||
<div class="folderBody">
|
||||
<input type="text" class="form-control" id="searchNotebookForList" placeholder="Search notebook"/>
|
||||
<input type="text" class="form-control" id="searchNotebookForList" placeholder="{{msg . "SearchNotebook"}}"/>
|
||||
<ul class="ztree" id="notebookList"></ul>
|
||||
<ul class="ztree" id="notebookListForSearch"></ul>
|
||||
</div>
|
||||
@@ -416,29 +417,7 @@ function log(o) {
|
||||
<div class="noteSplit" id="noteSplitter"></div>
|
||||
|
||||
<div id="note">
|
||||
<!-- 只读模式 -->
|
||||
<div id="noteRead">
|
||||
<div id="noteReadContainer">
|
||||
<div id="noteReadTop">
|
||||
<h2 id="noteReadTitle"></h2>
|
||||
<div class="clearfix" id="noteReadInfo">
|
||||
<i class="fa fa-bookmark-o"></i>
|
||||
<span id="noteReadTags"></span>
|
||||
|
||||
<!-- 修改时间 -->
|
||||
<i class="fa fa-clock-o"></i>{{msg . "update"}}
|
||||
<span id="noteReadUpdatedTime"></span>
|
||||
|
||||
<!-- 修改时间 -->
|
||||
<i class="fa fa-clock-o"></i>{{msg . "create"}}
|
||||
<span id="noteReadCreatedTime"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="noteReadContent">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 遮罩, 为了resize3Columns用 -->
|
||||
<div id="noteMask" class="note-mask"></div>
|
||||
<div id="noteMaskForLoading" class="note-mask">
|
||||
@@ -546,17 +525,38 @@ function log(o) {
|
||||
<div id="noteTitleDiv">
|
||||
<input name="noteTitle" id="noteTitle" value="" placeholder="{{msg . "unTitled"}}" tabindex="1" />
|
||||
</div>
|
||||
|
||||
<!-- 只读时 -->
|
||||
<div id="noteReadTop">
|
||||
<h2 id="noteReadTitle"></h2>
|
||||
<div class="clearfix" id="noteReadInfo">
|
||||
<i class="fa fa-bookmark-o"></i>
|
||||
<span id="noteReadTags"></span>
|
||||
|
||||
<!-- 修改时间 -->
|
||||
<i class="fa fa-clock-o"></i> {{msg . "update"}}
|
||||
<span id="noteReadUpdatedTime"></span>
|
||||
|
||||
<!-- 修改时间 -->
|
||||
<i class="fa fa-clock-o"></i> {{msg . "create"}}
|
||||
<span id="noteReadCreatedTime"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="editor">
|
||||
<div id="editor" class="read-only">
|
||||
<!-- 编辑器 -->
|
||||
<div id="mceToolbar">
|
||||
<div id="popularToolbar"
|
||||
style="position: absolute; right: 30px; left: 0"></div>
|
||||
<a
|
||||
style="dispaly: block; position: absolute; cursor: pointer; right: 10px; padding: 3px 10px"
|
||||
id="moreBtn"> <i class="fa fa-angle-down"></i>
|
||||
</a>
|
||||
<div id="mceToolbarContainer">
|
||||
<div id="popularToolbar" style="position: absolute; right: 30px; left: 0"></div>
|
||||
<a id="moreBtn"> <i class="fa more-fa"></i></a>
|
||||
</div>
|
||||
<!-- 查看信息 -->
|
||||
<div id="infoToolbar" class="info-toolbar invisible">
|
||||
<a class="toolbar-update"><i class="fa fa-pencil"></i> <span class="lang">{{msg . "modify"}}</span></a>
|
||||
<span class="lang">{{msg . "created"}}</span>: <span class="created-time"></span>
|
||||
<span class="lang">{{msg . "updated"}}</span>: <span class="updated-time"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editorBg"></div>
|
||||
<div id="leanoteNav" class="leanoteNav">
|
||||
@@ -584,50 +584,56 @@ function log(o) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="mdEditor">
|
||||
|
||||
|
||||
<div id="mdEditor" class="read-only">
|
||||
<div class="layout-wrapper-l1">
|
||||
<div class="layout-wrapper-l2">
|
||||
<div class="navbar navbar-default">
|
||||
<div class="navbar-inner" id="wmd-button-bar">
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group1 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group2 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group3 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group5 btn-group"></li>
|
||||
</ul>
|
||||
<!-- 帮助 -->
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group6 btn-group">
|
||||
<li class="wmd-button btn btn-success" id="wmd-help-button" title="Markdown syntax" style="left: 0px; display: none;"><span style="display: none; background-position: 0px 0px;"></span><i class="fa fa-question-circle"></i></li>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
<ul class="nav pull-right right-buttons">
|
||||
<li class="offline-status hide">
|
||||
<div class="text-danger">
|
||||
<i class="icon-attention-circled"></i>offline
|
||||
</div>
|
||||
</li>
|
||||
<li class="extension-buttons"></li>
|
||||
</ul>
|
||||
<ul class="nav pull-right title-container">
|
||||
<li><div class="working-indicator"></div></li>
|
||||
<li><a class="btn btn-success file-title-navbar" href="#"
|
||||
title="Rename document"> </a></li>
|
||||
<li><div class="input-file-title-container"><input type="text"
|
||||
class="col-sm-4 form-control hide input-file-title"
|
||||
placeholder="Document title" /></div></li>
|
||||
</ul>
|
||||
-->
|
||||
<div id="mdInfoToolbar" class="info-toolbar invisible">
|
||||
<a class="toolbar-update"><i class="fa fa-pencil"></i> <span class="lang">{{msg . "modify"}}</span></a>
|
||||
<span class="lang">{{msg . "created"}}</span>: <span class="created-time"></span>
|
||||
<span class="lang">{{msg . "updated"}}</span>: <span class="updated-time"></span>
|
||||
</div>
|
||||
|
||||
<div class="wmd-button-bar-inner">
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group1 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group2 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group3 btn-group"></li>
|
||||
</ul>
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group5 btn-group"></li>
|
||||
</ul>
|
||||
<!-- 帮助 -->
|
||||
<ul class="nav left-buttons">
|
||||
<li class="wmd-button-group6 btn-group">
|
||||
<li class="wmd-button btn btn-success" id="wmd-help-button" title="Markdown syntax" style="left: 0px; display: none;"><span style="display: none; background-position: 0px 0px;"></span><i class="fa fa-question-circle"></i></li>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
<ul class="nav pull-right right-buttons">
|
||||
<li class="offline-status hide">
|
||||
<div class="text-danger">
|
||||
<i class="icon-attention-circled"></i>offline
|
||||
</div>
|
||||
</li>
|
||||
<li class="extension-buttons"></li>
|
||||
</ul>
|
||||
<ul class="nav pull-right title-container">
|
||||
<li><div class="working-indicator"></div></li>
|
||||
<li><a class="btn btn-success file-title-navbar" href="#"
|
||||
title="Rename document"> </a></li>
|
||||
<li><div class="input-file-title-container"><input type="text"
|
||||
class="col-sm-4 form-control hide input-file-title"
|
||||
placeholder="Document title" /></div></li>
|
||||
</ul>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="editorBg"></div>
|
||||
</div>
|
||||
@@ -876,12 +882,12 @@ function log(o) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/jquery-1.9.0.min.js"></script>
|
||||
<script src="/js/jquery.ztree.all-3.5-min.js"></script>
|
||||
<script src="/js/i18n/msg.{{.locale}}.js"></script>
|
||||
<script src="/js/common-min.js"></script>
|
||||
|
||||
<script>
|
||||
var UrlPrefix = '{{.siteUrl}}'; // 为了发weibo
|
||||
var LEA = {};
|
||||
LEA.s1 = new Date();
|
||||
LEA.locale = "{{.locale}}";
|
||||
var UrlPrefix = '{{.siteUrl}}';
|
||||
var UserInfo = {{.userInfo|jsonJs}};
|
||||
var notebooks = {{.notebooks|jsonJs}};
|
||||
var shareNotebooks = {{.shareNotebooks|jsonJs}};
|
||||
@@ -894,38 +900,35 @@ var notes = {{.notes|jsonJs}};
|
||||
var latestNotes = {{if .latestNotes}}{{.latestNotes|jsonJs}}{{else}}[]{{end}};
|
||||
var noteContentJson = {{.noteContentJson|jsonJs}};
|
||||
var tagsJson = {{.tags|jsonJs}};
|
||||
LEA.locale = "{{.locale}}";
|
||||
var GlobalConfigs = {{.globalConfigs|jsonJs}}; // 2014/11/9 beta2
|
||||
var GlobalConfigs = {{.globalConfigs|jsonJs}};
|
||||
var tinyMCEPreInit = {base: '/public/tinymce', suffix: '.min'};
|
||||
</script>
|
||||
|
||||
<!-- 渲染view -->
|
||||
<script src="/tinymce/tinymce.min.js"></script>
|
||||
<script src="/js/i18n/msg.{{.locale}}.js"></script>
|
||||
|
||||
<script src="/js/dep.min.js"></script>
|
||||
|
||||
|
||||
|
||||
<script src="/public/libs/ace/ace.js"></script>
|
||||
<script src="/js/app/page-min.js"></script>
|
||||
<script src="/js/jQuery-slimScroll-1.3.0/jquery.slimscroll-min.js"></script>
|
||||
<script src="/js/contextmenu/jquery.contextmenu-min.js"></script>
|
||||
<script src="/js/bootstrap-min.js"></script>
|
||||
<script src="/js/app/note-min.js"></script>
|
||||
<script src="/js/app/tag-min.js"></script>
|
||||
<script src="/js/app/notebook-min.js"></script>
|
||||
<script src="/js/app/share-min.js"></script>
|
||||
<script src="/js/object_id-min.js"></script>
|
||||
|
||||
|
||||
|
||||
<script src="/js/app.min.js"></script>
|
||||
|
||||
<script>
|
||||
initPage();
|
||||
</script>
|
||||
|
||||
<!-- context-menu -->
|
||||
<link rel="stylesheet" href="/js/contextmenu/css/contextmenu.css" type="text/css" />
|
||||
|
||||
<!-- v2 use require.js, mdeditor -->
|
||||
<script>
|
||||
window.baseDir = '/public/dist';
|
||||
// 当tinymce.dev.js时, 请注释require
|
||||
window.require = {
|
||||
baseUrl: window.baseDir,
|
||||
deps: ['main']
|
||||
baseUrl: '/public',
|
||||
};
|
||||
</script>
|
||||
<script src="/js/require.js"></script>
|
||||
</script>
|
||||
|
||||
<script src="/js/markdown.min.js"></script>
|
||||
|
||||
|
||||
|
||||
<script src="/public/js/upload_paste/main.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -1,32 +0,0 @@
|
||||
{{template "home/header_box.html" .}}
|
||||
|
||||
<section id="box" class="animated fadeInUp">
|
||||
<div>
|
||||
<h1 id="logo">leanote</h1>
|
||||
<div id="boxForm">
|
||||
<div id="boxHeader">We got a error</div>
|
||||
<form>
|
||||
<div class="alert alert-danger" id="loginMsg" style="display: block">
|
||||
Sorry, we can't get your infomation.
|
||||
|
||||
<br />
|
||||
Please <a href="/login">{{msg . "login"}}</a> Or <a href="/register?email={{.email}}">{{msg . "register"}}</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div id="boxFooter">
|
||||
<p>
|
||||
<a href="/login">{{msg . "login"}}</a>
|
||||
|
||||
<a href="/index">{{msg . "home"}}</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="/index">leanote</a> © 2014
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+101
-39
@@ -2,40 +2,85 @@
|
||||
|
||||
# release leanote
|
||||
|
||||
# 当前路径
|
||||
SP=$(cd "$(dirname "$0")"; pwd)
|
||||
|
||||
cd $SP
|
||||
cd ../
|
||||
|
||||
# tmp path to store leanote release files
|
||||
tmp="/Users/life/Desktop/leanote_release"
|
||||
|
||||
version=x86_64.v1.0-beta.2
|
||||
# version
|
||||
V="v1.0.1"
|
||||
|
||||
##=================================
|
||||
# 1. 先build 成 3个平台, 2种bit = 6种
|
||||
##=================================
|
||||
|
||||
# cd /Documents/Go/package2/src/github.com/leanote/leanote/bin
|
||||
# GOOS=darwin GOARCH=amd64 go build -o leanote-darwin-amd64 ../app/tmp
|
||||
|
||||
cd $SP
|
||||
|
||||
# $1 = darwin, linux
|
||||
# $2 = amd64
|
||||
function build()
|
||||
{
|
||||
echo build-$1-$2
|
||||
if [ $1 = "linux" -o $1 = "darwin" ]
|
||||
then
|
||||
suffix=""
|
||||
else
|
||||
suffix=".exe"
|
||||
fi
|
||||
|
||||
GOOS=$1 GOARCH=$2 go build -o leanote-$1-$2$suffix ../app/tmp
|
||||
}
|
||||
|
||||
build "linux" "386";
|
||||
build "linux" "amd64";
|
||||
|
||||
build "windows" "386";
|
||||
build "windows" "amd64";
|
||||
|
||||
build "darwin" "386";
|
||||
build "darwin" "amd64";
|
||||
|
||||
|
||||
##======================
|
||||
# 2. release目录准备工作
|
||||
##======================
|
||||
rm -rf $tmp/leanote
|
||||
mkdir -p $tmp/leanote/app
|
||||
mkdir -p $tmp/leanote/conf
|
||||
mkdir -p $tmp/leanote/bin
|
||||
|
||||
##==================
|
||||
# 3. 复制
|
||||
##==================
|
||||
|
||||
cd $SP
|
||||
cd ../
|
||||
|
||||
# bin
|
||||
cp -r ./bin/src $tmp/leanote/bin/
|
||||
cp ./bin/run.sh $tmp/leanote/bin/
|
||||
|
||||
# LICENSE
|
||||
cp ./LICENSE $tmp/leanote/
|
||||
cp ./bin/run.bat $tmp/leanote/bin/
|
||||
|
||||
# views
|
||||
cp -r ./app/views $tmp/leanote/app
|
||||
# 可不要
|
||||
cp -r ./app/service $tmp/leanote/app/service
|
||||
cp -r ./app/controllers $tmp/leanote/app/controllers
|
||||
cp -r ./app/db $tmp/leanote/app/db
|
||||
cp -r ./app/info $tmp/leanote/app/info
|
||||
cp -r ./app/lea $tmp/leanote/app/lea
|
||||
# 可不要, 源码
|
||||
#cp -r ./app/service $tmp/leanote/app/service
|
||||
#cp -r ./app/controllers $tmp/leanote/app/controllers
|
||||
#cp -r ./app/db $tmp/leanote/app/db
|
||||
#cp -r ./app/info $tmp/leanote/app/info
|
||||
#cp -r ./app/lea $tmp/leanote/app/lea
|
||||
|
||||
# conf
|
||||
cp ./conf/app.conf-default $tmp/leanote/conf/app.conf
|
||||
cp ./conf/routes-default $tmp/leanote/conf/routes
|
||||
cp ./conf/app.conf $tmp/leanote/conf/app.conf
|
||||
cp ./conf/routes $tmp/leanote/conf/routes
|
||||
# 处理app.conf, 还原配置
|
||||
cat $tmp/leanote/conf/app.conf | sed 's/db.dbname=leanote.*#/db.dbname=leanote #/' > $tmp/leanote/conf/app.conf2 # 不能直接覆盖
|
||||
rm $tmp/leanote/conf/app.conf
|
||||
mv $tmp/leanote/conf/app.conf2 $tmp/leanote/conf/app.conf
|
||||
|
||||
# others
|
||||
cp -r ./messages ./public ./mongodb_backup $tmp/leanote/
|
||||
@@ -44,40 +89,57 @@ cp -r ./messages ./public ./mongodb_backup $tmp/leanote/
|
||||
rm -r $tmp/leanote/public/tinymce/classes
|
||||
rm -r $tmp/leanote/public/upload
|
||||
mkdir $tmp/leanote/public/upload
|
||||
mkdir $tmp/leanote/files
|
||||
rm -r $tmp/leanote/public/.codekit-cache
|
||||
rm $tmp/leanote/public/.DS_Store
|
||||
rm $tmp/leanote/public/config.codekit
|
||||
|
||||
# make link
|
||||
cd $tmp/leanote/bin
|
||||
mkdir ./src/github.com/leanote
|
||||
# cd $tmp/leanote/bin
|
||||
# ln -s ../../../../ ./src/github.com/leanote/leanote
|
||||
|
||||
# archieve
|
||||
# << 'BLOCK
|
||||
# linux
|
||||
cd $SP
|
||||
cd ../
|
||||
cp ./bin/leanote-linux $tmp/leanote/bin/
|
||||
cd $tmp
|
||||
tar -cvf $tmp/leanote-linux-$version.bin.tar leanote
|
||||
gzip $tmp/leanote-linux-$version.bin.tar
|
||||
|
||||
# mac
|
||||
rm $tmp/leanote/bin/leanote-linux
|
||||
cd $SP
|
||||
cd ../
|
||||
cp ./bin/leanote-mac $tmp/leanote/bin/
|
||||
cd $tmp
|
||||
tar -cvf $tmp/leanote-mac-$version.bin.tar leanote
|
||||
gzip $tmp/leanote-mac-$version.bin.tar
|
||||
##===========
|
||||
# 4. 打包
|
||||
##===========
|
||||
# $1 = linux
|
||||
# $2 = 386, amd64
|
||||
|
||||
cd $SP
|
||||
cd ../
|
||||
cp ./bin/leanote-linux $tmp/leanote/bin/
|
||||
# 创建一个$V的目录存放之
|
||||
rm -rf $tmp/$V
|
||||
mkdir $tmp/$V
|
||||
|
||||
rm $tmp/bin/src/github.com/leanote/leanote
|
||||
cp -r $tmp/leanote/* $tmp/leanote_release_github
|
||||
function tarRelease()
|
||||
{
|
||||
echo tar-$1-$2
|
||||
cd $SP
|
||||
cd ../
|
||||
rm $tmp/leanote/bin/leanote-* # 删除之前的bin文件
|
||||
rm $tmp/leanote/bin/run* # 删除之前的run.sh 或 run.bat
|
||||
|
||||
if [ $1 = "linux" -o $1 = "darwin" ]
|
||||
then
|
||||
suffix=""
|
||||
cp ./bin/run.sh $tmp/leanote/bin/
|
||||
else
|
||||
cp ./bin/run.bat $tmp/leanote/bin/
|
||||
suffix=".exe"
|
||||
fi
|
||||
|
||||
cp ./bin/leanote-$1-$2$suffix $tmp/leanote/bin/
|
||||
cd $tmp
|
||||
tar -cf $tmp/$V/leanote-$1-$2-$V.bin.tar leanote
|
||||
gzip $tmp/$V/leanote-$1-$2-$V.bin.tar
|
||||
}
|
||||
|
||||
# BLOCK'
|
||||
tarRelease "linux" "386";
|
||||
tarRelease "linux" "amd64";
|
||||
|
||||
tarRelease "windows" "386";
|
||||
tarRelease "windows" "amd64";
|
||||
|
||||
tarRelease "darwin" "386";
|
||||
tarRelease "darwin" "amd64";
|
||||
|
||||
# BLOCK'
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
@echo off
|
||||
|
||||
cd..
|
||||
set SCRIPTPATH=%cd%
|
||||
|
||||
: top src directory
|
||||
set path="%SCRIPTPATH%\bin\src\github.com\leanote"
|
||||
|
||||
if not exist "%path%" mkdir "%path%"
|
||||
|
||||
: create software link
|
||||
if exist "%path%\leanote" del /Q "%path%\leanote"
|
||||
mklink /D "%path%\leanote" %SCRIPTPATH%
|
||||
|
||||
: set GOPATH
|
||||
set GOPATH="%SCRIPTPATH%\bin"
|
||||
|
||||
: run
|
||||
if %processor_architecture%==x86 (
|
||||
"%SCRIPTPATH%\bin\leanote-windows-386.exe" -importPath github.com/leanote/leanote
|
||||
) else (
|
||||
"%SCRIPTPATH%\bin\leanote-windows-amd64.exe" -importPath github.com/leanote/leanote
|
||||
)
|
||||
+13
-7
@@ -7,17 +7,23 @@ path="$SCRIPTPATH/src/github.com/leanote"
|
||||
if [ ! -d "$path" ]; then
|
||||
mkdir -p "$path"
|
||||
fi
|
||||
rm -rf $SCRIPTPATH/src/github.com/leanote/leanote # 先删除
|
||||
ln -s ../../../../ $SCRIPTPATH/src/github.com/leanote/leanote
|
||||
|
||||
# set GOPATH
|
||||
export GOPATH=$GOPATH:$SCRIPTPATH
|
||||
export GOPATH=$SCRIPTPATH
|
||||
|
||||
# run
|
||||
osName=`uname`
|
||||
if [ $osName == "Darwin" ]; then
|
||||
chmod 777 "$SCRIPTPATH/leanote-mac"
|
||||
"$SCRIPTPATH/leanote-mac" -importPath github.com/leanote/leanote
|
||||
osName=`uname` # Darwin or Linux
|
||||
osName=`tr '[A-Z]' '[a-z]' <<<"$osName"` # toLowerCase
|
||||
bit=`getconf LONG_BIT` # 32, 64
|
||||
if [ $bit = "64" ]
|
||||
then
|
||||
bit="amd64"
|
||||
else
|
||||
chmod 777 "$SCRIPTPATH/leanote-linux"
|
||||
"$SCRIPTPATH/leanote-linux" -importPath github.com/leanote/leanote
|
||||
bit="386"
|
||||
fi
|
||||
|
||||
script="$SCRIPTPATH/leanote-$osName-$bit"
|
||||
chmod 777 $script
|
||||
$script -importPath github.com/leanote/leanote
|
||||
@@ -1,100 +0,0 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"os"
|
||||
fpath "path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type Static struct {
|
||||
*revel.Controller
|
||||
}
|
||||
|
||||
// This method handles requests for files. The supplied prefix may be absolute
|
||||
// or relative. If the prefix is relative it is assumed to be relative to the
|
||||
// application directory. The filepath may either be just a file or an
|
||||
// additional filepath to search for the given file. This response may return
|
||||
// the following responses in the event of an error or invalid request;
|
||||
// 403(Forbidden): If the prefix filepath combination results in a directory.
|
||||
// 404(Not found): If the prefix and filepath combination results in a non-existent file.
|
||||
// 500(Internal Server Error): There are a few edge cases that would likely indicate some configuration error outside of revel.
|
||||
//
|
||||
// Note that when defining routes in routes/conf the parameters must not have
|
||||
// spaces around the comma.
|
||||
// Bad: Static.Serve("public/img", "favicon.png")
|
||||
// Good: Static.Serve("public/img","favicon.png")
|
||||
//
|
||||
// Examples:
|
||||
// Serving a directory
|
||||
// Route (conf/routes):
|
||||
// GET /public/{<.*>filepath} Static.Serve("public")
|
||||
// Request:
|
||||
// public/js/sessvars.js
|
||||
// Calls
|
||||
// Static.Serve("public","js/sessvars.js")
|
||||
//
|
||||
// Serving a file
|
||||
// Route (conf/routes):
|
||||
// GET /favicon.ico Static.Serve("public/img","favicon.png")
|
||||
// Request:
|
||||
// favicon.ico
|
||||
// Calls:
|
||||
// Static.Serve("public/img", "favicon.png")
|
||||
func (c Static) Serve(prefix, filepath string) revel.Result {
|
||||
var basePath string
|
||||
|
||||
if !fpath.IsAbs(prefix) {
|
||||
basePath = revel.BasePath
|
||||
}
|
||||
|
||||
basePathPrefix := fpath.Join(basePath, fpath.FromSlash(prefix))
|
||||
fname := fpath.Join(basePathPrefix, fpath.FromSlash(filepath))
|
||||
if !strings.HasPrefix(fname, basePathPrefix) {
|
||||
revel.WARN.Printf("Attempted to read file outside of base path: %s", fname)
|
||||
return c.NotFound("")
|
||||
}
|
||||
|
||||
finfo, err := os.Stat(fname)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) || err.(*os.PathError).Err == syscall.ENOTDIR {
|
||||
revel.WARN.Printf("File not found (%s): %s ", fname, err)
|
||||
return c.NotFound("File not found")
|
||||
}
|
||||
revel.ERROR.Printf("Error trying to get fileinfo for '%s': %s", fname, err)
|
||||
return c.RenderError(err)
|
||||
}
|
||||
|
||||
if finfo.Mode().IsDir() {
|
||||
revel.WARN.Printf("Attempted directory listing of %s", fname)
|
||||
return c.Forbidden("Directory listing not allowed")
|
||||
}
|
||||
|
||||
file, err := os.Open(fname)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
revel.WARN.Printf("File not found (%s): %s ", fname, err)
|
||||
return c.NotFound("File not found")
|
||||
}
|
||||
revel.ERROR.Printf("Error opening '%s': %s", fname, err)
|
||||
return c.RenderError(err)
|
||||
}
|
||||
return c.RenderFile(file, revel.Inline)
|
||||
}
|
||||
|
||||
// This method allows modules to serve binary files. The parameters are the same
|
||||
// as Static.Serve with the additional module name pre-pended to the list of
|
||||
// arguments.
|
||||
func (c Static) ServeModule(moduleName, prefix, filepath string) revel.Result {
|
||||
var basePath string
|
||||
for _, module := range revel.Modules {
|
||||
if module.Name == moduleName {
|
||||
basePath = module.Path
|
||||
}
|
||||
}
|
||||
|
||||
absPath := fpath.Join(basePath, fpath.FromSlash(prefix))
|
||||
|
||||
return c.Serve(absPath, filepath)
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/revel/revel"
|
||||
"html"
|
||||
"html/template"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type TestRunner struct {
|
||||
*revel.Controller
|
||||
}
|
||||
|
||||
type TestSuiteDesc struct {
|
||||
Name string
|
||||
Tests []TestDesc
|
||||
}
|
||||
|
||||
type TestDesc struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type TestSuiteResult struct {
|
||||
Name string
|
||||
Passed bool
|
||||
Results []TestResult
|
||||
}
|
||||
|
||||
type TestResult struct {
|
||||
Name string
|
||||
Passed bool
|
||||
ErrorHtml template.HTML
|
||||
ErrorSummary string
|
||||
}
|
||||
|
||||
var NONE = []reflect.Value{}
|
||||
|
||||
func (c TestRunner) Index() revel.Result {
|
||||
var testSuites []TestSuiteDesc
|
||||
for _, testSuite := range revel.TestSuites {
|
||||
testSuites = append(testSuites, DescribeSuite(testSuite))
|
||||
}
|
||||
return c.Render(testSuites)
|
||||
}
|
||||
|
||||
// Run runs a single test, given by the argument.
|
||||
func (c TestRunner) Run(suite, test string) revel.Result {
|
||||
result := TestResult{Name: test}
|
||||
for _, testSuite := range revel.TestSuites {
|
||||
t := reflect.TypeOf(testSuite).Elem()
|
||||
if t.Name() != suite {
|
||||
continue
|
||||
}
|
||||
|
||||
// Found the suite, create a new instance and run the named method.
|
||||
v := reflect.New(t)
|
||||
func() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
error := revel.NewErrorFromPanic(err)
|
||||
if error == nil {
|
||||
result.ErrorHtml = template.HTML(html.EscapeString(fmt.Sprint(err)))
|
||||
} else {
|
||||
var buffer bytes.Buffer
|
||||
tmpl, _ := revel.MainTemplateLoader.Template("TestRunner/FailureDetail.html")
|
||||
tmpl.Render(&buffer, error)
|
||||
result.ErrorSummary = errorSummary(error)
|
||||
result.ErrorHtml = template.HTML(buffer.String())
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Initialize the test suite with a NewTestSuite()
|
||||
testSuiteInstance := v.Elem().FieldByName("TestSuite")
|
||||
testSuiteInstance.Set(reflect.ValueOf(revel.NewTestSuite()))
|
||||
|
||||
// Call Before(), call the test, and call After().
|
||||
if m := v.MethodByName("Before"); m.IsValid() {
|
||||
m.Call(NONE)
|
||||
}
|
||||
|
||||
if m := v.MethodByName("After"); m.IsValid() {
|
||||
defer m.Call(NONE)
|
||||
}
|
||||
|
||||
v.MethodByName(test).Call(NONE)
|
||||
|
||||
// No panic means success.
|
||||
result.Passed = true
|
||||
}()
|
||||
break
|
||||
}
|
||||
return c.RenderJson(result)
|
||||
}
|
||||
|
||||
// List returns a JSON list of test suites and tests.
|
||||
// Used by the "test" command line tool.
|
||||
func (c TestRunner) List() revel.Result {
|
||||
var testSuites []TestSuiteDesc
|
||||
for _, testSuite := range revel.TestSuites {
|
||||
testSuites = append(testSuites, DescribeSuite(testSuite))
|
||||
}
|
||||
return c.RenderJson(testSuites)
|
||||
}
|
||||
|
||||
func DescribeSuite(testSuite interface{}) TestSuiteDesc {
|
||||
t := reflect.TypeOf(testSuite)
|
||||
|
||||
// Get a list of methods of the embedded test type.
|
||||
super := t.Elem().Field(0).Type
|
||||
superMethodNameSet := map[string]struct{}{}
|
||||
for i := 0; i < super.NumMethod(); i++ {
|
||||
superMethodNameSet[super.Method(i).Name] = struct{}{}
|
||||
}
|
||||
|
||||
// Get a list of methods on the test suite that take no parameters, return
|
||||
// no results, and were not part of the embedded type's method set.
|
||||
var tests []TestDesc
|
||||
for i := 0; i < t.NumMethod(); i++ {
|
||||
m := t.Method(i)
|
||||
mt := m.Type
|
||||
_, isSuperMethod := superMethodNameSet[m.Name]
|
||||
if mt.NumIn() == 1 &&
|
||||
mt.NumOut() == 0 &&
|
||||
mt.In(0) == t &&
|
||||
!isSuperMethod &&
|
||||
strings.HasPrefix(m.Name, "Test") {
|
||||
tests = append(tests, TestDesc{m.Name})
|
||||
}
|
||||
}
|
||||
|
||||
return TestSuiteDesc{
|
||||
Name: t.Elem().Name(),
|
||||
Tests: tests,
|
||||
}
|
||||
}
|
||||
|
||||
func errorSummary(error *revel.Error) string {
|
||||
var message = fmt.Sprintf("%4sStatus: %s\n%4sIn %s", "", error.Description, "", error.Path)
|
||||
if error.Line != 0 {
|
||||
message += fmt.Sprintf(" (around line %d): ", error.Line)
|
||||
for _, line := range error.ContextSource() {
|
||||
if line.IsError {
|
||||
message += line.Source
|
||||
}
|
||||
}
|
||||
}
|
||||
return message
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
func init() {
|
||||
revel.OnAppStart(func() {
|
||||
fmt.Println("Go to /@tests to run the tests.")
|
||||
})
|
||||
}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
<b>{{.Description}}</b><br>
|
||||
In {{.Path}}
|
||||
{{if .Line}}
|
||||
(around {{if .Line}}line {{.Line}}{{end}}{{if .Column}} column {{.Column}}{{end}})
|
||||
{{end}}:
|
||||
{{range .ContextSource}}{{if .IsError}}<code>{{.Source}}</code>{{end}}{{end}}<br>
|
||||
<a style="cursor:pointer;"
|
||||
onclick="x=this.nextSibling.style;if(!x.display)x.display='none';else x.display=''">
|
||||
Show Stack</a><pre style="display:none;">{{.Stack}}</pre>
|
||||
@@ -1,84 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Revel Test Runner</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<link href="/@tests/public/css/bootstrap.css" type="text/css" rel="stylesheet"></link>
|
||||
<script src="/@tests/public/js/jquery-1.9.1.min.js" type="text/javascript"></script>
|
||||
<style>
|
||||
header { padding:20px 0; background-color:#ADD8E6 }
|
||||
.passed td { background-color: #90EE90 !important; }
|
||||
.failed td { background-color: #FFB6C1 !important; }
|
||||
.tests td.name, .tests td.result { padding-top: 13px; }
|
||||
pre { font-size:10px; white-space: pre; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container">
|
||||
<table><tr><td>
|
||||
<h1>Test Runner</h1>
|
||||
<p class="lead">Run all of your application's tests from here.</p>
|
||||
</td><td style="padding-left:150px;">
|
||||
<button class="btn btn-large" all-tests="">Run All Tests</button>
|
||||
</td></tr></table>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container">
|
||||
{{range .testSuites}}
|
||||
<p class="lead" style="margin-top:20px;">{{.Name}}</p>
|
||||
<table class="table table-striped tests" suite="{{.Name}}">
|
||||
{{range .Tests}}
|
||||
<tr>
|
||||
<td class="name">{{.Name}}</td>
|
||||
<td class="result">
|
||||
</td>
|
||||
<td><button test="{{.Name}}" class="btn">Run</button></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var running = 0;
|
||||
|
||||
$("button[test]").click(function() {
|
||||
var button = $(this).addClass("disabled").text("Running");
|
||||
running += 1;
|
||||
runTest(button);
|
||||
});
|
||||
|
||||
$("button[all-tests]").click(function() {
|
||||
var button = $(this).addClass("disabled").text("Running");
|
||||
$("button[test]").click();
|
||||
});
|
||||
|
||||
function runTest(button) {
|
||||
var suite = button.parents("table").attr("suite");
|
||||
var test = button.attr("test");
|
||||
var row = button.parents("tr");
|
||||
var resultCell = row.children(".result");
|
||||
$.ajax({
|
||||
dataType: "json",
|
||||
url: "/@tests/"+suite+"/"+test,
|
||||
async: false,
|
||||
success: function(result) {
|
||||
row.attr("class", result.Passed ? "passed" : "failed");
|
||||
if (result.Passed) {
|
||||
resultCell.html("");
|
||||
} else {
|
||||
resultCell.html(result.ErrorHtml);
|
||||
}
|
||||
button.removeClass("disabled").text("Run");
|
||||
running -= 1;
|
||||
if (running == 0) {
|
||||
$("button[all-tests]").removeClass("disabled").text("Run All Tests");
|
||||
}
|
||||
}});
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Revel Test Runner</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: #333333;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
header { padding:20px 0; }
|
||||
header.passed { background-color: #90EE90 !important; }
|
||||
header.failed { background-color: #FFB6C1 !important; }
|
||||
table { margin-top: 20px; padding: 8px; line-height: 20px; }
|
||||
td { vertical-align: top; padding-right:20px; }
|
||||
a { color: #0088cc; }
|
||||
.container { margin-left: auto; margin-right: auto; width: 940px; }
|
||||
.result.failed b { font-weight:bold; color: #C00; font-size: 14px; }
|
||||
.result.failed span { color: #C00; font-size: 14px; }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<header class="{{if .Passed}}passed{{else}}failed{{end}}">
|
||||
<div class="container">
|
||||
<h1>{{.Name}}</h1>
|
||||
<p>{{if .Passed}}PASSED{{else}}FAILED{{end}}</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container">
|
||||
<table>
|
||||
{{range .Results}}
|
||||
<tr class="result {{if .Passed}}passed{{else}}failed{{end}}">
|
||||
<td><span>{{.Name}}</span></td>
|
||||
<td>{{if .ErrorHtml}}{{.ErrorHtml}}{{else}}PASSED{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +0,0 @@
|
||||
GET /@tests TestRunner.Index
|
||||
GET /@tests.list TestRunner.List
|
||||
GET /@tests/public/*filepath Static.ServeModule(testrunner,public)
|
||||
GET /@tests/:suite/:test TestRunner.Run
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.5 KiB |
-5
@@ -1,5 +0,0 @@
|
||||
/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license
|
||||
//@ sourceMappingURL=jquery.min.map
|
||||
*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(Line truncated
|
||||
return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+Line truncated
|
||||
}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}reLine truncated
|
||||
+8
-4
@@ -2,9 +2,12 @@
|
||||
# leanote config
|
||||
#------------------------
|
||||
|
||||
http.port=80
|
||||
http.port=9000
|
||||
|
||||
site.url=http://localhost # or http://x.com:8080, http://www.xx.com:9000
|
||||
site.url=http://localhost:9000 # or http://x.com:8080, http://www.xx.com:9000
|
||||
|
||||
# admin username
|
||||
adminUsername=admin
|
||||
|
||||
# mongdb
|
||||
db.host=localhost
|
||||
@@ -15,6 +18,7 @@ db.password= # if not exists, please leave it blank
|
||||
# or you can set the mongdb url for more complex needs the format is:
|
||||
# mongodb://myuser:mypass@localhost:40001,otherhost:40001/mydb
|
||||
# db.url=mongodb://root:root123@localhost:27017/leanote
|
||||
db.urlEnv=${MONGODB_URL} # set url from env
|
||||
|
||||
# You Must Change It !! About Security!!
|
||||
app.secret=V85ZzBeTnzpsHyjQX4zukbQ8qqtju9y2aDM55VWxAH9Qop19poekx3xkcDVvrD0y
|
||||
@@ -42,14 +46,14 @@ log.error.prefix = "ERROR "
|
||||
# The default language of this application.
|
||||
i18n.default_language=en
|
||||
|
||||
module.static=github.com/revel/revel/modules/static
|
||||
module.static=github.com/revel/modules/static
|
||||
|
||||
[dev]
|
||||
mode.dev=true
|
||||
results.pretty=true
|
||||
watch=true
|
||||
|
||||
module.testrunner = github.com/revel/revel/modules/testrunner
|
||||
module.testrunner = github.com/revel/modules/testrunner
|
||||
|
||||
log.trace.output = stderr
|
||||
log.info.output = stderr
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 305 KiB After Width: | Height: | Size: 66 KiB |
@@ -0,0 +1,91 @@
|
||||
# blog
|
||||
|
||||
blogNavs=Navigation
|
||||
quickLinks=Liens rapides
|
||||
latestPosts=Dernières publications
|
||||
|
||||
noBlog=Aucun blog
|
||||
noTag=Aucune étiquette
|
||||
blogClass=Catégorie
|
||||
updatedTime=Mis à jour à
|
||||
createdTime=Créé à
|
||||
fullBlog=Blog entier
|
||||
blogNav=Navigation du blog
|
||||
more=Plus...
|
||||
previous=Précédent
|
||||
next=Suivant
|
||||
|
||||
#
|
||||
# set blog
|
||||
#
|
||||
blogSet=Configuration du blog
|
||||
baseInfoSet=Information de base
|
||||
commentSet=Commentaires
|
||||
themeSet=Thème
|
||||
theme=Thème
|
||||
blogName=Titre
|
||||
blogLogo=Logo
|
||||
blogDesc=Description
|
||||
aboutMe=A propos de moi
|
||||
|
||||
#domain
|
||||
domainSet=Domaine
|
||||
subDomain=Sous-domaine
|
||||
domain=Domaine personnalisé
|
||||
|
||||
# theme
|
||||
elegant=Elegant
|
||||
navFixed=Navigation figée sur le côté gauche
|
||||
|
||||
openComment=Ouvrir un commentaire?
|
||||
chooseComment=Système de commentaires
|
||||
disqusHelp=Veuillez renseigner votre identifiant Disqus
|
||||
needHelp=Besoin d'aide?
|
||||
blogLogoTips=Téléverser une image pour remplacer le titre du blog
|
||||
saveSuccess=Sauvegarde réussie
|
||||
|
||||
community=Communauté
|
||||
home=Accueil
|
||||
none=Aucun
|
||||
moreShare=Plus
|
||||
sinaWeibo=Weibo
|
||||
weixin=Weichat
|
||||
tencentWeibo=Tencent Weibo
|
||||
qqZone=QQ Zone
|
||||
renren=Renren
|
||||
report=Rapport
|
||||
like=J'aime
|
||||
unlike=Je n'aime plus
|
||||
viewers=Lecteurs
|
||||
author=Auteur
|
||||
delete=Effacer
|
||||
reply=Répondre
|
||||
comment=Commenter
|
||||
comments=Commentaires
|
||||
cancel=Annuler
|
||||
confirm=Confirmer
|
||||
signIn=S'identifier
|
||||
signUp=S'incrire
|
||||
submitComment=Soumettre
|
||||
reportReason1=不友善内容
|
||||
reportReason2=广告等垃圾信息
|
||||
reportReason3=违法违规内容
|
||||
reportReason4=不宜公开讨论的政治内容
|
||||
other=Autre
|
||||
reportReason=Raison
|
||||
chooseReason=请选择举报理由
|
||||
reportSuccess=举报成功, 我们处理后会通知作者, 感谢您的监督
|
||||
error=Erreur
|
||||
reportComment?=举报该评论?
|
||||
reportBlog?=举报该博客?
|
||||
confirmDeleteComment=Êtes-vous sûr?
|
||||
scanQRCode=Ouvrez Weichat et scannez le QR Code
|
||||
justNow=Seulement maintenant
|
||||
minutesAgo=Il y a quelques minutes
|
||||
hoursAgo=Il y a plusieurs heures
|
||||
daysAgo=Il y a plusieurs jours
|
||||
weeksAgo=Il y a plusieurs semaines
|
||||
monthsAgo=Il y a plusieurs mois
|
||||
|
||||
|
||||
a=a
|
||||
+44
-17
@@ -1,9 +1,9 @@
|
||||
# leanote
|
||||
app=leanote
|
||||
moto=Not Just A Notebook!
|
||||
moto2=Knowledge, Blog, Sharing, Cooperation... all in leanote
|
||||
app=Leanote
|
||||
moto=Not Just A Notepad!
|
||||
moto2=Knowledge, Blog, Sharing, Cooperation... all in Leanote
|
||||
moto3=Brief But Not Simple
|
||||
fork github=Fork leanote on Github
|
||||
fork github=Fork Leanote on Github
|
||||
|
||||
# 首页
|
||||
forgetPassword = Forget password?
|
||||
@@ -13,7 +13,8 @@ try=Try it
|
||||
usernameOrEmail=Username or email
|
||||
password=Password
|
||||
home=Home
|
||||
aboutLeanote=About leanote
|
||||
desktopApp=App
|
||||
aboutLeanote=About Leanote
|
||||
suggestions=Suggestions
|
||||
yourSuggestions=Suggestions
|
||||
leanoteBlog=Blog
|
||||
@@ -32,6 +33,7 @@ captcha=Captcha
|
||||
reloadCaptcha=Reload Captcha
|
||||
captchaError=Captcha Do Not Match
|
||||
inputCaptcha=Captcha is required
|
||||
noTag=No Tags
|
||||
|
||||
hi=Hi
|
||||
welcomeUseLeanote=Welcome!
|
||||
@@ -40,8 +42,10 @@ curUser=Email
|
||||
|
||||
# form
|
||||
submit=submit
|
||||
Submit=Submit
|
||||
register=Sign up
|
||||
login=Sign in
|
||||
Password=Password
|
||||
password2=Confirm your password
|
||||
email=Email
|
||||
inputUsername=Username(email) is required
|
||||
@@ -56,6 +60,7 @@ ing=processing
|
||||
use = Use
|
||||
hadAcount = Already have an account?
|
||||
hasAcount = Do not have an account?
|
||||
signInWithThird=Sign in with other account
|
||||
|
||||
# 注册
|
||||
registerSuccessAndRdirectToNote=Register success, redirecting...
|
||||
@@ -76,7 +81,7 @@ notGoodPassword=Tt's not a good password, the length is at least 6
|
||||
|
||||
# 笔记主页
|
||||
myBlog=Blog
|
||||
history=Histories
|
||||
history=History
|
||||
save=Save
|
||||
editorTips=Tips
|
||||
editorTipsInfo=<h4>1. Short cuts</h4>ctrl+shift+c Toggle code<h4>2. shift+enter Get out of current block</h4> eg. <img src="/images/outofcode.png" style="width: 90px"/> in this situation you can use shift+enter to get out of current code block.
|
||||
@@ -96,7 +101,7 @@ clearSearch=Clear Search
|
||||
all=Newest
|
||||
trash=Trash
|
||||
delete=Delete
|
||||
unTitled=UnTitled
|
||||
unTitled=Untitled
|
||||
defaultShare=Default sharing
|
||||
leftHidden=Hidden slide bar
|
||||
leftShow=Show slide bar
|
||||
@@ -105,6 +110,8 @@ writingMode=Writing Mode
|
||||
normalMode=Normal Mode
|
||||
saving=Saving
|
||||
saveSuccess=Save success
|
||||
SearchNote=Search Note
|
||||
SearchNotebook=Search Notebook
|
||||
|
||||
update=Update
|
||||
create=Create
|
||||
@@ -165,6 +172,7 @@ cancelPublic=Cancel public
|
||||
move=Move
|
||||
copy=Copy
|
||||
rename=Rename
|
||||
exportPdf=Export PDF
|
||||
addChildNotebook=Add child notebook
|
||||
deleteAllShared=Delete shared user
|
||||
deleteSharedNotebook=Delete shared notebook
|
||||
@@ -240,11 +248,6 @@ errorPerPageSize=Page size is error
|
||||
errorSortField=Sort Field is error
|
||||
themeValidHasRoundInclude=WARNING: Templates have circular references!
|
||||
|
||||
# lea++
|
||||
leaDesc=leanote blog platform
|
||||
recommend=Recommend
|
||||
latest=Latest
|
||||
|
||||
# 用户中心
|
||||
memberCenter=Member Center
|
||||
userNotExists=The user is not exists
|
||||
@@ -252,8 +255,9 @@ hasUsers=The user already exists
|
||||
|
||||
# yu
|
||||
service=Service
|
||||
imageSizeOver=Sorry, you have no image opacity, please <a href="/service">upgrade your account</a>.
|
||||
attachSizeOver=Sorry, you have no attachment opacity, please <a href="/service">upgrade your account</a>.
|
||||
trafficOver=Sorry, you have no web traffic, please go <a href="/service">upgrade your account</a>.
|
||||
imageSizeOver=Sorry, you have no image capacity, please go <a href="/service">upgrade your account</a>.
|
||||
attachSizeOver=Sorry, you have no attachment opacity, please go <a href="/service">upgrade your account</a>.
|
||||
|
||||
|
||||
#memeber
|
||||
@@ -262,8 +266,9 @@ accountInfo=Account Info
|
||||
accountType=Account Type
|
||||
premiumAccountType=Premium
|
||||
normalAccountType=Normal
|
||||
imageSize=Image Opacity
|
||||
attachSize=Attachment Opacity
|
||||
imageSize=Image Capacity
|
||||
attachSize=Attachment Capacity
|
||||
totalTraffic=Web Traffic
|
||||
upgrade=Upgrade My Account
|
||||
leanoteEvents=Leanote News
|
||||
addLeanoteAccount=New Leanote Account
|
||||
@@ -336,5 +341,27 @@ deleteGroup=Delete group
|
||||
addMemberTips=Input username or email to add member
|
||||
deleteMember=Delete member
|
||||
|
||||
created=Created
|
||||
updated=Updated
|
||||
modify=Modify
|
||||
|
||||
# share
|
||||
tokenExpired=Token Expired
|
||||
Share=Share
|
||||
hasSharedThisNote=has shared this note
|
||||
inputSharePwd=Please input password
|
||||
shareToGroup=Share to group
|
||||
shareByPwd=Share by password
|
||||
groupName=Group Name
|
||||
operation=Operation
|
||||
groupAndMemberManage=Manage group/member
|
||||
shareToGroupTips=If you share your note to group, the member belongs to group will have the right to access the note
|
||||
shared=Shared
|
||||
notShared=Not shared
|
||||
shareLink=Share link
|
||||
sharePwd=Access password
|
||||
cancelShare=Cancel
|
||||
getShareLinkAndPwd=Get link and password
|
||||
|
||||
# error
|
||||
notFound=This page cann't found.
|
||||
notFound=This page can't be found.
|
||||
+370
@@ -0,0 +1,370 @@
|
||||
# leanote
|
||||
app=Leanote
|
||||
moto=Plus qu'un simple bloc-notes!
|
||||
moto2=Connaissance, Blog, Partage, Coopération... tout est dans Leanote
|
||||
moto3=Simple mais pas simplet.
|
||||
fork github=Fork leanote sur Github
|
||||
|
||||
# Home
|
||||
forgetPassword = Mot de passe oublié?
|
||||
or=ou
|
||||
try=Essayer
|
||||
3th=Comptes tiers
|
||||
usernameOrEmail=Nom d'utilisateur ou adresse de courriel
|
||||
password=Mot de passe
|
||||
home=Mes blocs-notes
|
||||
desktopApp=Application
|
||||
aboutLeanote=A propos de leanote
|
||||
suggestions=Suggestions
|
||||
yourSuggestions=Suggestions
|
||||
leanoteBlog=Blog
|
||||
knowledge=Connaissances
|
||||
knowledgeInfo=Utiliser leanote comme une note, gérer ses connaissances dans leanote.
|
||||
share=Partager
|
||||
shareInfo=Partagez vos connaissances avec vos amis dans leanote.
|
||||
cooperation=Coopération
|
||||
cooperationInfo=Collaborez avec vos amis pour augmenter vos connaissances.
|
||||
blog=Blog
|
||||
blogInfo=Vous pouvez publier vos connaissances et leanote et votre blog!
|
||||
suggestionsInfo=Aidez-nous à améliorer leanote.
|
||||
yourContact=Vos contacts
|
||||
emailOrOthers=Courriel ou autre méthode de contact
|
||||
captcha=Captcha
|
||||
reloadCaptcha=Recharger Captcha
|
||||
captchaError=Le Captcha ne correspond pas
|
||||
inputCaptcha=Le Captcha est requis
|
||||
noTag=No Tags
|
||||
|
||||
hi=Coucou
|
||||
welcomeUseLeanote=Bienvenue!
|
||||
myNote=Mes notes
|
||||
curUser=Adresse courriel
|
||||
|
||||
# form
|
||||
submit=Soumettre
|
||||
Submit=Soumettre
|
||||
register=S'inscrire
|
||||
login=S'identifier
|
||||
password2=Confirmer votre mot de passe
|
||||
email=Adresse de courriel
|
||||
inputUsername=Le nom d'utilisateur(adresse courriel) est requis
|
||||
inputEmail=L'adresse courriel est requis
|
||||
wrongEmail=Wrong email
|
||||
wrongUsernameOrPassword=Mauvais nom d'utilisateur ou mot de passe
|
||||
inputPassword=Le mot de passe est requis
|
||||
wrongPassword=Mauvais mot de passe
|
||||
logining=S'identifier
|
||||
loginSuccess=Identification réussie!
|
||||
ing=En cours
|
||||
use = Utiliser
|
||||
hadAcount = Déjà inscrit?
|
||||
hasAcount = Pas encore inscrit?
|
||||
signInWithThird=S'identifier avec un compte tiers
|
||||
|
||||
# 注册
|
||||
registerSuccessAndRdirectToNote=inscription réussie, redirection...
|
||||
userHasBeenRegistered=%s a été inscrit
|
||||
|
||||
# 找回密码
|
||||
passwordTips=Doit comporter au moins 6 caractères
|
||||
findPassword=Demander le mot de passe
|
||||
findPasswordSendEmailOver=Nous avons déjà envoyer le lien pour demander un mot de passe sur votre adresse de courriel, veuillez consulter votre boite de réception.
|
||||
checkEmai=Vérifier le courriel
|
||||
findPasswordTimeout=Temps imparti écoulé
|
||||
reFindPassword=Re-demander le mot de passe
|
||||
updatePassword=Mettre à jour le mot de passe
|
||||
updatePasswordSuccessRedirectToLogin=Mise à jour du mot de passe réussie, redirection vers la page d'identification...
|
||||
inputPassword2=Veuillez taper votre mot de passe à nouveau
|
||||
confirmPassword=Veuillez confirmer votre mot de passe
|
||||
notGoodPassword=Le mot de passe est incorrect, il doit comporter au moins 6 caractères.
|
||||
|
||||
# 笔记主页
|
||||
myBlog=Blog
|
||||
history=Historique
|
||||
save=Sauvegarder
|
||||
editorTips=Astuces
|
||||
editorTipsInfo=<h4>1. Raccourcis</h4>ctrl+maj+c Active/désactive le code<h4>2. maj+entrée Sortir du bloc courant</h4> ex. <img src="/images/outofcode.png" style="width: 90px"/> dans cette situation vous pouvez utiliser maj+entrée pour sortir du bloc de code courant.
|
||||
newNote=Nouvelle note
|
||||
newMarkdownNote=Nouvelle Note Markdown
|
||||
noNoteNewNoteTips=Le bloc-note est vide, pourquoi ne pas...
|
||||
canntNewNoteTips=Désolé, impossible de créer une nouvelle note ici, veuillez d'abord choisir un bloc-note.
|
||||
new=Nouveau
|
||||
newMarkdown=Nouvelle note markdown
|
||||
clickAddTag=Cliquez pour ajouter une étiquette
|
||||
notebook=Bloc-note
|
||||
note=Note
|
||||
myNotebook=Mon bloc-note
|
||||
addNotebook=Ajouter un bloc-note
|
||||
search=Chercher
|
||||
clearSearch=Nettoyer la recherche
|
||||
all=Le plus récent
|
||||
trash=Corbeille
|
||||
delete=Effacer
|
||||
unTitled=Sans titre
|
||||
defaultShare=Partage par défaut
|
||||
leftHidden=Cacher la barre latérale
|
||||
leftShow=Montrer la barre latérale
|
||||
nav=Naviguer parmi les notes
|
||||
writingMode=Mode écriture
|
||||
normalMode=Mode normal
|
||||
saving=Sauvegarde
|
||||
saveSuccess=Sauvegarde réussie
|
||||
SearchNote=Search Note
|
||||
SearchNotebook=Search Notebook
|
||||
|
||||
update=Mettre à jour
|
||||
create=Créer
|
||||
|
||||
demoRegister=<a href="/register">S'inscrire</a>
|
||||
|
||||
close=Fermer
|
||||
cancel=Annuler
|
||||
send=Envoyer
|
||||
|
||||
# 标签
|
||||
tag=Etiquette
|
||||
myTag=Mes étiquettes
|
||||
red=rouge
|
||||
yellow=jaune
|
||||
blue=bleu
|
||||
green=vert
|
||||
|
||||
# 设置
|
||||
accountSetting=Compte
|
||||
themeSetting=Thème
|
||||
setAvatar=Avatar
|
||||
logout=Déconnexion
|
||||
basicInfo=Basique
|
||||
basicInfoSet=Réglages de base du blog
|
||||
updateEmail=Mettre à jour le courriel
|
||||
usernameSetting=Mettre à jour le nom d'utilisateur
|
||||
username=Nom d'utilisateur
|
||||
avatar=Avatar
|
||||
chooseImage=Choisir une image
|
||||
oldPassword=Ancien mot de passe
|
||||
newPassword=Nouveau mot de passe
|
||||
admin=Administrateur
|
||||
|
||||
default=Par défaut
|
||||
simple=Simple
|
||||
|
||||
# tinymce
|
||||
uploadImage=Téléverser une image
|
||||
|
||||
# blog
|
||||
aboutMe=A propos de moi
|
||||
blogSet=Réglages du blog
|
||||
|
||||
# index
|
||||
discussion=Discussion
|
||||
download=Téléchargement
|
||||
howToInstallLeanote=Comment installer leanote
|
||||
|
||||
#
|
||||
attachments = Pièces-jointes
|
||||
donate = Faire un don
|
||||
|
||||
# contextmenu
|
||||
shareToFriends=Partage avec ses amis
|
||||
publicAsBlog=Publier en tant que blog
|
||||
cancelPublic=Annuler la publication
|
||||
move=Déplacer
|
||||
copy=Copier
|
||||
rename=Renommer
|
||||
addChildNotebook=Ajouer un bloc-note enfant
|
||||
deleteAllShared=Effacer l'utilisateur partagé
|
||||
deleteSharedNotebook=Effacer le bloc-notes partagé
|
||||
copyToMyNotebook=Copier vers mon bloc-notes
|
||||
|
||||
####note-dev
|
||||
emailInSending=Envoi vers
|
||||
checkEmail=Vérifier courriel
|
||||
setUsername=Paramétrer le nom d'utilisateur
|
||||
setUsernameTips=Votre courriel actuel est: <code>%s</code>. Vous pouvez définir un nom d'utilisateur unique. <br />Nom d'utilisateur' Au moins 4 caractères et sans caractères spéciaux.
|
||||
currentEmail=Votre courriel actuel est: <code>%s</code>
|
||||
updateEmail=Mettre à jour le courriel
|
||||
updateEmailTips=Vous devez confirmer votre courriel après la mise-à-jour. Le courriel confirmé sera le nouveau compte.
|
||||
sendVerifiedEmail=Envoyer le courriel de confirmation
|
||||
verified=Confirmé
|
||||
unVerified=Non confirmé
|
||||
verifiedNow=Confirmer maintenant
|
||||
resendVerifiedEmail=Renvoyer le courriel de confirmation
|
||||
|
||||
# 分享
|
||||
defaulthhare=Par défaut
|
||||
addShare=Ajouter un ami
|
||||
friendEmail=Courriel de l'ami
|
||||
permission=Autorisation
|
||||
readOnly=Lecture seule
|
||||
writable=Editable
|
||||
inputFriendEmail=Le courriel de votre ami est requis/
|
||||
clickToChangePermission=Cliquez pour changer l'autorisation.
|
||||
sendInviteEmailToYourFriend=Envoyer un courriel d'invitation à votre ami.
|
||||
copySuccess=Copie réussie
|
||||
copyFailed=Copie échouée
|
||||
friendNotExits=Votre ami n'a pas de compte %s, lien d'invitation à s'enregistrer: %s
|
||||
emailBodyRequired=Corps du message requis
|
||||
clickToCopy=Cliquer pour copier
|
||||
sendSuccess=succès
|
||||
inviteEmailBody=Coucou, je suis %s, %s est génial, viens!
|
||||
|
||||
# 历史记录
|
||||
historiesNum=Nous avons enregistré au maximum <b>10</b> historiques récents de chaque note.
|
||||
noHistories=Pas d'historique.
|
||||
fold=Plier
|
||||
unfold=Déplier
|
||||
datetime=Date & Heure
|
||||
restoreFromThisVersion=Restaurer depuis cette version
|
||||
confirmBackup=Êtes-vous sûr de vouloir restaurer depuis cette version? Nous allons réaliser une copie de sauvegarde de la note actuelle.
|
||||
createAccount=Créer un compte
|
||||
createAccountSuccess=Compte créé avec succès
|
||||
createAccountFailed=Echec de la création du compte
|
||||
thirdCreateAcountTips=Vous utilisez un compte tiers pour connecter %(app)s, vous pouvrz créer un compte %(app) également. <br />Après avoir créé le compte %(app), vous pouvez utiliser ce compte et le compte tiers pour connecter %(app)s.
|
||||
|
||||
## valid msg
|
||||
inputUsername=Entrer le nom d'utilisateur
|
||||
updateUsernameSuccess=Mise à jour du nom d'utilisateur réussie
|
||||
usernameIsExisted=Le nom d'utilisateur existe déjà.
|
||||
noSpecialChars=le nom d'utilisateur ne peut pas contenir de caractères spéciaux
|
||||
minLength=La longueur doit être d'au moins %s
|
||||
errorEmail=Veuillez renseigner le courriel correct
|
||||
verifiedEmaiHasSent=Le courriel de confirmation a été envoyé, veuillez surveiller votre boite de réception.
|
||||
emailSendFailed=Envoi du courriel échoué.
|
||||
inputPassword=Mot de passe requis
|
||||
inputNewPassword=Le nouveau mot de passe est requis.
|
||||
inputPassword2=Veuillez rentrer le nouveau mot de passe à nouveau.
|
||||
errorPassword=La taille du mot de passe est d'au moins 6 caractères et aussi complexe que possible.
|
||||
oldPasswordError=L'ancien mot de passe ne correspond pas.
|
||||
confirmPassword=Le mot de passe ne correspond pas.
|
||||
updatePasswordSuccess=Mises à jour du mot de passe réussie.
|
||||
errorDomain=Le domaine personnalisé n'est pas valide, ex. www.myblog.com
|
||||
domainExisted=Le domaine personnalisé existe déjà.
|
||||
errorSubDomain=Veuillez entrer un sous domaine valide, au moins 4 caractères (non spéciaux)
|
||||
subDomainExisted=Le sous-domaine existe déjà.
|
||||
domainNotPointToLeanote=Le domaine personnalisé ne pointe pas vers d.leanote.com
|
||||
errorPerPageSize=Erreur dans la taille de la page
|
||||
errorSortField=Erreur dans le tri du champs
|
||||
themeValidHasRoundInclude=WARNING: Les modèles ont des références circulaires!
|
||||
|
||||
# lea++
|
||||
leaDesc=platerforme de blog leanote
|
||||
recommend=Recommandé
|
||||
latest=Plus récent.
|
||||
|
||||
# 用户中心
|
||||
memberCenter=Espace Membre
|
||||
userNotExists=L'utilisateur n'existe pas
|
||||
hasUsers=L'utilisateur existe déjà
|
||||
|
||||
# yu
|
||||
service=Service
|
||||
imageSizeOver=Désolé, l'image est trop volumineuse, veuillez <a href="/service">mettre votre compte à niveau</a>.
|
||||
attachSizeOver=Désolé, la pièce-jointe est trop volumineuse, veuillez <a href="/service">mettre votre compte à niveau.</a>.
|
||||
|
||||
|
||||
#memeber
|
||||
welcomeToLeanote=Bienvenue
|
||||
accountInfo=Info sur le Compte
|
||||
accountType=Type de Compte
|
||||
premiumAccountType=Premium
|
||||
normalAccountType=Normal
|
||||
imageSize=Taille de l'image
|
||||
attachSize=Taille de la pièce-jointe
|
||||
totalTraffic=Web Traffic
|
||||
upgrade=Mettre mon compte à niveau
|
||||
leanoteEvents=Nouvelles de Leanote
|
||||
addLeanoteAccount=Nouveau compte Leanote
|
||||
defaultComment=Système de commentaires Leanote par défaut
|
||||
upgradeAccountTips=Je veux utiliser un domaine personnalisé pour mon blog, <a class="btn btn-default" href="/service">mettre mon compte à niveau.</a>
|
||||
cateIsPublicNotebook=La catégorie est le bloc-note publié
|
||||
dragAndSort=Faire glisser pour trier
|
||||
permanentLink=Lien Permanent
|
||||
cate=Catégorie
|
||||
noCates=Sans catégorie
|
||||
single=Page simple
|
||||
singleTips=Vous pouvez ajouter beaucoup de pages simples
|
||||
addSingle=Nouvelle page simple
|
||||
updateSingle=Metter à jour une page simple
|
||||
inputSingleTitle=Le titre de la page simple est requis
|
||||
saveSort=Séquençage de la sauvegarde
|
||||
pagingAndSort=Réglages du tri et de la mise en page
|
||||
perPageSize=Taille par page
|
||||
sortField=Champ de tri
|
||||
sortType=Type de tri
|
||||
publicTime=Heure de publication
|
||||
createdTime=Heure de création
|
||||
updatedTime=Heure de mise à jour
|
||||
desc=Desc
|
||||
asc=Asc
|
||||
postList=Afficher la liste
|
||||
hasSelfDefined=Défini
|
||||
noSelfDefined=Non défini
|
||||
setAbstract=Autres réglages
|
||||
title=Titre
|
||||
content=Contenu
|
||||
|
||||
addTheme=Nouveau thème
|
||||
importTheme=Importer thème
|
||||
exportTheme=Exporter thème
|
||||
export=Exporter
|
||||
preview=Aperçu
|
||||
edit=Editer
|
||||
use=Utiliser
|
||||
install=Installer
|
||||
currentTheme=Thème actuel
|
||||
myOtherThemes=Mes autres thèmes
|
||||
leanoteThemeMarket=Marché aux thèmes Leanote
|
||||
updateTheme=Mettre à jour le thème
|
||||
tplStyleScript=modèle, style, script
|
||||
newFile=Nouveau fichier
|
||||
image=Image
|
||||
currentFile=Fichier actuel
|
||||
tpl=Modèle
|
||||
style=Style
|
||||
script=Script
|
||||
header=En-tête
|
||||
footer=Pied de page
|
||||
index=Accueil
|
||||
cate=Catégorie
|
||||
search=Chercher
|
||||
single=Page simple
|
||||
archive=Archive
|
||||
post=Poster
|
||||
tags=Etiquettes
|
||||
tag_posts=Etiquettes des publications
|
||||
share_comment=Commenter
|
||||
themeJson=Réglages du thème
|
||||
paging=Mise en page
|
||||
highlight=Surlignage du code
|
||||
|
||||
group=Groupe
|
||||
newGroup=Nouveau groupe
|
||||
deleteGroup=Effacer groupe
|
||||
addMemberTips=Rentrer le nom d'utilisateur et le courriel pour ajouter un membre
|
||||
deleteMember=Effacer membre
|
||||
|
||||
created=Created
|
||||
updated=Updated
|
||||
modify=Modify
|
||||
|
||||
# share
|
||||
tokenExpired=Token Expired
|
||||
Share=Share
|
||||
hasSharedThisNote=has shared this note
|
||||
inputSharePwd=Please input password
|
||||
shareToGroup=Share to group
|
||||
shareByPwd=Share by password
|
||||
groupName=Group Name
|
||||
operation=Operation
|
||||
groupAndMemberManage=Manage group/member
|
||||
shareToGroupTips=If you share your note to group, the member belongs to group will have the right to access the note
|
||||
shared=Shared
|
||||
notShared=Not shared
|
||||
shareLink=Share link
|
||||
sharePwd=Access password
|
||||
cancelShare=Cancel
|
||||
getShareLinkAndPwd=Get link and password
|
||||
|
||||
|
||||
# error
|
||||
notFound=Page introuvable.
|
||||
+46
-19
@@ -1,7 +1,7 @@
|
||||
# leanote
|
||||
app=leanote
|
||||
app=Leanote
|
||||
moto=不只是笔记!
|
||||
moto2=知识管理, 博客, 分享, 协作... 尽在leanote
|
||||
moto2=知识管理, 博客, 分享, 协作... 尽在Leanote
|
||||
moto3=简约而不简单
|
||||
fork github=Github 源码
|
||||
|
||||
@@ -13,9 +13,10 @@ try=体验一下
|
||||
usernameOrEmail=用户名或Email
|
||||
password=密码
|
||||
home=主页
|
||||
aboutLeanote=关于leanote
|
||||
desktopApp=客户端
|
||||
aboutLeanote=关于Leanote
|
||||
suggestions=建议
|
||||
yourSuggestions=帮助完善leanote
|
||||
yourSuggestions=帮助完善Leanote
|
||||
leanoteBlog=官方博客
|
||||
knowledge=知识
|
||||
knowledgeInfo=leanote是一个笔记, 你可以用它来管理自己的知识.
|
||||
@@ -32,6 +33,7 @@ captcha=验证码
|
||||
reloadCaptcha=刷新验证码
|
||||
captchaError=验证码错误
|
||||
inputCaptcha=请输入验证码
|
||||
noTag=无标签
|
||||
|
||||
hi=Hi
|
||||
welcomeUseLeanote=Welcome!
|
||||
@@ -39,9 +41,11 @@ myNote=My note
|
||||
curUser=Email
|
||||
|
||||
# form
|
||||
submit=submit
|
||||
submit=提交
|
||||
Submit=提交
|
||||
register=Sign up
|
||||
login=Sign in
|
||||
Password=密码
|
||||
password2=Confirm your password
|
||||
email=Email
|
||||
inputUsername=Username(email) is required
|
||||
@@ -76,6 +80,7 @@ ing=正在处理
|
||||
use = 使用
|
||||
hadAcount = 已有帐户?
|
||||
hasAcount = 还无帐户?
|
||||
signInWithThird=使用第三方帐号登录
|
||||
|
||||
# 注册
|
||||
registerSuccessAndRdirectToNote=注册成功, 正在跳转...
|
||||
@@ -101,7 +106,7 @@ history=历史记录
|
||||
save=保存
|
||||
editorTips=帮助
|
||||
editorTipsInfo=<h4>1. 快捷键</h4>ctrl+shift+c 代码块切换 <h4>2. shift+enter 跳出当前区域</h4>比如在代码块中<img src="/images/outofcode.png" style="width: 90px"/>按shift+enter可跳出当前代码块.
|
||||
newNote=新建笔记
|
||||
newNote=新建普通笔记
|
||||
newMarkdownNote=新建Markdown笔记
|
||||
noNoteNewNoteTips=该笔记本下空空如也...何不
|
||||
canntNewNoteTips=Sorry, 这里不能添加笔记的. 你需要先选择一个笔记本.
|
||||
@@ -118,7 +123,7 @@ all=最新
|
||||
trash=废纸篓
|
||||
delete=删除
|
||||
unTitled=无标题
|
||||
defaultShare=默认共享
|
||||
defaultShare=默认分享
|
||||
leftHidden=隐藏左侧
|
||||
leftShow=展开左侧
|
||||
nav=文档导航
|
||||
@@ -126,6 +131,8 @@ writingMode=写作模式
|
||||
normalMode=普通模式
|
||||
saving=正在保存
|
||||
saveSuccess=保存成功
|
||||
SearchNote=搜索笔记
|
||||
SearchNotebook=搜索笔记本
|
||||
|
||||
update=更新
|
||||
create=创建
|
||||
@@ -142,7 +149,7 @@ myTag=我的标签
|
||||
red=红色
|
||||
yellow=黄色
|
||||
blue=蓝色
|
||||
green=绿色
|
||||
green=绿色
|
||||
|
||||
# 设置
|
||||
accountSetting=帐户设置
|
||||
@@ -189,6 +196,7 @@ cancelPublic=取消公开为博客
|
||||
move=移动
|
||||
copy=复制
|
||||
rename=重命名
|
||||
exportPdf=导出PDF
|
||||
addChildNotebook=添加子笔记本
|
||||
deleteAllShared=删除所有共享
|
||||
deleteSharedNotebook=删除共享笔记本
|
||||
@@ -204,7 +212,7 @@ updateEmail=修改邮箱
|
||||
updateEmailTips=邮箱修改后, 验证之后才有效, 验证之后新的邮箱地址将会作为登录帐号使用.
|
||||
sendVerifiedEmail=发送验证邮箱
|
||||
sendSuccess=发送成功
|
||||
sendFailed=发送失败
|
||||
sendFailed=发送失败
|
||||
verified=已验证
|
||||
unVerified=未验证
|
||||
verifiedNow=现在去验证
|
||||
@@ -226,7 +234,7 @@ emailBodyRequired=邮件内容不能为空
|
||||
clickToCopy=点击复制
|
||||
sendSuccess=发送成功
|
||||
inviteEmailBody=Hi, 你好, 我是%s, %s非常好用, 快来注册吧!
|
||||
|
||||
|
||||
# 历史记录
|
||||
historiesNum=leanote会保存笔记的最近<b>10</b>份历史记录
|
||||
noHistories=无历史记录
|
||||
@@ -266,29 +274,26 @@ errorPerPageSize=每页记录数至少为1
|
||||
errorSortField=排序类型错误
|
||||
themeValidHasRoundInclude=警告: 模板存在循环引用问题!
|
||||
|
||||
# lea++
|
||||
leaDesc=leanote博客平台
|
||||
recommend=推荐
|
||||
latest=最新
|
||||
|
||||
# 用户中心
|
||||
memberCenter=用户中心
|
||||
memberCenter=个人中心
|
||||
userNotExists=该成员沿未注册
|
||||
hasUsers=已存在该成员
|
||||
|
||||
# yu
|
||||
service=服务
|
||||
imageSizeOver=对不起, 您的图片容量不足, 请<a href="/service">升级您的帐户</a>
|
||||
attachSizeOver=对不起, 您的附件容量不足, 请<a href="/service">升级您的帐户</a>
|
||||
trafficOver=对不起, 您本月的流量已用完, 请至<a href="/service">升级您的帐户</a>
|
||||
imageSizeOver=对不起, 您的图片容量不足, 请至<a href="/service">升级您的帐户</a>
|
||||
attachSizeOver=对不起, 您的附件容量不足, 请至<a href="/service">升级您的帐户</a>
|
||||
|
||||
#memeber
|
||||
welcomeToLeanote=欢迎来到leanote
|
||||
accountInfo=帐户信息
|
||||
accountType=帐户类型
|
||||
premiumAccountType=彩色套餐
|
||||
premiumAccountType=旗舰套餐
|
||||
normalAccountType=共享套餐
|
||||
imageSize=图片空间
|
||||
attachSize=附件空间
|
||||
totalTraffic=流量
|
||||
upgrade=升级套餐
|
||||
leanoteEvents=Leanote动态
|
||||
addLeanoteAccount=新建Leanote帐户
|
||||
@@ -361,6 +366,28 @@ deleteGroup=删除组
|
||||
addMemberTips=输入用户名或邮箱添加成员
|
||||
deleteMember=删除成员
|
||||
|
||||
created=创建
|
||||
updated=更新
|
||||
modify=修改
|
||||
|
||||
#share
|
||||
tokenExpired = 会话已过期
|
||||
Share=分享
|
||||
hasSharedThisNote=分享了笔记
|
||||
inputSharePwd=您需要输入分享密码才能查看
|
||||
shareToGroup=分享给项目组
|
||||
shareByPwd=通过密码分享
|
||||
groupName=分组名
|
||||
operation=操作
|
||||
groupAndMemberManage=项目组/成员管理
|
||||
shareToGroupTips=将笔记/笔记本分享给项目组后, 该组下的用户便拥有了该笔记/笔记本
|
||||
shared=已分享
|
||||
notShared=未分享
|
||||
shareLink=分享链接
|
||||
sharePwd=查看密码
|
||||
cancelShare=取消分享
|
||||
getShareLinkAndPwd=生成该笔记的分享链接和密码
|
||||
|
||||
|
||||
# 必须要加这个, 奇怪
|
||||
[CN]
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.albums" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.albums" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.attachs" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.attachs" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.blog_comments" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.blog_comments" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.blog_likes" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.blog_likes" } ] }
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.blog_singles" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.blog_singles" } ] }
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.configs" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.configs" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.email_logs" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.email_logs" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.files" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.files" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.find_pwds" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.find_pwds" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.group_users" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.group_users" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.groups" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.groups" } ] }
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.has_share_notes" }, { "v" : 1, "unique" : true, "key" : { "UserId" : 1, "ToUserId" : 1 }, "name" : "UserId_1_ToUserId_1", "ns" : "leanote6.has_share_notes" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.has_share_notes" }, { "v" : 1, "unique" : true, "key" : { "UserId" : 1, "ToUserId" : 1 }, "name" : "UserId_1_ToUserId_1", "ns" : "leanote9.has_share_notes" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.leanote.ShareNotes" }, { "v" : 1, "unique" : true, "key" : { "UserId" : 1, "ToUserId" : 1, "NoteId" : 1 }, "name" : "UserId_1_ToUserId_1_NoteId_1", "ns" : "leanote6.leanote.ShareNotes" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.leanote.ShareNotes" }, { "v" : 1, "unique" : true, "key" : { "UserId" : 1, "ToUserId" : 1, "NoteId" : 1 }, "name" : "UserId_1_ToUserId_1_NoteId_1", "ns" : "leanote9.leanote.ShareNotes" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.leanote.has_share_notes" }, { "v" : 1, "unique" : true, "key" : { "UserId" : 1, "ToUserId" : 1 }, "name" : "UserId_1_ToUserId_1", "ns" : "leanote6.leanote.has_share_notes" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.leanote.has_share_notes" }, { "v" : 1, "unique" : true, "key" : { "UserId" : 1, "ToUserId" : 1 }, "name" : "UserId_1_ToUserId_1", "ns" : "leanote9.leanote.has_share_notes" } ] }
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.note_content_histories" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.note_content_histories" } ] }
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.note_contents" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.note_contents" } ] }
|
||||
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.note_images" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.note_images" } ] }
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.note_tags" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.note_tags" } ] }
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote6.notebooks" }, { "v" : 1, "key" : { "UserId" : 1 }, "name" : "UserId_1", "ns" : "leanote6.notebooks" } ] }
|
||||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leanote9.notebooks" }, { "v" : 1, "key" : { "UserId" : 1 }, "name" : "UserId_1", "ns" : "leanote9.notebooks" } ] }
|
||||
Loaded 100 of 1673 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user