Weil Jimmer's BlogWeil Jimmer's Blog


不用寄信 檢查 Email 是否 真實 存在 PHP
No Comments

發布:
更新:2016-08-04 20:48:17

最近很常研究 Email,由於是自己架設伺服器,比較麻煩,所以更深入研究了一下下。

今天想到就寫一篇,真實檢查 Email 的方法,因為這個不是驗證 Email 格式與否,而是直接驗證 此Email是否存在,並且無須寄信即可以檢查。

首先先查詢 Email @後域名的MX紀錄,再查此IP,得到 IP 後即可透過 TCP 連線至該 SMTP 伺服器驗證以確立此 Email 確實存在,而不是亂打的。

//Check email is exist
var_dump(check_is_email_real_exist("test@example.com"));

function check_is_email_real_exist($email_address){
	if ((!filter_var($email_address, FILTER_VALIDATE_EMAIL)===false) and strlen($email_address)<=254){
		$emailxx=explode('@',$email_address);
		$dns_lookup_result=dns_get_record($emailxx[1],DNS_MX);
		if (count($dns_lookup_result)==0){
			return false;
		}else{
			$address=gethostbyname($dns_lookup_result[0]['target']);
			if ($address!=''){
				$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
				if ($socket === false) {
					echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
					return false;
				}
				$result = socket_connect($socket, $address, 25);
				if ($result === false) {
					echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
					return false;
				}
				$in = "HELO hi\r\n";
				socket_write($socket, $in, strlen($in));
				if(substr(socket_read($socket, 2048),0,3)=='220'){
					$in = "MAIL FROM:<thisistest@gmail.com>\r\n";
					socket_write($socket, $in, strlen($in));
					if(substr(socket_read($socket, 2048),0,3)=='250'){
						$in = "RCPT TO:<$email_address>\r\n";
						socket_write($socket, $in, strlen($in));
						if(substr(socket_read($socket, 2048),0,3)=='250'){
							$in = "QUIT\r\n";
							socket_write($socket, $in, strlen($in));
							if(substr(socket_read($socket, 2048),0,3)=='250'){
								return true;
							}else{
								return false;
							}
						}else{
							return false;
						}
					}else{
						return false;
					}
				}else{
					return false;
				}
			}else{
				return false;
			}
		}
	}else{
		return false;
	}
}

代碼醜陋,請各位看官不要介意。


This entry was posted in General, Experience, Functions, PHP By Weil Jimmer.

Bash 自動備份網站與異地備份
No Comments

發布:
更新:2016-07-25 17:48:02

這是我現在所用的方法,直接分享出來,備份壓縮網站資料與資料庫十日,自動刪除近十日之外的檔案。

建立一個 backup.sh 檔案,內容如下:(FTP地址帳密、網站路徑、資料庫密碼…要自己修改一下)

#!/bin/sh

THESITE="example.com"
THEDATE=$(date +%Y-%m-%d_%H_%M_%S)

mysqldump --defaults-file=/home/user/secret.cnf --user=root --host=localhost --all-databases | gzip > /var/www/$THESITE/backup/db_$THEDATE.sql.gz

tar czf /var/www/$THESITE/backup/site_${THEDATE}.tar /var/www/$THESITE/public_html/
gzip /var/www/$THESITE/backup/site_${THEDATE}.tar

find /var/www/$THESITE/backup/site* -mtime +10 -exec rm {} \;
find /var/www/$THESITE/backup/db* -mtime +10 -exec rm {} \;

echo "OK"

ftp -n 31.170.xxx.xxx <<End-Of-Session
user USERNAME "PASSWORD"
binary
cd /public_html/backup/secret_path
put "/var/www/$THESITE/backup/db_$THEDATE.sql.gz" "db_backup.sql.gz"
put "/var/www/$THESITE/backup/site_${THEDATE}.tar.gz" "site_backup.tar.gz"
bye
End-Of-Session

wget http://backupsite.com/ -O /tmp/keep_online
rm /tmp/keep_online

創一個文檔在 /home/user/secret.cnf (或你喜歡的地方),然後設定權限 400 或 600 內容填入如下。

[client]
password="MYSQL_PASSWORD"

最後 在終端機 打指令

crontab -e

在最下面加入:(設定定時任務,零時零分自動備份網站並透過FTP外寄出去)

0 0 * * * sh /the_path_you_want/backup.sh

這樣就可以完成幾乎全自動的備份。


This entry was posted in Bash, General, Experience, Functions, Note, WebHosting By Weil Jimmer.

Telegram Bot 開發機器人 (2) Python
No Comments

發布:
更新:2016-07-04 15:11:22

這是我第二篇文章有關於 Telegram 機器人,此機器人的功能極其簡單!監控伺服器的使用率,最近因為在伺服器又搞了一個很麻煩的東西,要時時刻刻注意有沒有異常。所以才寫了這個小程式(如圖)。

本文直接省略@BotFather產生機器人的說明,我想那應該不是問題。第一篇文章請參考:淺談Telegram開發機器人

本程式一旦運行,就不會停止,每隔固定幾秒鐘會自動更新訊息,會一直不斷的編輯,而不是一直送出(Telegram 有支持編輯訊息的功能)。直接上程式碼。這次使用Python,因為牽扯到系統,用 PHP 就不太適合了。

# coding: utf-8
"""By Weil Jimmer"""
import os,urllib.request,shutil,sys,re,datetime,json,psutil
from time import sleep
from sys import platform as _platform

def __init__(self):
	print("")

GRAY = "\033[1;30m"
RED = "\033[1;31m"
LIME = "\033[1;32m"
YELLOW = "\033[1;33m"
BLUE = "\033[1;34m"
MAGENTA = "\033[1;35m"
CYAN = "\033[1;36m"
WHITE = "\033[1;37m"
BGRAY = "\033[1;47m"
BRED = "\033[1;41m"
BLIME = "\033[1;42m"
BYELLOW = "\033[1;43m"
BBLUE = "\033[1;44m"
BMAGENTA = "\033[1;45m"
BCYAN = "\033[1;46m"
BDARK_RED = "\033[1;48m"
UNDERLINE = "\033[4m"
END = "\033[0m"

if _platform.find("linux")<0:
	GRAY = ""
	RED = ""
	LIME = ""
	YELLOW = ""
	BLUE = ""
	MAGENTA = ""
	CYAN = ""
	WHITE = ""
	BGRAY = ""
	BRED = ""
	BLIME = ""
	BYELLOW = ""
	BBLUE = ""
	BMAGENTA = ""
	BCYAN = ""
	UNDERLINE = ""
	END = ""
	os.system("color c")

print (RED)
print ("*" * 40)
print ("*  Name:\tServer Status Telegram Bot")
print ("*  Team:" + LIME + "\tWhite Birch Forum Team" + RED)
print ("*  Developer:\tWeil Jimmer")
print ("*  Website:\thttps://weils.net/")
print ("*  Date:\t2016.07.04")
print ("*" * 40)
print (END)

chat_id = "123456789"
api_key = "123456789:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
root_dir = "/tmp/"
msg_id = ""
sleep_second = 5

def int_s(k):
	try:
		return int(k)
	except:
		return -1

def reporthook2(blocknum, blocksize, totalsize):
	do_nothing=True

def url_encode(url_):
	return urllib.parse.quote(url_, safe='~@#$&()*!+=:;,.?/\'')

def upload_URL(url,encode,data_X,method_X):
	file_name="temp_file_pyserverstatus"
	opener = urllib.request.FancyURLopener({})
	opener.version = 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'
	opener.addheader("Referer", url)
	opener.addheader("X-Forwarded-For", "0.0.0.0")
	opener.addheader("Client-IP", "0.0.0.0")
	if method_X=="POST":
		local_file,response_header=opener.retrieve(url_encode(url), root_dir + file_name, reporthook2, urllib.parse.urlencode(data_X))
	else:
		local_file,response_header=opener.retrieve(url, root_dir + file_name, reporthook2)
	return open(local_file,encoding=encode).read()

def api_make_req_json(data_X):
	api_url = "https://api.telegram.org/bot" + api_key + "/"
	response=(upload_URL(api_url,"utf-8",data_X,"POST"))
	return json.loads(response)

def sendMessage(text,chatid):
	return api_make_req_json({"method":"sendMessage","chat_id":chatid,"text":text})

