Created
January 31, 2017 12:50
-
-
Save blueset/40edb208fd25c384213907e2489e311f to your computer and use it in GitHub Desktop.
BankComm AUD/CNY Exch Offer Monitor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$fp = fopen("http://www.bankcomm.com/BankCommSite/simple/cn/whpj/queryExchangeResult.do?type=simple", "r"); | |
if (FALSE === $fp) { | |
exit("Failed to open stream to URL"); | |
} | |
$result = ''; | |
while (!feof($fp)) { | |
$result .= fread($fp, 8192); | |
} | |
fclose($fp); | |
$result = str_replace("\r\n", "", $result); | |
echo "<pre>"; | |
preg_match('/<td align="center">澳大利亚元\(AUD\/CNY\)<\/td> <td align="center">100<\/td> <td align="center">\d+\.\d+<\/td> <td align="center">(\d+\.\d+)<\/td> <td align="center">\d+\.\d+<\/td> <td align="center">\d+\.\d+<\/td>/', $result, $m); | |
// $r = preg_match('/<td align="center">澳大利亚元\(AUD\/CNY\)<\/td>.*?</ms', $result, $m); | |
preg_match('/<B>更新时间:([0-9: -]+)<B>/', $result, $n); | |
echo "</pre>"; | |
$s = new PDO('sqlite:data.db'); | |
$s->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | |
$today = substr($n[1], 0, 10); | |
$last_val = floatval($s->query('SELECT * FROM data ORDER BY time DESC LIMIT 1')->fetch(PDO::FETCH_ASSOC)['value']); | |
$last_k_val = intval($last_val); | |
$last_k_val = 0; | |
$k_val = intval(floatval($m[1])); | |
if ($last_k_val - $k_val != 0){ // crossing border | |
$border = min($last_k_val, $k_val); | |
$db_date = $s->query('SELECT * FROM meta where key = "last_alarm_date"')->fetch(PDO::FETCH_ASSOC)['value']; | |
$db_border = intval($s->query('SELECT * FROM meta where key = "last_alarm_value"')->fetch(PDO::FETCH_ASSOC)['value']); | |
if ($db_date != $today or $db_border != $border){ | |
if ($last_k_val < $k_val) $type = "📈"; else $type = "📉"; | |
$now = $m[1]; | |
$msg = "汇率变动提醒\n交通银行 AUD/CNY 现汇卖出价\n\n $last_val $type $now"; | |
$url = "https://api.telegram.org/bot/sendMessage"; | |
$chat_id = -1; | |
$fields = "chat_id=$chat_id&text=" . urlencode($msg); | |
$ch = curl_init( $url ); | |
curl_setopt( $ch, CURLOPT_POST, 1); | |
curl_setopt( $ch, CURLOPT_POSTFIELDS, $fields); | |
curl_exec( $ch ); | |
curl_close($ch); | |
$s->prepare("UPDATE meta SET value = :date WHERE key = \"last_alarm_date\"")->execute(["date"=>$today]); | |
$s->prepare("UPDATE meta SET value = :border WHERE key = \"last_alarm_value\"")->execute(["border"=>$border]); | |
} | |
} | |
$q2 = $s->prepare('SELECT * FROM data WHERE time = :time'); | |
$q2->execute(["time"=>$n[1]]); | |
if (!boolval($q2->fetch())){ | |
$q = $s->prepare('INSERT INTO data (time, value) VALUES (:time, :value)'); | |
$q->execute(["time"=>$n[1], "value"=>floatval($m[1])]); | |
if ($q->rowCount() > 0) exit("Done."); | |
exit("Failed."); | |
} else { | |
exit("Exist."); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$s = new PDO('sqlite:data.db'); | |
$s->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | |
$q2 = $s->prepare('SELECT * FROM data ORDER BY time DESC LIMIT 1000'); | |
$q2->execute(); | |
$data = json_encode($q2->fetchAll(PDO::FETCH_ASSOC)); | |
?><!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>BankComm AUD/CNY</title> | |
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400" rel="stylesheet"> | |
<link rel="stylesheet" href="https://fonts.googleapis.com/earlyaccess/notosanssc.css"> | |
<meta name="viewport" content="width=device-width, minimum-scale=1.0"> | |
<script src="https://code.highcharts.com/stock/highstock.js"></script> | |
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script> | |
<script type="text/javascript"> | |
!function(e,t,n){typeof module!="undefined"&&module.exports?module.exports=n():typeof define=="function"&&define.amd?define(n):t[e]=n()}("reqwest",this,function(){function succeed(e){var t=protocolRe.exec(e.url);return t=t&&t[1]||context.location.protocol,httpsRe.test(t)?twoHundo.test(e.request.status):!!e.request.response}function handleReadyState(e,t,n){return function(){if(e._aborted)return n(e.request);if(e._timedOut)return n(e.request,"Request is aborted: timeout");e.request&&e.request[readyState]==4&&(e.request.onreadystatechange=noop,succeed(e)?t(e.request):n(e.request))}}function setHeaders(e,t){var n=t.headers||{},r;n.Accept=n.Accept||defaultHeaders.accept[t.type]||defaultHeaders.accept["*"];var i=typeof FormData!="undefined"&&t.data instanceof FormData;!t.crossOrigin&&!n[requestedWith]&&(n[requestedWith]=defaultHeaders.requestedWith),!n[contentType]&&!i&&(n[contentType]=t.contentType||defaultHeaders.contentType);for(r in n)n.hasOwnProperty(r)&&"setRequestHeader"in e&&e.setRequestHeader(r,n[r])}function setCredentials(e,t){typeof t.withCredentials!="undefined"&&typeof e.withCredentials!="undefined"&&(e.withCredentials=!!t.withCredentials)}function generalCallback(e){lastValue=e}function urlappend(e,t){return e+(/\?/.test(e)?"&":"?")+t}function handleJsonp(e,t,n,r){var i=uniqid++,s=e.jsonpCallback||"callback",o=e.jsonpCallbackName||reqwest.getcallbackPrefix(i),u=new RegExp("((^|\\?|&)"+s+")=([^&]+)"),a=r.match(u),f=doc.createElement("script"),l=0,c=navigator.userAgent.indexOf("MSIE 10.0")!==-1;return a?a[3]==="?"?r=r.replace(u,"$1="+o):o=a[3]:r=urlappend(r,s+"="+o),context[o]=generalCallback,f.type="text/javascript",f.src=r,f.async=!0,typeof f.onreadystatechange!="undefined"&&!c&&(f.htmlFor=f.id="_reqwest_"+i),f.onload=f.onreadystatechange=function(){if(f[readyState]&&f[readyState]!=="complete"&&f[readyState]!=="loaded"||l)return!1;f.onload=f.onreadystatechange=null,f.onclick&&f.onclick(),t(lastValue),lastValue=undefined,head.removeChild(f),l=1},head.appendChild(f),{abort:function(){f.onload=f.onreadystatechange=null,n({},"Request is aborted: timeout",{}),lastValue=undefined,head.removeChild(f),l=1}}}function getRequest(e,t){var n=this.o,r=(n.method||"GET").toUpperCase(),i=typeof n=="string"?n:n.url,s=n.processData!==!1&&n.data&&typeof n.data!="string"?reqwest.toQueryString(n.data):n.data||null,o,u=!1;return(n["type"]=="jsonp"||r=="GET")&&s&&(i=urlappend(i,s),s=null),n["type"]=="jsonp"?handleJsonp(n,e,t,i):(o=n.xhr&&n.xhr(n)||xhr(n),o.open(r,i,n.async===!1?!1:!0),setHeaders(o,n),setCredentials(o,n),context[xDomainRequest]&&o instanceof context[xDomainRequest]?(o.onload=e,o.onerror=t,o.onprogress=function(){},u=!0):o.onreadystatechange=handleReadyState(this,e,t),n.before&&n.before(o),u?setTimeout(function(){o.send(s)},200):o.send(s),o)}function Reqwest(e,t){this.o=e,this.fn=t,init.apply(this,arguments)}function setType(e){if(e===null)return undefined;if(e.match("json"))return"json";if(e.match("javascript"))return"js";if(e.match("text"))return"html";if(e.match("xml"))return"xml"}function init(o,fn){function complete(e){o.timeout&&clearTimeout(self.timeout),self.timeout=null;while(self._completeHandlers.length>0)self._completeHandlers.shift()(e)}function success(resp){var type=o.type||resp&&setType(resp.getResponseHeader("Content-Type"));resp=type!=="jsonp"?self.request:resp;var filteredResponse=globalSetupOptions.dataFilter(resp.responseText,type),r=filteredResponse;try{resp.responseText=r}catch(e){}if(r)switch(type){case"json":try{resp=context.JSON?context.JSON.parse(r):eval("("+r+")")}catch(err){return error(resp,"Could not parse JSON in response",err)}break;case"js":resp=eval(r);break;case"html":resp=r;break;case"xml":resp=resp.responseXML&&resp.responseXML.parseError&&resp.responseXML.parseError.errorCode&&resp.responseXML.parseError.reason?null:resp.responseXML}self._responseArgs.resp=resp,self._fulfilled=!0,fn(resp),self._successHandler(resp);while(self._fulfillmentHandlers.length>0)resp=self._fulfillmentHandlers.shift()(resp);complete(resp)}function timedOut(){self._timedOut=!0,self.request.abort()}function error(e,t,n){e=self.request,self._responseArgs.resp=e,self._responseArgs.msg=t,self._responseArgs.t=n,self._erred=!0;while(self._errorHandlers.length>0)self._errorHandlers.shift()(e,t,n);complete(e)}this.url=typeof o=="string"?o:o.url,this.timeout=null,this._fulfilled=!1,this._successHandler=function(){},this._fulfillmentHandlers=[],this._errorHandlers=[],this._completeHandlers=[],this._erred=!1,this._responseArgs={};var self=this;fn=fn||function(){},o.timeout&&(this.timeout=setTimeout(function(){timedOut()},o.timeout)),o.success&&(this._successHandler=function(){o.success.apply(o,arguments)}),o.error&&this._errorHandlers.push(function(){o.error.apply(o,arguments)}),o.complete&&this._completeHandlers.push(function(){o.complete.apply(o,arguments)}),this.request=getRequest.call(this,success,error)}function reqwest(e,t){return new Reqwest(e,t)}function normalize(e){return e?e.replace(/\r?\n/g,"\r\n"):""}function serial(e,t){var n=e.name,r=e.tagName.toLowerCase(),i=function(e){e&&!e.disabled&&t(n,normalize(e.attributes.value&&e.attributes.value.specified?e.value:e.text))},s,o,u,a;if(e.disabled||!n)return;switch(r){case"input":/reset|button|image|file/i.test(e.type)||(s=/checkbox/i.test(e.type),o=/radio/i.test(e.type),u=e.value,(!s&&!o||e.checked)&&t(n,normalize(s&&u===""?"on":u)));break;case"textarea":t(n,normalize(e.value));break;case"select":if(e.type.toLowerCase()==="select-one")i(e.selectedIndex>=0?e.options[e.selectedIndex]:null);else for(a=0;e.length&&a<e.length;a++)e.options[a].selected&&i(e.options[a])}}function eachFormElement(){var e=this,t,n,r=function(t,n){var r,i,s;for(r=0;r<n.length;r++){s=t[byTag](n[r]);for(i=0;i<s.length;i++)serial(s[i],e)}};for(n=0;n<arguments.length;n++)t=arguments[n],/input|select|textarea/i.test(t.tagName)&&serial(t,e),r(t,["input","select","textarea"])}function serializeQueryString(){return reqwest.toQueryString(reqwest.serializeArray.apply(null,arguments))}function serializeHash(){var e={};return eachFormElement.apply(function(t,n){t in e?(e[t]&&!isArray(e[t])&&(e[t]=[e[t]]),e[t].push(n)):e[t]=n},arguments),e}function buildParams(e,t,n,r){var i,s,o,u=/\[\]$/;if(isArray(t))for(s=0;t&&s<t.length;s++)o=t[s],n||u.test(e)?r(e,o):buildParams(e+"["+(typeof o=="object"?s:"")+"]",o,n,r);else if(t&&t.toString()==="[object Object]")for(i in t)buildParams(e+"["+i+"]",t[i],n,r);else r(e,t)}var context=this;if("window"in context)var doc=document,byTag="getElementsByTagName",head=doc[byTag]("head")[0];else{var XHR2;try{XHR2=require("xhr2")}catch(ex){throw new Error("Peer dependency `xhr2` required! Please npm install xhr2")}}var httpsRe=/^http/,protocolRe=/(^\w+):\/\//,twoHundo=/^(20\d|1223)$/,readyState="readyState",contentType="Content-Type",requestedWith="X-Requested-With",uniqid=0,callbackPrefix="reqwest_"+ +(new Date),lastValue,xmlHttpRequest="XMLHttpRequest",xDomainRequest="XDomainRequest",noop=function(){},isArray=typeof Array.isArray=="function"?Array.isArray:function(e){return e instanceof Array},defaultHeaders={contentType:"application/x-www-form-urlencoded",requestedWith:xmlHttpRequest,accept:{"*":"text/javascript, text/html, application/xml, text/xml, */*",xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript",js:"application/javascript, text/javascript"}},xhr=function(e){if(e.crossOrigin===!0){var t=context[xmlHttpRequest]?new XMLHttpRequest:null;if(t&&"withCredentials"in t)return t;if(context[xDomainRequest])return new XDomainRequest;throw new Error("Browser does not support cross-origin requests")}return context[xmlHttpRequest]?new XMLHttpRequest:XHR2?new XHR2:new ActiveXObject("Microsoft.XMLHTTP")},globalSetupOptions={dataFilter:function(e){return e}};return Reqwest.prototype={abort:function(){this._aborted=!0,this.request.abort()},retry:function(){init.call(this,this.o,this.fn)},then:function(e,t){return e=e||function(){},t=t||function(){},this._fulfilled?this._responseArgs.resp=e(this._responseArgs.resp):this._erred?t(this._responseArgs.resp,this._responseArgs.msg,this._responseArgs.t):(this._fulfillmentHandlers.push(e),this._errorHandlers.push(t)),this},always:function(e){return this._fulfilled||this._erred?e(this._responseArgs.resp):this._completeHandlers.push(e),this},fail:function(e){return this._erred?e(this._responseArgs.resp,this._responseArgs.msg,this._responseArgs.t):this._errorHandlers.push(e),this},"catch":function(e){return this.fail(e)}},reqwest.serializeArray=function(){var e=[];return eachFormElement.apply(function(t,n){e.push({name:t,value:n})},arguments),e},reqwest.serialize=function(){if(arguments.length===0)return"";var e,t,n=Array.prototype.slice.call(arguments,0);return e=n.pop(),e&&e.nodeType&&n.push(e)&&(e=null),e&&(e=e.type),e=="map"?t=serializeHash:e=="array"?t=reqwest.serializeArray:t=serializeQueryString,t.apply(null,n)},reqwest.toQueryString=function(e,t){var n,r,i=t||!1,s=[],o=encodeURIComponent,u=function(e,t){t="function"==typeof t?t():t==null?"":t,s[s.length]=o(e)+"="+o(t)};if(isArray(e))for(r=0;e&&r<e.length;r++)u(e[r].name,e[r].value);else for(n in e)e.hasOwnProperty(n)&&buildParams(n,e[n],i,u);return s.join("&").replace(/%20/g,"+")},reqwest.getcallbackPrefix=function(){return callbackPrefix},reqwest.compat=function(e,t){return e&&(e.type&&(e.method=e.type)&&delete e.type,e.dataType&&(e.type=e.dataType),e.jsonpCallback&&(e.jsonpCallbackName=e.jsonpCallback)&&delete e.jsonpCallback,e.jsonp&&(e.jsonpCallback=e.jsonp)),new Reqwest(e,t)},reqwest.ajaxSetup=function(e){e=e||{};for(var t in e)globalSetupOptions[t]=e[t]},reqwest}); | |
</script> | |
<meta name="theme-color" content="#2196F3"> | |
</head> | |
<body> | |
<style> | |
html, body{ | |
margin: 0; | |
padding: 0; | |
bottom: 0; | |
} | |
.card{ | |
display: flex; | |
align-items: stretch; | |
} | |
span.block{ | |
display: inline-block; | |
} | |
@media screen and (min-width: 720px) { | |
.card{ | |
position: absolute; | |
top: 5vh; | |
bottom: 5vh; | |
left: 5vh; | |
right: 5vh; | |
font-size: 15pt; | |
box-shadow: 0 0 5px rgba(0,0,0,0.3), 0 10px 20px rgba(0,0,0,0.3); | |
-webkit-flex-direction: row; | |
-moz-flex-direction: row; | |
-ms-flex-direction: row; | |
-o-flex-direction: row; | |
flex-direction: row; | |
} | |
.heading{ | |
padding-top: 2em; | |
} | |
.title{ | |
flex-basis: 33%; | |
} | |
.graph{ | |
flex-basis: 67%; | |
} | |
} | |
@media screen and (max-width: 719px){ | |
.card{ | |
-webkit-flex-direction: column; | |
-moz-flex-direction: column; | |
-ms-flex-direction: column; | |
-o-flex-direction: column; | |
flex-direction: column; | |
height: 100vh; | |
} | |
.heading{ | |
padding-top: 2em; | |
} | |
.graph{ | |
flex-grow: 1; | |
} | |
} | |
.title{ | |
background: #2196F3; | |
color: #fff; | |
font-family: "Roboto", "Noto Sans SC", "Noto Sans CJK SC", "Source Han Sans SC"; | |
font-weight: 100; | |
padding: 1em; | |
} | |
.heading-small{ | |
font-size: 1.5em; | |
} | |
.heading-large { | |
font-size: 2.5em; | |
} | |
.value { | |
font-size: 5em; | |
} | |
</style> | |
<div class="card"> | |
<div class="title"> | |
<div class="heading"> | |
<div class="heading-small">交通银行</div> | |
<div class="heading-large"><span class="block">AUD/CNY</span> <span class="block">现汇卖出价</span></div> | |
</div> | |
<div class="value" id="value"> | |
123.45 | |
</div> | |
</div> | |
<div class="graph" id="graph-container"> | |
</div> | |
</div> | |
<script> | |
var rdata = <?php echo $data ?>; | |
var data = []; | |
for (var i = rdata.length - 1; i >= 0; i--){ | |
data.push([new Date(rdata[i].time).valueOf(), parseFloat(rdata[i].value)]); | |
} | |
document.getElementById('value').innerText = data[data.length - 1][1]; | |
window.last_date = data[data.length - 1][0]; | |
Highcharts.setOptions({global : { | |
useUTC: false | |
}}); | |
var chart = Highcharts.stockChart('graph-container', { | |
rangeSelector: { | |
selected: 1 | |
}, | |
tooltip:{ | |
dateTimeLabelFormats: { | |
second: '%Y-%m-%d %H:%M:%S', | |
minute: '%Y-%m-%d %H:%M:%S', | |
hour: '%Y-%m-%d %H:%M:%S', | |
day: '%Y-%m-%d %H:%M:%S', | |
week: '%Y-%m-%d %H:%M:%S', | |
month: '%Y-%m-%d %H:%M:%S', | |
year: '%Y-%m-%d %H:%M:%S', | |
} | |
}, | |
series: [{ | |
name: '现汇卖出价', | |
data: data, | |
tooltip: { | |
valueDecimals: 2 | |
} | |
}] | |
}); | |
setInterval(function(){ | |
var a = new Date(); | |
var m = a.getMinutes(); | |
if (m % 5 == 1){ | |
reqwest("last.php").then(function(d){ | |
var date = new Date(d.time).valueOf(); | |
var val = parseFloat(d.value); | |
if (date > window.last_date){ | |
chart.series[0].addPoint([date, val], true, true); | |
window.last_date = date; | |
document.getElementById('value').innerText = val; | |
} | |
}); | |
} | |
}, 60000); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$s = new PDO('sqlite:data.db'); | |
$s->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | |
header("Content-type: application/json"); | |
echo json_encode($s->query('SELECT * FROM data ORDER BY time DESC LIMIT 1')->fetch(PDO::FETCH_ASSOC)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment