分類
記事

Cardboard體驗

google這個Cardboard可比上次那個glass親民多啦,雖然官網那些也都蠻貴,但是我們有淘寶啊,13塊從山西買了一個。效果挺好的,對手機像素要求挺高,我的Z(5.0吋TFT 螢幕 1600 萬色 1920 x 1080 畫素)感覺還可以,但是像素再低些應該就沒法看了。

資源方面先去谷歌市場裝一個Cardboard,然後就會引導你去下更多應用如過山車、星空漫遊等應用,也可以引導你去youtube觀看VR影片。應用方面,體驗很好,但是沒法操作手機算是一個遺憾,磁控鍵我就沒用成功過。說道這個磁控鍵,設計真是神奇,好像看到了二次元的東西。另外就是有些應用我始終對不上焦,應該是應用本身的問題。電影不僅考驗屏幕還考驗網速。總結就是Cardboard值得一試,直接從Cardboard裏推薦的應用玩一玩就很不錯了。

由於是紙板,所以有時位置不是很精確,但是手調整一下就好了。另外我沒用帶子,直接用手舉着看的,也比較舒服。還有我近視350度,不用眼鏡可以正常觀看。

分類
网站

php生成圖片與crontab

PHP生成圖片

//@function.php
//先獲取個GET參數等下寫圖片里
if ($_GET["name"]) {
    $name = htmlspecialchars($_GET["name"]);
} else {
    $name = '';
}
//創建圖像
$img=getImgType($img_path);
$img=createImg($img,$wordsPhoto,$left_px,$top_px,25,0,20,'19f','ARIALUNI');
//保存圖像
$img_info=saveImg($img,'png');

//創建圖像函數
function getImgType($img_path) {
	$img = getimagesize ( $img_path );
	switch ($img [2]) {
		case 1 :
			$img = @imagecreatefromgif ( $img_path );
			break;
		case 2 :
			$img = @imagecreatefromjpeg ( $img_path );
			break;
		case 3 :
			$img = @imagecreatefrompng ( $img_path );
			break;
		default :
			$img = @imagecreatefrompng ( $img_path );
	}
	return $img;
}
//修改圖像函數
function createImg($img, $str, $x, $y, $length = 20, $angle = 0, $size = 12, $color = '39f', $font = 'kanghua') {
	switch ($color) {
		case '19f' :
			$color = imagecolorallocate ( $img, 22, 157, 252 );
			break;
		case 'f37' :
			$color = imagecolorallocate ( $img, 255, 51, 119 );
			break;
		case '63a' :
			$color = imagecolorallocate ( $img, 68, 172, 106 );
			break;
		case 'f90' :
			$color = imagecolorallocate ( $img, 255, 158, 3 );
			break;
		case 'a60' :
			$color = imagecolorallocate ( $img, 172, 106, 0 );
			break;
		case '790' :
			$color = imagecolorallocate ( $img, 113, 149, 13 );
			break;
		case 'fff' :
			$color = imagecolorallocate ( $img, 255, 255, 255 );
			break;
		case '000' :
			$color = imagecolorallocate ( $img, 0, 0, 0 );
			break;
		default :
			$color = imagecolorallocate ( $img, 67, 157, 252 );
	}
	switch ($font) {
		case 'ARIALUNI' :
			$font = './../font/ARIALUNI.ttf';
			break;
		case 'CODE2000' :
			$font = './../font/CODE2000.ttf';
			break;
		case 'SarunsManorah' :
			$font = './../font/SarunsManorah.ttf';
			break;
		case 'FreeSerif' :
			$font = './../font/FreeSerif.ttf';
			break;
		case 'kanghua' :
			$font = './../font/kanghua.ttf';
			break;
		case 'shishang' :
			$font = './../font/shishang.ttf';
			break;
		case 'yahei' :
			$font = './../font/yahei.ttf';
			break;
		default :
			$font = './../a_include/font/kanghua.ttf';
	}
	$str = wordwrap_utf8 ( $str, $length );
	imagettftext ( $img, $size, $angle, $x, $y, $color, $font, $str );
	return $img;
}
//文字换行
function wordwrap_utf8($string, $length = 20, $break = "\n", $cut = false) {
	if ($length == 0) {
		return $string;
	}
	preg_match_all ( '/./u', $string, $matches );
	$s = $matches [0];
	$ct = count ( $s );
	for($i = 0; $i < ceil ( $ct / $length ); $i ++) {
		$ns .= implode ( '', array_slice ( $s, $i * $length, $length ) ) . $break;
	}
	return $ns;
}
function saveImg($img, $type = 'png') {
	$img_url = '';
	$img_name = time ().rand(10,99);
        //php5.5以上才支持webp
	if ($type == 'jpg') {
		$img_url = '/a_cache/' . $img_name . '.jpg';
		$img_filename = dirname ( dirname ( dirname ( __FILE__ ) ) ) . '/a_cache/' . $img_name . '.jpg';
		imagejpeg ( $img, $img_filename );
	} else {
		$img_url = '/a_cache/' . $img_name . '.png';
		$img_filename = dirname ( dirname ( dirname ( __FILE__ ) ) ) . '/a_cache/' . $img_name . '.png';
		imagepng ( $img, $img_filename );
	}
	imagedestroy ( $img );
	$img_info ['img_name'] = $img_name;
	$img_info ['img_url'] = '..' . $img_url;
        return $img_info;
}

網頁展示圖片

//@show.php
require_once 'function.php';

<div style="width:100%;text-align:center;background-color: #58C7C2;padding: 0.52em 0.1em 0.52em 0.1em;">
<img id="res_pic" style="display: block;width: 70%;margin-left: 15%;" src="<?php echo $img_info['img_url'];?>" />
</div>

用corntab定期清理緩存圖片

創建可執行文件/www/del_cache,內容如下,意思是刪除兩天前的文件

#!/bin/bash 
find /path/to/your/a_cache/* -mtime +2 -exec rm -f {} \;

把執行文件加入定時任務

crontab -e
#如果有多個編輯器,可能會讓選擇編輯器,但我CentOS中有nano,並沒有提示,我還是得用vi

修改並把下面一行粘貼到最後,意思是每小時的0分執行一次

00 * * * * /path/to/the/script

有時我們需要每30秒執行一次定時任務,但是crontab只能精確到分,可以這麼做:

* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )

這裡還有一個每90秒的例子:

*/3 * * * * /path/to/executable param1 param2
*/3 * * * * ( sleep 90 ; /path/to/executable param1 param2 )

有時我們需要以root用戶來執行crontab中的命令,僅僅切換到root用戶然後使用crontab -e似乎還是不行,後來發現(CentOS下)可以這樣:

nano /etc/crontab
#在這裡編輯需要定時執行的命令,並指定運行命令的用戶
03 * * * * root /path/to/the/script

有時的需求是這樣的,定時任務執行時間不確定,比如有時10分鐘,有時30分鐘,但是我們還不想同時執行兩個任務,這時可以使用flock文件鎖來控制只有一個程序在跑。

#下面的效果就是,每5分鐘檢查一次,如果在ping就跳過此次執行
*/5 * * * * flock -xn /tmp/42ping.lock -c 'ping -c 1000 ft.wupo.info >> ping.log'
#測試發現即使程序異常中斷,lock也會被解除,下次任務仍然得以運行

參考了How to Delete Old Files In A Folder Automatically In LinuxRunning a cron every 30 seconds。對於crontab的寫法,可以到crontab.guru來驗證是否正確。其實我主要是想記錄這一段。

本文更新於 2017/03/07。

分類
网站

Line分享

製作Line分享按鈕請先參考官方文檔用LINE傳送。簡單說是Line分享只能傳一條文本消息和一個url鏈接。http://形式會先跳轉到Line服務器的一個網頁,讓用戶選擇打開Line還是安裝Line。line://形式則直接打開Line進行分享,但是如果用戶沒有安裝Line則按鈕會沒有反應。

使用中發現,Line對Emoji的支持還是很好的,可以放到分享信息中,可以參見Emojiえもじ。同時還發現Line對url的支持有問題,即url中如果出現非英文字符,Line即會將url中剩餘部分丟棄,造成url丟失數據。其實這個解決起來很簡單,用php自帶的base64函數把中文編碼一下再傳遞就好了。只用base64是不行的,因為裡面會有空格等字符會被Line裁掉,所以在加一層urlencode就好了。

//js中定義好Line的分享鏈接,name用base64加密,下面一行php被wordpress保護機制注釋了。
var urlShare="http://www.55mun.com/gameh5/match3/indexv.php?name=<?php echo urlencode(base64_encode($name));?>";
//php中接收並解析出name
$n=htmlspecialchars(base64_decode(urldecode($_GET["name"])));


Line分享網址抓取錯誤

有次分享網址,抓取到的縮略圖和標題都是網站主頁的信息,後來發現是head裏有一條meta信息導致的,這條meta中的url必須是分享的url,否則line就肯定會按照這個meta中的url來抓取:

<meta http-equiv="mobile-agent" content="format=html5;url=http://thePage.you.wishToShare/">

關注Line@

寫法1:

Follow <a href="line://ti/p/@myLineAtAccount">myLineAtAccount</a>

寫法2:

Follow <a href="intent://ti/p/@myLineAtAccount#Intent;scheme=line;action=android.intent.action.VIEW;category=android.intent.category.BROWSABLE;package=jp.naver.line.android;end">myLineAtAccount</a>

本文更新於 2016/07/15。

分類
程序

Emojiえもじ

Emoji即顏文字,現在還挺流行的,像?,完整表可以看Emoji Unicode Tables。其中第一列就是當前設備原生顏文字的表現形式。由於顏文字實際上是字符,所以不同平台有不同的展現形式,就像不同的字體一樣。如果想在網頁中加入顏文字,直接把顏文字當字符複製到網頁中就可以了。

最近用到一個功能,讓Line分享的信息中包含顏文字排列出的圖案,像這種
     ??     ??
???????
???????
???????
     ?????
          ???
               ?
問題主要在於空格和換行,空格無需處理,直接放到待分享信息中即可,換行用\n代替,就可把上面圖案傳至Line分享框了。Line的分享格式我是這樣寫的:

var shareMsg='好搞笑哦\n?';
function shareToLine42(){
	lineUrl="line://msg/text/"+encodeURIComponent(shareMsg)+"%0D%0Ahttps://ft.wupo.info/";
	//如果你有谷歌統計,下面一行可以統計按鈕的點擊次數
	//ga('send', 'event', 'button', 'click', 'share-line-button');
	window.open(lineUrl, 'sharer', 'toolbar=0,status=0,width=626,height=436');
}
注意,shareMsg中顏文字被wordpress做了修改,用來兼容沒有顏文字的平台,實際直接這樣寫"好搞笑哦\n?"就可以。後面代碼中再有顏文字我用"顏文字UTF8"代替。

在wordpress4.4中,顏文字是這樣展現的,把真正的utf8字符放到了alt標籤里。

<img class="emoji" draggable="false" alt="顏文字UTF8" src="https://s.w.org/images/core/emoji/72x72/1f602.png">
去數據庫發現posts表中post_content字段類型為longtext,排序規則為utf8mb4_unicode_ci。其中保存的就是?,而用圖片替換顏文字是發生在文章輸出過程中的。關於排序規則請參考:What's the difference between utf8_general_ci and utf8_unicode_ci,如果沒空細看,那麼結論是直接用utf8mb4_unicode_ci就好。如果你還在用utf8-general-ci,是無法儲存顏文字的。

本文更新於 2016/07/20。

分類
記事

原來Airbnb是這個意思啊

字幕好評。以前真不知道Airbnb的意思,理念很不錯!

如果你有意加入Airbnb,可以通過下面的鏈接來註冊,這樣你將獲得¥262的獎勵。推薦鏈接:zh.airbnb.com/c/qianz69?s=8

我深圳的單間:https://zh.airbnb.com/rooms/8514245

本文更新於 2016/08/18。

分類
网站

網站用上了letsencrypt的免費ssl證書

使用 certbot 獲取證書

請訪問 certbot instructions 安裝 cerbot。在 CentOS 7 和 8 中使用 certbot 搭配 Cloudflare 插件實現自動更新證書的安裝與配置流程是這樣的:

#安裝 snapd 參考:https://snapcraft.io/docs/installing-snap-on-centos
sudo yum install epel-release
sudo yum install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
sudo snap install core
sudo snap refresh core

