Skip to content

Commit 199846e

Browse files
committed
Merge pull request hzlzh#36 from wyicwx/master
update tencent-portfolio 0.2
2 parents e63a784 + 79ec5b5 commit 199846e

File tree

4 files changed

+277
-14
lines changed

4 files changed

+277
-14
lines changed
Binary file not shown.

Sources/Workflows/Tencent-portfolio/info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<plist version="1.0">
44
<dict>
55
<key>bundleid</key>
6-
<string>com.alfredapp.weixinchen.portfolilo</string>
6+
<string>com.alfredapp.weixinchen.portfolio</string>
77
<key>category</key>
88
<string>Tools</string>
99
<key>connections</key>
@@ -23,7 +23,7 @@
2323
<key>createdby</key>
2424
<string>Weixin Chen</string>
2525
<key>description</key>
26-
<string>Get Stock Quotes</string>
26+
<string>Tencent Portfolilo v0.2</string>
2727
<key>disabled</key>
2828
<false/>
2929
<key>name</key>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
class QT
3+
{
4+
private $market;
5+
private $category;
6+
7+
function __construct($qtData = false, $market, $category) {
8+
$this->market = $market;
9+
$this->category = $category;
10+
if($qtData) {
11+
$this->items = $qtData;
12+
}
13+
}
14+
//股票名称
15+
public function getName(){
16+
return $this->items[1];
17+
}
18+
//获得涨跌幅
19+
public function getPercent() {
20+
$ret = $this->items[32];
21+
22+
if($ret > 0) {
23+
$ret = '+'.$ret;
24+
}
25+
26+
return $ret.'%';
27+
}
28+
//得到当前市价
29+
public function getPrice(){
30+
if($this->items[40] && $this->category != 'ZS') {
31+
return $this->items[40];
32+
} else {
33+
return $this->items[3];
34+
}
35+
}
36+
//得到昨收价
37+
public function getLastClosePrice(){
38+
return $this->items[4];
39+
}
40+
//得到今开盘
41+
public function getTodayOpenPrice(){
42+
return $this->items[5];
43+
}
44+
//最高
45+
public function getHighPrice(){
46+
return $this->items[33];
47+
}
48+
//最低
49+
public function getLowPrice(){
50+
return $this->items[34];
51+
}
52+
//获取状态
53+
public function getStatus() {
54+
return $this->items[40];
55+
}
56+
//获取普通状态
57+
public function getErrorStatus() {
58+
$status = $this->getStatus();
59+
switch($status) {
60+
case 'D':
61+
return '退市';
62+
case 'S':
63+
return '停牌';
64+
case 'U':
65+
return '未上市';
66+
case 'Z':
67+
return '暂停上市';
68+
break;
69+
}
70+
71+
return false;
72+
}
73+
}
74+
75+
class QTHk extends QT {}
76+
77+
class QTUs extends QT {}
78+
79+
class QTJj extends QT
80+
{
81+
public function getPrice(){
82+
return $this->items[3];
83+
}
84+
85+
public function getValueDate() {
86+
return $this->items[2];
87+
}
88+
89+
public function isHBType() {
90+
return $this->items[18] == '货币型';
91+
}
92+
93+
public function getEarnPer() {
94+
return $this->items[27];
95+
}
96+
97+
public function getYearRadio() {
98+
return $this->items[28].'%';
99+
}
100+
}

Sources/Workflows/Tencent-portfolio/stock.php

Lines changed: 175 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88
require_once("workflows.php");
99
require_once("filecache.php");
10+
require_once("qt.php");
1011

