linux_mail

在Linux系统下mail命令的测试

  1. 最简单的一个例子:
     mail -s test admin@aispider.com
    这条命令的结果是发一封标题为test的空信给后面的邮箱,如果你有mta并且后面的邮箱不会挡这种可能莫名奇妙的信的时候,就能收到这封信了。如果你不想被这种乱七八糟的事情干扰,后面的邮箱请使用本地帐户。 
  2. 第二个例子:
     三种常用格式发信
    mail -s test admin@aispider.com #第一种方法,你可以把当前shell当成编辑器来用,编辑完内容后Ctrl-D结束
    echo “mail content”|mail -s test admin@aispider.com #第二种方法,我用的最多,可能是喜欢管道的缘故吧
    mail -s test admin@aispider.com< file #第三种方法,以file的内容为邮件内.容发信
    mail -s test  admin@aispider.com < file #第三种方法,以file的内容为邮件内容发信
    mail -s test -c admin@aispider.com  root@aispider.com< file #第四种方法,给多个用户发送邮件

docker

mac(10.12.6)中的docker (17.06.2-ce-mac27)不支持 -net host 模式。。。 部署个人博客,看了一晚上,端口能ping通,但是宿主机一直访问不到

https://www.oschina.net/question/2329725_2216168

pipe 服务器运行命令

1
2
docker run --detach --name pipe --network=host \
b3log/pipe --mysql="yunggao:123456@(127.0.0.1:3306)/pipe?charset=utf8mb4&parseTime=True&loc=Local" --runtime_mode=prod --port=5897 --server=http://ghub.club

pipe 本地运行命令

1
docker run --detach --name pipe -p 5897:5897 -p 8888:8888 b3log/pipe --mysql="yunggao:123456@(192.168.3.26:3306)/pipe?charset=utf8mb4&parseTime=True&loc=Local" --runtime_mode=prod --port=5897 --server=http://localhost:5897

miniprogram_plugin

小程序插件提审调研

审核流程: 提交插件所有者 -> 提交插件

小程序插件所有者小程序审核

1、插件所有者小程序: 以下官方解释

指的是与插件 AppID 相同的小程序。例如,“小程序示例”小程序开发了一个“小程序示例插件”,那么无论这个插件被哪个小程序使用,这个插件的 插件所有者小程序 都是“小程序示例”

2、在我们小程序支付插件提交的时候,使用到了 “插件所有者小程序” 中的一个“支付功能页”, 这是一个存在于插件所有者小程序中的一个js,内容是 进行 支付时用到的获取用户信息,和调用微信支付接口 的逻辑。测试开发阶段,这个js(插件所有者小程序)可以是未发布的;正式版的插件需要保证这个js(插件所有者小程序)必须是发布的。

插件功能页: https://developers.weixin.qq.com/miniprogram/dev/framework/plugin/functional-pages.html

3、审核插件所有者小程序和普通小程序的审核规则是一样的(规则)。在app.json中添加一个字段激活插件功能页。这里提交审核的插件所有者小程序内容可以是任意的,只要保证审核通过,并且app.json添加了以下配置。

1
2
3
4
5

{
"functionalPages": true
}

小程序插件审核

1、插件的目录结构包含三部分

  • 文档

  • 调试和审核需要的插件demo代码(是正常使用插件的一个小程序demo)

  • 插件代码

插件和demo的根目录在最外层的project.config.json中配置

2、调试环境 插件appid,appsecret 注意事项 (会导致真机下不能请求到demo小程序配置的域名)

  • 插件在pc端开发调试时用的是 project.config.json 里的 appid, 而且调试用的demo小程序的appid 也必须是插件的appid。这个时候pc上开发者工具上调试用到的域名都是在所有者小程序配置的。

  • 插件在手机上调试时用的并不是 project.config.json 里的 appid。这个时候真机调试的域名都是在一个特定小程序中。官方建议申请一个测试号,https://developers.weixin.qq.com/weloginpage?redirect_url=%2Fsandbox,插件真机调试优先使用这个测试号,配置真机调试的服务器域名。 (审核人员都是会进行真机调试,所以这一步很重要