#刪除舊版 certbot
sudo yum remove certbot
#安裝 certbot
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo snap set certbot trust-plugin-with-root=ok
#安裝 Cloudflare 插件
sudo snap install certbot-dns-cloudflare
#配置 Cloudflare api token
nano .cloudflare.ini
#配置文件內容爲

# Cloudflare API token used by Certbot
dns_cloudflare_api_token = QYuhPLUGSPvN30Yry0CXe3PSYJlkIjc_laJgUifd

#修改配置文件權限
chmod 600 .cloudflare.ini

#申請證書
sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.cloudflare.ini \
  --dns-cloudflare-propagation-seconds 60 \
  -d ft.shaman.eu.org\
  -d plausible.manchuria.eu.org

#測試自動更新
sudo certbot renew --dry-run --dns-cloudflare --dns-cloudflare-credentials ~/.cloudflare.ini --dns-cloudflare-propagation-seconds 60
# crontab 自動更新配置
52 2 * * 0 certbot renew --dns-cloudflare --dns-cloudflare-credentials /home/42/.cloudflare.ini --dns-cloudflare-propagation-seconds 60 --post-hook "nginx -s reload"

#查看當前已經申請的證書
sudo certbot certificates 

通過 DNS-01 challenge 方式獲取證書

由於有台服務器未打開 80 端口且用了 Cloudflare 的 CDN,所以採用 DNS 的方式來獲取證書。>

sudo certbot certonly --manual --preferred-challenges=dns -d ft.wupo.info
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.

Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.ft.wupo.info with the following value:

7G6Qad5U7z4u4036tk1e5DAPGZ2WSbaSDFhlYLBnjcQ

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
#此時去 Cloudflare 的 DNS 記錄中新增一條 TXT 類型,名稱是 _acme-challenge.ft,內容為 
# 7G6Qad5U7z4u4036tk1e5DAPGZ2WSbaSDFhlYLBnjcQ 
# 的記錄,保存後稍微等待一下下待 DNS 生效,然後回來繼續
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/ft.wupo.info/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/ft.wupo.info/privkey.pem

不使用 snap

有台 CentOS 8 安裝 snap 不成功,使用 pip 來申請 Let’s Encrypt 證書也是很方便的。

首先在 nginx 配置一個空網站,如

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    root /var/www/html;
    server_name ft.shaman.eu.org;
}

然後:



sudo dnf install python3 augeas-libs
sudo dnf remove certbot
sudo python3 -m venv /opt/certbot/
sudo /opt/certbot/bin/pip install --upgrade pip
sudo /opt/certbot/bin/pip install certbot certbot-nginx
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot

#生成證書並自動配置 nginx
sudo certbot --nginx
#或僅生成證書
sudo certbot certonly --nginx


小撇步

雖然已經 2024 年底,但是客戶的 CentOS 7 還在運行。安裝的時候不要使用系統自帶的 python3.6,太舊啦。最好自己編譯一個新版 python3 。降級 urllib3 sudo /opt/certbot/bin/pip install urllib3==1.26.7 可以避免 ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+

--以下爲久遠內容不足爲看--

藉助於SSL For Free,可以快速申請Let's Encrypt的SSL證書,然後複製到Vesta Panel中就OK啦,非常方便。實在太簡單啦,所以沒什麼可寫的。證書有效期三個月,快過期時可再次免費更新。

nginx中將http重定向到https,可以在配置文件中這樣設置:

server {
    listen      80;   #listen for all the HTTP requests
    server_name example.com www.example.com;
    return      301         https://www.example.com$request_uri;
}

SSL For Free的證書直接用在nginx上

Certificate Successfully Generated後,下載生成的證書,合併certificate.crt和ca_bundle.crt

cat certificate.crt >> bundle.crt
printf "\n" >> bundle.crt
cat ca_bundle.crt >> bundle.crt

nginx的配置可以這樣寫

server {
    listen 192.111.111.111:443 ssl;
    server_name ft.wupo.info;

    ssl_certificate     /etc/letsencrypt/42/bundle.crt;
    ssl_certificate_key /etc/letsencrypt/42/private.key;
    ssl_protocols	TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

本文更新於 2024/11/29。

分類
网站

Mobile Detect

Mobile_Detect is a lightweight PHP class for detecting mobile devices (including tablets). It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.