├── .gitignore
├── LICENSE
├── README.md
├── blockchain
├── README.md
└── money.py
├── bug_notify
├── README.md
├── avd.py
└── wecom.py
├── check_pic
├── .gitignore
├── 1.jpg
├── LICENSE
├── README.md
├── TencentYoutuyun
│ ├── __init__.py
│ ├── auth.py
│ ├── conf.py
│ └── youtu.py
├── check.py
└── requirements.txt
├── etcd2consul
├── 333.csv
├── README.md
├── consulkv2service.py
├── csv_base_service2consul_service.py
├── etcd2consul_kv.py
├── etcd2consul_service.py
└── salt2consul_service.py
├── google-authenticator
├── LICENSE
├── README.md
└── google-authenticator.py
├── how-to-look-the-plate
├── README.md
├── capture.jpg
└── rise.py
├── hwpy
├── 3rd
│ ├── SSU.exe
│ ├── disk.sh
│ ├── hwinfo.sh
│ └── ssu.sh
├── README.md
├── deploy.sh
├── hwpy
│ ├── __init__.py
│ ├── __main__.py
│ ├── _dmide.py
│ ├── _hwdisk.py
│ ├── _hwnet.py
│ ├── _hwpart.py
│ └── info.py
└── setup.py
├── rabbitmq-test
├── README.md
├── send.py
├── work.py
├── work.py.bak
├── work.py.false
└── work.py.new
├── short-url
├── README.md
└── short-url.py
├── wechatbot
├── README.md
├── bot.png
└── wechatbot.py
└── ws-test
├── .gevent.py
├── README.md
├── iws.sh
└── wsc.py
/.gitignore:
--------------------------------------------------------------------------------
1 | check_pic/config
2 | __pycache__/
3 | *.pyc
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 StarsL.cn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tools
2 | Python写的小工具集合
3 |
--------------------------------------------------------------------------------
/blockchain/README.md:
--------------------------------------------------------------------------------
1 | ## 注意:火币的sdk不支持python3.9,请使用3.9以下的版本,3.6测试正常。
2 |
3 | # 运维同学,如何优雅的炒币?
4 |
5 | ## 痛点分析:
6 | 1. 在币安和火币都有交易,需要经常切换APP来查看资产涨跌情况。
7 | 2. 目前币安和火币都无法查看持有币种的收益与收益率,只有当前币值。
8 | 3. 当同一币种多次调整仓位后,无法清楚了解自己的成本价是多少。
9 |
10 | ## 使用前提:
11 | 1. 需要创建调用币安和火币API的只读API Key。
12 | 2. 必须使用中国大陆以外的服务器来调用币安和火币的API。
13 | 3. 使用python3.6开发。
14 |
15 | ## API文档
16 | ```
17 | # 火币
18 | https://huobiapi.github.io/docs/spot/v1/cn/
19 | # 币安
20 | https://binance-docs.github.io/apidocs/spot/cn/
21 | ```
22 |
23 | ## 实现功能:
24 | 1. 把币安和火币所持有币种的信息聚合到一起展示。
25 | 2. 能展示所持有币种的数量、总价、最新价、成本价、收益、收益率。
26 | 3. 以文本和图片的方式输出表格信息。
27 | 4. 币安可开启展示所持有币种的历史交易收益与收益率。
28 | 5. 火币信息采集是使用官方的python sdk,币安无现货sdk,直接调用API。
29 |
30 | ## 扩展功能:
31 | 1. 定时推送微信群或者钉钉群。
32 | 2. 发消息来触发推送微信群或者钉钉群。
33 | 3. 微信群报价机器人。
34 |
35 | ### 火币Python SDK安装
36 | ```
37 | git clone https://github.com/HuobiRDCenter/huobi_Python.git
38 | cd huobi_Python
39 | pip3 install-r requirements.txt
40 | python3 setup.py build
41 | python3 setup.py install
42 | ```
43 |
44 | ### 完整代码请参考github或点击阅读原文
45 | https://github.com/starsliao/tools/tree/master/blockchain
46 |
47 |
48 | ## 部分代码解析:
49 |
50 | ### 币安私有接口鉴权签名代码
51 | ```
52 | import requests,json,time
53 | import hashlib
54 | import hmac
55 |
56 | ab_apikey = ''
57 | ab_apisecret = ''
58 | ab_url = 'https://api.binance.com'
59 |
60 | def getjson(api,params=''):
61 | ts = round(time.time()*1000)
62 | query = f'{params}×tamp={ts}' if params != '' else f'timestamp={ts}'
63 | signature = hmac.new(ab_apisecret.encode(), msg=query.encode(), digestmod=hashlib.sha256).hexdigest()
64 | queryurl = f'{ab_url}{api}?{query}&signature={signature}'
65 | headers = {'Content-Type': 'application/json','X-MBX-APIKEY': ab_apikey}
66 | resjson = requests.request("GET", queryurl, headers=headers).json()
67 | return resjson
68 |
69 | ab_listjson = getjson('/api/v3/account')
70 | borderjson = getjson('/api/v3/allOrders',f"symbol={i['asset']}USDT")
71 | ```
72 |
73 | ### 把最终数据以文本表格方式输出
74 | ```
75 | from prettytable import PrettyTable
76 | table_list.sort(key=lambda x:float(x[-1].replace('%','')),reverse = True)
77 | tab = PrettyTable()
78 | tab.field_names = ['币种','数量','总价','最新价','成本价','收益','收益率']
79 | tab.align['币种'] = "l"
80 | tab.align['数量'] = "r"
81 | tab.align['总价'] = "r"
82 | tab.align['最新价'] = "r"
83 | tab.align['成本价'] = "r"
84 | tab.align['收益'] = "r"
85 | tab.align['收益率'] = "r"
86 | for x in table_list:
87 | tab.add_row(x)
88 | tab_info = str(tab)
89 | space = 5
90 | print(tab)
91 | ```
92 |
93 | ### 把文本表格转换成图片
94 | ```
95 | from PIL import Image, ImageDraw, ImageFont
96 | import uuid
97 | font = ImageFont.truetype('/opt/yahei_mono.ttf', 20,encoding="utf-8")
98 | im = Image.new('RGB',(10, 10),(0,0,0,0))
99 | draw = ImageDraw.Draw(im, "RGB")
100 | img_size = draw.multiline_textsize(tab_info, font=font)
101 | im_new = im.resize((img_size[0]+space*2, img_size[1]+space*6))
102 | draw = ImageDraw.Draw(im_new, 'RGB')
103 | draw.multiline_text((space,space), tab_info, spacing=6, fill=(255,255,255), font=font)
104 | filename = str(uuid.uuid1())
105 | im_new.save(f'/tmp/b/b-{filename}.png', "PNG")
106 | print(f'img_path:/tmp/b/b-{filename}.png')
107 | ```
108 |
109 | ### 图片推送钉钉群,需要图床支持,上传到阿里云OSS例子
110 | ```
111 | # 上传OSS
112 | import oss2,os
113 | auth = oss2.Auth(Key, Secret)
114 | bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'oss_bucket')
115 | bucket.put_object_from_file(目标路径/文件名, 源文件)
116 | os.remove(源文件)
117 |
118 | # 推送消息
119 | from dingtalkchatbot.chatbot import DingtalkChatbot
120 | webhook = 'https://oapi.dingtalk.com/robot/send?access_token='
121 | msg = DingtalkChatbot(webhook)
122 | send = msg.send_markdown(title='xxxx', text='### xxxx:\n'
123 | '\n\n'
124 | '[点击查看明细](http://xxx.com)\n', is_at_all=True)
125 | print(send)
126 | ```
127 |
--------------------------------------------------------------------------------
/blockchain/money.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | import requests,json,time
3 | import hashlib
4 | import hmac
5 | from huobi.client.account import AccountClient
6 | from huobi.constant import *
7 | from huobi.client.trade import TradeClient
8 | from huobi.utils import *
9 | from huobi.client.market import MarketClient
10 | from datetime import datetime, timedelta
11 | from prettytable import PrettyTable
12 |
13 | ab_apikey = ''
14 | ab_apisecret = ''
15 | ab_url = 'https://api.binance.com'
16 |
17 | hb_api_key=''
18 | hb_secret_key=''
19 | hb_iglist = ['hbpoint','meetone','add','eon','eop','iq','usdt']
20 |
21 | def getjson(api,params=''):
22 | ts = round(time.time()*1000)
23 | query = f'{params}×tamp={ts}' if params != '' else f'timestamp={ts}'
24 | signature = hmac.new(ab_apisecret.encode(), msg=query.encode(), digestmod=hashlib.sha256).hexdigest()
25 | queryurl = f'{ab_url}{api}?{query}&signature={signature}'
26 | headers = {'Content-Type': 'application/json','X-MBX-APIKEY': ab_apikey}
27 | resjson = requests.request("GET", queryurl, headers=headers).json()
28 | return resjson
29 |
30 | def getlastprice(buss,symbol):
31 | if buss == '安':
32 | return requests.request("GET",f'{ab_url}/api/v3/ticker/price?symbol={symbol}USDT').json()['price']
33 | else:
34 | market_client = MarketClient()
35 | return market_client.get_market_trade(symbol=f"{symbol}usdt")[0].price
36 | def showmethemoney(buss,asset,border):
37 | #print("**********************************************")
38 | count = [float(i['executedQty']) if i['side'] == 'BUY' else -float(i['executedQty']) for i in border]
39 | amount = [float(i['cummulativeQuoteQty']) if i['side'] == 'BUY' else -float(i['cummulativeQuoteQty']) for i in border]
40 | avgprice = round(sum(amount)/sum(count),8)
41 | #print(f"========={i['asset']}========{sum(amount)}/{sum(count)}={avgprice}")
42 | #print(json.dumps(border,indent=4))
43 | buy_count,buy_amount,sell_count,sell_amount = 0,0,0,0
44 | last_order = border[-1]['orderId']
45 | for j in border:
46 | if j['side'] == 'BUY':
47 | buy_count = buy_count + float(j['executedQty'])
48 | buy_amount = buy_amount + float(j['cummulativeQuoteQty'])
49 | else:
50 | sell_count = sell_count + float(j['executedQty'])
51 | sell_amount = sell_amount + float(j['cummulativeQuoteQty'])
52 |
53 | last_count = buy_count - sell_count
54 | if round(last_count,8) == 0 or j['orderId'] == last_order:
55 | if j['orderId'] == last_order and round(last_count,8) != 0:
56 | last_price = float(getlastprice(buss,asset))
57 | ccost_price = (buy_amount - sell_amount)/last_count
58 | u_price = last_count * last_price
59 | sell_amount = sell_amount + (last_price * last_count)
60 |
61 | p = f'{round(last_count,2)}个,币值:{round(u_price,2)}u,最新:{round(last_price,6)}u,成本:{round(ccost_price,6)}u,'
62 |
63 | profit = sell_amount - buy_amount
64 | rate = round((sell_amount - buy_amount)*100/buy_amount,2)
65 | #print(f"{buss}:{asset.upper()}:{p}收益:{round(profit,2)}u,收益率:{rate}%")
66 | table_list.append([f'{buss}:{asset.upper()}',round(last_count,2),'%.2fu' % u_price,f'{round(last_price,6)}u',f'{round(ccost_price,6)}u',f'{round(profit,2)}u',f'{rate}%'])
67 | else:
68 | ptime = time.strftime("%y-%m-%d_%H:%M", time.localtime(j['updateTime']/1000))
69 | p = f'成交时间:{ptime},'
70 |
71 | #profit = sell_amount - buy_amount
72 | #rate = round((sell_amount - buy_amount)*100/buy_amount,2)
73 | #print(f"{i['asset']}:{p}收益:{round(profit,6)}u,收益率:{rate}%")
74 | buy_count,buy_amount,sell_count,sell_amount = 0,0,0,0
75 |
76 |
77 | if __name__ == "__main__":
78 | table_list = []
79 |
80 | #币安处理
81 | ab_listjson = getjson('/api/v3/account')
82 | ab_list = [i for i in ab_listjson['balances'] if float(i['free']) != 0 or float(i['locked']) != 0]
83 | #print(ab_list)
84 | for i in ab_list:
85 | if i['asset'] != 'BNB' and i['asset'] != 'USDT':
86 | borderjson = getjson('/api/v3/allOrders',f"symbol={i['asset']}USDT")
87 |
88 | #单个币的交易订单记录,格式为列表内每个订单为一个字典:订单id,单价,成交量,成交金额,类型,成交时间。
89 | ab_border = [{"orderId":i['orderId'],
90 | "price":i['price'],
91 | "executedQty":i['executedQty'],
92 | "cummulativeQuoteQty":i['cummulativeQuoteQty'],
93 | "side":i['side'],
94 | "updateTime":i['updateTime']}
95 | for i in borderjson if float(i['executedQty']) != 0 and i['orderId'] != 8472222]
96 |
97 | showmethemoney('安',i['asset'],ab_border)
98 |
99 | #火币处理
100 | hb_balance = {}
101 | account_client = AccountClient(api_key=hb_api_key,secret_key=hb_secret_key)
102 | account_balance_list = account_client.get_account_balance()
103 | for account_balance_obj in account_balance_list:
104 | for balance_obj in account_balance_obj.list:
105 | if float(balance_obj.balance) > 0.01 and balance_obj.currency not in hb_iglist:
106 | hb_balance[balance_obj.currency] = float(balance_obj.balance) if balance_obj.currency not in hb_balance else hb_balance[balance_obj.currency] + float(balance_obj.balance)
107 |
108 | trade_client = TradeClient(api_key=hb_api_key,secret_key=hb_secret_key)
109 | for symbol,bcount in hb_balance.items():
110 | x,order_bcount = 0,0
111 | hb_border = []
112 | while abs(order_bcount - bcount) >0.1 and x < 30:
113 | list_obj = trade_client.get_orders(symbol=f'{symbol}usdt',
114 | start_date=(datetime.now() - timedelta(days=2*x+1)).strftime('%Y-%m-%d'),
115 | end_date=(datetime.now() - timedelta(days=2*x)).strftime('%Y-%m-%d'),
116 | order_state="partial-filled,filled,partial-canceled")
117 | if len(list_obj) != 0:
118 | for order in list_obj:
119 | hb_border.append({"orderId":order.id, "price":order.price,
120 | "executedQty":order.filled_amount,
121 | "cummulativeQuoteQty":order.filled_cash_amount,
122 | "side":'BUY' if order.type.startswith("buy-") else 'SELL',
123 | "updateTime":order.finished_at})
124 | order_bcount = order_bcount + (float(order.filled_amount) if order.type.startswith("buy-") else -float(order.filled_amount))
125 | if abs(abs(order_bcount) - bcount) <0.1:
126 | break
127 | x=x+1
128 | showmethemoney('火',symbol,hb_border)
129 |
130 | table_list.sort(key=lambda x:float(x[-1].replace('%','')),reverse = True)
131 | tab = PrettyTable()
132 | tab.field_names = ['币种','数量','总价','最新价','成本价','收益','收益率']
133 | tab.align['币种'] = "l"
134 | tab.align['数量'] = "r"
135 | tab.align['总价'] = "r"
136 | tab.align['最新价'] = "r"
137 | tab.align['成本价'] = "r"
138 | tab.align['收益'] = "r"
139 | tab.align['收益率'] = "r"
140 | for x in table_list:
141 | tab.add_row(x)
142 | tab_info = str(tab)
143 | space = 5
144 | print(tab)
145 |
146 | from PIL import Image, ImageDraw, ImageFont
147 | import uuid
148 | font = ImageFont.truetype('/opt/yahei_mono.ttf', 20,encoding="utf-8")
149 | im = Image.new('RGB',(10, 10),(0,0,0,0))
150 | draw = ImageDraw.Draw(im, "RGB")
151 | img_size = draw.multiline_textsize(tab_info, font=font)
152 | im_new = im.resize((img_size[0]+space*2, img_size[1]+space*6))
153 | draw = ImageDraw.Draw(im_new, 'RGB')
154 | draw.multiline_text((space,space), tab_info, spacing=6, fill=(255,255,255), font=font)
155 | filename = str(uuid.uuid1())
156 | im_new.save(f'/tmp/b/b-{filename}.png', "PNG")
157 | print(f'img_path:/tmp/b/b-{filename}.png')
158 |
--------------------------------------------------------------------------------
/bug_notify/README.md:
--------------------------------------------------------------------------------
1 | ### 从阿里云漏洞库采集最新漏洞推送到企业微信
2 |
--------------------------------------------------------------------------------
/bug_notify/avd.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | from bs4 import BeautifulSoup
3 | import requests,sys,os,pickle
4 | from datetime import datetime
5 | import wecom,hashlib
6 | weixin = wecom.WXQY()
7 |
8 | avd_url = 'https://avd.aliyun.com'
9 | avd_file = './last_avd_id.pkl'
10 | wxkey = 'xxxxx-xxxxx-xxxxx-xxx'
11 | res = requests.get(avd_url + '/high-risk/list')
12 | res.encoding = 'utf-8'
13 | soup = BeautifulSoup(res.text, 'html.parser')
14 | bugs = soup.select('tr')
15 | '''
16 |
17 | AVD编号 |
18 | 漏洞名称 |
19 | 漏洞类型 |
20 | 披露时间 |
21 | 漏洞状态 |
22 |
23 | '''
24 | bug_info = bugs[1].select('td')
25 | bug_info_md5 = hashlib.md5(f'{bug_info}'.encode(encoding='UTF-8')).hexdigest()
26 | avd_id = bug_info[0].getText(strip=True)
27 | print(avd_id)
28 | if os.path.exists(avd_file):
29 | with open(avd_file, 'rb') as f:
30 | last_avd_md5 = pickle.load(f)
31 | if last_avd_md5 == bug_info_md5:
32 | print('avd_id 存在')
33 | sys.exit()
34 | if os.path.exists(avd_file) == False or last_avd_md5 != bug_info_md5:
35 | with open(avd_file, 'wb') as f:
36 | pickle.dump(bug_info_md5,f)
37 |
38 | avd_id_url = avd_url + bug_info[0].a.attrs['href']
39 | avd_name = bug_info[1].getText(strip=True)
40 | avd_type = bug_info[2].button.attrs.get('title',bug_info[2].getText(strip=True))
41 | avd_time = bug_info[3].getText(strip=True)
42 | avd_stat = bug_info[4].select('button')[1].attrs['title']
43 | now = datetime.now().strftime('%Y-%m-%d')
44 | print(avd_id,avd_id_url,avd_name,avd_type,avd_time,avd_stat)
45 | md = f'# {avd_name}\n' \
46 | f'- 编号:{avd_id}[【详情】]({avd_id_url})\n' \
47 | f'- 类型:{avd_type}\n' \
48 | f'- 披露:{avd_time}\n' \
49 | f'- 状态:{avd_stat}({now})\n'
50 | sendwx = weixin.send_message_group(wxkey, 'markdown', md, '@xxxxx')
51 | print(sendwx)
52 |
--------------------------------------------------------------------------------
/bug_notify/wecom.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | # -*- coding: utf-8 -*-
3 | import time,datetime
4 | import requests
5 | import json
6 | import sys
7 |
8 | class WXQY:
9 | apiurl = "https://qyapi.weixin.qq.com/cgi-bin/"
10 | def send_message_group(self, key, type, data, at):
11 | at = '<@'+'><@'.join(at.split('@')[1:])+'>'
12 | if not key or not data:
13 | return
14 | params = {'msgtype' : type}
15 | if len(data.encode('utf-8')) > 4000:
16 | data = data[0:1000]
17 | if type == "text":
18 | params[type] = {'content' : data,'mentioned_list':['@all']}
19 | elif type == "markdown":
20 | params[type] = {'content' : f'{data}\n{at}'}
21 | elif type == "news":
22 | params[type] = {'articles' : data,'mentioned_mobile_list':[at]}
23 | else:
24 | params["msgtype"] = "text"
25 | params["text"] = {'content' : "不支持的消息类型 " + type}
26 |
27 | url = self.apiurl + 'webhook/send?key=%s'%(key)
28 | return self.http_request_v2(url, "POST", params=params)
29 |
30 | def http_request_v2(self, url, method="GET", headers={}, params=None):
31 | if method == "GET":
32 | response = requests.get(url)
33 | elif method == "POST":
34 | data = bytes(json.dumps(params), 'utf-8')
35 | response = requests.post(url, data= data)
36 | elif method == "DELETE":
37 | response = requests.delete(url, data= data)
38 | result = response.json()
39 | return result
40 |
41 | if __name__ == "__main__":
42 | key = sys.argv[1]
43 | info = sys.argv[2]
44 | weixin = WXQY()
45 | md = '# 实时新增用户反馈132例\n \
46 | ## 类型:用户反馈\n \
47 | ### 普通用户反馈:117例\n \
48 | #### VIP用户反馈:15例\n'
49 | result = weixin.send_message_group(key, "text", info, '@all');
50 |
51 | print(result)
52 |
--------------------------------------------------------------------------------
/check_pic/.gitignore:
--------------------------------------------------------------------------------
1 | config
2 |
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | .hypothesis/
50 | .pytest_cache/
51 |
52 | # Translations
53 | *.mo
54 | *.pot
55 |
56 | # Django stuff:
57 | *.log
58 | local_settings.py
59 | db.sqlite3
60 |
61 | # Flask stuff:
62 | instance/
63 | .webassets-cache
64 |
65 | # Scrapy stuff:
66 | .scrapy
67 |
68 | # Sphinx documentation
69 | docs/_build/
70 |
71 | # PyBuilder
72 | target/
73 |
74 | # Jupyter Notebook
75 | .ipynb_checkpoints
76 |
77 | # pyenv
78 | .python-version
79 |
80 | # celery beat schedule file
81 | celerybeat-schedule
82 |
83 | # SageMath parsed files
84 | *.sage.py
85 |
86 | # Environments
87 | .env
88 | .venv
89 | env/
90 | venv/
91 | ENV/
92 | env.bak/
93 | venv.bak/
94 |
95 | # Spyder project settings
96 | .spyderproject
97 | .spyproject
98 |
99 | # Rope project settings
100 | .ropeproject
101 |
102 | # mkdocs documentation
103 | /site
104 |
105 | # mypy
106 | .mypy_cache/
107 |
--------------------------------------------------------------------------------
/check_pic/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/starsliao/PythonTools/3bdd7fc988529ea75e927f4a3f1ed9b10424eaba/check_pic/1.jpg
--------------------------------------------------------------------------------
/check_pic/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 StarsL.cn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/check_pic/README.md:
--------------------------------------------------------------------------------
1 | # check_pic
2 | 
3 | > 图片检测、照片评分、人脸识别、鉴黄
4 |
5 | 基于腾讯优图接口,[https://open.youtu.qq.com](https://open.youtu.qq.com),请注册账号并添加应用获取AppID等信息填写到check.py中。
6 |
7 | ### install
8 | ```
9 | pip install -U requests
10 |
11 | vim check.py
12 |
13 | appid = 'xxxxx'
14 | secret_id = 'xxxxx'
15 | secret_key = 'xxxxx'
16 | userid = 'xxxxx'
17 | ```
18 | ### Usage
19 | ```
20 | [root@i check_pic]#./check.py 1.jpg
21 | checking img...
22 | 图像标签识别:
23 | ['60%:女孩', '15%:写真照', '12%:头发']
24 | 人脸分析:
25 | ['性别:女', '年龄:26', '魅力:94', '笑容:20', '不戴眼镜']
26 | 性感检测:
27 | ['99%:性感', '100%:女性胸部', '34%:色情综合值']
28 | ```
29 |
--------------------------------------------------------------------------------
/check_pic/TencentYoutuyun/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from .youtu import YouTu
4 | from .auth import Auth
5 |
6 |
7 |
--------------------------------------------------------------------------------
/check_pic/TencentYoutuyun/auth.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import time
4 | import random
5 | import hmac, hashlib
6 | import binascii
7 | import base64
8 | from TencentYoutuyun import conf
9 |
10 | class Auth(object):
11 |
12 | def __init__(self, secret_id, secret_key, appid, userid):
13 | self.AUTH_URL_FORMAT_ERROR = -1
14 | self.AUTH_SECRET_ID_KEY_ERROR = -2
15 |
16 | self._secret_id = secret_id
17 | self._secret_key = secret_key
18 | self._appid = appid
19 | self._userid = userid
20 |
21 | def app_sign(self, expired=0):
22 | if not self._secret_id or not self._secret_key:
23 | return self.AUTH_SECRET_ID_KEY_ERROR
24 |
25 | puserid = ''
26 | if self._userid != '':
27 | if len(self._userid) > 64:
28 | return self.AUTH_URL_FORMAT_ERROR
29 | puserid = self._userid
30 |
31 | now = int(time.time())
32 | rdm = random.randint(0, 999999999)
33 | plain_text = 'a=' + self._appid + '&k=' + self._secret_id + '&e=' + str(expired) + '&t=' + str(now) + '&r=' + str(rdm) + '&u=' + puserid + '&f='
34 | bin = hmac.new(self._secret_key.encode(), plain_text.encode(), hashlib.sha1)
35 | s = bin.hexdigest()
36 | s = binascii.unhexlify(s)
37 | s = s + plain_text.encode('ascii')
38 | signature = base64.b64encode(s).rstrip() #生成签名
39 | return signature
40 |
41 |
--------------------------------------------------------------------------------
/check_pic/TencentYoutuyun/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import pkg_resources
3 | import platform
4 |
5 | API_YOUTU_END_POINT = 'http://api.youtu.qq.com/'
6 | API_YOUTU_VIP_END_POINT = 'https://vip-api.youtu.qq.com/'
7 |
8 | APPID = 'xxx'
9 | SECRET_ID = 'xxx'
10 | SECRET_KEY = 'xx'
11 | USER_ID = 'xx'
12 |
13 | _config = {
14 | 'end_point':API_YOUTU_END_POINT,
15 | 'appid':APPID,
16 | 'secret_id':SECRET_ID,
17 | 'secret_key':SECRET_KEY,
18 | 'userid':USER_ID,
19 | }
20 |
21 | def get_app_info():
22 | return _config
23 |
24 | def set_app_info(appid=None, secret_id=None, secret_key=None, userid=None, end_point=None):
25 | if appid:
26 | _config['appid'] = appid
27 | if secret_id:
28 | _config['secret_id'] = secret_id
29 | if secret_key:
30 | _config['secret_key'] = secret_key
31 | if userid:
32 | _config['userid'] = userid
33 | if end_point:
34 | _config['end_point'] = end_point
35 |
36 |
37 |
--------------------------------------------------------------------------------
/check_pic/TencentYoutuyun/youtu.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os.path
4 | import time
5 | import requests
6 | import base64
7 | import json
8 | from TencentYoutuyun import conf
9 | from .auth import Auth
10 |
11 | class YouTu(object):
12 |
13 | def __init__(self, appid, secret_id, secret_key, userid='0', end_point=conf.API_YOUTU_END_POINT):
14 | self.IMAGE_FILE_NOT_EXISTS = -1
15 | self.IMAGE_NETWORK_ERROR = -2
16 | self.IMAGE_PARAMS_ERROR = -3
17 | self.PERSON_ID_EMPTY = -4
18 | self.GROUP_ID_EMPTY = -5
19 | self.GROUP_IDS_EMPTY = -6
20 | self.IMAGES_EMPTY = -7
21 | self.FACE_IDS_EMPTY = -8
22 | self.FACE_ID_EMPTY = -9
23 | self.LIST_TYPE_INVALID = -10
24 | self.IMAGE_PATH_EMPTY = -11
25 |
26 | self.VALIDATE_DATA_EMPTY = -12
27 | self.VIDEO_PATH_EMPTY = -13
28 | self.CARD_PATH_EMPTY = -14
29 | self.IDCARD_NAME_OR_ID_EMPTY = -15
30 |
31 | self.VIDEO_FILE_NOT_EXISTS = -16
32 | self.CARD_FILE_NOT_EXISTS = -17
33 |
34 | self.UNKNOW_CARD_TYPE = -18
35 |
36 | self.EXPIRED_SECONDS = 2592000
37 | self._secret_id = secret_id
38 | self._secret_key = secret_key
39 | self._appid = appid
40 | self._userid = userid
41 | self._end_point = end_point
42 | conf.set_app_info(appid, secret_id, secret_key, userid, end_point)
43 |
44 | def get_headers(self, req_type):
45 |
46 | expired = int(time.time()) + self.EXPIRED_SECONDS
47 | auth = Auth(self._secret_id, self._secret_key, self._appid, self._userid)
48 |
49 | sign = auth.app_sign(expired)
50 | headers = {
51 | 'Authorization':sign,
52 | 'Content-Type':'text/json'
53 | }
54 |
55 | return headers
56 |
57 | def generate_res_url(self, req_type, url_type = 0):
58 |
59 | app_info = conf.get_app_info()
60 | url_api_str = ''
61 | if url_type == 4:
62 | url_api_str = 'youtu/carapi'
63 | elif url_type == 3:
64 | url_api_str = 'youtu/openliveapi'
65 | elif url_type == 2:
66 | url_api_str = 'youtu/ocrapi'
67 | elif url_type == 1:
68 | url_api_str = 'youtu/imageapi'
69 | else :
70 | url_api_str = 'youtu/api'
71 |
72 | return app_info['end_point'] + url_api_str + '/' + str(req_type)
73 |
74 | def FaceCompare(self, image_pathA, image_pathB, data_type = 0):
75 |
76 | req_type = 'facecompare'
77 | headers = self.get_headers(req_type)
78 | url = self.generate_res_url(req_type)
79 |
80 | data = {
81 | "app_id": self._appid
82 | }
83 |
84 | if len(image_pathA) == 0 or len(image_pathB) == 0:
85 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY', 'session_id':'', 'similarity':0}
86 |
87 | if data_type == 0:
88 | filepathA = os.path.abspath(image_pathA)
89 | filepathB = os.path.abspath(image_pathB)
90 |
91 | if not os.path.exists(filepathA):
92 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS', 'session_id':'', 'similarity':0}
93 | if not os.path.exists(filepathB):
94 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS', 'session_id':'', 'similarity':0}
95 |
96 | data["imageA"] = base64.b64encode(open(filepathA, 'rb').read()).rstrip().decode('utf-8')
97 | data["imageB"] = base64.b64encode(open(filepathB, 'rb').read()).rstrip().decode('utf-8')
98 | else :
99 | data["urlA"] = image_pathA
100 | data["urlB"] = image_pathB
101 |
102 | r = {}
103 | try:
104 | r = requests.post(url, headers=headers, data = json.dumps(data))
105 | if r.status_code != 200:
106 | return {'httpcode':r.status_code, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':'', 'session_id':'', 'similarity':0}
107 | ret = r.json()
108 |
109 | except Exception as e:
110 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), 'session_id':'', 'similarity':0}
111 |
112 | return ret
113 |
114 | def FaceVerify(self, person_id, image_path, data_type = 0):
115 |
116 | req_type='faceverify'
117 | headers = self.get_headers(req_type)
118 | url = self.generate_res_url(req_type)
119 |
120 | data = {
121 | "app_id": self._appid,
122 | "person_id": person_id
123 | }
124 |
125 | if len(image_path) == 0:
126 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY', "confidence":0, "ismatch":0, "session_id":''}
127 |
128 | if data_type == 0:
129 | filepath = os.path.abspath(image_path)
130 | if not os.path.exists(filepath):
131 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS', "confidence":0, "ismatch":0, "session_id":''}
132 | if len(person_id) == 0:
133 | return {'httpcode':0, 'errorcode':self.PERSON_ID_EMPTY, 'errormsg':'PERSON_ID_EMPTY', "confidence":0, "ismatch":0, "session_id":''}
134 |
135 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
136 | else :
137 | data["url"] = image_path
138 |
139 | r = {}
140 | try:
141 | r = requests.post(url, headers=headers, data = json.dumps(data))
142 | if r.status_code != 200:
143 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "confidence":0, "ismatch":0, "session_id":''}
144 | ret = r.json()
145 |
146 | except Exception as e:
147 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "confidence":0, "ismatch":0, "session_id":''}
148 |
149 | return ret
150 |
151 | def FaceIdentify(self, group_id, image_path, data_type = 0):
152 |
153 | req_type='faceidentify'
154 | headers = self.get_headers(req_type)
155 | url = self.generate_res_url(req_type)
156 |
157 | data = {
158 | "app_id": self._appid
159 | }
160 |
161 | if len(image_path) == 0:
162 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY', "session_id":'', "candidates":[{}]}
163 |
164 | if data_type == 0:
165 | filepath = os.path.abspath(image_path)
166 | if not os.path.exists(filepath):
167 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS', "session_id":'', "candidates":[{}]}
168 |
169 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
170 | else :
171 | data["url"] = image_path
172 |
173 | if len(group_id) == 0:
174 | return {'httpcode':0, 'errorcode':self.GROUP_ID_EMPTY, 'errormsg':'GROUP_ID_EMPTY', "session_id":'', "candidates":[{}]}
175 | else :
176 | data["group_id"] = group_id
177 |
178 | r = {}
179 | try:
180 | r = requests.post(url, headers=headers, data = json.dumps(data))
181 | if r.status_code != 200:
182 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "session_id":'', "candidates":[{}]}
183 | ret = r.json()
184 |
185 | except Exception as e:
186 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "session_id":'', "candidates":[{}]}
187 |
188 | return ret
189 |
190 | def MultiFaceIdentify(self, group_id, group_ids, image_path, data_type = 0, topn = 5, min_size = 40):
191 |
192 | req_type='multifaceidentify'
193 | headers = self.get_headers(req_type)
194 | url = self.generate_res_url(req_type)
195 |
196 | data = {
197 | "app_id": self._appid,
198 | "topn": topn,
199 | "min_size": min_size
200 | }
201 |
202 | if len(image_path) == 0:
203 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY', "session_id":'', "candidates":[{}]}
204 |
205 | if data_type == 0:
206 | filepath = os.path.abspath(image_path)
207 | if not os.path.exists(filepath):
208 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS', "session_id":'', "candidates":[{}]}
209 |
210 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
211 | else :
212 | data["url"] = image_path
213 |
214 | if len(group_id) == 0 and len(group_ids) == 0:
215 | return {'httpcode':0, 'errorcode':self.ERROR_PARAMETER_EMPTY, 'errormsg':'ERROR_PARAMETER_EMPTY', "session_id":'', "candidates":[{}]}
216 | elif len(group_id) != 0:
217 | data["group_id"] = group_id
218 | else :
219 | data["group_ids"] = group_ids
220 |
221 | r = {}
222 | try:
223 | r = requests.post(url, headers=headers, data = json.dumps(data))
224 | if r.status_code != 200:
225 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "session_id":'', "candidates":[{}]}
226 | ret = r.json()
227 |
228 | except Exception as e:
229 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "session_id":'', "candidates":[{}]}
230 |
231 | return ret
232 |
233 | def DetectFace(self, image_path, mode = 0, data_type = 0):
234 |
235 | req_type='detectface'
236 | headers = self.get_headers(req_type)
237 | url = self.generate_res_url(req_type)
238 |
239 | data = {
240 | "app_id": self._appid,
241 | "mode": mode
242 | }
243 |
244 | if len(image_path) == 0:
245 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY', "session_id":'', "image_id":'', "image_height":0, "image_width":0, "face":[{}]}
246 |
247 | if data_type == 0:
248 | filepath = os.path.abspath(image_path)
249 | if not os.path.exists(filepath):
250 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS', "session_id":'', "image_id":'', "image_height":0, "image_width":0, "face":[{}]}
251 |
252 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
253 | else :
254 | data["url"] = image_path
255 |
256 | r = {}
257 | try:
258 | r = requests.post(url, headers=headers, data = json.dumps(data))
259 | if r.status_code != 200:
260 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "session_id":'', "image_id":'', "image_height":0, "image_width":0, "face":[{}]}
261 | ret = r.json()
262 |
263 | except Exception as e:
264 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "session_id":'', "image_id":'', "image_height":0, "image_width":0, "face":[{}]}
265 |
266 | return ret
267 |
268 |
269 | def NewPerson(self, person_id, image_path, group_ids, person_name= '', tag='', data_type = 0):
270 |
271 | req_type='newperson'
272 | headers = self.get_headers(req_type)
273 | url = self.generate_res_url(req_type)
274 |
275 | if len(person_id) == 0:
276 | return {'httpcode':0, 'errorcode':self.PERSON_ID_EMPTY, 'errormsg':'PERSON_ID_EMPTY', "person_id":'', "suc_group":'', "suc_face":0, "session_id":0, "face_id":'', "group_ids":''}
277 |
278 | if len(group_ids) == 0:
279 | return {'httpcode':0, 'errorcode':self.GROUP_IDS_EMPTY, 'errormsg':'GROUP_IDS_EMPTY', "person_id":'', "suc_group":'', "suc_face":0, "session_id":0, "face_id":'', "group_ids":''}
280 |
281 | if type(group_ids) != list:
282 | return {'httpcode':0, 'errorcode': self.LIST_TYPE_INVALID, 'errormsg':'LIST_TYPE_INVALID', "person_id":'', "suc_group":'', "suc_face":0, "session_id":0, "face_id":'', "group_ids":''}
283 |
284 | data = {
285 | "app_id": self._appid,
286 | "person_id" : person_id,
287 | "person_name": person_name,
288 | "group_ids": group_ids,
289 | "tag": tag
290 | }
291 |
292 | if len(image_path) == 0:
293 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY', "person_id":'', "suc_group":'', "suc_face":0, "session_id":0, "face_id":'', "group_ids":''}
294 |
295 | if data_type == 0:
296 | filepath = os.path.abspath(image_path)
297 | if not os.path.exists(filepath):
298 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS', "person_id":'', "suc_group":'', "suc_face":0, "session_id":0, "face_id":'', "group_ids":''}
299 |
300 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
301 | else:
302 | data["url"] = image_path
303 |
304 | r = {}
305 | try:
306 | r = requests.post(url, headers=headers, data = json.dumps(data))
307 | if r.status_code != 200:
308 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "person_id":'', "suc_group":'', "suc_face":0, "session_id":0, "face_id":'', "group_ids":''}
309 |
310 | ret = r.json()
311 | except Exception as e:
312 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "person_id":'', "suc_group":'', "suc_face":0, "session_id":0, "face_id":'', "group_ids":''}
313 |
314 | return ret
315 |
316 | def DelPerson(self, person_id) :
317 |
318 | req_type='delperson'
319 | headers = self.get_headers(req_type)
320 | url = self.generate_res_url(req_type)
321 |
322 | if len(person_id) == 0:
323 | return {'httpcode':0, 'errorcode':self.PERSON_ID_EMPTY, 'errormsg':'PERSON_ID_EMPTY', "deleted":0, "session_id":''}
324 |
325 | data = {
326 | "app_id": self._appid,
327 | "person_id" : person_id
328 | }
329 |
330 | r = {}
331 | try:
332 | r = requests.post(url, headers=headers, data = json.dumps(data))
333 | if r.status_code != 200:
334 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "deleted":0, "session_id":''}
335 |
336 | ret = r.json()
337 | except Exception as e:
338 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "deleted":0, "session_id":''}
339 |
340 | return ret
341 |
342 | def AddFace(self, person_id, images, tag='', data_type = 0):
343 |
344 | req_type='addface'
345 | headers = self.get_headers(req_type)
346 | url = self.generate_res_url(req_type)
347 |
348 | if len(person_id) == 0:
349 | return {'httpcode':0, 'errorcode':self.PERSON_ID_EMPTY, 'errormsg':'PERSON_ID_EMPTY', "face_ids":[], "session_id":'', "added": 0, "ret_codes":[]}
350 |
351 | data = {
352 | "app_id": self._appid,
353 | "person_id" : person_id,
354 | "tag" : tag
355 | }
356 |
357 | if len(images) == 0:
358 | return {'httpcode':0, 'errorcode':self.IMAGES_EMPTY, 'errormsg':'IMAGES_EMPTY', "face_ids":[], "session_id":'', "added": 0, "ret_codes":[]}
359 |
360 | if type(images) != list:
361 | return {'httpcode':0, 'errorcode':self.LIST_TYPE_INVALID, 'errormsg':'LIST_TYPE_INVALID', "face_ids":[], "session_id":'', "added": 0, "ret_codes":[]}
362 |
363 | if data_type == 0:
364 | images_content = []
365 | for image in images:
366 | filepath = os.path.abspath(image)
367 | if not os.path.exists(filepath):
368 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS', "face_ids":[], "session_id":'', "added": 0, "ret_codes":[]}
369 |
370 | images_content.append(base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8'))
371 | data["images"] = images_content
372 | else :
373 | data["urls"] = images
374 |
375 | r = {}
376 | try:
377 | r = requests.post(url, headers=headers, data = json.dumps(data))
378 | if r.status_code != 200:
379 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "face_ids":[], "session_id":'', "added": 0, "ret_codes":[]}
380 |
381 | ret = r.json()
382 | except Exception as e:
383 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "face_ids":[], "session_id":'', "added": 0, "ret_codes":[]}
384 |
385 | return ret
386 |
387 | def DelFace(self, person_id, face_ids):
388 |
389 | req_type='delface'
390 | headers = self.get_headers(req_type)
391 | url = self.generate_res_url(req_type)
392 |
393 | if len(person_id) == 0:
394 | return {'httpcode':0, 'errorcode':self.PERSON_ID_EMPTY, 'errormsg':'PERSON_ID_EMPTY', "session_id":'', "deleted ": 0}
395 |
396 | if len(face_ids) == 0:
397 | return {'httpcode':0, 'errorcode':self.FACE_IDS_IMPTY, 'errormsg':'FACE_IDS_IMPTY', "session_id":'', "deleted ": 0}
398 |
399 | if type(face_ids) != list:
400 | return {'httpcode':0, 'errorcode':self.LIST_TYPE_INVALID, 'errormsg':'LIST_TYPE_INVALID', "session_id":'', "deleted ": 0}
401 |
402 | data = {
403 | "app_id": self._appid,
404 | "person_id":person_id,
405 | "face_ids":face_ids
406 | }
407 |
408 | r = {}
409 | try:
410 | r = requests.post(url, headers=headers, data = json.dumps(data))
411 | if r.status_code != 200:
412 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "session_id":'', "deleted ": 0}
413 |
414 | ret = r.json()
415 | except Exception as e:
416 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "session_id":'', "deleted ": 0}
417 |
418 | return ret
419 |
420 |
421 | def SetInfo(self, person_id, person_name='', tag=''):
422 |
423 | req_type='setinfo'
424 | headers = self.get_headers(req_type)
425 | url = self.generate_res_url(req_type)
426 | url_type
427 | if len(person_id) == 0:
428 | return {'httpcode':0, 'errorcode':self.PERSON_ID_EMPTY, 'errormsg':'PERSON_ID_EMPTY', "person_id":'', "session_id ": ''}
429 |
430 | data = {
431 | "app_id": self._appid,
432 | "person_id": person_id,
433 | "person_name": person_name,
434 | "tag":tag
435 | }
436 |
437 | r = {}
438 | try:
439 | r = requests.post(url, headers=headers, data = json.dumps(data))
440 | if r.status_code != 200:
441 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "person_id":'', "session_id ": ''}
442 |
443 | ret = r.json()
444 | except Exception as e:
445 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "person_id":'', "session_id ": ''}
446 |
447 | return ret
448 |
449 | def GetInfo(self, person_id):
450 |
451 | req_type='getinfo'
452 | headers = self.get_headers(req_type)
453 | url = self.generate_res_url(req_type)
454 |
455 | if len(person_id) == 0:
456 | return {'httpcode':0, 'errorcode':self.PERSON_ID_EMPTY, 'errormsg':'PERSON_ID_EMPTY', "person_id":'', "person_name ": '', "face_ids":[], "tag":'', "secret_id":''}
457 |
458 | data = {
459 | "app_id": self._appid,
460 | "person_id": person_id
461 | }
462 |
463 | r = {}
464 | try:
465 | r = requests.post(url, headers=headers, data = json.dumps(data))
466 | if r.status_code != 200:
467 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "person_id":'', "person_name ": '', "face_ids":[], "tag":'', "secret_id":''}
468 | ret = r.json()
469 |
470 | except Exception as e:
471 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "person_id":'', "person_name ": '', "face_ids":[], "tag":'', "secret_id":''}
472 |
473 | return ret
474 |
475 | def GetGroupIds(self):
476 |
477 | req_type='getgroupids'
478 | headers = self.get_headers(req_type)
479 | url = self.generate_res_url(req_type)
480 |
481 | data = {
482 | "app_id": self._appid
483 | }
484 |
485 | r = {}
486 | try:
487 | r = requests.post(url, headers=headers, data = json.dumps(data))
488 | if r.status_code != 200:
489 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "group_ids":[]}
490 |
491 | ret = r.json()
492 | except Exception as e:
493 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "group_ids":[]}
494 |
495 | return ret
496 |
497 | def GetPersonIds(self, group_id) :
498 |
499 | req_type='getpersonids'
500 | headers = self.get_headers(req_type)
501 | url = self.generate_res_url(req_type)
502 |
503 | if len(group_id) == 0:
504 | return {'httpcode':0, 'errorcode':self.GROUP_ID_EMPTY, 'errormsg':'GROUP_ID_EMPTY', "person_ids":[]}
505 |
506 | data = {
507 | "app_id": self._appid,
508 | "group_id": group_id
509 | }
510 |
511 | r = {}
512 | try:
513 | r = requests.post(url, headers=headers, data = json.dumps(data))
514 | if r.status_code != 200:
515 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "person_ids":[]}
516 |
517 | ret = r.json()
518 | except Exception as e:
519 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "person_ids":[]}
520 |
521 | return ret
522 |
523 | def GetFaceIds(self, person_id):
524 |
525 | req_type='getfaceids'
526 | headers = self.get_headers(req_type)
527 | url = self.generate_res_url(req_type)
528 |
529 | if len(person_id) == 0:
530 | return {'httpcode':0, 'errorcode':self.PERSON_ID_EMPTY, 'errormsg':'PERSON_ID_EMPTY', "face_ids":[]}
531 |
532 | data = {
533 | "app_id": self._appid,
534 | "person_id": person_id
535 | }
536 |
537 | r = {}
538 | try:
539 | r = requests.post(url, headers=headers, data = json.dumps(data))
540 | if r.status_code != 200:
541 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "face_ids":[]}
542 |
543 | ret = r.json()
544 | except Exception as e:
545 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "face_ids":[]}
546 |
547 | return ret
548 |
549 | def GetFaceInfo(self, face_id):
550 |
551 | req_type='getfaceinfo'
552 | headers = self.get_headers(req_type)
553 | url = self.generate_res_url(req_type)
554 |
555 | if len(face_id) == 0:
556 | return {'httpcode':0, 'errorcode':self.FACE_ID_EMPTY, 'errormsg':'FACE_ID_EMPTY', "face_info":[]}
557 |
558 | data = {
559 | "app_id": self._appid,
560 | "face_id": face_id
561 | }
562 |
563 | r = {}
564 | try:
565 | r = requests.post(url, headers=headers, data = json.dumps(data))
566 | if r.status_code != 200:
567 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "face_info":[]}
568 |
569 | ret = r.json()
570 | except Exception as e:
571 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "face_info":[]}
572 |
573 | return ret
574 |
575 | def FaceShape(self, image_path, mode = 0, data_type = 0):
576 |
577 | req_type='faceshape'
578 | headers = self.get_headers(req_type)
579 | url = self.generate_res_url(req_type)
580 |
581 | data = {
582 | "app_id": self._appid,
583 | "mode": mode
584 | }
585 |
586 | if len(image_path) == 0:
587 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY', "face_shape":[{}], "image_height":0, "image_width":0, "session_id":''}
588 |
589 | if data_type == 0:
590 | filepath = os.path.abspath(image_path)
591 | if not os.path.exists(filepath):
592 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS', "face_shape":[{}], "image_height":0, "image_width":0, "session_id":''}
593 |
594 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
595 | else:
596 | data["url"] = image_path
597 |
598 | r = {}
599 | try:
600 | r = requests.post(url, headers=headers, data = json.dumps(data))
601 | if r.status_code != 200:
602 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':'', "face_shape":[{}], "image_height":0, "image_width":0, "session_id":''}
603 |
604 | ret = r.json()
605 | except Exception as e:
606 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), "face_shape":[{}], "image_height":0, "image_width":0, "session_id":''}
607 |
608 | return ret
609 |
610 | def fuzzydetect(self, image_path, data_type = 0, seq = ''):
611 |
612 | req_type='fuzzydetect'
613 | headers = self.get_headers(req_type)
614 | url = self.generate_res_url(req_type, 1)
615 |
616 | data = {
617 | "app_id": self._appid,
618 | "seq": seq
619 | }
620 |
621 | if len(image_path) == 0:
622 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
623 |
624 | if data_type == 0:
625 | filepath = os.path.abspath(image_path)
626 | if not os.path.exists(filepath):
627 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
628 |
629 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
630 | else:
631 | data["url"] = image_path
632 |
633 | r = {}
634 | try:
635 | r = requests.post(url, headers=headers, data = json.dumps(data))
636 | if r.status_code != 200:
637 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
638 |
639 | ret = r.json()
640 | except Exception as e:
641 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
642 |
643 | return ret
644 |
645 | def fooddetect(self, image_path, data_type = 0, seq = ''):
646 |
647 | req_type='fooddetect'
648 | headers = self.get_headers(req_type)
649 | url = self.generate_res_url(req_type, 1)
650 |
651 | data = {
652 | "app_id": self._appid,
653 | "seq": seq
654 | }
655 |
656 | if len(image_path) == 0:
657 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
658 |
659 | if data_type == 0:
660 | filepath = os.path.abspath(image_path)
661 | if not os.path.exists(filepath):
662 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
663 |
664 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
665 | else:
666 | data["url"] = image_path
667 |
668 | r = {}
669 | try:
670 | r = requests.post(url, headers=headers, data = json.dumps(data))
671 | if r.status_code != 200:
672 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
673 |
674 | ret = r.json()
675 | except Exception as e:
676 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
677 |
678 | return ret
679 |
680 |
681 |
682 | def imagetag(self, image_path, data_type = 0, seq = ''):
683 |
684 | req_type='imagetag'
685 | headers = self.get_headers(req_type)
686 | url = self.generate_res_url(req_type, 1)
687 |
688 | data = {
689 | "app_id": self._appid,
690 | "seq": seq
691 | }
692 |
693 | if len(image_path) == 0:
694 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
695 |
696 | if data_type == 0:
697 | filepath = os.path.abspath(image_path)
698 | if not os.path.exists(filepath):
699 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
700 |
701 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
702 | else:
703 | data["url"] = image_path
704 |
705 | r = {}
706 | try:
707 | r = requests.post(url, headers=headers, data = json.dumps(data))
708 | if r.status_code != 200:
709 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
710 |
711 | ret = r.json()
712 | except Exception as e:
713 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
714 |
715 | return ret
716 |
717 | def imageporn(self, image_path, data_type = 0, seq = ''):
718 |
719 | req_type='imageporn'
720 | headers = self.get_headers(req_type)
721 | url = self.generate_res_url(req_type, 1)
722 |
723 | data = {
724 | "app_id": self._appid,
725 | "seq": seq
726 | }
727 |
728 | if len(image_path) == 0:
729 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
730 |
731 | if data_type == 0:
732 | filepath = os.path.abspath(image_path)
733 | if not os.path.exists(filepath):
734 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
735 |
736 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
737 | else:
738 | data["url"] = image_path
739 |
740 | r = {}
741 | try:
742 | r = requests.post(url, headers=headers, data = json.dumps(data))
743 | if r.status_code != 200:
744 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
745 |
746 | ret = r.json()
747 | except Exception as e:
748 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
749 |
750 | return ret
751 |
752 | def imageterrorism(self, image_path, data_type = 0, seq = ''):
753 |
754 | req_type='imageterrorism'
755 | headers = self.get_headers(req_type)
756 | url = self.generate_res_url(req_type, 1)
757 |
758 | data = {
759 | "app_id": self._appid,
760 | "seq": seq
761 | }
762 |
763 | if len(image_path) == 0:
764 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
765 |
766 | if data_type == 0:
767 | filepath = os.path.abspath(image_path)
768 | if not os.path.exists(filepath):
769 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
770 |
771 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
772 | else:
773 | data["url"] = image_path
774 |
775 | r = {}
776 | try:
777 | r = requests.post(url, headers=headers, data = json.dumps(data))
778 | if r.status_code != 200:
779 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
780 |
781 | ret = r.json()
782 | except Exception as e:
783 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
784 |
785 | return ret
786 |
787 | def carclassify(self, image_path, data_type = 0, seq = ''):
788 |
789 | req_type='carclassify'
790 | headers = self.get_headers(req_type)
791 | url = self.generate_res_url(req_type, 4)
792 |
793 | data = {
794 | "app_id": self._appid,
795 | "seq": seq
796 | }
797 |
798 | if len(image_path) == 0:
799 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
800 |
801 | if data_type == 0:
802 | filepath = os.path.abspath(image_path)
803 | if not os.path.exists(filepath):
804 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
805 |
806 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
807 | else:
808 | data["url"] = image_path
809 |
810 | r = {}
811 | try:
812 | r = requests.post(url, headers=headers, data = json.dumps(data))
813 | if r.status_code != 200:
814 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
815 |
816 | ret = r.json()
817 | except Exception as e:
818 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
819 |
820 | return ret
821 |
822 | def idcardocr(self, image_path, data_type = 0, card_type = 1 ,seq = ''):
823 |
824 | req_type='idcardocr'
825 | headers = self.get_headers(req_type)
826 | url = self.generate_res_url(req_type, 2)
827 |
828 | data = {
829 | "app_id": self._appid,
830 | "seq": seq,
831 | "card_type":card_type
832 | }
833 |
834 | if len(image_path) == 0:
835 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
836 |
837 | if data_type == 0:
838 | filepath = os.path.abspath(image_path)
839 | if not os.path.exists(filepath):
840 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
841 |
842 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
843 | else:
844 | data["url"] = image_path
845 | r = {}
846 | try:
847 | r = requests.post(url, headers=headers, data = json.dumps(data))
848 | if r.status_code != 200:
849 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
850 |
851 | ret = r.json()
852 | except Exception as e:
853 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
854 |
855 | return ret
856 |
857 | def driverlicenseocr(self, image_path, data_type = 0, proc_type = 0, seq = ''):
858 |
859 | req_type='driverlicenseocr'
860 | headers = self.get_headers(req_type)
861 | url = self.generate_res_url(req_type, 2)
862 | data = {
863 | "app_id": self._appid,
864 | "session_id": seq,
865 | "type": proc_type
866 | }
867 |
868 | if len(image_path) == 0:
869 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
870 |
871 | if data_type == 0:
872 | filepath = os.path.abspath(image_path)
873 | if not os.path.exists(filepath):
874 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
875 |
876 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
877 | else:
878 | data["url"] = image_path
879 |
880 | r = {}
881 | try:
882 | r = requests.post(url, headers=headers, data = json.dumps(data))
883 | if r.status_code != 200:
884 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
885 |
886 | ret = r.json()
887 | except Exception as e:
888 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
889 |
890 | return ret
891 |
892 | def bcocr(self, image_path, data_type = 0, seq = ''):
893 |
894 | req_type='bcocr'
895 | headers = self.get_headers(req_type)
896 | url = self.generate_res_url(req_type, 2)
897 | data = {
898 | "app_id": self._appid,
899 | "session_id": seq,
900 | }
901 |
902 | if len(image_path) == 0:
903 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
904 |
905 | if data_type == 0:
906 | filepath = os.path.abspath(image_path)
907 | if not os.path.exists(filepath):
908 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
909 |
910 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
911 | else:
912 | data["url"] = image_path
913 |
914 | r = {}
915 | try:
916 | r = requests.post(url, headers=headers, data = json.dumps(data))
917 | if r.status_code != 200:
918 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
919 |
920 | ret = r.json()
921 | except Exception as e:
922 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
923 |
924 | return ret
925 |
926 | def generalocr(self, image_path, data_type = 0, seq = ''):
927 |
928 | req_type='generalocr'
929 | headers = self.get_headers(req_type)
930 | url = self.generate_res_url(req_type, 2)
931 | data = {
932 | "app_id": self._appid,
933 | "session_id": seq,
934 | }
935 |
936 | if len(image_path) == 0:
937 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
938 |
939 | if data_type == 0:
940 | filepath = os.path.abspath(image_path)
941 | if not os.path.exists(filepath):
942 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
943 |
944 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
945 | else:
946 | data["url"] = image_path
947 |
948 | r = {}
949 | try:
950 | r = requests.post(url, headers=headers, data = json.dumps(data))
951 | if r.status_code != 200:
952 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
953 |
954 | ret = r.json()
955 | except Exception as e:
956 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
957 |
958 | return ret
959 |
960 | def creditcardocr(self, image_path, data_type = 0, seq = ''):
961 |
962 | req_type='creditcardocr'
963 | headers = self.get_headers(req_type)
964 | url = self.generate_res_url(req_type, 2)
965 | data = {
966 | "app_id": self._appid,
967 | "session_id": seq,
968 | }
969 |
970 | if len(image_path) == 0:
971 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
972 |
973 | if data_type == 0:
974 | filepath = os.path.abspath(image_path)
975 | if not os.path.exists(filepath):
976 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
977 |
978 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
979 | else:
980 | data["url"] = image_path
981 |
982 | r = {}
983 | try:
984 | r = requests.post(url, headers=headers, data = json.dumps(data))
985 | if r.status_code != 200:
986 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
987 |
988 | ret = r.json()
989 | except Exception as e:
990 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
991 |
992 | return ret
993 |
994 | def bizlicenseocr(self, image_path, data_type = 0, seq = ''):
995 |
996 | req_type='bizlicenseocr'
997 | headers = self.get_headers(req_type)
998 | url = self.generate_res_url(req_type, 2)
999 | data = {
1000 | "app_id": self._appid,
1001 | "session_id": seq,
1002 | }
1003 |
1004 | if len(image_path) == 0:
1005 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
1006 |
1007 | if data_type == 0:
1008 | filepath = os.path.abspath(image_path)
1009 | if not os.path.exists(filepath):
1010 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
1011 |
1012 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
1013 | else:
1014 | data["url"] = image_path
1015 |
1016 | r = {}
1017 | try:
1018 | r = requests.post(url, headers=headers, data = json.dumps(data))
1019 | if r.status_code != 200:
1020 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
1021 |
1022 | ret = r.json()
1023 | except Exception as e:
1024 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
1025 |
1026 | return ret
1027 |
1028 | def plateocr(self, image_path, data_type = 0, seq = ''):
1029 |
1030 | req_type='plateocr'
1031 | headers = self.get_headers(req_type)
1032 | url = self.generate_res_url(req_type, 2)
1033 | data = {
1034 | "app_id": self._appid,
1035 | "session_id": seq,
1036 | }
1037 |
1038 | if len(image_path) == 0:
1039 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY'}
1040 |
1041 | if data_type == 0:
1042 | filepath = os.path.abspath(image_path)
1043 | if not os.path.exists(filepath):
1044 | return {'httpcode':0, 'errorcode':self.IMAGE_FILE_NOT_EXISTS, 'errormsg':'IMAGE_FILE_NOT_EXISTS'}
1045 |
1046 | data["image"] = base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8')
1047 | else:
1048 | data["url"] = image_path
1049 |
1050 | r = {}
1051 | try:
1052 | r = requests.post(url, headers=headers, data = json.dumps(data))
1053 | if r.status_code != 200:
1054 | return {'httpcode':r.status_code, 'errorcode':'', 'errormsg':''}
1055 |
1056 | ret = r.json()
1057 | except Exception as e:
1058 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e)}
1059 |
1060 | return ret
1061 |
1062 | def livegetfour(self, seq = ''):
1063 |
1064 | req_type = 'livegetfour'
1065 | headers = self.get_headers(req_type)
1066 | url = self.generate_res_url(req_type, 3)
1067 |
1068 | data = {
1069 | 'app_id' : self._appid,
1070 | 'seq' : seq
1071 | }
1072 |
1073 | r = {}
1074 | try:
1075 | r = requests.post(url, headers = headers, data = json.dumps(data))
1076 | if r.status_code != 200:
1077 | return {'httpcode' : r.status_code, 'errorcode' : '', 'errormsg' : '', 'validate_data' : ''}
1078 | ret = r.json()
1079 | except Exception as e:
1080 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), 'validate_data' : ''}
1081 |
1082 | return ret
1083 |
1084 | def livedetectfour(self, validate_data, video_path, seq = '', card_path = '', compare_flag = False):
1085 |
1086 | req_type = 'livedetectfour'
1087 | headers = self.get_headers(req_type)
1088 | url = self.generate_res_url(req_type, 3)
1089 |
1090 | data = {
1091 | 'app_id' : self._appid,
1092 | 'seq' : seq
1093 | }
1094 |
1095 | if len(validate_data) == 0:
1096 | return {'httpcode' : 0, 'errorcode' : self.VALIDATE_DATA_EMPTY, 'errormsg' : 'VALIDATE_DATA_EMPTY', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'photo' : ''}
1097 |
1098 | if len(video_path) == 0:
1099 | return {'httpcode' : 0, 'errorcode' : self.VIDEO_PATH_EMPTY, 'errormsg' : 'VIDEO_PATH_EMPTY,', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'photo' : ''}
1100 |
1101 | if compare_flag == True and len(card_path) == 0:
1102 | return {'httpcode' : 0, 'errorcode' : self.CARD_PATH_EMPTY, 'errormsg' : 'CARD_PATH_EMPTY', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'photo' : ''}
1103 |
1104 | videofile = os.path.abspath(video_path)
1105 | if not os.path.exists(videofile):
1106 | return {'httpcode' : 0, 'errorcode' : self.VIDEO_FILE_NOT_EXISTS, 'errormsg' : 'VIDEO_FILE_NOT_EXISTS', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'photo' : ''}
1107 | else:
1108 | data["video"] = base64.b64encode(open(videofile, 'rb').read()).rstrip()
1109 |
1110 |
1111 | cardfile = os.path.abspath(card_path)
1112 | if compare_flag == True :
1113 | if not os.path.exists(cardfile):
1114 | return {'httpcode' : 0, 'errorcode' : self.CARD_FILE_NOT_EXISTS, 'errormsg' : 'CARD_FILE_NOT_EXISTS', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'photo' : ''}
1115 | else:
1116 | data["card"] = base64.b64encode(open(cardfile, 'rb').read()).rstrip()
1117 |
1118 | data['validate_data'] = validate_data
1119 | data['compare_flag'] = compare_flag
1120 |
1121 | r = {}
1122 | try:
1123 | r = requests.post(url, headers = headers, data = json.dumps(data))
1124 | if r.status_code != 200:
1125 | return {'httpcode' : r.status_code, 'errorcode' : '', 'errormsg' : '', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'photo' : ''}
1126 | ret = r.json()
1127 | except Exception as e:
1128 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'photo' : ''}
1129 |
1130 | return ret
1131 |
1132 | def idcardlivedetectfour(self, idcard_number, idcard_name, validate_data, video_path, seq = ''):
1133 |
1134 | req_type = 'idcardlivedetectfour'
1135 | headers = self.get_headers(req_type)
1136 | url = self.generate_res_url(req_type, 3)
1137 |
1138 | data = {
1139 | 'app_id' : self._appid,
1140 | 'seq' : seq
1141 | }
1142 |
1143 | if len(idcard_name) == 0 or len(idcard_number) == 0:
1144 | return {'httpcode' : 0, 'errorcode' : self.IDCARD_NAME_OR_ID_EMPTY , 'errormsg' : 'IDCARD_NAME_OR_ID_EMPTY ', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'video_photo' : ''}
1145 |
1146 | if len(validate_data) == 0:
1147 | return {'httpcode' : 0, 'errorcode' : self.VALIDATE_DATA_EMPTY, 'errormsg' : 'VALIDATE_DATA_EMPTY', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'video_photo' : ''}
1148 |
1149 | if len(video_path) == 0:
1150 | return {'httpcode' : 0, 'errorcode' : self.VIDEO_PATH_EMPTY, 'errormsg' : 'VIDEO_PATH_EMPTY', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'video_photo' : ''}
1151 |
1152 | videofile = os.path.abspath(video_path)
1153 | if not os.path.exists(videofile):
1154 | return {'httpcode' : 0, 'errorcode' : self.VIDEO_FILE_NOT_EXISTS, 'errormsg' : 'VIDEO_FILE_NOT_EXISTS', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'video_photo' : ''}
1155 | else:
1156 | data["video"] = base64.b64encode(open(videofile, 'rb').read()).rstrip()
1157 |
1158 | data['idcard_number'] = idcard_number
1159 | data['idcard_name'] = idcard_name
1160 | data['validate_data'] = validate_data
1161 |
1162 | r = {}
1163 | try:
1164 | r = requests.post(url, headers = headers, data = json.dumps(data))
1165 | if r.status_code != 200 :
1166 | return {'httpcode' : r.status_code, 'errorcode' : '', 'errormsg' : '', 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'video_photo' : ''}
1167 | ret = r.json()
1168 | except Exception as e:
1169 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), 'live_status' : '', 'live_msg' : '', 'compare_status' : '', 'compare_msg' : '', 'sim' : 0, 'video_photo' : ''}
1170 |
1171 | return ret
1172 |
1173 | def idcardfacecompare(self, idcard_number, idcard_name, image_path, data_type = 0 , session_id = ''):
1174 |
1175 | req_type = 'idcardfacecompare'
1176 | headers = self.get_headers(req_type)
1177 | url = self.generate_res_url(req_type, 3)
1178 |
1179 | data = {
1180 | 'app_id' : self._appid,
1181 | 'session_id' : session_id
1182 | }
1183 |
1184 | if len(idcard_name) == 0 or len(idcard_number) == 0 :
1185 | return {'httpcode' : 0, 'errorcode' : self.IDCARD_NAME_OR_ID_EMPTY , 'errormsg' : 'IDCARD_NAME_OR_ID_EMPTY ', 'similarity' : '', 'session_id' : session_id}
1186 |
1187 | if len(image_path) == 0 :
1188 | return {'httpcode':0, 'errorcode':self.IMAGE_PATH_EMPTY, 'errormsg':'IMAGE_PATH_EMPTY', 'similarity' : '', 'session_id' : session_id}
1189 |
1190 | if data_type == 0:
1191 | imagefile = os.path.abspath(image_path)
1192 | if not os.path.exists(imagefile):
1193 | return {'httpcode' : 0, 'errorcode' : self.IMAGE_FILE_NOT_EXISTS, 'errormsg' : 'IMAGE_FILE_NOT_EXISTS', 'similarity' : '', 'session_id' : session_id}
1194 | else:
1195 | data['image'] = base64.b64encode(open(imagefile, 'rb').read()).rstrip()
1196 | else:
1197 | data['url'] = image_path
1198 | data['idcard_number'] = idcard_number
1199 | data['idcard_name'] = idcard_name
1200 |
1201 | r = {}
1202 | try:
1203 | r = requests.post(url, headers = headers, data = json.dumps(data))
1204 | if r.status_code != 200:
1205 | return {'httpcode' : r.status_code, 'errorcode' : '', 'errormsg' : '', 'similarity' : '', 'session_id' : session_id}
1206 | ret = r.json()
1207 | except Exception as e:
1208 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), 'similarity' : '', 'session_id' : session_id}
1209 |
1210 | return ret
1211 |
1212 | def ValidateIdcard(self, idcard_number, idcard_name, seq = "default"):
1213 |
1214 | req_type = 'validateidcard'
1215 | headers = self.get_headers(req_type)
1216 | url = self.generate_res_url(req_type, 3)
1217 |
1218 | data = {
1219 | "app_id": self._appid,
1220 | "idcard_number": idcard_number,
1221 | "idcard_name": idcard_name,
1222 | "seq": seq
1223 | }
1224 |
1225 | r = {}
1226 | try:
1227 | r = requests.post(url, headers=headers, data = json.dumps(data))
1228 | if r.status_code != 200:
1229 | return {'httpcode':r.status_code, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':'', 'session_id':''}
1230 | ret = r.json()
1231 |
1232 | except Exception as e:
1233 | return {'httpcode':0, 'errorcode':self.IMAGE_NETWORK_ERROR, 'errormsg':str(e), 'session_id':''}
1234 |
1235 | return ret
1236 |
1237 |
1238 |
--------------------------------------------------------------------------------
/check_pic/check.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | #-*- coding: utf-8 -*-
3 | import sys,os
4 | import configparser
5 | import TencentYoutuyun
6 |
7 | if len(sys.argv) == 2 :
8 | print ("checking img...")
9 | img = sys.argv[1]
10 | if os.access(img, os.R_OK) == False:
11 | print ("指定的路径不存在")
12 | sys.exit()
13 | else:
14 | print ("请指定一张图片文件路径")
15 | sys.exit()
16 |
17 | def getConfig(section, key):
18 | config = configparser.ConfigParser()
19 | path = os.path.split(os.path.realpath(__file__))[0] + '/config'
20 | config.read(path)
21 | return config.get(section, key)
22 |
23 | appid = getConfig("appinfo","appid")
24 | secret_id = getConfig("appinfo","secret_id")
25 | secret_key = getConfig("appinfo","secret_key")
26 | userid = getConfig("appinfo","userid")
27 | end_point = TencentYoutuyun.conf.API_YOUTU_END_POINT
28 | youtu = TencentYoutuyun.YouTu(appid, secret_id, secret_key, userid, end_point)
29 |
30 | print("图像标签识别:")
31 | tag_list=youtu.imagetag(img)['tags']
32 | new_tag=[]
33 | for i in tag_list:
34 | new_tag.append("{}%:{}".format(i['tag_confidence'],i['tag_name'].encode('iso8859-1').decode('utf-8')))
35 |
36 | new_tag.sort(reverse=True)
37 | print(new_tag)
38 |
39 | print("人脸分析:")
40 | face=youtu.DetectFace(img)
41 | if len(face['face']) == 0:
42 | print("非人脸图片")
43 | else:
44 | # sex = {0:"女",100:"男"}
45 | glass = {0:"不戴眼镜",1:"戴眼镜",2:"戴墨镜"}
46 | face_dict=face['face'][0]
47 | if face_dict['gender'] <= 50:
48 | sex = "女"
49 | else:
50 | sex = "男"
51 | face_info = ("性别:{},年龄:{},魅力:{},笑容:{},{}".format \
52 | (sex,face_dict['age'],face_dict['beauty'],face_dict['expression'],glass[face_dict['glasses']])).split(",")
53 | print(face_info)
54 |
55 | print("性感检测:")
56 | hsex = {"normal":"正常","hot":"性感","porn":"色情图像","normal_level":"正常级别","breast":"胸","female-breast":"女性胸部","ass":"屁股","bare-body":"裸露身体","unreal-hot-people":"非真实的性感人物","porn-level":"色情级别","normal_hot_porn":"色情综合值"}
57 | sexp=youtu.imageporn(img)['tags']
58 | sex_info = ["{}%:{}".format(i['tag_confidence'],hsex[i['tag_name']]) for i in sexp if i['tag_confidence'] > 9]
59 | print(sex_info)
60 |
--------------------------------------------------------------------------------
/check_pic/requirements.txt:
--------------------------------------------------------------------------------
1 | requests==2.21.0
2 | configparser==3.5.0
3 |
--------------------------------------------------------------------------------
/etcd2consul/333.csv:
--------------------------------------------------------------------------------
1 | service,env,ip,domain,port,usr,passwd
2 | mysql,sit,192.168.200.227,mysql.sit.server,3306,wluser,dyei1@SW
3 | redis,sit,192.168.200.227,redis.sit.server,6379,,sje1gDK
4 | rabbitmq,sit,192.168.200.227,mq.sit.server,5672,cg,d9a1kqb
5 | riak-http,sit,192.168.200.227,riak-kv.sit.server,8098,,
6 | riak-tcp,sit,192.168.200.227,riak-kv.sit.server,8087,,
7 | mysql,uat,10.200.124.181,mysql.uat.server,3306,wluser,dhs611DE
8 | redis,uat,10.200.124.181,redis.uat.server,6379,,38shiav4
9 | rabbitmq,uat,10.200.124.181,mq.uat.server,5672,wl,sjh1y26d
10 | riak-http,uat,10.200.124.181,riak-kv.uat.server,8098,,
11 | riak-tcp,uat,10.200.124.181,riak-kv.uat.server,8087,,
12 | api,pro,10.200.78.34,api.cg.server,9090,,
13 | mysql-m,pro,10.200.78.100,mysql-m.cg.server,3306,usr_wladmin,ios0DaC1f9yj5
14 | mysql-s,pro,10.200.78.101,mysql-s.cg.server,3306,usr_wladmin,ios0DaC1f9yj5
15 | rabbitmq,pro,10.200.78.90,mq.cg.server,5672,cg,s7ay147qo
16 | redis,pro,10.200.78.40,redis.cg.server,6379,,ye2i1ab0f
17 | riak-http,pro,10.200.78.50,riak-kv.cg.server,8098,,
18 | riak-tcp,pro,10.200.78.50,riak-kv.cg.server,8087,,
19 |
--------------------------------------------------------------------------------
/etcd2consul/README.md:
--------------------------------------------------------------------------------
1 | #### 项目中使用的把etcd数据导入到consul的KV和SERVICE,仅供参考。
2 | ```
3 | #add
4 | svc导入consul service
5 | salt导入consul service
6 | consul kv导入consul service
7 | ```
8 |
--------------------------------------------------------------------------------
/etcd2consul/consulkv2service.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3.6
2 | # -*- coding:utf-8 -*-
3 | import requests,json,base64
4 | service_list = []
5 | headers = {"X-Consul-Token": "xxxxxxxx"}
6 | req = requests.get("http://192.168.200.60:8500/v1/kv/nginx?recurse=ture", headers=headers).json()
7 | for i in req:
8 | k=i['Key']
9 | name = f"SV_{k.split('/')[2]}"
10 | if name not in ['SV_fg_dev','SV_fg_pdev','SV_fg_sit','SV_wl_sit']:
11 | continue
12 | v=json.loads(base64.b64decode(i['Value']))
13 | id = k.split('/')[4]
14 | tags = [k.split('/')[3], f'{v["ndomain"]}:{v["nport"]}']
15 | address = v['sip']
16 | port = int(v['sport'])
17 | data = {
18 | "id": id,
19 | "name": name,
20 | "tags": tags,
21 | "address": address,
22 | "port": port,
23 | "check": {
24 | "name": id,
25 | "tcp": f"{address}:{port}",
26 | "interval": "10s"
27 | }
28 | }
29 | reg = requests.put("http://192.168.200.60:8500/v1/agent/service/register", headers=headers, data=json.dumps(data))
30 | print(name,reg.status_code,reg.text)
31 |
--------------------------------------------------------------------------------
/etcd2consul/csv_base_service2consul_service.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3.6
2 | # -*- coding:utf-8 -*-
3 | import requests,json,csv
4 | csvFile = open("333.csv", "r")
5 | dict_reader = csv.DictReader(csvFile)
6 | service_list = []
7 | headers = {"X-Consul-Token": "xxxxxxxx"}
8 | for i in dict_reader:
9 | service_list.append(i)
10 | for i in service_list:
11 | meta_dict = {}
12 | for k,v in i.items():
13 | meta_dict[k] = v
14 |
15 | data = {
16 | "id": f"{i['env']}/{i['service']}",
17 | "name": i['env'],
18 | "tags": [i['service']],
19 | "address": i['ip'],
20 | "port": int(i['port']),
21 | "Meta": meta_dict,
22 | "check": {
23 | "name": f"{i['env']} {i['service']}",
24 | "tcp": f"{i['ip']}:{i['port']}",
25 | "interval": "10s"
26 | }
27 | }
28 | reg = requests.put("http://192.168.200.60:8500/v1/agent/service/register", headers=headers, data=json.dumps(data))
29 | print(f"{i['env']}/{i['service']}",reg.status_code,reg.text)
30 | reg = requests.put(f"http://192.168.200.60:8500/v1/kv/hosts/{i['env']}/{i['domain']}", headers=headers,data=i['ip'])
31 | print(f"{i['domain']}={i['ip']}",reg.status_code,reg.text)
32 |
33 | """
34 | 注册
35 | curl --request PUT --data @playload.json http://192.168.200.60:8500/v1/agent/service/register
36 |
37 | 删除
38 | curl --request PUT http://192.168.200.60:8500/v1/agent/service/deregister/DEVtest
39 |
40 | 查询所有服务详情
41 | curl http://192.168.200.60:8500/v1/agent/services|python -m json.tool
42 |
43 | 查询单个服务(精简)
44 | curl http://192.168.200.60:8500/v1/agent/service/dev/redis|python -m json.tool
45 | ------
46 | 查询所有服务列表(精简)
47 | curl http://192.168.200.60:8500/v1/catalog/services|python -m json.tool
48 |
49 | 查询指定环境的所有服务(详细)
50 | curl http://192.168.200.60:8500/v1/catalog/service/dev|python -m json.tool
51 |
52 | 查询指定环境的单个服务(详细)
53 | curl http://192.168.200.60:8500/v1/catalog/service/dev?tag=redis|python -m json.tool
54 |
55 | K/V
56 | curl -H "X-Consul-Token: xxxxxxxxxxxxx" -X PUT -d 'test' http://192.168.200.60:8500/v1/kv/web/key1
57 | curl -H "X-Consul-Token: xxxxxxxxxxxxx" --request DELETE http://192.168.200.60:8500/v1/kv/web/?recurse=ture
58 | """
59 |
--------------------------------------------------------------------------------
/etcd2consul/etcd2consul_kv.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import os,linecache
3 | import requests,json,csv
4 | conf = os.system("etcdctl get --prefix /nginx/>/tmp/php.etcd")
5 | count = len(open('/tmp/php.etcd').readlines())
6 | php = {}
7 | for i in range(1,count+1,2):
8 | fst_line=linecache.getline('/tmp/php.etcd',i).strip('\n')
9 | sec_line=linecache.getline('/tmp/php.etcd',i+1).strip('\n')
10 | php[fst_line] = sec_line
11 |
12 | headers = {"X-Consul-Token": "xxxxxxxx"}
13 | for k,v in php.items():
14 | reg = requests.put(f"http://192.168.200.60:8500/v1/kv{k}", headers=headers,data=v)
15 | print(k,v,reg.status_code,reg.text)
16 |
--------------------------------------------------------------------------------
/etcd2consul/etcd2consul_service.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import os,linecache
3 | import requests,json,csv
4 | conf = os.system("etcdctl get --prefix /nginx/|grep -A1 -E 'fg_sit|fg_dev|fg_pdev|wl_sit'|grep -v '\-\-' >/tmp/sgame")
5 | count = len(open('/tmp/sgame').readlines())
6 | game = {}
7 | for i in range(1,count+1,2):
8 | fst_line=linecache.getline('/tmp/sgame',i).strip('\n')
9 | sec_line=linecache.getline('/tmp/sgame',i+1).strip('\n')
10 | game[fst_line] = sec_line
11 |
12 | headers = {"X-Consul-Token": "xxxxxxxx"}
13 | for k,v in game.items():
14 | gameinfo = json.loads(v)
15 | name = f"game_{k.split('/')[3]}"
16 | id = k.split('/')[5]
17 | tags = [k.split('/')[4], f'{gameinfo["ndomain"]}:{gameinfo["nport"]}']
18 | address = gameinfo['sip']
19 | port = int(gameinfo['sport'])
20 |
21 | data = {
22 | "id": id,
23 | "name": name,
24 | "tags": tags,
25 | "address": address,
26 | "port": port,
27 | "check": {
28 | "name": name,
29 | "tcp": f"{address}:{port}",
30 | "interval": "10s"
31 | }
32 | }
33 | reg = requests.put("http://192.168.200.60:8500/v1/agent/service/register", headers=headers, data=json.dumps(data))
34 | print(name,reg.status_code,reg.text)
35 |
--------------------------------------------------------------------------------
/etcd2consul/salt2consul_service.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3.6
2 | # -*- coding:utf-8 -*-
3 | import os,re,requests,json
4 | headers = {"X-Consul-Token": "xxxxxxxx"}
5 | iplist=os.popen('salt \* grains.item ipv4 --out=txt').readlines()
6 | host_dict = {}
7 | for i in iplist:
8 | hostname = i.split(':')[0]
9 | ips = re.sub('[u\'\ ]','',re.split('.*\[(.*)\].*',i)[1]).split(",")
10 | ip = [j for j in ips if j.startswith('192.168.2') or j.startswith('192.168.10.')][0]
11 | host_dict[hostname] = ip
12 | print(host_dict)
13 | del host_dict['openshift.201-all01']
14 | del host_dict['openshift.203-all02']
15 | del host_dict['openshift.202-all03']
16 | #host_dict = {}
17 | #host_dict = {'openshift.201-all01':'192.168.200.201','openshift.203-all02':'192.168.200.203','openshift.202-all03':'192.168.200.202'}
18 | for k,v in host_dict.items():
19 | if '-test-' in k:
20 | env = 'HW-SIT'
21 | elif '-dev-' in k:
22 | env = 'HW-DEV'
23 | elif '-pdev-' in k:
24 | env = 'HW-FGPDEV'
25 | elif '-wlsit-' in k:
26 | env = 'HW-WLSIT'
27 | else:
28 | env = 'HW-BASE'
29 |
30 | data = {
31 | "id": k,
32 | "name": env,
33 | "tags": ["node_exporter",env,k,v],
34 | "address": v,
35 | "port": 9100,
36 | "check": {
37 | "tcp": f"{v}:9100",
38 | "interval": "10s"
39 | }
40 | }
41 | reg = requests.put("http://192.168.200.60:8500/v1/agent/service/register", headers=headers, data=json.dumps(data))
42 | print(env,k,v,reg.status_code)
43 |
--------------------------------------------------------------------------------
/google-authenticator/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 StarsL.cn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/google-authenticator/README.md:
--------------------------------------------------------------------------------
1 | # google-authenticator
2 | 谷歌验证器的python3实现,根据明文字符串即可生成二维码、秘钥串、验证码
3 |
--------------------------------------------------------------------------------
/google-authenticator/google-authenticator.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding:utf-8 -*-
3 | import hmac, base64, struct, hashlib, time
4 | import sys
5 | import qrcode,qrcode_terminal
6 | class google(object):
7 | def SecretKey(self, pubKey):
8 | return base64.b32encode(pubKey.encode('utf-8')).decode('utf-8')
9 |
10 | def QR(self, name, secretKey):
11 | qr = qrcode.QRCode(
12 | version=1,
13 | error_correction=qrcode.constants.ERROR_CORRECT_H,
14 | box_size=7,
15 | border=4
16 | )
17 | qrdata = f'otpauth://totp/{name}?secret={secretKey}'
18 | qr.add_data(qrdata)
19 | qr.make(fit=True)
20 | img = qr.make_image()
21 | img.save("/tmp/test.png")
22 | return qrcode_terminal.draw(qrdata)
23 |
24 | def GoogleCode(self, secretKey):
25 | input = int(time.time()) // 30
26 | key = base64.b32decode(secretKey)
27 | msg = struct.pack(">Q", input)
28 | googleCode = hmac.new(key, msg, hashlib.sha1).digest()
29 | if (sys.version_info> (2, 7)):
30 | o = googleCode[19] & 15
31 | else:
32 | o = ord(googleCode[19]) & 15
33 | googleCode = str((struct.unpack(">I", googleCode[o:o + 4])[0] & 0x7fffffff) % 1000000)
34 | if len(googleCode) == 5:
35 | googleCode = '0' + googleCode
36 | return googleCode
37 |
38 | if __name__ == "__main__":
39 | new = google()
40 | key = new.SecretKey('starsliao')
41 | print ('\n谷歌验证器导入二维码:\n')
42 | qr = new.QR('StarsL.cn',key)
43 | gc = new.GoogleCode(key)
44 | print (f'\n秘钥串:{key}\n验证码:{gc}')
45 |
--------------------------------------------------------------------------------
/how-to-look-the-plate/README.md:
--------------------------------------------------------------------------------
1 |
2 | # 如何使用钉钉优雅的看盘
3 | ### 实现功能
4 | - 基于python3 + DingtalkChatbot 实现消息推送。
5 |
6 | - 交易期间,每10分钟推送一次关注的股票涨幅与价格。(红涨绿跌)
7 |
8 | - 当关注股票涨跌幅达到每个百分点,会实时推送消息和分时图。
9 |
10 | - 点击任意股票右侧的【分时】,即可在钉钉侧边栏展示当前股票的分时图。
11 |
12 | - 无后台服务,通过系统定时任务运行。
13 |
14 | ### 如何使用
15 |
16 | 安装依赖:
17 | ```
18 | pip3 install requests DingtalkChatbot==1.5.1
19 | ```
20 |
21 | 编辑脚本加入股票,钉钉@手机号,钉钉自定义机器人Token
22 | ```
23 | # 增加需要展示的股票代码
24 | stock_list = ['600869','601118','600682','600546','002223']
25 | # @到钉钉手机号
26 | at = '170xxx'
27 | # 钉钉群自定义webhook机器人地址,自定义关键字:股票
28 | webhook = 'https://oapi.dingtalk.com/robot/send?access_token=xxx'
29 | ```
30 | 增加crontab:
31 | ```
32 | * 9-15 * * 1-5 /opt/rise.py
33 | 0 8 * * 1-5 rm -rvf /tmp/.rise.json
34 | ```
35 | ### 关注公众号【**全栈运维开发**】加入运维群交流,获取更多...
36 | 
37 |
38 |
39 | ### 截图
40 | 
41 |
--------------------------------------------------------------------------------
/how-to-look-the-plate/capture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/starsliao/PythonTools/3bdd7fc988529ea75e927f4a3f1ed9b10424eaba/how-to-look-the-plate/capture.jpg
--------------------------------------------------------------------------------
/how-to-look-the-plate/rise.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | # -*- coding: utf-8 -*-
3 | # @Author : StarsL.cn
4 | # @Email : starsliao@163.com
5 | # @describe: 如何使用钉钉优雅的看盘
6 |
7 | '''
8 | 安装依赖:
9 | pip install DingtalkChatbot==1.5.1
10 |
11 | 增加crontab:
12 | * 9-15 * * 1-5 /opt/rise.py
13 | 0 8 * * 1-5 rm -rvf /tmp/.rise.json
14 |
15 | 参考接口:
16 | http://api.money.163.com/data/feed/0000001,0601998,0600734,0600006,money.api
17 | http://hq.sinajs.cn/list=sh000001,sh601998,sh600734,sh600006
18 | http://hq.sinajs.cn/list=s_sh000001,s_sh601998,s_sh600734,s_sh600006,s_sz002505
19 | http://image.sinajs.cn/newchart/min/n/sh600006.gif
20 | '''
21 |
22 | import requests,datetime,os,json
23 | from dingtalkchatbot.chatbot import DingtalkChatbot
24 | now = datetime.datetime.now()
25 | time930 = datetime.datetime.strptime(str(now.date())+'09:30', '%Y-%m-%d%H:%M')
26 | time1132 = datetime.datetime.strptime(str(now.date())+'11:32', '%Y-%m-%d%H:%M')
27 | time1300 = datetime.datetime.strptime(str(now.date())+'13:00', '%Y-%m-%d%H:%M')
28 | time1502 = datetime.datetime.strptime(str(now.date())+'15:02', '%Y-%m-%d%H:%M')
29 | stock = ''
30 |
31 | # 增加需要展示的股票代码
32 | stock_list = ['600869','601118','600682','600546','002223']
33 | # @到钉钉手机号
34 | at = '170xxx'
35 | # 钉钉群自定义webhook机器人地址,自定义关键字:股票
36 | webhook = 'https://oapi.dingtalk.com/robot/send?access_token=xxx'
37 |
38 | for i in stock_list:
39 | i = 's_sh' + i if int(i) >= 600000 else 's_sz' + i
40 | stock = stock + i + ','
41 | if (now > time930 and now < time1132) or (now > time1300 and now < time1502):
42 | response = requests.get(f'http://hq.sinajs.cn/list=s_sh000001,{stock}',stream=True)
43 | md=''
44 | if os.path.exists('/tmp/.rise.json'):
45 | with open('/tmp/.rise.json', 'r') as fr:
46 | info_dict = json.load(fr)
47 | else:
48 | info_dict = {}
49 | for j in [(i.split('"')[1] + ',' + i.split('=')[0].split('_')[-1]).split(',') for i in response.iter_lines(decode_unicode=True)]:
50 | info = f'{j[0]}:{j[3]}%,{round(float(j[1]),2)}'
51 | imgurl = f'http://image.sinajs.cn/newchart/min/n/{j[-1]}.gif?{now.timestamp()}'
52 | if j[-1] not in info_dict:
53 | info_dict[j[-1]] = []
54 | if '-' in info:
55 | info = f'{info}[【分时】](dingtalk://dingtalkclient/page/link?url={imgurl}&pc_slide=true)'
56 | else:
57 | info = f'{info}[【分时】](dingtalk://dingtalkclient/page/link?url={imgurl}&pc_slide=true)'
58 | if abs(float(j[3])) >= 1 and int(float(j[3])) not in info_dict[j[-1]]:
59 | info = info + '\n' + f'![{j[3]}分时图]({imgurl})\n\n'
60 | info_dict[j[-1]].append(int(float(j[3])))
61 | md = md + f'- {info}\n'
62 | with open(f'/tmp/.rise.json', 'w') as f:
63 | json.dump(info_dict,f)
64 |
65 | if "分时图" in md:
66 | msg = DingtalkChatbot(webhook)
67 | send = msg.send_markdown(title='股票波动推图',text=f'{md}\n',at_mobiles=[at])
68 |
69 | elif now.minute in [1,11,21,31,41,51]:
70 | msg = DingtalkChatbot(webhook)
71 | send = msg.send_markdown(title='股票定时推送',text=f'{md}\n',at_mobiles=[at])
72 | else:
73 | print('time not match')
74 |
--------------------------------------------------------------------------------
/hwpy/3rd/SSU.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/starsliao/PythonTools/3bdd7fc988529ea75e927f4a3f1ed9b10424eaba/hwpy/3rd/SSU.exe
--------------------------------------------------------------------------------
/hwpy/3rd/disk.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | for i in $(lsblk -s | grep disk | awk '{print $1}' | sed "s#└─##");do
3 | hdinfo=`sudo -S smartctl -a /dev/$i | grep -E "Device Model|Serial Number|test result|Power_On_Hours|SATA Version"`
4 | dm=`echo "$hdinfo"|grep "Device Model"|awk '{print $NF}'`
5 | sn=`echo "$hdinfo"|grep "Serial Number"|awk '{print $NF}'`
6 | tr=`echo "$hdinfo"|grep "test result"|awk '{print $NF}'`
7 | ph=`echo "$hdinfo"|grep "Power_On_Hours"|awk '{print $NF}'`
8 | ph=`echo "$hdinfo"|grep "SATA Version"|awk -F 'SATA Version is:' '{print $NF}'|xargs`
9 | echo "$i 型号:$dm 序列号:$sn 状态:$tr 通电(时):$ph 速度:$sv"
10 | done
11 |
--------------------------------------------------------------------------------
/hwpy/3rd/hwinfo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo -e '\e[31;1m#############\e[0m'
3 | echo -e '\e[31;1m#\e[0m服务器信息:\e[31;1m#\e[0m'
4 | echo -e '\e[31;1m#############\e[0m'
5 | echo "服务器型号:`dmidecode -t system|grep -A1 Manufacturer|awk -F: '{print $2}'|xargs`,服务器类型/高度:`dmidecode -t chassis|grep -E 'Type|Height'|awk -F:\ '{print $2}'|xargs -i printf {}.`"
6 | echo -e '\n'
7 | echo -e '\e[31;1m##########\e[0m'
8 | echo -e '\e[31;1m#\e[0mCPU信息:\e[31;1m#\e[0m'
9 | echo -e '\e[31;1m##########\e[0m'
10 | x=`dmidecode -t processor|grep 'Status: Populated'|wc -l`
11 | y=1
12 | if [ `grep 'model name' /proc/cpuinfo|sort|uniq|wc -l` == 1 ];
13 | then
14 | cpu=`grep 'model name' /proc/cpuinfo|awk -F:\ '{print $2}'|sed 's/[[:space:]][[:space:]]*/ /g'|sed -n 1p`
15 | while [ $y -le $x ]; do
16 | echo "物理CPU:`dmidecode -t processor|grep 'Socket Designation'|awk -F:\ '{print $2}'|sed -n $y\p`:型号:$cpu,核心数:`dmidecode -t processor|grep 'Core Count'|awk -F:\ '{print $2}'|sed -n $y\p`,共`dmidecode -t processor|grep 'Thread Count'|awk -F:\ '{print $2}'|sed -n $y\p`个线程,当前频率:`dmidecode -t processor|grep 'Current Speed'|awk -F:\ '{print $2}'|sed -n $y\p`."
17 | y=`expr $y + 1`
18 | done
19 | else
20 | while [ $y -le $x ]; do
21 | cpu=`grep 'model name' /proc/cpuinfo|sort|uniq|awk -F:\ '{print $2}'|sed 's/[[:space:]][[:space:]]*/ /g'|sed -n $y\p`
22 | echo "物理CPU:`dmidecode -t processor|grep 'Socket Designation'|awk -F:\ '{print $2}'|sed -n $y\p`:型号:$cpu,核心数:`dmidecode -t processor|grep 'Core Count'|awk -F:\ '{print $2}'|sed -n $y\p`,共`dmidecode -t processor|grep 'Thread Count'|awk -F:\ '{print $2}'|sed -n $y\p`个线程,当前频率:`dmidecode -t processor|grep 'Current Speed'|awk -F:\ '{print $2}'|sed -n $y\p`."
23 | y=`expr $y + 1`
24 | done
25 | fi
26 | echo "支持的物理CPU数:`dmidecode -t processor|grep Version|wc -l`个,已安装的CPU数:$x个,支持的CPU插槽接口:`dmidecode -t processor|grep 'Upgrade'|awk -F:\ '{print $2}'|sed -n 1p`,所支持的最大CPU频率:`dmidecode -t processor|grep 'Max Speed'|awk -F:\ '{print $2}'|sed -n 1p`."
27 | echo -e '\n'
28 | echo -e '\e[31;1m###########\e[0m'
29 | echo -e '\e[31;1m#\e[0m内存信息:\e[31;1m#\e[0m'
30 | echo -e '\e[31;1m###########\e[0m'
31 | x=`dmidecode -t memory|grep 'Size'|wc -l`
32 | y=1
33 | s=`echo -e '\e[31;1m该插槽未安装内存\e[0m'`
34 | while [ $y -le $x ]; do
35 | echo "内存`dmidecode -t memory|grep 'Locator:'|grep -v 'Bank'|awk -F:\ '{print $2}'|sed 's/ *$//g'|sed -n $y\p`:容量为:`dmidecode -t memory|grep 'Size:'|awk -F:\ '{print $2}'|sed -n $y\p`,类型为:`dmidecode -t memory|grep 'Type:'|grep -v 'Error Correction Type'|awk -F:\ '{print $2}'|sed -n $y\p`,频率为:`dmidecode -t memory|grep 'Speed:'|awk -F:\ '{print $2}'|sed -n $y\p`,生产厂商为:`dmidecode -t memory|grep 'Manufacturer:'|awk -F:\ '{print $2}'|sed 's/ *$//g'|sed -n $y\p`."|sed "s/No\ Module\ Installed.*/$s/g"
36 | y=`expr $y + 1`
37 | done
38 | echo "支持的最大总内存容量:`dmidecode -t memory|grep 'Maximum Capacity'|awk -F:\ '{print $2}'`,支持的总内存数量:`dmidecode -t memory|grep 'Number Of Devices'|awk -F:\ '{print $2}'`根,支持的纠错类型:`dmidecode -t memory|grep 'Error Correction Type'|awk -F:\ '{print $2}'`."
39 | echo -e '\n'
40 | echo -e '\e[31;1m###########\e[0m'
41 | echo -e '\e[31;1m#\e[0m硬盘信息:\e[31;1m#\e[0m'
42 | echo -e '\e[31;1m###########\e[0m'
43 | fdisk -l &>/tmp/tmp.disk && grep -E 'Disk /dev/sd|Disk /dev/hd|Disk /dev/cciss' /tmp/tmp.disk|awk -F, '{print $1}' && rm -rf /tmp/tmp.disk
44 | if [ -f /usr/sbin/smartctl ];
45 | then
46 | if [ -b /dev/sda ] || [ -b /dev/hda ];
47 | then
48 | ls -1 /dev/?d[a-z]|while read line ;
49 | do
50 | smartctl -i $line>/tmp/disk.1
51 | if [ "`grep 'SMART support is: Enabled' /tmp/disk.1`" = "SMART support is: Enabled" ] ;
52 | then
53 | smartctl -A $line>/tmp/disk.2
54 | echo "硬盘$line:型号:`grep 'Device Model' /tmp/disk.1|awk -F: '{print $2}'|xargs`,ATA标准:`grep 'ATA Standard is' /tmp/disk.1|awk -F: '{print $2}'|xargs`, SMART模式:已开启,使用时间:`grep -E 'Power_On_Hours' /tmp/disk.2|awk -F\ '{print $10}'`小时,当前硬盘温度:`grep -E 'Temperature_Celsius' /tmp/disk.2|awk -F\ '{print $10}'`度."
55 | # elif [ "`grep 'Device does not support SMART' /tmp/disk.1`" = "Device does not support SMART" ];
56 | # then
57 | # echo "硬盘$line:型号:`grep -E 'Vendor|Product' /tmp/disk.1|awk -F: '{print $2}'|xargs`,传输协议:`grep 'Transport protocol' /tmp/disk.1|awk -F: '{print $2}'|xargs`, SMART模式:不支持."
58 | # else
59 | # echo "硬盘$line:型号:`grep -E 'Vendor|Product' /tmp/disk.1|awk -F: '{print $2}'|xargs`,传输协议:`grep 'Transport protocol' /tmp/disk.1|awk -F: '{print $2}'|xargs`, SMART模式:支持,未开启."
60 | else
61 | echo "硬盘$line:型号:`grep -E 'Vendor|Product' /tmp/disk.1|awk -F: '{print $2}'|xargs`,传输协议:`grep 'Transport protocol' /tmp/disk.1|awk -F: '{print $2}'|xargs`, SMART模式:`tail -1 /tmp/disk.1`."
62 | fi;
63 | done
64 | fi
65 | if [ -d /dev/cciss ];
66 | then
67 | ls -1 /dev/cciss/????|while read line ;
68 | do
69 | smartctl -i -d cciss,0 $line>/tmp/disk.1
70 | if [ "`grep 'Device supports SMART and is Enabled' /tmp/disk.1`" = "Device supports SMART and is Enabled" ];
71 | then
72 | smartctl -A -d cciss,0 $line>/tmp/disk.2
73 | echo "硬盘$line:型号:`grep -E 'Vendor|Product' /tmp/disk.1|awk -F: '{print $2}'|xargs`,传输协议:`grep 'Transport protocol' /tmp/disk.1|awk -F: '{print $2}'|xargs`, SMART模式:已开启,使用时间:`grep 'number of hours powered up' /tmp/disk.2|awk -F= '{print $2}'|xargs`小时,当前硬盘温度:`grep 'Current Drive Temperature' /tmp/disk.2|awk -F\ '{print $4}'|xargs`度,极限温度:`grep 'Drive Trip Temperature' /tmp/disk.2|awk -F\ '{print $4}'|xargs`度."
74 | else
75 | echo "硬盘$line:型号:`grep -E 'Vendor|Product' /tmp/disk.1|awk -F: '{print $2}'|xargs`,传输协议:`grep 'Transport protocol' /tmp/disk.1|awk -F: '{print $2}'|xargs`, SMART模式:`tail -1 /tmp/disk.1`."
76 | fi;
77 | done
78 | fi
79 | rm -rf /tmp/disk.1 /tmp/disk.2
80 | else
81 | echo "smartmontools未安装,硬盘部分信息无法检测,请根据系统使用yum或者apt-get等来进行安装."
82 | fi
83 | echo -e '\n'
84 | echo -e '\e[31;1m###########\e[0m'
85 | echo -e '\e[31;1m#\e[0m网卡信息:\e[31;1m#\e[0m'
86 | echo -e '\e[31;1m###########\e[0m'
87 | echo "共检测到`lspci|grep 'Ethernet controller'|wc -l`块网卡,型号如下:"
88 | echo "`lspci|grep 'Ethernet controller'|awk -F:\ '{print $2}'|awk -F\( '{print $1}'|awk '{print NR,$0}'`"
89 | if [ -f /sbin/ethtool ] || [ -f /usr/sbin/ethtool ];
90 | then
91 | x=`lspci|grep 'Ethernet controller'|wc -l`
92 | y=0
93 | while [ $y -lt $x ];
94 | do
95 | echo "网卡eth$y:支持最大速度:`ethtool eth$y|grep -B1 'Supports auto-negotiation'|sed -n 1p|xargs`,当前连接速度:`ethtool eth$y|grep -E 'Speed|Duplex'|awk -F:\ '{print $2}'|xargs`,当前链路状态:`ethtool eth$y|grep -E 'Link detected'|awk -F:\ '{print $2}'`."
96 | y=`expr $y + 1`
97 | done
98 | else
99 | echo "ethtool未安装,网卡部分信息无法检测,请根据系统使用yum或者apt-get等来进行安装."
100 | fi
101 | echo -e '\n'
102 | echo -e '\e[31;1m###########\e[0m'
103 | echo -e '\e[31;1m#\e[0m系统版本:\e[31;1m#\e[0m'
104 | echo -e '\e[31;1m###########\e[0m'
105 | if [ -f /usr/bin/lsb_release ];
106 | then
107 | lsb=`lsb_release -d|awk -F: '{ print $2 }'|xargs`
108 | else
109 | lsb=`sed -n 1p /etc/issue`
110 | fi
111 | echo "发行版本:$lsb `getconf LONG_BIT`位,内核版本:`uname -r`"
112 | echo -e '\n'
113 | echo -e '\e[31;1m###########\e[0m'
114 | echo -e '\e[31;1m#\e[0m网络信息:\e[31;1m#\e[0m'
115 | echo -e '\e[31;1m###########\e[0m'
116 | /sbin/ifconfig|grep -B1 "inet addr"|xargs|sed s/\ --\ /\\n/g|grep -v 'lo'|awk -F\ '{print "网卡""\033[31;1m"$1"\033[0m"":IP地址:"$7",MAC地址:"$5}'|sed s/addr://g
117 | echo "默认网关:`route -n|awk '{if($1=="0.0.0.0")print $2 }'`,DNS:`grep 'nameserver' /etc/resolv.conf|awk -F\ '{print $2}'|sed ':a;N;s/\n/,/;ta'`"
118 | echo -e '\n'
119 | echo -e '\e[31;1m###########\e[0m'
120 | echo -e '\e[31;1m#\e[0m已开端口:\e[31;1m#\e[0m'
121 | echo -e '\e[31;1m###########\e[0m'
122 | netstat -nlptu|sed -n '3,$p'>/tmp/net.1
123 | grep tcp /tmp/net.1|awk -F\ '{print $4"\t"$7}'|sed s/:::/0.0.0.0:/g|sed s/::ffff://g|awk -F: '{print $2}'|sed '/^$/d'|sed 's/^/TCP\t/'>/tmp/net.2
124 | udp=`echo -e '\e[31;1mUDP\e[0m'`
125 | grep udp /tmp/net.1|awk -F\ '{print $4"\t"$6}'|sed s/:::/0.0.0.0:/g|sed s/::ffff://g|awk -F: '{print $2}'|sed '/^$/d'|sed "s/^/$udp\t/">>/tmp/net.2
126 | echo -e "协议\t端口\t进程号/进程名"
127 | sort -k2n /tmp/net.2|uniq
128 | rm -rf /tmp/net.1 /tmp/net.2
129 | echo -e '\n'
130 | echo -e '\e[31;1m#############检测完成#############\e[0m'
131 | echo -e '\n'
--------------------------------------------------------------------------------
/hwpy/3rd/ssu.sh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/starsliao/PythonTools/3bdd7fc988529ea75e927f4a3f1ed9b10424eaba/hwpy/3rd/ssu.sh
--------------------------------------------------------------------------------
/hwpy/README.md:
--------------------------------------------------------------------------------
1 | # 获取Linux服务器硬件明细。Get linux server hardware information.
2 |
3 | # install(python2.7 and python3.6)
4 |
5 | #### lastest psutil maybe required
6 | ```
7 | # yum install -y gcc python-devel dmidecode pciutils
8 | # pip install -U setuptools
9 | # pip install -U psutil
10 | ```
11 |
12 | ```
13 | # pip install hwpy
14 | ```
15 |
16 | # usage
17 | ```
18 | # python -m hwpy
19 | ```
20 | ```
21 | from hwpy import info
22 | info.main()
23 | info.hwlist
24 | ```
25 | ```
26 | info.cpu
27 | info.net
28 | info.disk
29 | info.part
30 | info.host
31 | info.mem
32 | ```
33 |
--------------------------------------------------------------------------------
/hwpy/deploy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | if [ "$1" ]
3 | then
4 | msg=$1
5 | else
6 | msg="update"
7 | fi
8 | rm -rvf hwpy.egg-info dist hwpy/*.pyc
9 | python setup.py sdist
10 | twine upload dist/hwpy*.tar.gz && \
11 | rm -rvf hwpy.egg-info dist && \
12 | git add --all && \
13 | git commit -m "$msg" && \
14 | git push
15 |
--------------------------------------------------------------------------------
/hwpy/hwpy/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/starsliao/PythonTools/3bdd7fc988529ea75e927f4a3f1ed9b10424eaba/hwpy/hwpy/__init__.py
--------------------------------------------------------------------------------
/hwpy/hwpy/__main__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | from . import info as _info
3 | if __name__ == '__main__':
4 | _info.main()
5 |
--------------------------------------------------------------------------------
/hwpy/hwpy/_dmide.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | import subprocess,sys
3 |
4 | def parse_dmi(content,hwtype):
5 | info = []
6 | lines = iter(content)
7 | # lines = iter(content.strip().splitlines())
8 | while True:
9 | try:
10 | line = next(lines)
11 | except StopIteration:
12 | break
13 | if line.startswith('Handle 0x'):
14 | info.append((hwtype, _parse_handle_section(lines)))
15 | return info
16 |
17 | def _parse_handle_section(lines):
18 | data = {
19 | '_title': next(lines).rstrip(),
20 | }
21 |
22 | for line in lines:
23 | line = line.rstrip()
24 | if line.startswith('\t\t'):
25 | if isinstance(data[k], list):
26 | data[k].append(line.lstrip())
27 | elif line.startswith('\t'):
28 | k, v = [i.strip() for i in line.lstrip().split(':', 1)]
29 | if v:
30 | data[k] = v
31 | else:
32 | data[k] = []
33 | else:
34 | break
35 | return data
36 |
37 | def info(shell):
38 | try:
39 | output = subprocess.check_output(
40 | 'PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin '
41 | 'sudo ' + shell, shell=True)
42 | except Exception as e:
43 | print(e)
44 | if str(e).find("command not found") == -1:
45 | print("please install dmidecode")
46 | print("e.g. sudo yum install dmidecode")
47 |
48 | sys.exit(1)
49 | return output.decode('utf-8').strip().splitlines()
50 | # return output.decode('utf-8').strip().split('\n')
51 |
52 |
53 | def getserver():
54 | hwvendor = info("dmidecode -t system|grep -C2 Version|awk -F:\ '{print $2}'")
55 | hwclass = info("dmidecode -t chassis|grep -E 'Type|Height'|awk -F:\ '{print $2}'")
56 | serverdict = {'Server':{'Vendor':hwvendor[0],'Type':hwvendor[1],'Version':hwvendor[2],'SN':hwvendor[3],'UUID':hwvendor[4]},'Class':{'Server Type':hwclass[0],'Height':hwclass[1]}}
57 | return serverdict
58 |
59 |
60 | def getcpu():
61 | hwcpu = parse_dmi(info("dmidecode -t processor"),"cpu")
62 | cpudict = {}
63 | hascpu = 0
64 | disbyb = 0
65 | for i in hwcpu:
66 | cnum = i[1]['Socket Designation']
67 | if i[1]['Status'] == 'Populated, Enabled':
68 | hascpu += 1
69 | ctype = i[1].get('Version', False)
70 | ccc = i[1].get('Core Count', False)
71 | ctc = i[1].get('Thread Count', False)
72 | ccspeed = i[1].get('Current Speed', False)
73 | cpudict[cnum] = {'Type':ctype,'Core Count':ccc,'Thread Count':ctc,'Current Speed':ccspeed}
74 | elif i[1]['Status'] == 'Populated, Disabled By BIOS':
75 | disbyb += 1
76 | cpudict['CPU #Populated, Disabled By BIOS'] = {'Count':str(disbyb)}
77 | else:
78 | cpudict[cnum] = {'Status':i[1]['Status']}
79 |
80 | hwctotal = str(len(hwcpu))
81 | hwcsocket = hwcpu[0][1].get('Upgrade', False)
82 | hwcmspeed = hwcpu[0][1].get('Max Speed', False)
83 | cpudict['CpuSocket'] = {'Socket Count':hwctotal,'CPU Count':str(hascpu),'Socket Type':hwcsocket,'Max Speed':hwcmspeed}
84 | return cpudict
85 |
86 |
87 | def getmem():
88 | hwmem = parse_dmi(info("dmidecode -t memory"),"memory")
89 | memdict = {}
90 | hasmem = 0
91 | for i in hwmem:
92 | if i[1]['_title'] == 'Memory Device':
93 | memnum = 'MEM-' + i[1]['Locator']
94 | if i[1]['Size'] != 'No Module Installed':
95 | hasmem +=1
96 | msize = i[1].get('Size', False)
97 | mtype = i[1].get('Type', False)
98 | mmspeed = i[1].get('Speed', False)
99 | mcspeed = i[1].get('Configured Clock Speed', False)
100 | mfac = i[1].get('Manufacturer', False)
101 | mpn = i[1].get('Part Number', False)
102 | memdict[memnum] = {'Size':msize,'Type':mtype,'Speed':mmspeed,'Current Speed':mcspeed,'Vendor':mfac,'Model':mpn}
103 | # else:
104 | # memdict[memnum] = {'Status':"No Module Installed"}
105 | elif i[1]['_title'] == 'Physical Memory Array':
106 | hwmtotalnum = i[1].get('Number Of Devices', False)
107 | hwmtotalsize = i[1].get('Maximum Capacity', False)
108 | hwmerr = i[1].get('Error Correction Type', False)
109 | memdict['Memsocket'] = {'Mem Socket Count':hwmtotalnum,'Max Size':hwmtotalsize,'Error Correction Type':hwmerr}
110 | memdict['Memsocket']['Current Mem Count'] = str(hasmem)
111 | return memdict
112 |
--------------------------------------------------------------------------------
/hwpy/hwpy/_hwdisk.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | from __future__ import print_function
3 | import os
4 | import re
5 | import sys
6 | import errno
7 | from subprocess import Popen,PIPE
8 |
9 | def find_device(data, pciid):
10 | id = re.escape(pciid)
11 | m = re.search("^" + id + "\s(.*)$", data, re.MULTILINE)
12 | return m.group(1)
13 |
14 | def pretty_size(size):
15 | size_strs = ['B', 'KiB', 'MiB', 'GiB', 'TiB']
16 | last_size = size
17 | fract_size = size
18 | num_divs = 0
19 |
20 | while size > 1:
21 | fract_size = last_size
22 | last_size = size
23 | size /= 1024
24 | num_divs += 1
25 |
26 | num_divs -= 1
27 | fraction = fract_size / 1024
28 | pretty = "%.2f" % fraction
29 | pretty = pretty + size_strs[num_divs]
30 | return pretty
31 |
32 | def virtual_device(path):
33 | for dir in os.listdir(path):
34 | if re.search("device", dir):
35 | return 0
36 | return 1
37 |
38 | class Device:
39 | def __init__(self):
40 | self.sectorsize = ""
41 | self.sectors = ""
42 | self.rotational = ""
43 | self.sysdir = ""
44 | self.host = ""
45 | self.model = ""
46 | self.vendor = ""
47 | self.holders = []
48 | self.diskname = ""
49 | self.partitions = []
50 | self.removable = ""
51 | self.start = ""
52 | self.discard = ""
53 | self.sysfs_no_links = 0
54 |
55 | def populate_model(self):
56 | try:
57 | f = open(self.sysdir + "/device/model")
58 | self.model = f.read().rstrip()
59 | f.close()
60 | except IOError:
61 | # do nothing
62 | pass
63 |
64 | def populate_vendor(self):
65 | try:
66 | f = open(self.sysdir + "/device/vendor")
67 | self.vendor = f.read().rstrip()
68 | f.close()
69 | except IOError:
70 | #do nothing
71 | pass
72 |
73 | def populate_sectors(self):
74 | try:
75 | f = open(self.sysdir + "/size")
76 | self.sectors = f.read().rstrip()
77 | f.close()
78 | except IOError:
79 | self.sectors = 0
80 |
81 | def populate_sector_size(self):
82 | try:
83 | f = open(self.sysdir + "/queue/hw_sector_size")
84 | self.sectorsize = f.read().rstrip()
85 | f.close()
86 | except IOError:
87 | # if this sysfs doesnt show us sectorsize then just assume 512
88 | self.sectorsize = "512"
89 |
90 | def populate_rotational(self):
91 | try:
92 | f = open(self.sysdir + "/queue/rotational")
93 | rotation = f.read().rstrip()
94 | f.close()
95 | except IOError:
96 | self.rotational = "Could not determine rotational"
97 | return
98 | if rotation == "1":
99 | self.rotational = "Spinning disk"
100 | else:
101 | self.rotational = "SSD"
102 |
103 | def populate_host(self, pcidata):
104 | if self.sysfs_no_links == 1:
105 | try:
106 | sysdir = os.readlink(os.path.join(self.sysdir, "device"))
107 | except:
108 | pass
109 | else:
110 | sysdir = self.sysdir
111 | # m = re.match(".+/\d+:(\w+:\w+\.\w)/host\d+/\s*", sysdir)
112 | m = re.match(".+/\d+:(\w+:\w+\.\w)/[a-z]+\d+/\s*", sysdir)
113 | if m:
114 | pciid = m.group(1)
115 | self.host = find_device(pcidata, pciid)
116 | else:
117 | self.host = ""
118 |
119 | def populate_diskname(self):
120 | m = re.match(".*/(.+)$", self.sysdir)
121 | self.diskname = m.group(1)
122 |
123 | def populate_holders(self):
124 | for dir in os.listdir(self.sysdir + "/holders"):
125 | if re.search("^dm-.*", dir):
126 | try:
127 | f = open(self.sysdir + "/holders/" + dir + "/dm/name")
128 | name = f.read().rstrip()
129 | f.close()
130 | self.holders.append(name)
131 | except IOError:
132 | self.holders.append(dir)
133 | else:
134 | self.holders.append(dir)
135 |
136 | def populate_discard(self):
137 | try:
138 | f = open(self.sysdir + "/queue/discard_granularity")
139 | discard = f.read().rstrip()
140 | f.close()
141 | if discard == "0":
142 | self.discard = "No"
143 | else:
144 | self.discard = "Yes"
145 | except IOError:
146 | self.discard = "No"
147 |
148 | def populate_start(self):
149 | try:
150 | f = open(self.sysdir + "/start")
151 | self.start = f.read().rstrip()
152 | f.close()
153 | except IOError:
154 | pass
155 |
156 | def populate_partitions(self):
157 | for dir in os.listdir(self.sysdir):
158 | m = re.search("(" + self.diskname + "\d+)", dir)
159 | if m:
160 | partname = m.group(1)
161 | part = Device()
162 | part.sysdir = self.sysdir + "/" + partname
163 | part.populate_part_info()
164 | self.partitions.append(part)
165 |
166 | def populate_part_info(self):
167 | """ Only call this if we are a partition """
168 | self.populate_diskname()
169 | self.populate_holders()
170 | self.populate_sectors()
171 | self.populate_start()
172 |
173 | def populate_removable(self):
174 | try:
175 | f = open(self.sysdir + "/removable")
176 | remove = f.read().rstrip()
177 | f.close()
178 | if remove == "1":
179 | self.removable = "Yes"
180 | else:
181 | self.removable = "No"
182 | except IOError:
183 | self.removable = "No"
184 |
185 | def populate_all(self, pcidata):
186 | self.populate_diskname()
187 | self.populate_holders()
188 | self.populate_partitions()
189 | self.populate_removable()
190 | self.populate_model()
191 | self.populate_vendor()
192 | self.populate_sectors()
193 | self.populate_sector_size()
194 | self.populate_rotational()
195 | self.populate_discard()
196 | self.populate_host(pcidata)
197 |
198 | def getdisk():
199 | p = Popen(["lspci"], stdout=PIPE)
200 | err = p.wait()
201 | if err:
202 | print ("Error running lspci")
203 | sys.exit()
204 | pcidata = p.stdout.read().decode('utf-8')
205 |
206 | sysfs_no_links = 0
207 | devices = []
208 |
209 | if len(sys.argv) > 1:
210 | m = re.match("/dev/(\D+)\d*", sys.argv[1])
211 | if m:
212 | block = m.group(1)
213 | else:
214 | block = sys.argv[1]
215 |
216 | try:
217 | path = os.readlink(os.path.join("/sys/block/", block))
218 | except OSError as e:
219 | if e.errno == errno.EINVAL:
220 | path = block
221 | else:
222 | print ("Invalid device name " + block)
223 | sys.exit()
224 | d = Device()
225 | d.sysdir = os.path.join("/sys/block", path)
226 | d.populate_all(pcidata)
227 | devices.append(d)
228 | else:
229 | for block in os.listdir("/sys/block"):
230 | try:
231 | if sysfs_no_links == 0:
232 | path = os.readlink(os.path.join("/sys/block/", block))
233 | else:
234 | path = block
235 | except OSError as e:
236 | if e.errno == errno.EINVAL:
237 | path = block
238 | sysfs_no_links = 1
239 | else:
240 | continue
241 | if re.search("virtual", path):
242 | continue
243 | if sysfs_no_links == 1:
244 | sysdir = os.path.join("/sys/block", path)
245 | if virtual_device(sysdir) == 1:
246 | continue
247 | d = Device()
248 | d.sysdir = os.path.join("/sys/block", path)
249 | d.sysfs_no_links = sysfs_no_links
250 | d.populate_all(pcidata)
251 | devices.append(d)
252 | diskdict = {}
253 | devices.sort()
254 | for d in devices:
255 | diskdict[d.diskname] = []
256 | size = float(d.sectors) * float(d.sectorsize)
257 | allpretty = pretty_size(size)
258 | diskdict[d.diskname] = {'host':d.host,'vendor':d.vendor,'model':d.model,'size':allpretty,'type':d.rotational}
259 | return diskdict
260 |
--------------------------------------------------------------------------------
/hwpy/hwpy/_hwnet.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | from __future__ import print_function
3 | from psutil import net_if_addrs,net_if_stats
4 | import os
5 | import re
6 | import sys
7 | import errno
8 | from subprocess import Popen,PIPE
9 | p = Popen(["lspci"], stdout=PIPE)
10 | err = p.wait()
11 | if err:
12 | print ("Error running lspci")
13 | sys.exit()
14 | pcidata = p.stdout.read().decode('utf-8')
15 |
16 | def _find_device(data, pciid):
17 | id = re.escape(pciid)
18 | m = re.search("^" + id + "\s(.*)$", data, re.MULTILINE)
19 | return m.group(1)
20 | def getnet():
21 | netdict = {}
22 | for k, v in net_if_addrs().items():
23 | if not (k.startswith('tap') or k.startswith('vir') or k.startswith('br') or k.startswith('lo') or k.startswith('docker')):
24 | for item in v:
25 | mac = item[1]
26 | if ':' in mac and len(mac)==17:
27 | netdir = os.readlink(os.path.join("/sys/class/net", k))
28 | m = re.match(".+/\d+:(\w+:\w+\.\w)/[a-z]+\w*/\s*", netdir)
29 | if m:
30 | pciid = m.group(1)
31 | host = _find_device(pcidata, pciid)
32 | else:
33 | host = ""
34 | eth = Popen("sudo ethtool {}|grep 'Link detected'|awk -F:\ '{{print $2}}'".format(k), stdout=PIPE,shell=True)
35 | err = eth.wait()
36 | if err:
37 | print ("Error running ethtool")
38 | sys.exit()
39 | isup = eth.stdout.read().decode('utf-8').strip("\n")
40 | if isup == "yes" and net_if_stats()[k].speed != 65535:
41 | speed = str(net_if_stats()[k].speed) + 'Mbps'
42 | elif isup == "no":
43 | speed = False
44 | else:
45 | speed = 'Unknown'
46 | netdict[k] = {'host':host,'mac':mac,'isup':isup,'speed':speed}
47 | return netdict
48 |
--------------------------------------------------------------------------------
/hwpy/hwpy/_hwpart.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | from psutil import disk_partitions as _disk_partitions, disk_usage as _disk_usage
3 |
4 | def _pretty_size(size):
5 | size_strs = ['B', 'KiB', 'MiB', 'GiB', 'TiB']
6 | last_size = size
7 | fract_size = size
8 | num_divs = 0
9 |
10 | while size > 1:
11 | fract_size = last_size
12 | last_size = size
13 | size /= 1024.0
14 | num_divs += 1
15 |
16 | num_divs -= 1
17 | fraction = fract_size / 1024.0
18 | pretty = "%.2f" % fraction
19 | pretty = pretty + size_strs[num_divs]
20 | return pretty
21 |
22 | def getpart():
23 | partlist = _disk_partitions()
24 | partlist.sort()
25 | partdict={}
26 | for i in partlist:
27 | dev = i.device
28 | mount = i.mountpoint
29 | fstype = i.fstype
30 | total = _pretty_size(_disk_usage(mount).total)
31 | partdict[i.device]={'mount':mount,'fstype':fstype,'total':total}
32 | return partdict
33 |
--------------------------------------------------------------------------------
/hwpy/hwpy/info.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | from . import _hwnet, _hwpart, _hwdisk, _dmide
3 | net = _hwnet.getnet()
4 | part = _hwpart.getpart()
5 | disk = _hwdisk.getdisk()
6 | cpu = _dmide.getcpu()
7 | host = _dmide.getserver()
8 | mem = _dmide.getmem()
9 | hwlist = [host,cpu,mem,disk,part,net]
10 | def main():
11 | for i in hwlist:
12 | items = i.keys()
13 | itemslist = sorted(items)
14 | for m in itemslist:
15 | print (m + ':')
16 | for ik,iv in i[m].items():
17 | print ("\t" + ik + ':' + str(iv))
18 |
--------------------------------------------------------------------------------
/hwpy/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #-*- coding:utf-8 -*-
3 |
4 | #############################################
5 | # File Name: hwpy
6 | # Author: Stars Liao
7 | # Mail: starsliaop@163.com
8 | # Created Time: 2018-12-24 19:17:34
9 | #############################################
10 |
11 | from setuptools import setup, find_packages
12 | with open("README.md", "r") as fh:
13 | long_description = fh.read()
14 |
15 | setup(
16 | name = "hwpy",
17 | version = "0.3.8",
18 | keywords = ("pip", "hwpy","Hardware","硬件检测"),
19 | description = "Get linux server hardware information. 获取Linux服务器硬件明细。",
20 | long_description = long_description,
21 | long_description_content_type="text/markdown",
22 | license = "MIT Licence",
23 |
24 | url = "https://github.com/starsliao/PythonTools",
25 | author = "Stars Liao",
26 | author_email = "starsliao@163.com",
27 |
28 | packages = find_packages(),
29 | include_package_data = True,
30 | platforms = "any",
31 | install_requires = ["psutil==5.9.5"],
32 | classifiers=[
33 | 'Intended Audience :: System Administrators',
34 | 'Operating System :: POSIX :: Linux',
35 | 'Programming Language :: Python :: 2.7',
36 | 'Programming Language :: Python :: 3.6',
37 | 'Topic :: Utilities',
38 | ],
39 | )
40 |
--------------------------------------------------------------------------------
/rabbitmq-test/README.md:
--------------------------------------------------------------------------------
1 | ### obsolete
2 |
--------------------------------------------------------------------------------
/rabbitmq-test/send.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3.6
2 | import pika
3 | import sys,datetime,time
4 | import multiprocessing,logging
5 |
6 | logger = logging.getLogger("MQ_SENDER")
7 | logger.setLevel(logging.DEBUG)
8 | fh = logging.FileHandler("/var/log/mq_sender.log")
9 | fh.setLevel(logging.DEBUG)
10 | #ch = logging.StreamHandler()
11 | #ch.setLevel(logging.INFO)
12 | formatter = logging.Formatter("[%(asctime)s] [%(levelname)s] [%(process)d] %(message)s")
13 | #ch.setFormatter(formatter)
14 | fh.setFormatter(formatter)
15 | #logger.addHandler(ch)
16 | logger.addHandler(fh)
17 |
18 | def sender():
19 | credentials = pika.PlainCredentials('admin','app')
20 | connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.200.201',5672,'test',credentials))
21 | channel = connection.channel()
22 | channel.queue_declare(queue='deploy', durable=True)
23 | try:
24 | for i in range(1,100001):
25 | #message = datetime.datetime.now().strftime('%Y_%m_%d_%H:%M:%S.%f')
26 | channel.basic_publish(exchange='',routing_key='deploy',body=str(i),properties=pika.BasicProperties(delivery_mode=2))
27 | logger.info(f'[sender]{i}')
28 | time.sleep(1)
29 | connection.close()
30 | except KeyboardInterrupt:
31 | connection.close()
32 | print('EXIT!')
33 | for i in range(600):
34 | p = multiprocessing.Process(target=sender)
35 | p.start()
36 |
--------------------------------------------------------------------------------
/rabbitmq-test/work.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3.6
2 | import multiprocessing
3 | import threading
4 | import pika
5 | import os,sys,time,logging,random
6 | class Worker:
7 | def __init__(self, username, password, host, vhost, queue_name):
8 | self.username = username
9 | self.password = password
10 | self.host = host
11 | self.vhost = vhost
12 | self.queue_name = queue_name
13 | self.connection = None
14 | self.channel = None
15 |
16 | logger = logging.getLogger("MQ_WORKER")
17 | logger.setLevel(logging.DEBUG)
18 | fh = logging.FileHandler("/var/log/mq_worker.log")
19 | fh.setLevel(logging.DEBUG)
20 | ch = logging.StreamHandler()
21 | ch.setLevel(logging.INFO)
22 | formatter = logging.Formatter("[%(asctime)s] [%(levelname)s] [%(process)d] %(message)s")
23 | ch.setFormatter(formatter)
24 | fh.setFormatter(formatter)
25 | logger.addHandler(ch)
26 | logger.addHandler(fh)
27 |
28 | self.logger = logger
29 |
30 | def conn(self):
31 | if self.connection and not self.connection.is_closed:
32 | self.connection.close()
33 | credentials = pika.PlainCredentials(self.username, self.password)
34 | is_closed = True
35 | while is_closed:
36 | try:
37 | self.connection = pika.BlockingConnection(pika.ConnectionParameters(self.host,5672,self.vhost,credentials,heartbeat=60))
38 | is_closed = False
39 | except:
40 | self.logger.error('[main] AMQP_Connection_Error')
41 | time.sleep(2)
42 | self.channel = self.connection.channel()
43 | self.channel.basic_qos(prefetch_count=1)
44 | self.channel.queue_declare(queue=self.queue_name, durable=True)
45 | self.channel.basic_consume(queue=self.queue_name, on_message_callback=self.task)
46 | self.logger.info('[Connect Successfully] Waiting for messages. To exit press CTRL+C')
47 | self.channel.start_consuming()
48 |
49 | def heart(self):
50 | while True:
51 | time.sleep(20)
52 | try:
53 | self.connection.process_data_events()
54 | self.logger.debug(f'[heartbeat] Heartbeat check succeeded')
55 | except Exception as err:
56 | self.logger.error(f'[heartbeat] {err}')
57 | t = threading.Thread(target=self.conn)
58 | t.daemon = True
59 | t.start()
60 | k = True
61 | while k:
62 | if self.connection.is_open:
63 | k = False
64 |
65 | def task(self, ch, method, properties, body):
66 | num = random.uniform(0,1)
67 | self.logger.info(f'Received: {body},{num}')
68 | time.sleep(num)
69 | self.logger.info(f'Done: {body}')
70 | ch.basic_ack(delivery_tag=method.delivery_tag)
71 | self.logger.info(f'ACK: {body}')
72 |
73 | # def doit(self)
74 | # t = threading.Thread(target=self.task, args=(ch, method, properties, body,))
75 | # t.daemon = True
76 | # t.start()
77 |
78 | def main(self):
79 | t = threading.Thread(target=self.conn)
80 | t.daemon = True
81 | t.start()
82 | while True:
83 | if self.connection and not self.connection.is_closed:
84 | self.heart()
85 |
86 | if __name__ == '__main__':
87 | w = Worker('admin','app','192.168.200.201','test','deploy')
88 | for i in range(400):
89 | p = multiprocessing.Process(target=w.main)
90 | p.start()
91 |
--------------------------------------------------------------------------------
/rabbitmq-test/work.py.bak:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3.6
2 | import multiprocessing
3 | import threading
4 | import pika
5 | import sys,time,logging
6 | class Worker:
7 | def __init__(self, username, password, host, vhost, queue_name):
8 | self.username = username
9 | self.password = password
10 | self.host = host
11 | self.vhost = vhost
12 | self.queue_name = queue_name
13 | self.connection = None
14 | self.channel = None
15 | self.credentials = None
16 |
17 | logger = logging.getLogger("MQ_WORKER")
18 | logger.setLevel(logging.DEBUG)
19 | fh = logging.FileHandler("/var/log/mq_worker.log")
20 | fh.setLevel(logging.DEBUG)
21 | ch = logging.StreamHandler()
22 | ch.setLevel(logging.INFO)
23 | formatter = logging.Formatter("[%(asctime)s] [%(levelname)s] %(message)s")
24 | ch.setFormatter(formatter)
25 | fh.setFormatter(formatter)
26 | logger.addHandler(ch)
27 | logger.addHandler(fh)
28 |
29 | self.logger = logger
30 |
31 | def conn(self):
32 | if self.connection and not self.connection.is_closed:
33 | self.connection.close()
34 | self.credentials = pika.PlainCredentials(self.username, self.password)
35 | is_closed = True
36 | while is_closed:
37 | try:
38 | self.connection = pika.BlockingConnection(pika.ConnectionParameters(self.host,5672,self.vhost,self.credentials,heartbeat=60))
39 | is_closed = False
40 | except:
41 | self.logger.error('[main] AMQPConnectionError')
42 | time.sleep(2)
43 | self.channel = self.connection.channel()
44 | self.channel.basic_qos(prefetch_count=1)
45 | self.channel.queue_declare(queue=self.queue_name, durable=True)
46 | self.logger.info('[Connect Successfully] Waiting for messages. To exit press CTRL+C')
47 |
48 | def task(self,body,ch,method):
49 | self.logger.info(f'Received: {body}')
50 | time.sleep(3)
51 | self.logger.info(f'Done: {body}')
52 | ch.basic_ack(delivery_tag=method.delivery_tag)
53 | self.logger.info(f'ACK: {body}\n')
54 |
55 | def receive(self,callback):
56 | def cb(ch, method, properties, body):
57 | t = threading.Thread(target=callback, args=(body,ch,method,))
58 | t.daemon = True
59 | t.start()
60 | while t.is_alive():
61 | time.sleep(5)
62 | self.logger.info(f'[heartbeat] Heart beating...')
63 | #print(f'[INFO] [{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}] heart beating')
64 | try:
65 | self.connection.process_data_events()
66 | except Exception as err:
67 | self.logger.error(f'[heartbeat] {err}')
68 | self.conn()
69 | self.channel.basic_consume(queue=self.queue_name, on_message_callback=cb)
70 | self.channel.start_consuming()
71 | self.conn()
72 | self.channel.basic_consume(queue=self.queue_name, on_message_callback=cb)
73 | self.channel.start_consuming()
74 |
75 | if __name__ == '__main__':
76 | w = Worker('app','app','192.168.200.201','app','deploy')
77 | w.receive(w.task)
78 | #p = multiprocessing.Process(target=w.receive, args=(w.task,))
79 | #p.start()
80 |
--------------------------------------------------------------------------------
/rabbitmq-test/work.py.false:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3.6
2 | import multiprocessing
3 | import threading
4 | import pika
5 | import sys,time,logging,random
6 | class Worker:
7 | def __init__(self, username, password, host, vhost, queue_name):
8 | self.username = username
9 | self.password = password
10 | self.host = host
11 | self.vhost = vhost
12 | self.queue_name = queue_name
13 | self.connection = None
14 | self.channel = None
15 | self.credentials = None
16 |
17 | logger = logging.getLogger("MQ_WORKER")
18 | logger.setLevel(logging.DEBUG)
19 | fh = logging.FileHandler("/var/log/mq_worker.log")
20 | fh.setLevel(logging.DEBUG)
21 | ch = logging.StreamHandler()
22 | ch.setLevel(logging.INFO)
23 | formatter = logging.Formatter("[%(asctime)s] [%(levelname)s] %(message)s")
24 | ch.setFormatter(formatter)
25 | fh.setFormatter(formatter)
26 | logger.addHandler(ch)
27 | logger.addHandler(fh)
28 |
29 | self.logger = logger
30 |
31 | def conn(self):
32 | if self.connection and not self.connection.is_closed:
33 | self.connection.close()
34 | self.credentials = pika.PlainCredentials(self.username, self.password)
35 | is_closed = True
36 | while is_closed:
37 | try:
38 | self.connection = pika.BlockingConnection(pika.ConnectionParameters(self.host,5672,self.vhost,self.credentials,heartbeat=10))
39 | is_closed = False
40 | except:
41 | self.logger.error('[main] AMQPConnectionError')
42 | time.sleep(2)
43 | self.channel = self.connection.channel()
44 | self.channel.basic_qos(prefetch_count=1)
45 | self.channel.queue_declare(queue=self.queue_name, durable=True)
46 | self.channel.basic_consume(queue=self.queue_name, on_message_callback=self.task)
47 | t = threading.Thread(target=self.heart)
48 | t.daemon = True
49 | t.start()
50 | self.logger.info('[Connect Successfully] Waiting for messages. To exit press CTRL+C')
51 | self.channel.start_consuming()
52 |
53 | def heart(self):
54 | while True:
55 | time.sleep(3)
56 | try:
57 | self.connection.process_data_events()
58 | self.logger.info(f'[heartbeat] Heartbeat check succeeded')
59 | except Exception as err:
60 | self.logger.error(f'[heartbeat] {err}')
61 | self.conn()
62 |
63 | def task(self, ch, method, properties, body):
64 | num = random.uniform(200,300)
65 | self.logger.info(f'Received: {body},{num}')
66 | time.sleep(3600)
67 | self.logger.info(f'Done: {body}')
68 | ch.basic_ack(delivery_tag=method.delivery_tag)
69 | self.logger.info(f'ACK: {body}\n')
70 |
71 | if __name__ == '__main__':
72 | w = Worker('app','app','192.168.200.201','app','deploy')
73 | w.conn()
74 | # for i in range(1):
75 | # p = multiprocessing.Process(target=w.conn)
76 | # p.start()
77 |
--------------------------------------------------------------------------------
/rabbitmq-test/work.py.new:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3.6
2 | import multiprocessing
3 | import threading
4 | import pika
5 | import sys,time,logging,random
6 | class Worker:
7 | def __init__(self, username, password, host, vhost, queue_name):
8 | self.username = username
9 | self.password = password
10 | self.host = host
11 | self.vhost = vhost
12 | self.queue_name = queue_name
13 | self.connection = None
14 | self.channel = None
15 | self.credentials = None
16 |
17 | logger = logging.getLogger("MQ_WORKER")
18 | logger.setLevel(logging.DEBUG)
19 | fh = logging.FileHandler("/var/log/mq_worker.log")
20 | fh.setLevel(logging.DEBUG)
21 | ch = logging.StreamHandler()
22 | ch.setLevel(logging.INFO)
23 | formatter = logging.Formatter("[%(asctime)s] [%(levelname)s] %(message)s")
24 | ch.setFormatter(formatter)
25 | fh.setFormatter(formatter)
26 | logger.addHandler(ch)
27 | logger.addHandler(fh)
28 |
29 | self.logger = logger
30 |
31 | def conn(self):
32 | if self.connection and not self.connection.is_closed:
33 | self.connection.close()
34 | self.credentials = pika.PlainCredentials(self.username, self.password)
35 | is_closed = True
36 | while is_closed:
37 | try:
38 | self.connection = pika.BlockingConnection(pika.ConnectionParameters(self.host,5672,self.vhost,self.credentials,heartbeat=60))
39 | is_closed = False
40 | except:
41 | self.logger.error('[main] AMQPConnectionError')
42 | time.sleep(2)
43 | self.channel = self.connection.channel()
44 | self.channel.basic_qos(prefetch_count=1)
45 | self.channel.queue_declare(queue=self.queue_name, durable=True)
46 | self.channel.basic_consume(queue=self.queue_name, on_message_callback=self.cb)
47 | self.logger.info('[Connect Successfully] Waiting for messages. To exit press CTRL+C')
48 | self.channel.start_consuming()
49 |
50 | def cb(self, ch, method, properties, body):
51 | t = threading.Thread(target=self.task, args=(body,ch,method,))
52 | t.daemon = True
53 | t.start()
54 | while t.is_alive():
55 | time.sleep(0.2)
56 | self.logger.info(f'[heartbeat] Heart beating...')
57 | #print(f'[INFO] [{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}] heart beating')
58 | try:
59 | self.connection.process_data_events()
60 | except Exception as err:
61 | self.logger.error(f'[heartbeat] {err}')
62 | self.conn()
63 |
64 | def task(self,body,ch,method):
65 | self.logger.info(f'Received: {body}')
66 | num = random.uniform(0,2)
67 | time.sleep(0.5)
68 | self.logger.info(f'Done: {body}')
69 | ch.basic_ack(delivery_tag=method.delivery_tag)
70 | self.logger.info(f'ACK: {body}\n')
71 |
72 | if __name__ == '__main__':
73 | w = Worker('app','app','192.168.200.201','app','deploy')
74 | w.conn()
75 | # for i in range(1):
76 | # p = multiprocessing.Process(target=w.conn)
77 | # p.start()
78 |
--------------------------------------------------------------------------------
/short-url/README.md:
--------------------------------------------------------------------------------
1 | ```
2 | import requests
3 | url = "http://yourServerIp:888/shorturl"
4 | payload={'url': "https://baidu.com"}
5 | response = requests.post(url, data=payload)
6 | response.json()['surl']
7 | ```
8 |
--------------------------------------------------------------------------------
/short-url/short-url.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | '''
3 | import requests
4 | url = "http://yourServerIp:888/shorturl"
5 | payload={'url': "https://baidu.com"}
6 | response = requests.post(url, data=payload)
7 | response.json()['surl']
8 | '''
9 |
10 | import redis
11 | from flask import Flask, request, Response, jsonify, redirect
12 |
13 | base62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
14 | len_base62 = len(base62)
15 | base_url = 'http://s.openiops.com/'
16 | r = redis.StrictRedis(host='127.0.0.1', port=6379, db=6, password='xxxxxxxxxx')
17 |
18 | def base62_encode(num):
19 | string = ''
20 | while num:
21 | string = base62[num % len_base62] + string
22 | num //= len_base62
23 | return string
24 |
25 | app = Flask(__name__)
26 | @app.route("/shorturl", methods=['POST'])
27 | def shorturl():
28 | if request.method == 'POST':
29 | url = request.form['url']
30 | sid = base62_encode(r.incr('SID'))
31 | r.hset('URL', sid, url)
32 | surl = base_url + sid
33 | return jsonify({'surl': surl})
34 |
35 | @app.route('/')
36 | def longurl(token):
37 | long_url = r.hget('URL', token).decode(encoding='utf-8')
38 | return redirect(long_url, 301)
39 |
40 | if __name__ == "__main__":
41 | app.run(host="0.0.0.0", port=888)
42 |
--------------------------------------------------------------------------------
/wechatbot/README.md:
--------------------------------------------------------------------------------
1 | 使用UOS微信协议,web版接口复活!实现一个微信群报价机器人
2 |
3 | 如果之前你的微信提示不能登录web端,使得itchat等基于微信网页版模拟操作的库无法使用,那么这个更新将会是你的福音。因为这个修改版的itchat已经支持使用UOS微信桌面版协议实现登录!
4 |
5 | ## 如何使用:
6 | 安装修改版的ItChat即可:
7 |
8 | ```
9 | yum install xdg-utils -y
10 | pip3 uninstall itchat
11 | pip3 install git+https://github.com/StarsL-cn/ItChat-UOS.git
12 | ```
13 |
14 | 对itchat不熟悉的同学可以参考该项目说明
15 |
16 | ## 原理说明:
17 |
18 | 原理很简单:UOS下的微信只是网页版套了个electron。所以目前采用的绕过web端的限制方式,其实是使用了UOS的桌面版微信请求头,只要在请求的地址上首先加一个?target=t 就是这样:https://wx.qq.com/?target=t 然后在扫码登陆后拦截 https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage 这个请求,并在请求头上添加两个固定的参数:
19 | ```
20 | extspam ='Gp8ICJkIEpkICggwMDAwMDAwMRAGGoAI1GiJSIpeO1RZTq9QBKsRbPJdi84ropi16EYI10WB6g74sGmRwSNXjPQnYUKYotKkvLGpshucCaeWZMOylnc6o2AgDX9grhQQx7fm2DJRTyuNhUlwmEoWhjoG3F0ySAWUsEbH3bJMsEBwoB//0qmFJob74ffdaslqL+IrSy7LJ76/G5TkvNC+J0VQkpH1u3iJJs0uUYyLDzdBIQ6Ogd8LDQ3VKnJLm4g/uDLe+G7zzzkOPzCjXL+70naaQ9medzqmh+/SmaQ6uFWLDQLcRln++wBwoEibNpG4uOJvqXy+ql50DjlNchSuqLmeadFoo9/mDT0q3G7o/80P15ostktjb7h9bfNc+nZVSnUEJXbCjTeqS5UYuxn+HTS5nZsPVxJA2O5GdKCYK4x8lTTKShRstqPfbQpplfllx2fwXcSljuYi3YipPyS3GCAqf5A7aYYwJ7AvGqUiR2SsVQ9Nbp8MGHET1GxhifC692APj6SJxZD3i1drSYZPMMsS9rKAJTGz2FEupohtpf2tgXm6c16nDk/cw+C7K7me5j5PLHv55DFCS84b06AytZPdkFZLj7FHOkcFGJXitHkX5cgww7vuf6F3p0yM/W73SoXTx6GX4G6Hg2rYx3O/9VU2Uq8lvURB4qIbD9XQpzmyiFMaytMnqxcZJcoXCtfkTJ6pI7a92JpRUvdSitg967VUDUAQnCXCM/m0snRkR9LtoXAO1FUGpwlp1EfIdCZFPKNnXMeqev0j9W9ZrkEs9ZWcUEexSj5z+dKYQBhIICviYUQHVqBTZSNy22PlUIeDeIs11j7q4t8rD8LPvzAKWVqXE+5lS1JPZkjg4y5hfX1Dod3t96clFfwsvDP6xBSe1NBcoKbkyGxYK0UvPGtKQEE0Se2zAymYDv41klYE9s+rxp8e94/H8XhrL9oGm8KWb2RmYnAE7ry9gd6e8ZuBRIsISlJAE/e8y8xFmP031S6Lnaet6YXPsFpuFsdQs535IjcFd75hh6DNMBYhSfjv456cvhsb99+fRw/KVZLC3yzNSCbLSyo9d9BI45Plma6V8akURQA/qsaAzU0VyTIqZJkPDTzhuCl92vD2AD/QOhx6iwRSVPAxcRFZcWjgc2wCKh+uCYkTVbNQpB9B90YlNmI3fWTuUOUjwOzQRxJZj11NsimjOJ50qQwTTFj6qQvQ1a/I+MkTx5UO+yNHl718JWcR3AXGmv/aa9rD1eNP8ioTGlOZwPgmr2sor2iBpKTOrB83QgZXP+xRYkb4zVC+LoAXEoIa1+zArywlgREer7DLePukkU6wHTkuSaF+ge5Of1bXuU4i938WJHj0t3D8uQxkJvoFi/EYN/7u2P1zGRLV4dHVUsZMGCCtnO6BBigFMAA='
21 | client-version' = '2.0.0'
22 | ```
23 | 这样就可以完美使用桌面版协议了。
24 |
25 | # 开发一个微信群数字货币报价机器人:
26 |
27 | ## 实现功能:
28 | 1. 基于itchat库实现微信群机器人,只需要把该微信号加入到对应的群,群成员发送币种名称消息即可触发机器人报价。
29 | 2. 目前接入了币安,火币,抹茶3个交易所的行情数据。
30 | 3. 这些都是开放的接口不需要认证。
31 | 4. 记得使用非国内的服务器来请求这些接口。
32 | 5. 另外基于apscheduler写了个简单的定时任务,可定时推送消息到微信群。
33 |
34 | ## 截图:
35 | 
36 |
37 | ## 完整代码请参考gitlab:
38 | https://github.com/starsliao/tools/blob/master/wechatbot/wechatbot.py
39 |
--------------------------------------------------------------------------------
/wechatbot/bot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/starsliao/PythonTools/3bdd7fc988529ea75e927f4a3f1ed9b10424eaba/wechatbot/bot.png
--------------------------------------------------------------------------------
/wechatbot/wechatbot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | import itchat,os,threading,requests
3 | from apscheduler.schedulers.blocking import BlockingScheduler
4 | def kline(symbol):
5 | queryurl = f"https://api.huobi.pro/market/history/kline?period=1day&size=1&symbol={symbol}usdt"
6 | res_dict = requests.request("GET", queryurl).json()
7 | if 'status' in res_dict and res_dict['status'] == 'ok':
8 | return res_dict['data'][0]
9 | else:
10 | queryurl = f"https://api.binance.com/api/v3/klines?limit=1&interval=1d&symbol={symbol.upper()}USDT"
11 | res_list = requests.request("GET", queryurl).json()
12 | if isinstance(res_list,list):
13 | return res_list[0]
14 | else:
15 | queryurl = f"https://www.mxc.com/open/api/v2/market/kline?limit=1&interval=1d&symbol={symbol.upper()}_USDT"
16 | res_dict = requests.request("GET", queryurl).json()
17 | if 'data' in res_dict and res_dict['data'] != []:
18 | return res_dict
19 | else:
20 | return 'error'
21 | def str_of_num(num):
22 | num = float(num)
23 | def strofsize(num, level):
24 | if level >= 2:
25 | return num, level
26 | elif num >= 10000:
27 | num /= 10000
28 | level += 1
29 | return strofsize(num, level)
30 | else:
31 | return num, level
32 | units = ['', '万', '亿']
33 | num, level = strofsize(num, 0)
34 | if level > len(units):
35 | level -= 1
36 | return '{}{}'.format(round(num, 3), units[level])
37 |
38 | def inquiry(symbol):
39 | binfo = kline(symbol)
40 | print(binfo)
41 | if 'data' in binfo and binfo['data'] != []:
42 | id,open,close,high,low,vol,amount = binfo['data'][0]
43 | b,t,count,open,close = '抹茶',8,-1,float(open),float(close)
44 | elif isinstance(binfo,dict):
45 | id,open,close,low,high,vol,amount,count = binfo.values()
46 | b,t = '火币',0
47 | elif isinstance(binfo,list):
48 | id,open,high,low,close,vol,x1,amount,count,x2,x3,x4 = binfo
49 | b,t,open,close = '币安',8,float(open),float(close)
50 | else:
51 | return binfo
52 | #return '火币、币安找不到该币种'
53 | quote = round((close - open)/open * 100,2)
54 | return f"今日【{b}】报价\n价格:{close}u\n涨幅:{quote}%\n开盘:{open}u\n最高:{high}u\n最低:{low}u\n成交量:{str_of_num(vol)}\n成交额:{str_of_num(amount)}u\n交易笔数:{str_of_num(count)}\n----------\n以每日{t}时为基准开始计算"
55 |
56 | @itchat.msg_register(itchat.content.TEXT, isGroupChat=True)
57 | def group_reply(msg):
58 | symbol = msg.text.strip()
59 | #print(symbol)
60 | if symbol.encode('UTF-8').isalpha() and len(symbol) < 10:
61 | output = inquiry(symbol.lower())
62 | if output != 'error':
63 | return f"【{symbol.upper()}】{output}"
64 |
65 | elif msg.actualNickName == '你的微信昵称' and msg.text == "查收益":
66 | stdout = os.popen("/opt/money.py").read()
67 | path = stdout.split('img_path:')[-1]
68 | print(stdout)
69 | itchat.send_image(path.strip(),toUserName=msg.FromUserName)
70 | #return "@"+msg.actualNickName+" 已接收消息:"+msg.text
71 |
72 | @itchat.msg_register(itchat.content.TEXT, isFriendChat=True)
73 | def friend_reply(msg):
74 | if msg.text == "查收益":
75 | stdout = os.popen("/opt/containerd/bin/b/money.py").read()
76 | path = stdout.split('img_path:')[-1]
77 | print(stdout)
78 | itchat.send_image(path.strip(),toUserName=msg.FromUserName)
79 | #return "@"+msg.actualNickName+" 已接收消息:"+msg.text
80 |
81 | def send_job():
82 | stdout = os.popen("/opt/containerd/bin/b/money.py").read()
83 | path = stdout.split('img_path:')[-1]
84 | print(stdout)
85 | itchat.send_image(path.strip(),toUserName='@@群ID')
86 | def start_job():
87 | sched = BlockingScheduler()
88 | sched.add_job(send_job, 'interval', seconds=120)
89 | sched.start()
90 | itchat.auto_login(hotReload=True,enableCmdQR=2)#登入
91 | thread = threading.Thread(target=start_job)
92 | thread.start()
93 | itchat.run()
94 |
--------------------------------------------------------------------------------
/ws-test/.gevent.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python2
2 | import sys
3 | port = int(sys.argv[1])
4 | from gevent import monkey; monkey.patch_all()
5 | from ws4py.websocket import EchoWebSocket
6 | from ws4py.server.geventserver import WSGIServer
7 | from ws4py.server.wsgiutils import WebSocketWSGIApplication
8 | import logging
9 | from ws4py import configure_logger
10 | try:
11 |
12 | logger = logging.getLogger('ws4py')
13 | configure_logger(level=10)
14 | server = WSGIServer(('0.0.0.0', port), WebSocketWSGIApplication(handler_cls=EchoWebSocket))
15 | print("=====START 0.0.0.0:{}=====".format(port))
16 | server.serve_forever()
17 | except KeyboardInterrupt:
18 | print ("=====STOP 0.0.0.0:{}=====".format(port))
19 |
--------------------------------------------------------------------------------
/ws-test/README.md:
--------------------------------------------------------------------------------
1 | # ws-test
2 | ## ws服务端连接测试
3 | #### `iws.sh`为一键安装ws服务端脚本,运行后,输入端口号即可监听(已存在的端口会被杀掉)。
4 | #### `wsc.py`为ws客户端,运行后会发送message到服务端,客户端能看服务器会不停的返回当前时间,服务端能看到请求的连接信息。
5 |
6 | ```
7 | # example
8 |
9 | wsc.py wss://xxx.com:999
10 | wsc.py ws://xxx.com:777
11 | ```
12 |
--------------------------------------------------------------------------------
/ws-test/iws.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | read -p "=====INPUT SERVER PORT:" port
3 | pid=`netstat -nlpt|grep $port|awk '{print $NF}'|awk -F / '{print $1}'`
4 | kill -9 $pid
5 | if [ ! -f "/usr/bin/pip2" ];then
6 | yum install epel-release -y --disablerepo=* --enablerepo=extras
7 | yum install python2-pip -y --disablerepo=* --enablerepo=epel
8 | fi
9 | pip2 install ws4py
10 | cat > /usr/bin/ws-server.py <