Peterfei

上主是我的牧者,我实在一无所缺


  • 首页

  • 归档

  • 标签

Sublime 中自定义snippets

发表于 2015-10-29   |   分类于 工具   |  

##选择tool->new snippet
内容如下:

1
2
3
4
5
6
7
8
9
<snippet>
<content><![CDATA[
Hello, ${1:this} is a ${2:snippet}.
]]></content>
<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
<!-- <tabTrigger>hello</tabTrigger> -->
<!-- Optional: Set a scope to limit where the snippet will trigger -->
<!-- <scope>source.python</scope> -->
</snippet>

  1. Hello, ${1:this} is a ${2:snippet} 这正是你要插入到文档中的文本。在此节放入的任何片段都会被插入到你的文档中。
  2. tabTrigger 此节是可选的配置,默认是被注释掉的。默认 hello 的意思是:如果你在某个文档里输入了单词 hello ,然后按下 Tab 键,接着 hello 就会被替换为1中定义的代码片段。再次按下Tab键,接着snippet会被替换为2中定义的代码片段
  3. scope 此节也是可选配置,默认是被注释掉的。默认 source.php 的意思是:只有在编辑 php 源码的时候,才能用此代码片段

##保存代码片段文件
在能自定义代码片段之前,应该首先保存。在保存文件对话框里,需要明确的指定文件的扩展名为.sublime-snippet,然后把文件保存到默认目录(当前用户主目录下的\Sublime Text 3\Packages\User目录中)。

保存文件之后,就可以测试上面提到的tabTrigger功能了。如果不再使用此功能,可以在此注释掉.

##修改代码片段文件
在创建新代码片段中提到过 Hello, ${1:this} is a ${2:snippet} ,其中 ${1:this} 和 ${2:snippet} 是占位符。在插入代码片段后,单词 this 被选中,如果键入内容,this 将会被替换掉,接着按下 Tab 键,将会选中单词 snippet,如果键入内容,snippet 将会被替换掉。

##绑定快捷键

可以将上述的操作绑定到一个快捷键,在不键入任何文本的情况下,直接按快捷键插入代码片段。

点击菜单栏的 Preferences 的子菜单 Key Binding – User,在打开的文件的方括号内部粘贴如下配置:

1
{ “keys”: [“ctrl+1″], “command”: “insert_snippet”, “args”: {“name”: “Packages/User/example.sublime-snippet”} }

现在简单介绍一下这段配置:

  1. “keys”: [“ctrl+1″] 这个定义了触发此命令的快捷键。

  2. “command”: “insert_snippet” 这个是需要触发的命令的名字。

  3. “args”: {“name”: “Packages/User/example.sublime-snippet”} 这个是需要传入到上述命令的参数。这里把代码片段文件的相对路径传递过去。

保存配置文件,现在就可以用快捷键插入代码片段了。

以下是我Ruby的注释代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<snippet>
<content><![CDATA[
# ########################################################
# | Software: ${1}
# | Version: 2015.10
# | Site: http://peterfei.me
# |--------------------------------------------------------
# | Author: peterfei <peterfeispace@gmail.com>
# | Copyright (c) 2012-2015, http://peterfei.me. All Rights
#Reserved.
# | Time: ${2}
# ########################################################
${3}
]]></content>
<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
<!-- <tabTrigger>hello</tabTrigger> -->
<!-- Optional: Set a scope to limit where the snippet will trigger -->
<!-- <scope>source.python</scope> -->
</snippet>

因为上例中有写Time 获取当前时间的,于是写个获取当前时间的:

创建插件:Tools → New Plugin:

1
2
3
4
5
6
7
8
9
import datetime
import sublime_plugin
class AddCurrentTimeCommand(sublime_plugin.TextCommand):
def run(self, edit):
self.view.run_command("insert_snippet",
{
"contents": "%s" % datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
)

保存为Sublime Text 2\Packages\User\addCurrentTime.py

创建快捷键:Preference → Key Bindings - User:

1
2
3
4
5
6
7
8
[
{
"command": "add_current_time",
"keys": [
"ctrl+shift+."
]
}
]

此时使用快捷键ctrl+shift+.即可在当前光标处插入当前时间,如下:

1
2
3
4
5
6
7
8
9
10
# ########################################################
# | Software: test
# | Version: 2015.10
# | Site: http://peterfei.me
# |--------------------------------------------------------
# | Author: peterfei <peterfeispace@gmail.com>
# | Copyright (c) 2012-2015, http://peterfei.me. All Rights
#Reserved.
# | Time: 2015-10-29 09:58:53
# ########################################################

angularjs mobiscroll 日期用例

发表于 2015-10-27   |   分类于 前端   |  

Angularjs 写了个mobiscroll directive :

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
.directive('mobiDateTimePicker', function() {
return {
restrict: 'A',
link: function($scope, element, attrs) {
return $(element).mobiscroll().datetime({
theme: 'default',
display: 'bottom',
lang:'zh',
minWidth:40,
steps:{ minute: 15},
rows:3,
// dayText: '日', monthText: '月', yearText: '年',
dateFormat: 'yy-MM-dd',
timeFormat: 'HH:ii:ss',
// timeWheels: 'HHii',
showNow: true,
showLabel:true,
dateOrder: 'yyyyMMddDD',
// tap:true,
// invalid:[{'10/27',start:'18:00',end:"19:00"}]
headerText: function (valueText) { //自定义弹出框头部格式
return valueText;
},
// dayNames:['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
});
}
};
})

其中:minWidth:40是控件的显示高度,dateOrder: 'yyyyMMddDD',可显示友好的星期+日期:

Angularjs 判断服务器401错误

发表于 2015-10-21   |   分类于 前端   |  

之前在github上有篇判断augularjs401状态码的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var logsOutUserOn401 = function($location, $q, SessionService, FlashService) {
var success = function(response) {
return response;
};
var error = function(response) {
if(response.status === 401) {
SessionService.unset('authenticated');
$location.path('/login');
FlashService.show(response.data.flash);
}
return $q.reject(response);
};
return function(promise) {
return promise.then(success, error);
};
};
$httpProvider.responseInterceptors.push(logsOutUserOn401);

今天用时才发现$httpProvider.responseInterceptors方法已经被官方弃用了。
改写了方案如下:

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
app.factory('errorInterceptor', ['$q', '$rootScope', '$location','FlashService',
function ($q, $rootScope, $location,FlashService) {
return {
request: function (config) {
return config || $q.when(config);
},
requestError: function(request){
return $q.reject(request);
},
response: function (response) {
return response || $q.when(response);
},
responseError: function (response) {
if(response.status === 401) {
// SessionService.unset('authenticated');
FlashService.show(response.data.error);
$location.path('/login');
}
if (response && response.status === 404) {
}
if (response && response.status >= 500) {
}
return $q.reject(response);
}
};
}]);

在app.js config 方法调用时:

1
$httpProvider.interceptors.push('errorInterceptor');

rails grape 用户登陆API

发表于 2015-10-20   |   分类于 ROR   |  

##新建apiUser表:
1.access_token
2.expires_at
3.user_id
4.active
rails g model api_key access_token:string expires_at:datetime user_id:integer active:boolean

##在建好的migrate 文件中加入索引:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CreateApiUserKeys < ActiveRecord::Migration
def change
create_table :api_user_keys do |t|
t.string :access_token
t.datetime :expires_at
t.integer :user_id
t.boolean :active
t.timestamps null: false
end
add_index :api_user_keys, ["user_id"], name: "index_api_keys_on_user_id", unique: false
add_index :api_user_keys, ["access_token"], name: "index_api_keys_on_access_token", unique: true
end
end

执行db:migrate rake db:migrate

##在model中生成token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ApiUserKey < ActiveRecord::Base
attr_accessible :access_token, :expires_at, :user_id, :active, :application
before_create :generate_access_token
before_create :set_expiration
belongs_to :user
def expired?
DateTime.now >= self.expires_at
end
private
def generate_access_token
begin
self.access_token = SecureRandom.hex
end while self.class.exists?(access_token: access_token)
end
def set_expiration
self.expires_at = DateTime.now+30
end
end

##在Grape中加入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
helpers do
def authenticate!
error!('Unauthorized. Invalid or expired token.', 401) unless current_user
end
def current_user
# find token. Check if valid.
token = ApiUserKey.where(access_token: params[:token]).first
if token && !token.expired?
@current_user = User.find(token.user_id)
else
false
end
end
end

##Post 和Get :

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
resource :auth do
desc "Creates and returns access_token if valid login"
params do
requires :login, type: String, desc: "Username or email address"
requires :password, type: String, desc: "Password"
end
post :login do
if params[:login]
user = User.find_by_col_user_phone params[:login].downcase
end
if user && user.authenticate(params[:password])
key = ApiUserKey.create(user_id: user.id)
{token: key.access_token}
else
error!('用户名或密码错误', 401)
end
end
desc "Returns pong if logged in correctly"
params do
requires :token, type: String, desc: "Access token."
end
get :ping do
authenticate!
{ message: "pong" }
end
end
end

rails mina+puma 部署

发表于 2015-10-19   |   分类于 ROR   |  

出于安全考虑,不要使用 root 帐号运行 web 应用。这里新建一个专门用于部署的用户,例如 deploy 或者其它你喜欢的名字。运行以下命令创建用户:

# useradd -m -s /bin/bash deploy

将用户加入 sudo 群组,以便使用 sudo 命令:
# adduser deploy sudo
为 deploy 用户设置密码:
# passwd deploy
给Linux deploy用户 加入rvm 权限
usermod -a -G rvm deploy
退出当前 SSH 链接,用 deploy 帐号重新登陆。

##加入gem mina
mina init, 生成config/deploy.rb

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
require 'mina/rails'
require 'mina/git'
require 'mina/bundler'
require 'mina/rvm'
#服务器地址,是使用ssh的方式登录服务器
set :domain, 'deploy@yourIPServer'
#服务器中项目部署位置
set :deploy_to, '/home/deploy/api'
#git代码仓库
set :repository, 'git@XXX.git'
#git分支
set :branch, 'master'
set :rvm_path, '/usr/local/rvm/bin/rvm'
set :bundle_gemfile, "app/Gemfile"
# 中括号里的文件 会出现在服务器项目附录的shared文件夹中,这里加入了secrets.yml,环境密钥无需跟开发计算机一样
set :shared_paths, ['config/database.yml', 'log', 'config/secrets.yml']
set :rails_env, 'development'
task :environment do
# 如果使用的是rbenv,这么设置,但需确保.rbenv-version(rbenv local 1.9.3-p374)已经存在于你的项目中
invoke :'rvm:use[ruby-2.1.2@default]'
# 如果使用rvm,可以这样加载一个RVM version@gemset
# invoke :'rvm:use[ruby-1.9.3-p374@default]'
end
# 这个块里面的代码表示运行 mina setup时运行的命令
task :setup => :environment do
# 在服务器项目目录的shared中创建log文件夹
queue! %[mkdir -p "#{deploy_to}/#{shared_path}/log"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/log"]
# 在服务器项目目录的shared中创建config文件夹 下同
queue! %[mkdir -p "#{deploy_to}/#{shared_path}/config"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/config"]
queue! %[touch "#{deploy_to}/#{shared_path}/config/database.yml"]
queue! %[touch "#{deploy_to}/#{shared_path}/config/secrets.yml"]
# puma.rb 配置puma必须得文件夹及文件
queue! %[mkdir -p "#{deploy_to}/shared/tmp/pids"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/tmp/pids"]
queue! %[mkdir -p "#{deploy_to}/shared/tmp/sockets"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/tmp/sockets"]
queue! %[touch "#{deploy_to}/shared/config/puma.rb"]
queue %[echo "-----> Be sure to edit 'shared/config/puma.rb'."]
# tmp/sockets/puma.state
queue! %[touch "#{deploy_to}/shared/tmp/sockets/puma.state"]
queue %[echo "-----> Be sure to edit 'shared/tmp/sockets/puma.state'."]
# log/puma.stdout.log
queue! %[touch "#{deploy_to}/shared/log/puma.stdout.log"]
queue %[echo "-----> Be sure to edit 'shared/log/puma.stdout.log'."]
# log/puma.stdout.log
queue! %[touch "#{deploy_to}/shared/log/puma.stderr.log"]
queue %[echo "-----> Be sure to edit 'shared/log/puma.stderr.log'."]
queue %[echo "-----> Be sure to edit '#{deploy_to}/#{shared_path}/config/database.yml'."]
end
#这个代码块表示运行 mina deploy时执行的命令
desc "Deploys the current version to the server."
task :deploy => :environment do
to :before_hook do
end
deploy do
#重新拉git服务器上的最新版本,即使没有改变
invoke :'git:clone'
#重新设定shared_path位置
invoke :'deploy:link_shared_paths'
invoke :'bundle:install'
# invoke :'rails:db_migrate'
invoke :'rails:assets_precompile'
invoke :'deploy:cleanup'
to :launch do
queue "mkdir -p #{deploy_to}/#{current_path}/tmp/"
# queue "chown -R www-data #{deploy_to}"
queue "touch #{deploy_to}/#{current_path}/tmp/restart.txt"
end
end
end

这样一来mina的基本配置就完成,接下来只要将你开发环境的项目上传到git服务器,然后运行下面的命令就完成了

mina deploy

##puma配置

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
#!/usr/bin/env puma
#rails的运行环境
# environment 'production'
environment 'development'
threads 2, 64
workers 4
#项目名
app_name = "api"
#项目路径
application_path = "/home/deploy/#{app_name}"
#这里一定要配置为项目路径下地current
directory "#{application_path}/current"
#下面都是 puma的配置项
pidfile "#{application_path}/shared/tmp/pids/puma.pid"
state_path "#{application_path}/shared/tmp/sockets/puma.state"
stdout_redirect "#{application_path}/shared/log/puma.stdout.log", "#{application_path}/shared/log/puma.stderr.log"
bind "unix://#{application_path}/shared/tmp/sockets/#{app_name}.sock"
activate_control_app "unix://#{application_path}/shared/tmp/sockets/pumactl.sock"
#后台运行
daemonize true
on_restart do
puts 'On restart...'
end
preload_app!

##启动puma
进入/yourprj/config
pumactl -F puma.rb start

##Nginx 配置

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
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#include /etc/nginx/conf.d/*.conf;
upstream deploy {
server unix:///var/www/ruby_sample/shared/tmp/sockets/ruby_sample.sock;
}
server {
listen 80;
server_name your.server.domain.ip; # change to match your URL
root /var/www/ruby_sample/current/public; # I assume your app is located at this location
location / {
proxy_pass http://deploy; # match the name of upstream directive which is defined above
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~* ^/assets/ {
# Per RFC2616 - 1 year maximum expiry
expires 1y;
add_header Cache-Control public;
# Some browsers still send conditional-GET requests if there's a
# Last-Modified header or an ETag header even if they haven't
# reached the expiry date sent in the Expires header.
add_header Last-Modified "";
add_header ETag "";
break;
}
}
}

接下里只需要重启nginx服务器,整个rails的环境就搭建完成了
nginx -s reload

1…101112…16
peterfei

peterfei

peterfei|技术|上主是我的牧者

77 日志
14 分类
62 标签
RSS
github
© 2023 peterfei
由 Hexo 强力驱动
主题 - NexT.Mist