def editMessageText(text,chatid,messageid):
	return api_make_req_json({"method":"editMessageText","chat_id":chatid,"message_id":messageid,"text":text})

while True:
	time_now_str = "當前時間:\n" + str(datetime.datetime.now())
	cpu_useage_str = "CPU使用率:" + str(psutil.cpu_percent(interval=1)) + " %"
	memory_useage = psutil.virtual_memory()
	memory_useage_str = "記憶體使用率:" + str(memory_useage.percent) + " %\n已用:" + str(round(memory_useage.total*0.01*memory_useage.percent/1024/1024/1024,3)) + " GB" + "\n總共:" + str(round(memory_useage.total/1024/1024/1024,3)) + " GB"
	str_value = time_now_str + "\n" + cpu_useage_str + "\n" + memory_useage_str
	if msg_id=="":
		dom=sendMessage(str_value,chat_id)
		msg_id=dom['result']['message_id']
	else:
		editMessageText(str_value,chat_id,msg_id)
	sleep(sleep_second)


input("\n\n請輸入ENTER鍵結束...")

若在 Linux 的環境下,使用 tmux 輸入指令會比較好。因為它可以在背景運作,可以直接關掉 terminal。


This entry was posted in General, The Internet, Note, Python By Weil Jimmer.

淺談Telegram開發機器人
No Comments

發布:
更新:2017-08-19 16:48:44

我做了一個很簡單的計時器,為了某群組裡面的高中生而設計,這也是我首次製作 tg 的機器人。我才做兩個而已,所以有些功能我真的不知道的我也沒辦法為您解答。

以下是講我的經歷:

首先必須先註冊個telegram帳號(廢話),然後搜索聯繫人@BotFather 這很重要,加入這個機器人之後,首先輸入:/newbot ,然後再輸入你想要取的名子(可以是中文),接著系統會提示你再輸入用戶名稱,結尾必須是 bot ,而且僅英文數字以及下畫線,接著你的機器人就創立了,BotFather會告訴你,你的Token,這很重要,因為等下傳送或是接收訊息都要用到這組文字。

開始就是程式設計的部分,我個人是比較熟PHP,所以用PHP開發。而且還是改寫自官方的腳本。但我現在已經明白原理了。

<?php

define('BOT_TOKEN', 'BotFather給你的Token');
define('API_URL', 'https://api.telegram.org/bot'.BOT_TOKEN.'/');

//這些AppFunction和處理資料有關係,我是覺得直接Copy就好了。
function apiRequestWebhook($method, $parameters) {
  if (!is_string($method)) {
    error_log("Method name must be a string\n");
    return false;
  }

  if (!$parameters) {
    $parameters = array();
  } else if (!is_array($parameters)) {
    error_log("Parameters must be an array\n");
    return false;
  }

  $parameters["method"] = $method;

  header("Content-Type: application/json");
  echo json_encode($parameters);
  return true;
}

function exec_curl_request($handle) {
  $response = curl_exec($handle);

  if ($response === false) {
    $errno = curl_errno($handle);
    $error = curl_error($handle);
    error_log("Curl returned error $errno: $error\n");
    curl_close($handle);
    return false;
  }

  $http_code = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
  curl_close($handle);

  if ($http_code >= 500) {
    // do not wat to DDOS server if something goes wrong
    sleep(10);
    return false;
  } else if ($http_code != 200) {
    $response = json_decode($response, true);
    error_log("Request has failed with error {$response['error_code']}: {$response['description']}\n");
    if ($http_code == 401) {
      throw new Exception('Invalid access token provided');
    }
    return false;
  } else {
    $response = json_decode($response, true);
    if (isset($response['description'])) {
      error_log("Request was successfull: {$response['description']}\n");
    }
    $response = $response['result'];
  }

  return $response;
}

function apiRequest($method, $parameters) {
  if (!is_string($method)) {
    error_log("Method name must be a string\n");
    return false;
  }

  if (!$parameters) {
    $parameters = array();
  } else if (!is_array($parameters)) {
    error_log("Parameters must be an array\n");
    return false;
  }

  foreach ($parameters as $key => &$val) {
    // encoding to JSON array parameters, for example reply_markup
    if (!is_numeric($val) && !is_string($val)) {
      $val = json_encode($val);
    }
  }
  $url = API_URL.$method.'?'.http_build_query($parameters);

  $handle = curl_init($url);
  curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
  curl_setopt($handle, CURLOPT_TIMEOUT, 60);

  return exec_curl_request($handle);
}

function apiRequestJson($method, $parameters) {
  if (!is_string($method)) {
    error_log("Method name must be a string\n");
    return false;
  }

  if (!$parameters) {
    $parameters = array();
  } else if (!is_array($parameters)) {
    error_log("Parameters must be an array\n");
    return false;
  }

  $parameters["method"] = $method;

  $handle = curl_init(API_URL);
  curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
  curl_setopt($handle, CURLOPT_TIMEOUT, 60);
  curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters));
  curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));

  return exec_curl_request($handle);
}

//上面的程式碼都建議直接Copy拿來用

//我自己的程式碼開始

$target_times=1465772400;
$msg = '距離【畢業典禮】還有'."\n".floor(($target_times-time())/86400).'天'.floor((($target_times-time())%86400)/3600).'時'.floor(((($target_times-time())%86400)%3600)/60).'分'.(((($target_times-time())%86400)%3600)%60).'秒!';

if (time()>$target_times){
	$msg="";
}

$target_times=1467327600;
$msg .= "\n".'距離【指考】還有'."\n".floor(($target_times-time())/86400).'天'.floor((($target_times-time())%86400)/3600).'時'.floor(((($target_times-time())%86400)%3600)/60).'分'.(((($target_times-time())%86400)%3600)%60).'秒!';

if (time()>$target_times){
	$msg="";
}


//處理開始函數,傳入$msg是因為我這個程式的功能所需,並非必要
function processMessage($message,$msg) {
  // process incoming message
  $message_id = $message['message_id'];
  $chat_id = $message['chat']['id'];
  if (isset($message['text'])) {
    // incoming text message
    $text = $message['text'];

    if ($text === "/start" or $text === "/start@botusername"){
		if ($msg!=""){
			apiRequestJson("sendMessage", array('chat_id' => $chat_id, "text" => $msg."\n聊天室ID:".$chat_id));
		}
    } else if ($text === "/show" or $text === "/show@botusername") {
		if ($msg!=""){
			apiRequestJson("sendMessage", array('chat_id' => $chat_id, "text" => $msg));
		}
    } else if (strpos($text, "/stop") === 0) {
	// stop now
    } else {
	// 其他指令或訊息
    }
  }
}

if (php_sapi_name() == 'cli') {
  // if run from console
  //這是為了定時任務的區別,如果是從Crontab跑,就從這邊
	if ($msg!=""){
		apiRequestJson("sendMessage", array('chat_id' => '00000000000', "text" => $msg));
	}
  exit;
}


$content = file_get_contents("php://input"); //讀取資料 (In)
$update = json_decode($content, true); //JSON解析

if (!$update) {
  // receive wrong update, must not happen
  // 接收到錯誤訊息
  exit;
}

if (isset($update["message"])) {
  //接收到正確訊息,調用處理函數
  processMessage($update["message"],$msg);
}

程式碼都獻上了,現在開始講原理。

首先必須要有一台服務器,來執行WebHook,把你寫好的PHP檔案上傳到伺服器上面,注意檔名最好建立很特殊的名稱,讓一般使用者無法猜到你用什麼檔名,以預防惡意人士直接訪問你的程式。(洪水轟炸,或偽造請求之類的。)

上傳後,請直接訪問 https://api.telegram.org/bot{TOKEN}/?method=setWebhook&url=https://www.example.com/{secret}bot.php

例如:
https://api.telegram.org/bot123456789:AAAAAAAAAAAAAAAAAAAAAA/?method=setWebhook&url=https://www.example.com/secret_random_path/bot.php

參數url後面接的就是你要接收的位置,僅支援https,完畢後一旦直接對bot講話輸入指令,telegram就會立刻送出對話內容傳到你的程式,而你的程式處理完之後再回傳給telegram,這就是它的工作原理。

得到的內容長得像:(已經被解析的Object["message"])

