├── .gitignore
├── README.md
├── css
├── interval.md
├── iphone_scroll.css
├── library
│ ├── align.scss
│ ├── display.scss
│ ├── reorder.scss
│ └── space.scss
├── mixin.scss
├── offset_right.scss
├── rated_star.scss
├── setting.scss
├── svg_ssetting.scss
└── tool.scss
├── git
└── git.md
├── html
└── fontawesome.html
├── jquery
├── ajax.md
├── get_url_path.js
└── image_show_immediate.md
├── js
├── audio_play_bar.html.erb
├── blob.js
├── clear_hover.md
├── css_block_debug.md
├── get_view_height_width.js
├── like_super.js
├── search_input_timer.js
├── timer.js
└── watch.js
├── rails
├── asset_boost_track.rb
├── cache_asset_pipline_known.rb
├── parperclip_defalut_img_setting.rb
└── precomplie_setting.rb
├── rspec
└── rspec.md
├── ruby
├── http_code_render_and_serialize.rb
└── plan_model.rb
├── server
├── azure_face_detection.md
├── elasticsearch.md
├── elk_config_settings.md
├── encrypt_like_pem.md
└── nginx_site_enable_yml.md
└── sql
├── remote_to_server_database.md
└── set_character.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 此處是我的人生小筆記
2 | 不記下來全部忘光光
3 |
4 | * 用心好文專區
5 | * [You are not a Sidekiq professional if you don’t know these tricks](https://medium.com/@et3216/9-ways-to-boost-sidekiq-performance-correctly-in-practical-experiences-bfebe9ee0f28)
6 | * [嚇死你的RubyMine怎麼帶我向上飛 分享它如何解省我的時間升生產力](https://medium.com/@et3216/rubymine-%E5%B8%B6%E6%88%91%E5%90%91%E4%B8%8A%E9%A3%9B-8478c30af49c#.909qxa3cc)
7 | * [私人手工製作的Library 內含可彈性的控制RWD的Library、大量省Code的觀念](https://github.com/lustan3216/Behavior-Bind-Media)
8 |
9 | * CSS
10 | * [CSS 文字溢出](https://github.com/lustan3216/BlogArticle/wiki/CSS-%E6%96%87%E5%AD%97%E6%BA%A2%E5%87%BA)
11 | * [RWD replace pull push trick](https://github.com/lustan3216/BlogArticle/wiki/RWD-replace-pull-push-trick)
12 | * [Display rated star by Font Awesome Scss](https://github.com/lustan3216/BlogArticle/wiki/Display-rated-star-by-Font-Awesome-scss)
13 | * [Create Svg Icon](https://github.com/lustan3216/BlogArticle/wiki/Create-Svg-Icon)
14 |
15 | * Rails
16 | * [Parperclip default_url 的設定](https://github.com/lustan3216/BlogArticle/wiki/Parperclip-default-_url-%E7%9A%84%E8%A8%AD%E5%AE%9A)
17 | * [DCI 學習小祕技](https://github.com/lustan3216/BlogArticle/wiki/DCI-%E5%AD%B8%E7%BF%92%E5%B0%8F%E7%A5%95%E6%8A%80)
18 | * [Searchkick Elastic search 使用祕技](https://github.com/lustan3216/BlogArticle/wiki/Searchkick-Elastic-search-%E4%BD%BF%E7%94%A8%E7%A5%95%E6%8A%80)
19 | * [Rails 怎麼切割 mobile/computer view 技巧](https://github.com/lustan3216/BlogArticle/wiki/Rails-%E6%80%8E%E9%BA%BC%E5%88%87%E5%89%B2-mobile-computer-view-%E6%8A%80%E5%B7%A7)
20 | * [本地precompiler 優化](https://github.com/lustan3216/BlogArticle/blob/master/rails/precomplie_setting.rb)
21 | * [指定JS、CSS只在需要的頁面作用技巧](https://github.com/lustan3216/BlogArticle/blob/master/rails/asset_boost_track.rb)
22 |
23 | * Ruby
24 | * [Ruby 讀書心得整理](https://github.com/lustan3216/BlogArticle/wiki/Ruby-%E8%AE%80%E6%9B%B8%E5%BF%83%E5%BE%97%E6%95%B4%E7%90%86)
25 | * [Parperclip exif wrong orientation from mobile upload](https://github.com/lustan3216/BlogArticle/wiki/Parperclip-exif-wrong-orientation-from-mobile-upload)
26 | * [超輕量化Rails model](https://github.com/lustan3216/BlogArticle/blob/master/ruby/plan_model.rb)
27 | * [Http code json render](https://github.com/lustan3216/BlogArticle/blob/master/ruby/http_code_render_and_serialize.rb)
28 |
29 | * SQL
30 | * [Mysql 匯出匯入資料用法](https://github.com/lustan3216/BlogArticle/wiki/Mysql--%E5%8C%AF%E5%87%BA%E5%8C%AF%E5%85%A5%E8%B3%87%E6%96%99%E7%94%A8%E6%B3%95)
31 | * [SQL SHELL.SCIPT語法 讓所有table新增欄位和更新欄位](https://github.com/lustan3216/BlogArticle/wiki/SQL-SHELL.SCIPT%E8%AA%9E%E6%B3%95-%E8%AE%93%E6%89%80%E6%9C%89table%E6%96%B0%E5%A2%9E%E6%AC%84%E4%BD%8D%E5%92%8C%E6%9B%B4%E6%96%B0%E6%AC%84%E4%BD%8D)
32 |
33 | * Server
34 | * [設定SSL Https & HSTS](https://github.com/lustan3216/BlogArticle/wiki/%E8%A8%AD%E5%AE%9ASSL-Https-&-HSTS)
35 | * [Nginx site-enable yml 設定](https://github.com/lustan3216/BlogArticle/blob/master/server/nginx_site_enable_yml.md)
36 | * [Azure face-detection Api中文解釋](https://github.com/lustan3216/BlogArticle/wiki/Azure-face-detection-Api%E4%B8%AD%E6%96%87%E8%A7%A3%E9%87%8B)
37 | * [Elasticsearch 一定會撞的坑](https://github.com/lustan3216/BlogArticle/blob/master/server/elasticsearch.md)
38 | * [ELK 設定檔](https://github.com/lustan3216/BlogArticle/blob/master/server/elk_config_settings.md)
39 |
40 | * JQuery/JS
41 | * [前端好用 套件](https://github.com/lustan3216/BlogArticle/wiki/%E5%89%8D%E7%AB%AF%E5%A5%BD%E7%94%A8-%E5%A5%97%E4%BB%B6)
42 | * [JS偵測 物件出現在 viewprot](https://github.com/lustan3216/BlogArticle/wiki/JS%E5%81%B5%E6%B8%AC--%E7%89%A9%E4%BB%B6%E5%87%BA%E7%8F%BE%E5%9C%A8-viewprot)
43 | * [3D Banner animate](https://github.com/lustan3216/BlogArticle/wiki/3D-Banner-animate)
44 | * [Modernizr 範例code](https://github.com/lustan3216/BlogArticle/wiki/Modernizr-%E7%AF%84%E4%BE%8Bcode)
45 | * [Change Svg path color](https://github.com/lustan3216/BlogArticle/wiki/Change-Svg-path-color)
46 | * [Audio play bar full example](https://github.com/lustan3216/BlogArticle/blob/master/js/audio_play_bar.html.erb)
47 | * [clear hover on mobile](https://github.com/lustan3216/BlogArticle/blob/master/js/clear_hover.md)
48 | * [js debug code, its can display block leyout random color](https://github.com/lustan3216/BlogArticle/blob/master/js/css_block_debug.md)
49 | * [search timer and clean/clean all timer](https://github.com/lustan3216/BlogArticle/blob/master/js/search_input_timer.js)
50 | * [Show image when upload](https://github.com/lustan3216/BlogArticle/blob/master/jquery/image_show_immediate.md)
51 | * [Simple Time prototype](https://github.com/lustan3216/BlogArticle/blob/master/js/timer.js)
52 | * [Act like super function](https://github.com/lustan3216/BlogArticle/blob/master/js/like_super.js)
53 | * [Act like watch function](https://github.com/lustan3216/BlogArticle/blob/master/js/watch.js)
54 |
55 | * Commend line
56 | * [Commend有時用到 指令 祕技](https://github.com/lustan3216/BlogArticle/wiki/Commend%E6%9C%89%E6%99%82%E7%94%A8%E5%88%B0-%E6%8C%87%E4%BB%A4-%E7%A5%95%E6%8A%80)
57 |
58 | * 密碼學
59 | * [仿造簡易Pem key步驟](https://github.com/lustan3216/BlogArticle/blob/master/server/encrypt_like_pem.md)
60 | * [BCrypt 加密演算法精闢解釋](https://github.com/lustan3216/BlogArticle/wiki/BCrypt-%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95%E7%B2%BE%E9%97%A2%E8%A7%A3%E9%87%8B)
61 |
--------------------------------------------------------------------------------
/css/interval.md:
--------------------------------------------------------------------------------
1 | ```
2 |
3 |
4 |
5 | ```
--------------------------------------------------------------------------------
/css/iphone_scroll.css:
--------------------------------------------------------------------------------
1 | body{
2 | -webkit-overflow-scrolling: touch;
3 | }
--------------------------------------------------------------------------------
/css/library/align.scss:
--------------------------------------------------------------------------------
1 | @mixin method_loop($media) {
2 | // text-align
3 | @each $direction,$direction_short in (right,'r'),(left,'l'),(center,'c'),(inherit,'n') {
4 | .ta#{$direction_short}-#{$media} { text-align:$direction;}
5 | }
6 | // float
7 | @each $direction,$direction_short in (right,'r'),(left,'l'),(inherit,'n') {
8 | .fl#{$direction_short}-#{$media} { float:$direction; }
9 | }
10 | }
11 |
12 | @include method_loop('xs');
13 |
14 | @media (min-width: $screen-sm-min) {
15 | @include method_loop('sm');
16 | }
17 |
18 | @media (min-width: $screen-md-min) {
19 | @include method_loop('md');
20 | }
21 |
22 | @media (min-width: $screen-lg-min) {
23 | @include method_loop('lg');
24 | }
--------------------------------------------------------------------------------
/css/library/display.scss:
--------------------------------------------------------------------------------
1 | @mixin flex{
2 | display: -webkit-box;
3 | display: -moz-box;
4 | display: -ms-flexbox;
5 | display: -webkit-flex;
6 | }
7 |
8 | @mixin method_loop($media) {
9 | //display
10 | @each $method,$method_short in (block,'b'),(inline-block,'ib'),(inline,'i'),(inherit,'n') {
11 | .d#{$method_short}-#{$media} { display: $method; }
12 | }
13 | }
14 | @mixin method_loop_f($media) {
15 | //display
16 | .df-#{$media} { @include flex;}
17 | }
18 | @mixin method_loop_f_no_media($media) {
19 | //display
20 | .df-#{$media} { @include flex; }
21 | }
22 |
23 | @include method_loop('xs');
24 | @include method_loop_f('xs');
25 | @include method_loop_f_no_media('xs');
26 |
27 | @media (min-width: $screen-sm-min) {
28 | @include method_loop('sm');
29 | @include method_loop_f('sm');
30 | @include method_loop_f_no_media('sm');
31 | }
32 |
33 | @media (min-width: $screen-md-min) {
34 | @include method_loop('md');
35 | @include method_loop_f('md');
36 | @include method_loop_f_no_media('md');
37 | }
38 |
39 | @media (min-width: $screen-lg-min) {
40 | @include method_loop('lg');
41 | @include method_loop_f('lg');
42 | @include method_loop_f_no_media('lg');
43 | }
--------------------------------------------------------------------------------
/css/library/reorder.scss:
--------------------------------------------------------------------------------
1 | .rotate_180{
2 | -webkit-transform: rotate(180deg);
3 | -moz-transform: rotate(180deg);
4 | -ms-transform: rotate(180deg);
5 | -o-transform: rotate(180deg);
6 | transform: rotate(180deg);
7 | }
8 |
9 | @mixin reverse_column($_){
10 | .row.reverse-#{$_}{
11 | @extend .rotate_180;
12 | direction: rtl;
13 | }
14 |
15 | .row.reverse-#{$_} > [class*="col-"]{
16 | @extend .rotate_180;
17 | direction: ltr;
18 | }
19 | }
20 | @media (max-width: $screen-xs-max) {
21 | @include reverse_column('xs');
22 | }
23 | @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
24 | @include reverse_column('sm');
25 | }
26 |
27 | @media (min-width: $screen-md-min) and (max-width: $screen-md-max) {
28 | @include reverse_column('md');
29 | }
30 |
31 | @media (min-width: $screen-lg-min) and (max-width: $screen-lg-max) {
32 | @include reverse_column('lg');
33 | }
--------------------------------------------------------------------------------
/css/library/space.scss:
--------------------------------------------------------------------------------
1 | // 用法解釋 *表示數字 數字可以是 0px,10px,15px,20px~~100px
2 | // 以上數字為最常用的數字 要增加自己家在下面
3 | // -------------------------------------------------------
4 | // xs(320up) | sm(768up) | md(992up) | lg(1200up)
5 | // -------------------------------------------------------
6 | // mt*-xs Yes | Yes | Yes | Yes
7 | // mt* Yes | Yes | Yes | Yes
8 | // -------------------------------------------------------
9 | // mt*-sm No | Yes | Yes | Yes
10 | // -------------------------------------------------------
11 | // mt*-md No | No | Yes | Yes
12 | // -------------------------------------------------------
13 | // mt*-lg No | No | No | Yes
14 | // -------------------------------------------------------
15 | // Yes 表示有作用的區域 No表示沒作用的區域
16 | //
17 | // 使用方式 【 直接對該class上 mb20-sm 這樣就只會在sm media以上作用magin-bottom 20px 】
18 | // 【 pl50-md 這樣就只會在md media以上作用padding-left 50px 】
19 | //
20 | // 使用時機 【 該區塊class很難取名 或是整塊區域只有單個元素需變動而不想再取class名字】
21 | // 適用於 【 喜歡 CSS 元件化 的工程師 】
22 |
23 | @mixin method_loop_two_way($media) {
24 | @each $method,$method_short in (margin,'m'),(padding,'p') {
25 | @for $i from 0 through 200 {
26 | @each $direction,$direction2,$direction_short,$direction2_short in (right,left,'r','l'),(top,bottom,'t','b') {
27 | @if $i % 5 == 0 {
28 | .#{$method_short}#{$direction_short}#{$direction2_short}#{$i}-#{$media} { #{$method}-#{$direction}: #{$i}px !important;#{$method}-#{$direction2}: #{$i}px !important; }
29 | @if $media == 'xs'{
30 | .#{$method_short}#{$direction_short}#{$direction2_short}#{$i} { #{$method}-#{$direction}: #{$i}px !important;#{$method}-#{$direction2}: #{$i}px !important; }
31 | }
32 | @if $i == 0{
33 | .#{$method_short}#{$direction_short}#{$direction2_short}a-#{$media} { #{$method}-#{$direction}: auto !important;#{$method}-#{$direction2}: auto !important; }
34 | @if $media == 'xs'{
35 | .#{$method_short}#{$direction_short}#{$direction2_short}a { #{$method}-#{$direction}: auto !important;#{$method}-#{$direction2}: auto !important; }
36 | }
37 | }
38 | }
39 | }
40 | }
41 | }
42 | }
43 | @mixin method_loop_full($media) {
44 | @each $method,$method_short in (margin,'m'),(padding,'p') {
45 | @for $i from 0 through 200 {
46 | @if $i % 5 == 0 {
47 | .#{$method_short}#{$i}-#{$media} { #{$method}: #{$i}px !important; }
48 | @if $media == 'xs'{
49 | .#{$method_short}#{$i} { #{$method}: #{$i}px !important; }
50 | }
51 | }
52 | }
53 | }
54 | }
55 | @mixin method_loop($media) {
56 | @each $method,$method_short in (margin,'m'),(padding,'p') {
57 | @for $i from 0 through 200 {
58 | @each $direction,$direction_short in (right,'r'),(left,'l'),(top,'t'),(bottom,'b') {
59 | @if $i % 5 == 0 {
60 | .#{$method_short}#{$direction_short}#{$i}-#{$media} { #{$method}-#{$direction}: #{$i}px !important; }
61 | @if $media == 'xs'{
62 | .#{$method_short}#{$direction_short}#{$i} { #{$method}-#{$direction}: #{$i}px !important; }
63 | }
64 | @if $i == 0{
65 | .#{$method_short}#{$direction_short}n-#{$media} { #{$method}-#{$direction}: inherit !important; }
66 | }
67 | }
68 | }
69 | }
70 | }
71 | }
72 | @include method_loop('xs');
73 | @include method_loop_full('xs');
74 | @include method_loop_two_way('xs');
75 |
76 | @media (min-width: $screen-sm-min) {
77 | @include method_loop('sm');
78 | @include method_loop_full('sm');
79 | @include method_loop_two_way('sm');
80 | }
81 |
82 | @media (min-width: $screen-md-min) {
83 | @include method_loop('md');
84 | @include method_loop_full('md');
85 | @include method_loop_two_way('md');
86 | }
87 |
88 | @media (min-width: $screen-lg-min) {
89 | @include method_loop('lg');
90 | @include method_loop_full('lg');
91 | @include method_loop_two_way('lg');
92 | }
--------------------------------------------------------------------------------
/css/mixin.scss:
--------------------------------------------------------------------------------
1 | @mixin justice-content ($_){
2 | justify-content:$_ ;
3 | -webkit-justify-content: $_;
4 | }
5 | @mixin align-items ($_){
6 | align-items:$_ ;
7 | -webkit-align-items: $_;
8 | }
9 |
10 | @mixin border-radius($_){
11 | -webkit-border-radius:$_;
12 | -moz-border-radius:$_;
13 | border-radius:$_;
14 | }
15 | @mixin border-radius-($_, $__ ,$___){
16 | border-#{$_}-#{$__}-radius: #{$___};
17 | -webkit-border-#{$_}-#{$__}-radius: #{$___};
18 | -moz-border-radius-#{$_}#{$__}: #{$___};
19 | }
20 | @mixin transition($_) {
21 | -webkit-transition: $_ ;
22 | -moz-transition: $_ ;
23 | -ms-transition: $_ ;
24 | -o-transition: $_ ;
25 | transition: $_ ;
26 | }
27 |
28 | @mixin background-size-cover {
29 | -webkit-background-size:cover;
30 | background-size:cover;
31 | }
32 | @mixin background-size($_) {
33 | -webkit-background-size:$_;
34 | background-size:$_;
35 | }
36 | @mixin square_icon($pixel: 40px){
37 | font-size:$pixel / 2;
38 | color: $main_red;
39 | background-color: #FFFFFF;
40 | border-radius: $main_radius;
41 | height: $pixel;
42 | line-height: $pixel;
43 | width: $pixel;
44 | text-align: center;
45 | }
46 | @mixin flex{
47 | display: -webkit-box;
48 | display: -moz-box;
49 | display: -ms-flexbox;
50 | display: -webkit-flex;
51 | display: flex;
52 | }
53 | @mixin flex_($vertical,$horizon){
54 | @include flex;
55 | -webkit-justify-content: $horizon;
56 | justify-content: $horizon;
57 | -webkit-align-items: $vertical;
58 | align-items: $vertical;
59 | }
60 | @mixin calc($_,$__){
61 | #{$_}:-moz-calc(#{$__});
62 | #{$_}:-webkit-calc(#{$__});
63 | #{$_}:calc(#{$__});
64 | }
65 | @mixin flex_wrap($_){
66 | @include flex;
67 | flex-wrap: $_;
68 | -webkit-flex-wrap: $_;
69 | -ms-flex-wrap: $_;
70 | }
71 | @mixin basic_bg($top,$bottom){
72 | border-top-left-radius: $top;
73 | border-top-right-radius: $top;
74 | border-bottom-right-radius: $bottom;
75 | border-bottom-left-radius: $bottom;
76 | background-color: #FFFFFF;
77 | margin-bottom: 30px;
78 | width: 100%;
79 | padding:30px;
80 | }
81 | @mixin text_overflow($font-size,$line-height){
82 | font-size: $font-size;
83 | line-height: $line-height;
84 | $lines-to-show: 3;
85 | display: block; /* Fallback for non-webkit */
86 | display: -webkit-box;
87 | height: $font-size*$line-height*$lines-to-show; /* Fallback for non-webkit */
88 | margin: 0 auto;
89 | font-size: $font-size;
90 | -webkit-line-clamp: $lines-to-show;
91 | -webkit-box-orient: vertical;
92 | overflow: hidden;
93 | text-overflow: ellipsis;
94 | }
--------------------------------------------------------------------------------
/css/offset_right.scss:
--------------------------------------------------------------------------------
1 | .col-xs-offset-right-12 {
2 | margin-right: 100%;
3 | }
4 | .col-xs-offset-right-11 {
5 | margin-right: 91.66666667%;
6 | }
7 | .col-xs-offset-right-10 {
8 | margin-right: 83.33333333%;
9 | }
10 | .col-xs-offset-right-9 {
11 | margin-right: 75%;
12 | }
13 | .col-xs-offset-right-8 {
14 | margin-right: 66.66666667%;
15 | }
16 | .col-xs-offset-right-7 {
17 | margin-right: 58.33333333%;
18 | }
19 | .col-xs-offset-right-6 {
20 | margin-right: 50%;
21 | }
22 | .col-xs-offset-right-5 {
23 | margin-right: 41.66666667%;
24 | }
25 | .col-xs-offset-right-4 {
26 | margin-right: 33.33333333%;
27 | }
28 | .col-xs-offset-right-3 {
29 | margin-right: 25%;
30 | }
31 | .col-xs-offset-right-2 {
32 | margin-right: 16.66666667%;
33 | }
34 | .col-xs-offset-right-1 {
35 | margin-right: 8.33333333%;
36 | }
37 | .col-xs-offset-right-0 {
38 | margin-right: 0;
39 | }
40 | @media (min-width: 768px) {
41 | .col-sm-offset-right-12 {
42 | margin-right: 100%;
43 | }
44 | .col-sm-offset-right-11 {
45 | margin-right: 91.66666667%;
46 | }
47 | .col-sm-offset-right-10 {
48 | margin-right: 83.33333333%;
49 | }
50 | .col-sm-offset-right-9 {
51 | margin-right: 75%;
52 | }
53 | .col-sm-offset-right-8 {
54 | margin-right: 66.66666667%;
55 | }
56 | .col-sm-offset-right-7 {
57 | margin-right: 58.33333333%;
58 | }
59 | .col-sm-offset-right-6 {
60 | margin-right: 50%;
61 | }
62 | .col-sm-offset-right-5 {
63 | margin-right: 41.66666667%;
64 | }
65 | .col-sm-offset-right-4 {
66 | margin-right: 33.33333333%;
67 | }
68 | .col-sm-offset-right-3 {
69 | margin-right: 25%;
70 | }
71 | .col-sm-offset-right-2 {
72 | margin-right: 16.66666667%;
73 | }
74 | .col-sm-offset-right-1 {
75 | margin-right: 8.33333333%;
76 | }
77 | .col-sm-offset-right-0 {
78 | margin-right: 0;
79 | }
80 | }
81 | @media (min-width: 992px) {
82 | .col-md-offset-right-12 {
83 | margin-right: 100%;
84 | }
85 | .col-md-offset-right-11 {
86 | margin-right: 91.66666667%;
87 | }
88 | .col-md-offset-right-10 {
89 | margin-right: 83.33333333%;
90 | }
91 | .col-md-offset-right-9 {
92 | margin-right: 75%;
93 | }
94 | .col-md-offset-right-8 {
95 | margin-right: 66.66666667%;
96 | }
97 | .col-md-offset-right-7 {
98 | margin-right: 58.33333333%;
99 | }
100 | .col-md-offset-right-6 {
101 | margin-right: 50%;
102 | }
103 | .col-md-offset-right-5 {
104 | margin-right: 41.66666667%;
105 | }
106 | .col-md-offset-right-4 {
107 | margin-right: 33.33333333%;
108 | }
109 | .col-md-offset-right-3 {
110 | margin-right: 25%;
111 | }
112 | .col-md-offset-right-2 {
113 | margin-right: 16.66666667%;
114 | }
115 | .col-md-offset-right-1 {
116 | margin-right: 8.33333333%;
117 | }
118 | .col-md-offset-right-0 {
119 | margin-right: 0;
120 | }
121 | }
122 | @media (min-width: 1200px) {
123 | .col-lg-offset-right-12 {
124 | margin-right: 100%;
125 | }
126 | .col-lg-offset-right-11 {
127 | margin-right: 91.66666667%;
128 | }
129 | .col-lg-offset-right-10 {
130 | margin-right: 83.33333333%;
131 | }
132 | .col-lg-offset-right-9 {
133 | margin-right: 75%;
134 | }
135 | .col-lg-offset-right-8 {
136 | margin-right: 66.66666667%;
137 | }
138 | .col-lg-offset-right-7 {
139 | margin-right: 58.33333333%;
140 | }
141 | .col-lg-offset-right-6 {
142 | margin-right: 50%;
143 | }
144 | .col-lg-offset-right-5 {
145 | margin-right: 41.66666667%;
146 | }
147 | .col-lg-offset-right-4 {
148 | margin-right: 33.33333333%;
149 | }
150 | .col-lg-offset-right-3 {
151 | margin-right: 25%;
152 | }
153 | .col-lg-offset-right-2 {
154 | margin-right: 16.66666667%;
155 | }
156 | .col-lg-offset-right-1 {
157 | margin-right: 8.33333333%;
158 | }
159 | .col-lg-offset-right-0 {
160 | margin-right: 0;
161 | }
162 | }
--------------------------------------------------------------------------------
/css/rated_star.scss:
--------------------------------------------------------------------------------
1 | [class^="show_rated_"]{
2 | display: inline-block;
3 | font: normal normal normal 14px/1 FontAwesome;
4 | font-size: 15px;
5 | text-rendering: auto;
6 | -webkit-font-smoothing: antialiased;
7 | moz-osx-font-smoothing: grayscale;
8 | color: $main_red;
9 | margin-top: 5px;
10 | letter-spacing: 5px;
11 | }
12 | .show_rated_0::before{
13 | content: "\f006 \f006 \f006 \f006 \f006";
14 | }
15 | .show_rated_0_5::before{
16 | content: "\f123 \f006 \f006 \f006 \f006";
17 | }
18 | .show_rated_1::before{
19 | content: "\f005 \f006 \f006 \f006 \f006";
20 | }
21 | .show_rated_1_5::before{
22 | content: "\f005 \f123 \f006 \f006 \f006";
23 | }
24 | .show_rated_2::before{
25 | content: "\f005 \f005 \f006 \f006 \f006";
26 | }
27 | .show_rated_2_5::before{
28 | content: "\f005 \f005 \f123 \f006 \f006";
29 | }
30 | .show_rated_3::before{
31 | content: "\f005 \f005 \f005 \f006 \f006";
32 | }
33 | .show_rated_3_5::before{
34 | content: "\f005 \f005 \f005 \f123 \f006";
35 | }
36 | .show_rated_4::before{
37 | content: "\f005 \f005 \f005 \f005 \f006";
38 | }
39 | .show_rated_4_5::before{
40 | content: "\f005 \f005 \f005 \f005 \f123";
41 | }
42 | .show_rated_5::before{
43 | content: "\f005 \f005 \f005 \f005 \f005";
44 | }
45 |
--------------------------------------------------------------------------------
/css/setting.scss:
--------------------------------------------------------------------------------
1 | body{
2 | font-family: 'Microsoft JhengHei',Tahoma, Helvetica, Arial, "Microsoft Yahei","微软雅黑", STXihei, "华文细黑", sans-serif;
3 | }
4 | //@import "bootstrap-sprockets";
5 | //@import "bootstrap/variables";
6 | //@import "bootstrap/mixins";
7 | //@import "bootstrap/normalize";
8 | //@import "bootstrap/print";
9 | //@import "bootstrap/forms";
10 | //@import "bootstrap/scaffolding";
11 | //@import "bootstrap/type";
12 | //@import "bootstrap/grid";
13 | //@import "bootstrap/component-animations";
14 | //@import "bootstrap/dropdowns";
15 | //@import "bootstrap/navs";
16 | //@import "bootstrap/navbar";
17 | //@import "bootstrap/carousel";
18 | //@import "bootstrap/utilities";
19 | //@import "bootstrap/responsive-utilities";
20 |
--------------------------------------------------------------------------------
/css/svg_ssetting.scss:
--------------------------------------------------------------------------------
1 | .icon_setting{
2 | @include background_size_cover;
3 | background-position: center;
4 | display: inline-block;
5 | margin-right: 5px;
6 | font-size:inherit;
7 | }
8 | @mixin share_icon($color){
9 | background-image:url('data:image/svg+xml;utf8,');
26 | @extend .icon_setting;
27 | width: 1em;
28 | height: 0.9em;
29 | margin-bottom: -3px;
30 | }
31 | .share_icon_white{
32 | @include share_icon(white);
33 | }
34 | .share_icon_red{
35 | @include share_icon($main_red);
36 | }
--------------------------------------------------------------------------------
/css/tool.scss:
--------------------------------------------------------------------------------
1 | .white{
2 | color: #FFFFFF;
3 | }
4 | .red{
5 | color: $main_red;
6 | }
7 | .black{
8 | color: $main_black;
9 | }
10 | .gray{
11 | color: #9B9B9B;
12 | }
13 | .orange{
14 | color: #FF7663;
15 | }
16 | .lighter{
17 | font-weight: lighter;
18 | }
19 | .normal{
20 | font-weight: normal;
21 | }
22 | .background_red{
23 | background-color: $main_red;
24 | }
25 | .background_white{
26 | background-color: #FFFFFF;
27 | }
28 | .background_black{
29 | background-color: #444444;
30 | }
31 | .border_red{
32 | border: 1px solid $main_red ;
33 | }
34 | .border_black{
35 | border:1px solid #444444;
36 | }
37 | .sub_link{
38 | color: #003470;
39 | text-decoration: underline;
40 | }
41 | .vertical_align{
42 | vertical-align: middle;
43 | }
44 | .black_border_block{
45 | @extend .border_black;
46 | margin:15px 25px;
47 | padding: 30px;
48 | }
49 | .l_line:before{
50 | @extend .red;
51 | content:'|';
52 | font-size:16px;
53 | margin: 0 15px;
54 | }
55 | .cursor_pointer{
56 | cursor: pointer;
57 | }
58 | .background_img_setting{
59 | @include background_size_cover;
60 | background-position: center;
61 | }
62 | .border_main_radius{
63 | @include border_radius($main_radius);
64 | }
65 | .border_sub_radius{
66 | @include border_radius($sub_radius);
67 | }
68 | .border_circle{
69 | @include border_radius(50%);
70 | }
71 | .border_none_radius{
72 | @include border_radius(0px);
73 | }
74 | .fluid{
75 | width: 100%;
76 | }
77 | .small_btn{
78 | width: 84px;
79 | height: 32px;
80 | }
81 | .square_icon {
82 | @include square_icon;
83 | }
84 | .flex{
85 | @include flex;
86 | }
87 | .flex_wrap{
88 | @include flex_wrap(wrap);
89 | }
90 | .flex_space_around{
91 | @include flex_(inherit,space-around);
92 | }
93 | .vertical_space_around{
94 | @extend .flex;
95 | @extend .flex_space_between;
96 | -ms-flex-direction: column;
97 | -webkit-flex-direction: column;
98 | flex-direction: column;
99 | }
100 | .flex_space_between{
101 | @include flex_(inherit,space-between);
102 | }
103 | .flex_center_start{
104 | @include flex_(inherit,flex-start);
105 | }
106 | .flex_center{
107 | @include flex_(center,center);
108 | }
109 | .flex_vertical_center{
110 | @include flex_(center,inherit);
111 | }
112 | .bold{
113 | font-weight: bold;
114 | }
115 | .red_line{
116 | border-bottom: 1px solid $main_red;
117 | width: 100%;
118 | margin:15px auto;
119 | display: block;
120 | }
121 | .gray{
122 | color: #D4D5D6;
123 | }
124 | .gray_line{
125 | border-bottom: 1px solid #D4D5D6;
126 | width: 100%;
127 | margin:15px auto;
128 | display: block;
129 | }
130 | .absolute_center{
131 | position: absolute;
132 | left: 50%;
133 | transform: translateX(-50%);
134 | }
135 | .btn_setting{
136 | @extend .border_sub_radius;
137 | @extend .tac;
138 | @extend .cursor_pointer;
139 | display: inline-block;
140 | font-weight: inherit;
141 | font-size:1em;
142 | padding: 0 15px;
143 | line-height: 40px;
144 | min-width: 100px;
145 | height: 40px;
146 | }
147 | .ui.button.my_btn,.my_btn{
148 | @extend .background_red;
149 | @extend .white;
150 | @extend .border_red;
151 | @extend .btn_setting;
152 | }
153 | .ui.button.my_btn_reserve,.my_btn_reserve{
154 | @extend .background_white;
155 | @extend .red;
156 | @extend .border_red;
157 | @extend .btn_setting;
158 | }
159 | .my_black_btn{
160 | @extend .background_black;
161 | @extend .white;
162 | @extend .border_black;
163 | @extend .btn_setting;
164 | }
165 | .my_black_btn_reserve{
166 | @extend .border_black;
167 | @extend .background_white;
168 | @extend .black;
169 | @extend .btn_setting;
170 | }
171 | .four_btn{
172 | @extend .df;
173 | [class*=_btn],[class*=_btn_reserve]{
174 | @include calc(width,'100% / 4');
175 | margin: 5px;
176 | i{
177 | font-size: 40px;
178 | }
179 | p{
180 | line-height: 10px;
181 | margin: 0;
182 | }
183 | }
184 | }
185 | //----------------load more -----------------
186 | //
187 | //
188 | //
189 |
190 | .load_more {
191 | display: block;
192 | text-align: center;
193 | input {
194 | @extend .background_red;
195 | @extend .white;
196 | @extend .border_sub_radius;
197 | @extend .border_red;
198 | font-weight: inherit;
199 | font-size: 1em;
200 | width: 175px;
201 | height: 40px;
202 | }
203 | }
204 | .square_img{
205 | position: relative;
206 | width: 100%;
207 | padding-top: 100%;
208 | overflow: hidden;
209 | @extend .background_img_setting;
210 | img{
211 | position: absolute;
212 | left: 0;
213 | right: 0;
214 | top: 0;
215 | bottom: 0;
216 | width: 100%;
217 | height: 100%;
218 | }
219 | }
220 | @mixin align_two_side{
221 | &:after,&:before{
222 | content:' ';
223 | display: table;
224 | }
225 | &:after{
226 | clear: both;
227 | }
228 | &>:first-child{
229 | float: left;
230 | }
231 | &>:last-child{
232 | float: right;
233 | }
234 | }
235 | .align_two_side{
236 | @include align_two_side;
237 | }
238 | .align_two_side_sm{
239 | @include align_two_side;
240 | }
241 | @media (max-width: $screen-xs-max ){
242 | [class*=basic_bg]{
243 | .four_btn{
244 | @include calc(width,'100% + 10px');
245 | margin-left: -5px;
246 | padding: 0;
247 | [class*=_btn],[class*=_btn_reserve]{
248 | margin: 0;
249 | border-right: none;
250 | }
251 | }
252 | }
253 | .align_two_side_sm{
254 | & > :last-child,& > :first-child{
255 | float: inherit;
256 | display: block;
257 | }
258 | }
259 | .black_border_block{
260 | margin: -1px 0 0 -20px;
261 | @include calc(width,'100% + 40px');
262 | }
263 | }
264 |
--------------------------------------------------------------------------------
/git/git.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lustan3216/BlogArticle/949e997cbfd64bac611bf2a81bff04f47c364de8/git/git.md
--------------------------------------------------------------------------------
/html/fontawesome.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/jquery/ajax.md:
--------------------------------------------------------------------------------
1 | If u use jquery ajax to send "DELETE" to rails
2 | U need to use
3 | **data: {"_method":"delete"}**
4 |
5 | Dosen't work right below method.
6 | **type : 'DELETE'**
7 |
8 | ```js
9 | $.ajax({
10 | type: 'POST',
11 | url: "/likes/"+$(this).data('product-id'),
12 | data: {"_method":"delete"},
13 | success: function(){
14 | console.log(321);
15 | _this.removeClass('liked').addClass('unliked')
16 | }
17 | })
18 | ```
19 |
20 |
21 | 如果有時候js.erb一直沒有反應,就要去查format是不是空的
22 | 或是直接在ajax的url網址後面加.js
23 | ```js
24 | $.ajax({
25 | type: 'get',
26 | url: '<%= restaurant_path(@restaurant) %>'+'.js',
27 | data: {date:date}
28 | });
29 | ```
--------------------------------------------------------------------------------
/jquery/get_url_path.js:
--------------------------------------------------------------------------------
1 |
2 | alert('location.href: '+location.href); //輸出値為 location.href: http://www.wibibi.com/test.html?tid=222#333
3 | alert('location.protocol: '+location.protocol); //輸出値為 location.protocol: http:
4 | alert('location.hostname: '+location.hostname); //輸出値為 location.hostname: www.wibibi.com
5 | alert('location.host: '+location.host); //輸出値為 location.host: www.wibibi.com
6 | alert('location.port: '+location.port); //輸出値為 80
7 | alert('location.pathname: '+location.pathname); //輸出値為 location.pathname: /test.html
8 | alert('location.search: '+location.search); //輸出値為 location.search: ?tid=222
9 | alert('location.hash: '+location.hash); //輸出値為 location.hash: #333
10 |
--------------------------------------------------------------------------------
/jquery/image_show_immediate.md:
--------------------------------------------------------------------------------
1 | **Show pic immediately with image upload**
2 |
3 | _is trick not even upload yet skill!_
4 |
5 | ```
6 | $(function() {
7 | $('#pictureInput').on('change', function(event) {
8 | var files = event.target.files;
9 | var image = files[0]
10 | var reader = new FileReader();
11 | reader.onload = function(file) {
12 | var img = new Image();
13 | console.log(file);
14 | img.src = file.target.result;
15 | $('#target').html(img);
16 | }
17 | reader.readAsDataURL(image);
18 | console.log(files);
19 | });
20 | });
21 |
22 |
25 |
26 |
27 | ```
28 |
--------------------------------------------------------------------------------
/js/audio_play_bar.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <% if @post.audio.present? %>
7 |
11 | <% end %>
12 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
163 |
164 |
--------------------------------------------------------------------------------
/js/blob.js:
--------------------------------------------------------------------------------
1 | // HTML5 canvas, save jpeg blob and restore to canvas from blob
2 | function blob2canvas(canvas,blob){
3 | var img = new Img;
4 | var ctx = canvas.getContext('2d');
5 | img.onload = function () {
6 | ctx.drawImage(img,0,0);
7 | }
8 | img.src = blob;
9 | }
10 |
11 | // The blob was received when calling canvas.toDataURL("image/jpeg")
--------------------------------------------------------------------------------
/js/clear_hover.md:
--------------------------------------------------------------------------------
1 | 想要清掉hover可以用下面的程式碼技巧
2 | 原理只是把該元素刪除又馬上補回去 這樣就會清掉hover狀態
3 |
4 | 在手機版上常需要用到
5 |
6 | ```js
7 | $('collect_product_btn button,.follow_designer').click(function(){
8 | var el = this;
9 | var par = el.parentNode;
10 | var next = el.nextSibling;
11 | par.removeChild(el);
12 | setTimeout(function() {par.insertBefore(el, next);}, 0)
13 | })
14 | ```
--------------------------------------------------------------------------------
/js/css_block_debug.md:
--------------------------------------------------------------------------------
1 | 108 byte version
2 | ```
3 | [].forEach.call($$("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})
4 | ```
5 | 131 byte version
6 | ```
7 | [].forEach.call(document.querySelectorAll("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})
8 | ```
--------------------------------------------------------------------------------
/js/get_view_height_width.js:
--------------------------------------------------------------------------------
1 | function getInfo()
2 | {
3 | var s = "";
4 | s += " 網頁可見區域寬:"+ document.body.clientWidth;
5 | s += " 網頁可見區域高:"+ document.body.clientHeight;
6 | s += " 網頁可見區域寬:"+ document.body.offsetWidth + " (包括邊線和捲軸的寬)";
7 | s += " 網頁可見區域高:"+ document.body.offsetHeight + " (包括邊線的寬)";
8 | s += " 網頁正文全文寬:"+ document.body.scrollWidth;
9 | s += " 網頁正文全文高:"+ document.body.scrollHeight;
10 | s += " 網頁被卷去的高(ff):"+ document.body.scrollTop;
11 | s += " 網頁被卷去的高(ie):"+ document.documentElement.scrollTop;
12 | s += " 網頁被卷去的左:"+ document.body.scrollLeft;
13 | s += " 網頁正文部分上:"+ window.screenTop;
14 | s += " 網頁正文部分左:"+ window.screenLeft;
15 | s += " 螢幕解析度的高:"+ window.screen.height;
16 | s += " 螢幕解析度的寬:"+ window.screen.width;
17 | s += " 螢幕可用工作區高度:"+ window.screen.availHeight;
18 | s += " 螢幕可用工作區寬度:"+ window.screen.availWidth;
19 | s += " 你的螢幕設置是 "+ window.screen.colorDepth +" 位彩色";
20 | s += " 你的螢幕設置 "+ window.screen.deviceXDPI +" 像素/英寸";
21 | s += " 這個elecment離上螢幕匡的邊 "+ some_element.getBoundingClientRect().top ;
22 | //alert (s);
23 | }
24 | //get this x,y座標
25 | var X= this.getBoundingClientRect().left+document.documentElement.scrollLeft;
26 | var Y =this.getBoundingClientRect().top+document.documentElement.scrollTop;
27 |
28 |
29 | // getBoundingClientRect用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。
30 | // getBoundingClientRect是DOM元素到浏览器可视范围的距离(不包含文档卷起的部分)。
31 | // 该函数返回一个Object对象,该对象有6个属性:top,lef,right,bottom,width,height;
32 | // 这里的top、left和css中的理解很相似,width、height是元素自身的宽高,但是right,bottom和css中的理解有点不一样。
33 | // right是指元素右边界距窗口最左边的距离,bottom是指元素下边界距窗口最上面的距离。
34 |
--------------------------------------------------------------------------------
/js/like_super.js:
--------------------------------------------------------------------------------
1 | someFunction = function(str) {
2 | console.log('Original function: ' + str);
3 | }
4 |
5 | someFunction = (function() {
6 | var cached_function = someFunction;
7 |
8 | return function(str) {
9 | console.log('New function before: ' + str);
10 |
11 | cached_function.apply(this, arguments); // use .apply() to call it
12 |
13 | console.log('New function after: ' + str);
14 | };
15 | }());
16 |
17 | someFunction('It works!');
18 |
--------------------------------------------------------------------------------
/js/search_input_timer.js:
--------------------------------------------------------------------------------
1 | //清除當下的timer
2 | var delayTimer;
3 |
4 | clearTimeout(delayTimer);
5 | delayTimer = setTimeout(function() {
6 | $.ajax({
7 | url: '/api/v1/check_delivery_location',
8 | dataType: "json",
9 | data: {
10 | text: location_val,
11 | restaurant_id: get_restaurant_id()
12 | },
13 | type: 'GET',
14 | complete:function(data){
15 | $('.alert_message').removeClass('hidden')
16 | $('#alert_notice').html($.parseJSON(data.responseText).message)
17 | }
18 | })
19 | }, 1000);
20 |
21 |
22 | // 清除所有的timer
23 | var timers = [];
24 | // add a timer to the array
25 | timers.push(setTimeout(someFunc, 1000));
26 | // clear all timers in the array
27 | for (var i = 0; i < timers.length; i++)
28 | {
29 | clearTimeout(timers[i]);
30 | }
--------------------------------------------------------------------------------
/js/timer.js:
--------------------------------------------------------------------------------
1 | function Timer(fn, t) {
2 | var timerObj = setInterval(fn, t);
3 |
4 | this.stop = function() {
5 | if (timerObj) {
6 | clearInterval(timerObj);
7 | timerObj = null;
8 | }
9 | return this;
10 | }
11 |
12 | // start timer using current settings (if it's not already running)
13 | this.start = function() {
14 | if (!timerObj) {
15 | this.stop();
16 | timerObj = setInterval(fn, t);
17 | }
18 | return this;
19 | }
20 |
21 | // start with new interval, stop current interval
22 | this.reset = function(newT) {
23 | t = newT;
24 | return this.stop().start();
25 | }
26 | }
--------------------------------------------------------------------------------
/js/watch.js:
--------------------------------------------------------------------------------
1 | /*
2 | * object.watch polyfill
3 | *
4 | * 2012-04-03
5 | *
6 | * By Eli Grey, http://eligrey.com
7 | * Public Domain.
8 | * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
9 | */
10 |
11 | // object.watch
12 | if (!Object.prototype.watch) {
13 | Object.defineProperty(Object.prototype, "watch", {
14 | enumerable: false
15 | , configurable: true
16 | , writable: false
17 | , value: function (prop, handler) {
18 | var
19 | oldval = this[prop]
20 | , newval = oldval
21 | , getter = function () {
22 | return newval;
23 | }
24 | , setter = function (val) {
25 | oldval = newval;
26 | return newval = handler.call(this, prop, oldval, val);
27 | }
28 | ;
29 |
30 | if (delete this[prop]) { // can't watch constants
31 | Object.defineProperty(this, prop, {
32 | get: getter
33 | , set: setter
34 | , enumerable: true
35 | , configurable: true
36 | });
37 | }
38 | }
39 | });
40 | }
41 |
42 | // object.unwatch
43 | if (!Object.prototype.unwatch) {
44 | Object.defineProperty(Object.prototype, "unwatch", {
45 | enumerable: false
46 | , configurable: true
47 | , writable: false
48 | , value: function (prop) {
49 | var val = this[prop];
50 | delete this[prop]; // remove accessors
51 | this[prop] = val;
52 | }
53 | });
54 | }
--------------------------------------------------------------------------------
/rails/asset_boost_track.rb:
--------------------------------------------------------------------------------
1 | 小技巧是可以將 js 和 css code 放進 Asset Pipeline 裡面,但是只有特定頁面才會作用(這一招不管 Turbolinks 有沒有移除都適用)。方法是每一頁的 body 標籤加上 id,修改 app/views/layout/application.html.erb:
2 |
3 |
4 | 這樣如果 welcome controller 的 index 頁面的話,就會產生出 的標籤。如此這樣我們的 css 或 javascript 就可以定位了。例如可以在上述的 assets/javascript/common.js 寫:
5 |
6 | $(document).on("turbolinks:load", function() {
7 | if ( $("#welcome-index").length > 0 ) {
8 | console.log("this is welcome-index page");
9 | }
10 | })
--------------------------------------------------------------------------------
/rails/cache_asset_pipline_known.rb:
--------------------------------------------------------------------------------
1 | 此網址是參考文章,寫得非常好
2 | # http://blog.techbridge.cc/2017/06/17/cache-introduction/
3 |
4 | cache-control public 是可以存在本地、CDN,private 的話可以存在本地但不能存在CDN,max-age 就是指可以存活多久 Cache-Control: max-age=30,就是存活30秒
5 |
6 | Etag 像是該檔案的ID,http上使用的,但是該Etag是會變的,變得時機是該檔案有變更過時。
7 |
8 | Etag跟If-None-Match 是配合使用的,Server 在回傳 Response 的時候帶上Etag表示這個檔案獨有的 hash,
9 | 快取過期後瀏覽器發送If-None-Match詢問 Server 是否有新的資料(不符合這個Etag的資料),有的話就回傳新的,沒有的話就只要回傳 304 就好了。
10 |
11 | 但配合Etag 的cache方式有個不好的地方是,每次都要跟server詢問要不要更新檔案,如果不用更新就吐304,
12 | Rails的方式可以讓檔案都不用詢問server且也知道何時該更新,增加畫面render速度。
13 |
14 | Rails Asset cache(image/js/css等等)的機制是使用cache-control 設定成有效期限是 1 年 且 public,
15 | 這樣所有檔案都會直接拉本機的cache執行不再問server需不需要更新,
16 | 每次頁面都會重新加載,所以當檔案有被更新過時,asset的hash-key就會不一樣(透過MD5編碼 )
17 | 如果該檔案有被更新過,Asset pipline就會產生新的MD5編碼(模仿Etag),這樣就會去找新的檔案。
18 | e.g [https://www.fusaki.com.tw/assets/application-aa36dfddac96f89542bd893edfd9ed95d4ffebf0696b5cbec522f6f58788309a.js]
19 |
20 | 所以會變成像是index.html每次都會重新詢問server要不要重新加載畫面(Cache-Control:max-age=0, private, must-revalidate),
21 | 假如當下照片的網址是 photo-c96f89542bd8.jpg,他就會去server問第一次,然後就會拿到cache-control:public 一年有效期,第二次訪問時就直接load本地端的,
22 | 假如photo有變更了這樣hash就會變更photo-95d4ffebf069.jpg,這樣他就會重新去server找檔案了。
23 |
24 | 跟普通的Etag實作方式最大差異是,Etag每次都要跟server問需不需要更新,Rails cache實作方式不用。
--------------------------------------------------------------------------------
/rails/parperclip_defalut_img_setting.rb:
--------------------------------------------------------------------------------
1 | has_attached_file :image,
2 | styles: { medium: "300x300>", thumb: "100x100>" },
3 | default_url: ->(attachment) { ActionController::Base.helpers.asset_path('tmp/a64.png') }
--------------------------------------------------------------------------------
/rails/precomplie_setting.rb:
--------------------------------------------------------------------------------
1 | # https://gogojimmy.net/2012/07/03/understand-assets-pipline/
2 | # 覆寫 assets:precompile 來判斷是否有更新 assets,如果沒有才執行 precompile
3 | namespace :deploy do
4 | namespace :assets do
5 | task :precompile, :roles => :web, :except => { :no_release => true } do
6 | from = source.next_revision(current_revision)
7 | if capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0
8 | run_locally "bundle exec rake assets:precompile"
9 | find_servers_for_task(current_task).each do |server|
10 | run_locally "rsync -vr --exclude='.DS_Store' public/assets #{user}@#{server.host}:#{shared_path}/"
11 | end
12 | else
13 | logger.info "Skipping asset pre-compilation because there were no asset changes"
14 | end
15 | end
16 | end
17 | end
--------------------------------------------------------------------------------
/rspec/rspec.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lustan3216/BlogArticle/949e997cbfd64bac611bf2a81bff04f47c364de8/rspec/rspec.md
--------------------------------------------------------------------------------
/ruby/http_code_render_and_serialize.rb:
--------------------------------------------------------------------------------
1 | module Render
2 |
3 | HTTP_SUCCESS_CODE = [[200, 'OK'], [204, 'No Content']]
4 |
5 | HTTP_SUCCESS_CODE.each do |array|
6 | define_method(:"render_#{array[0]}") do |data, hash_options = {}, data_options = {}|
7 | render json: { status: 'Success',
8 | message: array[1],
9 | data: serialize_data(data, data_options)
10 | }.merge(hash_options), status: array[0]
11 | end
12 | end
13 |
14 |
15 | HTTP_ERROR_CODE = [[400, 'Bad Request'], [401, 'Unauthorized'], [403, 'Forbidden'], [404, 'Not Found'],
16 | [500, 'Internal Server Error']]
17 |
18 | HTTP_ERROR_CODE.each do |array|
19 | define_method(:"render_#{array[0]}") do |hash_options = {}|
20 | render json: { status: 'Error',
21 | message: array[1]
22 | }.merge(hash_options), status: array[0]
23 | end
24 | end
25 |
26 | private
27 |
28 | def serialize_data(data, options = {})
29 | serialize_class = serialize_class(data)
30 | if data.respond_to?(:to_ary)
31 | data.map { |record| serialize_class.new(record, options).as_json }
32 | else
33 | serialize_class.new(data, options).as_json
34 | end
35 | end
36 |
37 | def serialize_class(data)
38 | name = data.respond_to?(:to_ary) ? data.table_name : data.class.name
39 | name = name.singularize.capitalize + 'Serializer'
40 | name.constantize
41 | end
42 | end
--------------------------------------------------------------------------------
/ruby/plan_model.rb:
--------------------------------------------------------------------------------
1 | class PlainModel
2 | include ActiveModel::Model
3 | include ActiveSupport::Callbacks
4 | include ActiveModel::Validations::Callbacks
5 | define_callbacks :save
6 |
7 | def save
8 | if valid?
9 | run_callbacks :save do
10 | true
11 | end
12 | else
13 | false
14 | end
15 | end
16 | end
--------------------------------------------------------------------------------
/server/azure_face_detection.md:
--------------------------------------------------------------------------------
1 | ## Face - Detect
2 | 找每個人臉的 特徵
3 |
4 | 年紀 / 性別 / 毛髮 / 化妝
5 |
6 | return faceId / it will expire after 24hours
7 |
8 | ## Face - Find Similar
9 | 如果用detect 搜尋過人臉之後會被存起來,再用 detect 拿到當下照片的faceId 再去faceList 建立名單或是 faceIds array 中查找相似
10 |
11 | ## Face - Group
12 | 暫存faceId 的group會回傳的group會是個array,如果其中的人臉是相同的人會被分在同組,and return messyGroup
13 |
14 | ## Face - Identify
15 | 從person group辨識不認識的人臉,會給出信心指數排名
16 | person group應該要被訓練成可以被辨識的
17 | 1. 可以一次至多10張臉辨識一個group
18 | 2. Face - Find Similar 可以從facelist來辨識 similar 臉,取代person group
19 |
20 | ## Face - Verify
21 | 便是兩張照片是否同一個人
22 |
23 | ## Face List - Add a Face to a Face List post
24 | 被塞進去的臉都會具有一個 targetFace rectangle,新增一個臉進去 faceList 被塞進list裡面的臉都會具有一個presistedDaceId
25 | 1. 要刪除就用Delete
26 | 2. JPEG, PNG GIF BMP 照片須大魚1kb 小於4MB
27 | 3. 可以偵測的face size 36*36 ~4096*4096
28 | 4. 如果多張臉或是被東西擋住也會被視為error
29 | 5. 被指定的方筐如果不是從face detect來的話不保證資料正確性
30 |
31 | Facelist 裡面的資料都不會過期,可以用Find Similar 查找相似臉。
32 | 常用於查找慶祝會,朋友群,家庭群組
33 | face group have a maximum of 1000 faces
34 |
35 | ## Face List - Create a Face List put
36 | 可以創建空的list 附帶名字和userData
37 |
38 | ## Person - Add a Person Face post
39 | 加入一個這個人的辨識圖.這個臉會有個 targetFace rectangle, 這個會return 一個persistedFaceId代表這張臉。
40 | 也可以是用face - detect 偵測臉
41 |
42 | 1. 每個人可以有248張照片
43 | 2. JPEG, PNG GIF BMP 照片須大魚1kb 小於4MB
44 | 3. 可以偵測的face size 36*36 ~4096*4096
45 | 4. 如果多張臉或是被東西擋住也會被視為error
46 |
47 | ## Person - Create a Person post
48 | 可以用name userData
49 | person會被create 在一個person group裡面
50 | 如果有照片沒有主人 就可以create一個person拿來放照片
51 | 免費的等級每個group只能有1000個人,付費的話可以有10000或更多的人數
52 |
53 | ## Person Group - Create a Person Group put
54 | 可以 create 一個 person group
55 | 這個可以被 Face - Identify 用來查詢臉
56 |
57 | ## Person Group - Get Person Group Training Status get
58 | status : person group需要被訓練成successed才可以被 Face - Identify 拿來查找
59 |
60 | ## Person Group - Train Person Group post
61 | 指定 group 進序列開始等待訓練,並不會馬上開始訓練
62 | 訓練完才能開始被 Face - Identify 使用,可以用上面這隻一直去get status 詢問好了沒
63 |
64 |
65 |
66 |
67 |
68 | TIER |
69 | FEATURES |
70 | PRICE |
71 |
72 |
73 |
74 |
75 | Face API – Free |
76 | Up to 20 transactions per minute |
77 | 30,000 transactions free per month |
78 |
79 |
80 | Face API – Standard |
81 | Up to 10 transactions per second |
82 | |
83 |
84 |
85 | |
86 | 0 - 1,000,000 transactions |
87 | NT$46.55 per 1,000 transactions |
88 |
89 |
90 | |
91 | 1,000,001 - 5,000,000 transactions |
92 | NT$34.14 per 1,000 transactions |
93 |
94 |
95 | |
96 | 5,000,001 - 20,000,000 transactions |
97 | NT$20.17 per 1,000 transactions |
98 |
99 |
100 | Face Storage |
101 | Face storage - images size up to 4 MB each |
102 | NT$15.52 per 1,000 images per month |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/server/elasticsearch.md:
--------------------------------------------------------------------------------
1 | elasticsearch 預設就會對所有的字串做分詞,且會變成「小寫」
2 | 如果不把自動分析關掉的話,你用term去搜尋一定會搜不到東西
3 |
4 | 因為你打大寫,可是他會用小寫去查
5 | 所以為了關掉
6 |
7 | 要先把原本的刪掉 在新增建一個,並改成以下這樣
8 |
9 | ```
10 | PUT /my_store <2>
11 | {
12 | "mappings" : {
13 | "products" : {
14 | "properties" : {
15 | "productID" : {
16 | "type" : "string",
17 | "index" : "not_analyzed" <3>
18 | }
19 | }
20 | }
21 | }
22 |
23 | }
24 | ```
--------------------------------------------------------------------------------
/server/elk_config_settings.md:
--------------------------------------------------------------------------------
1 | ```json
2 | server {
3 | listen 80;
4 | server_name kibana.inforcharge.com;
5 | rewrite ^ https://$server_name$request_uri? permanent;
6 |
7 | }
8 | server{
9 | listen 443 ssl http2;
10 | server_name kibana.inforcharge.com 104.199.142.24;
11 |
12 | #auth_basic "Restricted Access";
13 | #auth_basic_user_file /etc/nginx/.kibana-user;
14 |
15 | ssl on;
16 | ssl_certificate /etc/nginx/ssl/inforcharge.crt;
17 | ssl_certificate_key /etc/nginx/ssl/inforcharge.key;
18 | ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
19 | ssl_prefer_server_ciphers on;
20 |
21 | location /dashboard/ {
22 | # rewrite ^/kibana/(.*) /$1 break;
23 | proxy_pass http://localhost:5601/;
24 | proxy_redirect http://host:5601/ /dashboard/;
25 | proxy_http_version 1.1;
26 | proxy_set_header Upgrade $http_upgrade;
27 | proxy_set_header Connection 'upgrade';
28 | proxy_set_header Host $host;
29 | proxy_cache_bypass $http_upgrade;
30 | }
31 | location / {
32 | proxy_pass http://localhost:9200/;
33 | proxy_http_version 1.1;
34 | proxy_set_header Upgrade $http_upgrade;
35 | proxy_set_header Connection 'upgrade';
36 | proxy_set_header Host $host;
37 | proxy_cache_bypass $http_upgrade;
38 | }
39 | location /logstash/ {
40 | add_header Access-Control-Allow-Origin *;
41 | default_type application/json;
42 | proxy_pass http://localhost:8080/;
43 | proxy_http_version 1.1;
44 | proxy_set_header Upgrade $http_upgrade;
45 | proxy_set_header Connection 'upgrade';
46 | proxy_set_header Host $host;
47 | proxy_cache_bypass $http_upgrade;
48 | add_header 'Access-Control-Allow-Headers' 'Content-Type';
49 | }
50 |
51 |
52 | }
53 |
54 | ```
55 |
56 | ```json
57 | network.bind_host: localhost
58 | network.publish_host: kibana.inforcharge.com
59 | #transport.publish_port: 443
60 | #transport.tcp.port: 443
61 | # Set a custom port for HTTP:
62 | #
63 | http.publish_port: 443
64 | http.port: 9200
65 | #transport.tcp.port: 9201
66 |
67 | ```
68 |
69 |
70 | ```json
71 | input {
72 | http {
73 | port => 8080
74 | host => "127.0.0.1"
75 | }
76 | }
77 | filter{
78 | # ruby {code => "require 'pry'; binding.pry"}
79 | if [message] =~ /^\s*$/ {
80 | drop { }
81 | }
82 |
83 | split{ field => "results" }
84 | mutate {
85 | rename => [
86 | "[results][sn]", "sn",
87 | "[results][ad_id]", "ad_id",
88 | "[results][ad_type]", "ad_type",
89 | "[results][faces_length]", "faces_length",
90 | "[results][male]", "male",
91 | "[results][female]", "female",
92 | "[results][average_age]", "average_age",
93 | "[results][ad_faces_price]", "ad_faces_price",
94 | "[results][ad_impression_price]", "ad_impression_price",
95 | "[results][ad_calculated_faces_price]", "ad_calculated_faces_price",
96 | "[results][ad_click_price]", "ad_click_price",
97 | "[results][faces_data]", "faces_data"
98 | ]
99 | remove_field => "results"
100 | }
101 | }
102 | output{
103 | #stdout { codec => rubydebug }
104 | # if "_split_type_failure" not in [tags] {
105 | elasticsearch {
106 | index => "ads-%{+YYYY.MM.dd}"
107 |
108 | ```
--------------------------------------------------------------------------------
/server/encrypt_like_pem.md:
--------------------------------------------------------------------------------
1 | 1. 假設你先在使用者電腦localstorage 存著 localstorage.Auth = ‘ABC’ (這個ABC裡面可以加一些expired_time,or 你想要的uniq值)
2 |
3 | 2. 那他登入前會帶著 Auth,不管裡面是什麼值,只要Rails認得 ABC 他就覺得這是我認識的人,我要給他許可權限。
4 |
5 | 3. 那RAILS 就會用,IP、瀏覽器資訊、時間、Rails的sercret key,做加密變成一個「好像是憑證的東西」,再把這個字串丟回給頁面用JS 用locastroage存起來。
6 |
7 | 4. 然後以後每次有帶這個「好像是憑證的東西」,Rails就會先用 IP、瀏覽器資訊、時間、Rails的sercret key再加密,看這個結果會不會跟「好像是憑證的東西」一樣,一樣就通過。
8 |
9 | 5. 這樣加密邏輯是做在後端,前端也只知道你會丟Auth,不會知道你是用IP和瀏覽器資訊做加密的。
10 | 換去別的電腦也會因為瀏覽器資訊、IP不一樣所以在步驟4 RailS再驗證的時候就不合格
11 |
12 | 6. 假設你要讓所有「好像是憑證的東西」失效,把Rails的sercret key改掉就可以了
13 |
14 | 最一開始要發可以「有權限拿「好像是憑證的東西」」的那個字串
15 | 可以做成Emails的方式寄給那個人開,這個字串裡面要有expried_time,不然會換別人拿去開。
16 |
17 | 打開會跳掉那個網站裡面,然後最開始作剛剛上面那些事。
18 |
--------------------------------------------------------------------------------
/server/nginx_site_enable_yml.md:
--------------------------------------------------------------------------------
1 | ```
2 | upstream inforcharge_sock {
3 | server unix:/var/tmp/nginx.sock fail_timeout=0;
4 | }
5 |
6 | server {
7 | listen 80 default_server;
8 | listen [::]:80 default_server ipv6only=on;
9 |
10 | root /home/deployer/inforcharge/current/public;
11 |
12 | # Make site accessible from http://localhost/
13 | server_name 54.169.174.47;
14 |
15 |
16 | location / {
17 | proxy_redirect off;
18 | proxy_set_header Host $host;
19 | proxy_set_header X-Forwarded-Host $host;
20 | proxy_set_header X-Forwarded-Server $host;
21 | proxy_set_header X-Real-IP $remote_addr;
22 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
23 | proxy_buffering on;
24 | proxy_pass http://inforcharge_sock;
25 | }
26 |
27 | location ~ ^/assets/ {
28 | expires 1y;
29 | add_header Cache-Control public;
30 | add_header ETag "";
31 | break;
32 | }
33 |
34 | location ~ ^/data/ {
35 | expires 1y;
36 | add_header Cache-Control public;
37 | add_header ETag "";
38 | break;
39 | }
40 |
41 | location ~* \.(?:htm|pdf|svg|ico)$ {
42 | expires 1y;
43 | add_header Cache-Control public;
44 | add_header ETag "";
45 | break;
46 | }
47 | }
48 |
49 | server {
50 | listen 443;
51 | listen [::]:443 ipv6only=on;
52 | server_name 54.169.174.47;
53 |
54 | root /home/deployer/inforcharge/current/public;
55 |
56 | ssl on;
57 | ssl_certificate /etc/nginx/ssl/ssl-bundle2.crt;
58 | ssl_certificate_key /etc/nginx/ssl/inforcharge.key;
59 |
60 | ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
61 | ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
62 | ssl_prefer_server_ciphers on;
63 |
64 | location ~ ^/assets/ {
65 | expires 1y;
66 | add_header Cache-Control public;
67 | add_header ETag "";
68 | break;
69 | }
70 |
71 | location ~ ^/data/ {
72 | expires 1y;
73 | add_header Cache-Control public;
74 | add_header ETag "";
75 | break;
76 | }
77 |
78 | location / {
79 | proxy_redirect off;
80 | proxy_set_header Host $host;
81 | proxy_set_header X-Forwarded-Host $host;
82 | proxy_set_header X-Forwarded-Server $host;
83 | proxy_set_header X-Real-IP $remote_addr;
84 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
85 | proxy_buffering on;
86 | proxy_pass http://inforcharge_sock;
87 | }
88 |
89 | location ~* \.(?:htm|pdf|ico|svg)$ {
90 | expires 1y;
91 | add_header Cache-Control public;
92 | add_header ETag "";
93 | break;
94 | }
95 |
96 | location /download-app/c209r {
97 | return 301 https://www.inforcharge.com/download/c209r;
98 | }
99 | location /privacy-policy/c98r {
100 | return 301 https://www.inforcharge.com/privacy/c98r;
101 | }
102 | location /rate/c1r55 {
103 | return 301 https://www.inforcharge.com/rate-x/c1r55;
104 | }
105 |
106 | }
107 | ```
--------------------------------------------------------------------------------
/sql/remote_to_server_database.md:
--------------------------------------------------------------------------------
1 | http://zackwang.blogspot.tw/2013/11/mysql.html
2 | http://eportfolio.lib.ksu.edu.tw/~T093000170/blog?node=000000174
3 |
4 | GRANT ALL PRIVILEGES ON food_p.* TO 161.202.37.152 IDENTIFIED BY 'PassWord' WITH GRANT OPTION;
5 |
6 | GRANT ALL PRIVILEGES ON food_p.* TO ‘root'@'161.202.37.152’ IDENTIFIED BY ‘12345678’ WITH GRANT OPTION;
--------------------------------------------------------------------------------
/sql/set_character.md:
--------------------------------------------------------------------------------
1 | 改掉 原本的character
2 |
3 | ```sql
4 | ALTER TABLE featured_links CONVERT TO CHARACTER SET utf8mb4;
5 | ```
6 |
--------------------------------------------------------------------------------