1112
class SmartBox extends Workflows
1213
{
@@ -18,20 +19,48 @@ function setKeyWord($keyword) {
1819
}
1920

2021
function search() {
21-
$qtData = FileCache::get($this->keyword);
22+
$cacheData = FileCache::get('__cache__'.$this->keyword);
2223

23-
if(!$qtData) {
24+
if(!$cacheData) {
2425
$url = $this->queryUrl.urlencode($this->keyword);
2526

2627
$request_result = $this->request($url);
2728
$json = json_decode($request_result);
28-
$qtData = $json->data;
29+
$searchData = $json->data;
30+
if(count($searchData) > 0) {
31+
FileCache::set('__cache__'.$this->keyword, $searchData, 24*60*60);
32+
}
33+
} else {
34+
$searchData = $cacheData;
2935
}
3036

31-
if(count($qtData) > 0) {
32-
FileCache::set($this->keyword, $qtData);
33-
foreach ($qtData as $key => $value) {
34-
$stock = new Stock($value);
37+
if(count($searchData) > 0) {
38+
39+
$codeArray = array();
40+
41+
foreach ($searchData as $value) {
42+
$d = explode('~', $value);
43+
if(preg_match('/(\..*)$/', $d[1], $re)) {
44+
$d[1] = str_replace($re[1], "", $d[1]);
45+
}
46+
if($d[0] == 'us') {
47+
$d[1] = strtoupper($d[1]);
48+
}
49+
$dCode = $d[0].$d[1];
50+
if($d[0] == 'hk') {
51+
$dCode = 'r_'.$dCode;
52+
}
53+
if($d[0] == 'jj') {
54+
$dCode = 's_'.$dCode;
55+
}
56+
array_push($codeArray, $dCode);
57+
}
58+
59+
$qt = new StockQt();
60+
$qt->fetchQt(implode(',', $codeArray));
61+
62+
foreach ($searchData as $key => $value) {
63+
$stock = new Stock($value, $qt);
3564
$this->result($key, $stock->getLink(), $stock->getTitle(), $stock->getSubTitle(), null);
3665
}
3766
} else {
@@ -61,14 +90,40 @@ class Stock
6190
// 类别
6291
public $category;
6392

64-
function __construct($data) {
93+
private $qt;
94+
95+
function __construct($data, $stockQt) {
6596
$result = explode("~", $data);
97+
if($result[0] == 'us') {
98+
if(preg_match('/(\..*)$/', $result[1], $re)) {
99+
$result[1] = str_replace($re[1], "", $result[1]);
100+
}
101+
$result[1] = strtoupper($result[1]);
102+
}
66103
$this->market = $result[0];
67104
$this->code = $result[1];
68105
$this->fullCode = $this->market.$this->code;
69106
$this->name = $result[2];
70107
$this->pinyin = $result[3];
71108
$this->category = $result[4];
109+
$qtData = $stockQt->getItem($this->fullCode);
110+
if($qtData) {
111+
switch($this->market) {
112+
case 'sh':
113+
case 'sz':
114+
$this->qt = new QT($qtData, $this->market, $this->category);
115+
break;
116+
case 'hk':
117+
$this->qt = new QTHk($qtData, $this->market, $this->category);
118+
break;
119+
case 'us':
120+
$this->qt = new QTUs($qtData, $this->market, $this->category);
121+
break;
122+
case 'jj':
123+
$this->qt = new QTJj($qtData, $this->market, $this->category);
124+
break;
125+
}
126+
}
72127

73128
$this->parse();
74129
}
@@ -114,23 +169,131 @@ function getTitle() {
114169
$name = $this->name;
115170
$code = $this->code;
116171

117-
return "[{$typeName}] {$name} {$code}";
172+
$return = sprintf("[%s] %-20s %-12s", $typeName, $name, $code);
173+
if($this->qt) {
174+
if(!$this->qt->getErrorStatus()) {
175+
$price = $this->qt->getPrice();
176+
if($this->market != 'jj') {
177+
$percent = $this->qt->getPercent();
178+
$return .= sprintf(" %-12s %-12s", $price, $percent);
179+
} else {
180+
if(!$this->qt->isHBType()) {
181+
$return .= sprintf(" 净值:%-12s", $price);
182+
} else {
183+
$price = $this->qt->getEarnPer();
184+
$return .= sprintf(" 万份收益:%-12s", $price);
185+
}
186+
}
187+
} else {
188+
$status = $this->qt->getErrorStatus();
189+
$return .= " {$status}";
190+
}
191+
}
192+
193+
return $return;
118194
}
119195

120196
function getSubTitle() {
121197
$fullCode = $this->fullCode;
198+
199+
$return = "{$fullCode}";
122200
if($this->pinyin != '*') {
123201
$pinyin = strtoupper($this->pinyin);
124-
return "{$fullCode}{$pinyin}";
125-
} else {
126-
return "{$fullCode}";
202+
$return .= "{$pinyin}";
127203
}
128204

205+
if($this->qt) {
206+
if(!$this->qt->getErrorStatus()) {
207+
if($this->market != 'jj') {
208+
$lastClose = $this->qt->getLastClosePrice();
209+
$todayOpen = $this->qt->getTodayOpenPrice();
210+
$hPrice = $this->qt->getHighPrice();
211+
$lPrice = $this->qt->getLowPrice();
212+
213+
$return .= " 高:{$hPrice} 低:{$lPrice} 收:{$lastClose} 开:{$todayOpen}";
214+
} else {
215+
if(!$this->qt->isHBType()) {
216+
$valueDate = $this->qt->getValueDate();
217+
$return .= " 净值更新时间:{$valueDate}";
218+
} else {
219+
$yearRadio = $this->qt->getYearRadio();
220+
$return .= " 七日年化收益率:{$yearRadio}";
221+
}
222+
}
223+
}
224+
}
225+
226+
return $return;
129227
}
130228

131229
function getLink() {
132230
return "http://gu.qq.com/".$this->fullCode;
133231
}
232+
}
233+
234+
235+
236+
class StockQt
237+
{
238+
protected $items = array();
239+
240+
//查询行情数据
241+
public function fetchQt($stock_code){
242+
$url = 'http://qt.gtimg.cn/q='.$stock_code;
243+
$data = $this->getCurlData($url, 80, 2);
244+
$data = iconv("GB2312", "UTF-8//IGNORE", $data);
245+
$data = trim($data);
246+
$edatas = explode(';', $data);
247+
248+
$codes = array();
249+
foreach($edatas as $value){
250+
$it = explode('~',$value);
251+
if(trim($it[0])){
252+
preg_match('/_([^_]*?)\=/', $it[0], $result);
253+
$this->items[$result[1]] = $it;
254+
}
255+
}
256+
}
257+
//获得数据
258+
public function getItem($code) {
259+
$data = $this->items[$code];
260+
if($data) {
261+
return $data;
262+
} else {
263+
return false;
264+
}
265+
}
134266

267+
private function getCurlData($url, $port=80,$timeout=10) {
268+
$ch = curl_init();
269+
// set port
270+
curl_setopt($ch, CURLOPT_PORT, $port);
271+
// drop http header
272+
curl_setopt($ch, CURLOPT_HEADER, FALSE);
273+
// get data as string
274+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
275+
// set timeout
276+
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
277+
curl_setopt($ch, CURLOPT_URL, $url);
278+
if(defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4')){
279+
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
280+
}
281+
282+
// execute fetch
283+
$data = curl_exec($ch);
284+
$errno = curl_errno($ch);
285+
if($errno > 0) {
286+
//try one time
287+
$data = curl_exec($ch);
288+
$errno = curl_errno($ch);
289+
if($errno > 0){
290+
return false;
291+
}
292+
}
293+
if(empty($data)) {
294+
return array();
295+
}
296+
return $data;
297+
}
135298
}
136299
?>

0 commit comments

Comments
 (0)