3、插件审核的规则和小程序审核规则一样,会对小程序插件的demo小程序进行审核。(规则

审核规则 (比较重要的几条)

  • 保证真机关闭调试下 可以正常预览,并且有内容。
  • 保证demo小程序数据没有测试两个字,填充比较正式可信的运营内容,价格不要设置1分钱这么小的价格,很容易被当作测试数据。
  • ios 环境不能显示价格;ios环境不能显示 “去**” 之类引导的词汇;ios 不能引导复制链接
  • 能够正常调用插件进行使用
  • 小程序审核可以随时撤回或者覆盖,插件审核不能,所以提交插件审核要比较谨慎。

miniprogram_richtext

根据小程序开发人员的设计 setData 最多只支持 1024 kb 的内容,所以一般富文本编辑,上传大图什么的,默认是转成base64 img 标签内容会超长,试了一个移动端常见的长图,富文本大小有20多mb。。。

所以富文本内容用于小程序中渲染时

  • 一种是web-view渲染一个h5页面

  • 一种方法是富文本上传图片,自定义上传图片的方法,把上传后的地址拼接进去

比如vue-quill-editor 的实现自定义上传图片方法:

https://github.com/surmon-china/vue-quill-editor/issues/134

input上传 type 的坑

信息转自 https://segmentfault.com/a/1190000017281291

Chrome获取MIME类型

在chromium开源代码中
https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=314 314-318行中提到了:

1
2
3
4
5
// We implement the same algorithm as Mozilla for mapping a file extension to
// a mime type. That is, we first check a hard-coded list (that cannot be
// overridden), and then if not found there, we defer to the system registry.
// Finally, we scan a secondary hard-coded list to catch types that we can
// deduce but that we also want to allow the OS to override.

Chrome实现了与Mozilla相同的算法,将文件扩展名映射到MIME类型。
首先,Chrome会检测一个硬编码列表(不能被覆盖)源码中的kPrimaryMappings,然后如果没有找到符合的,Chrome会从操作系统注册表中找,最后会扫描一个二级硬编码列表,源码中的kSecondaryMappings,用来捕获可以推断但是也希望允许操作系统覆盖的类型。

例如:从安装了Microsoft Excel的Windows系统上传CSV文件时,Chrome会将其报告为application/vnd.ms-excel。这是因为.csv未在第一个硬编码列表中指定,因此浏览器会回退到系统注册表。HKEY_CLASSES_ROOT.csv有一个名为的值Content Type设置为application/vnd.ms-excel。

几台windows 和 mac 机器测试,有一台win10,装有office的情况下,上传ppt 文件无法获取 文件 type (MIME)。根据上文里面资料推断,这台及其的office 注册表可能有问题,导致上传时候从机器找不到这个类型的MIME。

一个解决办法是,对于第三方安装的应用的类型,前端还是只做文件名后缀名的判断…shit!

gulp学习记录

gulp + browserify ES6环境搭建

gulp 环境安装

  • 安装全局gulp(已经安装可以跳过)
1
2
cnpm install gulp -g
cnpm i gulp -g
  • 初始化项目(cd 项目文件夹)
1
2
cnpm init
cnpm init -y (后面加上-y 可以跳过配置,后续可以在编辑器里修改文件)
  • 发现多了一个package.json,类似下面的内容
1
2
3
4
5
6
7
8
9
10
11
12
{
"name": "gulp-new",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
  • 安装需要的依赖(需要用到的插件)
1
2
3
cnpm install --save-dev gulp gulp-less gulp-minify-css gulp-uglify gulp-rename gulp-connect gulp-concat

cnpm i -D gulp
  • 新建一个资源文件比如’src’,在里面放入文件
/src index.html
/less /js
board.less board.js
  • 根目录下新建gulpfile.js文件

  • 书写gulp task

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var gulp = require('gulp');
var less = require('gulp-less');
var minifycss = require('gulp-minify-css');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var connect = require('gulp-connect');

//less文件编译
gulp.task('less2css', function() {
return gulp.src('src/less/*.less')
.pipe(less())
.pipe(gulp.dest('src/css'))
});

//css文件合并压缩导出
gulp.task('css', function() {
return gulp.src('src/css/*.css')
.pipe(concat('main.css'))
.pipe(gulp.dest('dest/css'))
.pipe(rename({ suffix: '.min' }))
.pipe(minifycss())
.pipe(gulp.dest('dest/css'))
.pipe(connect.reload());
})

//检测文件变化
gulp.task('watch', function() {
gulp.watch('src/less/*.less', ['less2css', 'css']);
});

//本地服务器,这里使用的是 gulp-connect
gulp.task('webserver', function() {
connect.server({
livereload: true,
port: 8000
});
})

gulp.task('default', ['less2css', 'css', 'watch', 'webserver']);

命令行gulp 跑一下default任务,在./src/dest/css 下会生成main.css ,main.min.css文件。

这一部分的问题:

1、任务是并行的,导致编译less之前,main.css已经压缩完

解决办法

1、通过插件 gulp-sequence 整理运行顺序

2、官方做法

https://www.gulpjs.com.cn/docs/api/

对于这个例子,让我们先假定你有两个 task,”one” 和 “two”,并且你希望它们按照这个顺序执行:

1、在 “one” 中,你加入一个提示,来告知什么时候它会完成:可以再完成时候返回一个 callback,或者返回一个 promise 或 stream,这样系统会去等待它完成。

2、在 “two” 中,你需要添加一个提示来告诉系统它需要依赖第一个 task 完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var gulp = require('gulp');

// 返回一个 callback,因此系统可以知道它什么时候完成
gulp.task('one', function(cb) {
// 做一些事 -- 异步的或者其他的
cb(err); // 如果 err 不是 null 或 undefined,则会停止执行,且注意,这样代表执行失败了
});

// 定义一个所依赖的 task 必须在这个 task 执行之前完成
gulp.task('two', ['one'], function() {
// 'one' 完成后
});

gulp.task('default', ['one', 'two']);

browserify 打包es6环境

  • 安装依赖
1
cnpm install --save-dev vinyl-source-stream vinyl-buffer browserify gulp-connect gulp-concat babelify babel-preset-es2015
  • 改写pacakge.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
"devDependencies": {
...
},
"babel": {
"presets": [
"es2015"
]
},
"browserify": {
"transform": [
[
"babelify",
{
"presets": [
"es2015"
]
}
]
]
}

  • 改写gulpfile.babel.js, 可以写es6语法了,js 被编译到 ./dest/js/app.js ./dest/js/app.min.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import gulp from 'gulp';
import uglify from 'gulp-uglify';
import less from 'gulp-less';
import minifycss from 'gulp-minify-css';
import concat from 'gulp-concat';
import rename from 'gulp-rename';
import browserify from 'browserify';
import source from 'vinyl-source-stream';
import buffer from 'vinyl-buffer';
import connect from 'gulp-connect';

gulp.task('convertJS', function() {
return browserify({
entries: ['src/js/board.js']
})
.bundle()
.pipe(source('app.js'))
.pipe(buffer())
.pipe(gulp.dest('dest/js'))
.pipe(uglify())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest('dest/js'))
.pipe(connect.reload());
});

gulp.task('less2css', function() {
return gulp.src('src/less/*.less')
.pipe(less())
.pipe(gulp.dest('src/css'))
});

gulp.task('css', function() {
return gulp.src('src/css/*.css')
.pipe(concat('main.css'))
.pipe(gulp.dest('dest/css'))
.pipe(rename({ suffix: '.min' }))
.pipe(minifycss())
.pipe(gulp.dest('dest/css'))
.pipe(connect.reload());
})


gulp.task('watch', function() {
gulp.watch('src/js/*.js', ['convertJS']);
gulp.watch('src/less/*.less', ['less2css', 'css']);
});

gulp.task('webserver', function() {
connect.server({
livereload: true,
port: 8000
});
})

gulp.task('default', ['convertJS', 'less2css', 'css', 'watch', 'webserver']);

注意点

1、gulp.src(globs[, options])

glob 匹配模式
return stream可以pipe到其他插件中

mysql

1、查看数据文件存储目录

1
mysqladmin -u root -p variables | grep datadir

/usr/local/etc/my.cnf

1
bind-address = 127.0.0.1 // 只允许本地访问

2、重启mysql(brew 安装的)

  • launchctl unload -w /usr/local/Cellar/mysql/5.7.18_1/homebrew.mxcl.mysql.plist

  • launchctl load -w /usr/local/Cellar/mysql/5.7.18_1/homebrew.mxcl.mysql.plist

  • mysql.server restart

  • mysql.server stop/mysql.server start

3、mysql 5.7 + ssl 需要配置

安装时需要运行

1
bin/mysql_ssl_rsa_setup

会在datadir 里新建ssl证书

4、mysql 授权命令

1
2
grant all privileges on pipe.* to yyyyyy@'%' identified by 'xxxxxx';
// yyyyyy 操作pipe 数据库的所有权限 密码为 xxxxxx

https://www.cnblogs.com/crxis/p/7044582.html

flutter android studio 配置 小记

maven { url ‘https://maven.aliyun.com/repository/google' }
maven { url ‘https://maven.aliyun.com/repository/jcenter' }
maven { url ‘http://maven.aliyun.com/nexus/content/groups/public' }

flutter 目录下 更改 android gradle 镜像

1
2
3
4
5
6
7
8
9
10
11
buildscript{
repositories {
- google()
- jcenter()
+ maven { url https://maven.aliyun.com/repository/google' }
+ maven { url 'https://maven.aliyun.com/repository/jcenter'}
+ maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
dependencies {
classpath 'com.android. tools.build: gradle:3.2.1'

soucecode

vue 源码解读

1、clone 官网代码仓库,下载依赖

2、运行开发模式 npm run dev

3、dev 模式下打包的文件为 /dist/vue.js, 更改 examples/commits/index.html 的vue 引入文件名到vue.js

4、vue.prototype.$event 的属性,在组件中调用this.$delete 可以删除一个对象的属性和响应式监听

5、Vue.config.keyCodes 直接赋值,可以自定义事件触发按键

1
Vue.config.keyCodes = {f1: 112}
1
<input @keyup.f1="sayHi"></input>

当前输入框内抬起f1 会出发sayHi 事件

6、Vue.options._base === Vue