(
    [message_id] => 01
    [from] => Array
        (
            [id] => 123456789
            [first_name] => Nickname
            [username] => username
        )

    [chat] => Array
        (
            [id] => -123456789
            [title] => test
            [type] => group
        )

    [date] => 1464504645
    [text] => /say I just say?
    [entities] => Array
        (
            [0] => Array
                (
                    [type] => bot_command
                    [offset] => 0
                    [length] => 17
                )

        )

)

簡單明瞭,這只是message的部分,有可能會出現其他資料,例如傳圖片,有人加入群組時,就會不同了,請參閱 telegram 文檔,https://core.telegram.org/bots/api

而我的設計是當使用者輸入 /start 時,就會回傳 聊天室 id,因為我需要 id 才可以讓我直接發訊息回去,否則必須每次都是被動型傳輸,這樣我就可以主動傳送了,因為我不需要依靠對方先傳訊息給我才可以取得 id 回傳。

而我設定輸入指令 /show 時 就會彈出距離目標時間還有多久。而且利用 cron job 定時任務,每天都會 run 這程式發送一次倒數訊息。這就是整個簡單的概念。

接下來,在 tg 上就可以直接操作並直接顯示結果了,唯一缺陷就是沒有指令選單。這時可以再向 BotFather設定,輸入 /setcommands,再輸入 @botname指令(英文)+空格+簡介。(可以多行輸入)

最終預防機器人被濫用亂加入群組,可以設定鎖定,/setjoingroups@botname → Disable

這樣就大功告成了。其他功能自己探索,其實很簡單的。


This entry was posted in General, Software, Experience, Functions, Note, PHP By Weil Jimmer.

音樂播放程式 Media List Viewer
No Comments

發布:
更新:2017-11-17 00:52:47

本程式可以選擇特定資料夾目錄並列舉資料夾內所有音樂,以資料夾為第一級/或子資料夾分類,並包含搜尋功能(可自訂資料夾內搜尋),置頂功能(一律顯示在最上方)。只是個簡單版的輕巧小程式。

本程式已過時,請改用:http://web.wbftw.org/product/newmediaviewerplus

下載地址【一】:https://url.weils.net/m

下載地址【二】:http://cht.tw/h/p9bxu

產品頁面:http://web.wbftw.org/product/yinlebofangchengshimedialistview


This entry was posted in General, Software, Free, Product By Weil Jimmer.

最前頁 上一頁  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 /25 頁)下一頁 最終頁

Visitor Count

pop
nonenonenone

Note

重啟核四,關閉維修火力發電廠,減少空氣汙染,以核能養綠能。

支持網路中立性.
Support Net Neutrality.

Celebration for General Data Protection Regulation.

隨時注意自己的CPU使用狀態,有不少網站會沒有徵求同意就用您的電腦挖礦。

不用 Line 改用 Telegram。跟上最新潮流。

支持臺灣實施無條件基本收入

歡迎前來本站。

Words Quiz


Search

Music

Counter

2301
天前是本網站的生日

Republic Of China
The strong do what they can and the weak suffer what they must.

Privacy is your right and ability to be yourself and express yourself without the fear that someone is looking over your shoulder and that you might be punished for being yourself, whatever that may be.

It is quality rather than quantity that matters.

I WANT Internet Freedom.

Reality made most of people lost their childishness.

Justice,Freedom,Knowledge.

Support/Donate

This site also need a little money to maintain operations, not entirely without any cost in the Internet. Your donations will be the best support and power of the site.
MethodBitcoin Address
bitcoin1NRMVGGpm2T1pmeejisLSEhCXfCefEW9V4
paypal
Register in linode via invitation link and stay active for three months.Linode

The Lie We Live

The Lie We Live

The Questions We Never Ask

The Questions We Never Ask

Support The Zeitgeist Movement

The Zeitgeist Movement

Man

Man

In The Fall

In The Fall

Facebook is EATING the Internet

Facebook

Categories

Android (7)

Announcement (4)

Arduino (2)

Bash (2)

C (3)

C# (5)

C++ (1)

Experience (42)

Flash (2)

Free (13)

Functions (36)

Games (13)

General (50)

HTML (7)

Java (13)

JS (7)

Mood (24)

Note (28)

Office (1)

PHP (9)

Privacy (4)

Product (12)

Python (4)

Software (11)

The Internet (16)

Tools (14)

VB.NET (8)

WebHosting (7)

Wi-Fi (5)

XML (4)