Openwrt路由器上开发微信公众号应用
利用nohup命令创建启动服务
#!/bin/sh /etc/rc.common
# Example script
# Copyright (C) 2007 OpenWrt.org START=10
STOP=15 start() {
echo "wechat start" >> /mnt/sda1/temp/log
date -R >> /mnt/sda1/temp/log
nohup python -u /mnt/sda1/projects/openwrtpytest/utils/webhelper.py 2>>/mnt/sda1/temp/log 1>>/mnt/sda1/temp/log & # commands to launch application
} stop() {
echo "wechat stop" >> /mnt/sda1/temp/log
date -R >> /mnt/sda1/temp/log
# commands to kill application
注意wechat里面的\r\n要换成linux下的\n,不然会出错
如果重复启动后报错端口被占用,要先把原先的进程杀掉
kill 2626
webhelper.py
from wsgiref.simple_server import make_server
from wechat import app PORT = 8001
httpd = make_server('', PORT, app)
httpd.allow_reuse_address = True
httpd.serve_forever()
wechat.py
#!/mnt/sda1/opkg/usr/bin/python
#coding:utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import time
from flask import Flask, request,make_response,render_template
import hashlib
import xml.etree.ElementTree as ET
import loghelper
import traceback
import requests
import os
import pprint
import uniout
import apihelper
import yaml
import pickledb app = Flask(__name__)
app.debug=True
logger = loghelper.create_logger(r'/mnt/sda1/temp/log')
app_root = os.path.dirname(__file__)
templates_root = os.path.join(app_root, 'templates/reply_text.xml')
api = apihelper.ApiHelper()
cachefpath='../data/cache.db'
cachedb = pickledb.load(cachefpath,True) @app.route('/',methods=['GET','POST'])
def wechat_auth():
msg = "funcname : %s , request.args : %s" % (__name__ ,request.args)
logger.info(msg)
response = make_response("")
try:
if request.method == 'GET':
token='weixintest'
data = request.args
pprint.pprint( "Request get data:",data)
signature = data.get('signature','')
timestamp = data.get('timestamp','')
nonce = data.get('nonce','')
echostr = data.get('echostr','')
s = [timestamp,nonce,token]
s.sort()
s = ''.join(s)
if (hashlib.sha1(s).hexdigest() == signature):
response = make_response(echostr)
else:
response = make_response("Not Valid!")
else:
rec = request.stream.read()
print "Request post data:",rec
xml_rec = ET.fromstring(rec)
datadict = get_replydata(xml_rec)
pprint.pprint(datadict)
render = render_template("reply_text.xml",dict=datadict)
response = make_response(render)
#xml_rep = get_response(xml_rec)
#response = make_response(xml_rep)
response.content_type='application/xml;charset=utf-8'
except Exception,e:
type =xml_rec.find("MsgType").text
tou = xml_rec.find('ToUserName').text
fromu = xml_rec.find('FromUserName').text
datadict = {"to":fromu,"from":tou,"time":str(int(time.time())),"type":type,"msg":e.message}
render = render_template("reply_text.xml",dict=datadict)
response = make_response(render)
# log the exception
err = "exception : %s , %s" % (e.message ,traceback.format_exc())
logger.exception(err)
finally:
#pprint.pprint( request.__dict__)
pprint.pprint( response.__dict__)
return response def get_replydata(xml_rec):
'''
import xml2dict
xml = xml2dict.XML2Dict()
r = xml.fromstring(textdata)
r.get('xml').get('FromUserName').get('value')
'''
type =xml_rec.find("MsgType").text
tou = xml_rec.find('ToUserName').text
fromu = xml_rec.find('FromUserName').text
datadict = {"to":fromu,"from":tou,"time":str(int(time.time())),"type":type,"msg":""}
if type == 'image' or type == 'voice':
dmedia_id = xml_rec.find('MediaId').text
purl = xml_rec.find('PicUrl').text
fname = xml_rec.find('CreateTime').text
import urllib
urllib.urlretrieve(purl,'/mnt/sda1/data/image/%s.jpg' % fname)
print purl
elif type == 'location':
locx = xml_rec.find('Location_X').text
locy = xml_rec.find('Location_Y').text
scale = xml_rec.find('Scale').text
location = xml_rec.find('Label').text
wjdu="%s,%s" % (locx,locy)
data = api.location(wjdu)
datadict["msg"]=data
else:
content = xml_rec.find("Content").text
data = get_replytext(content)
datadict["msg"]=data
print datadict.get("msg")
return datadict def get_replytext(content):
content = content.strip()
print 'enter content :',content
cvalue = cachedb.get(content)
cvalue =None
if cvalue<>None:
print 'get it from cache'
data=cvalue
else:
if content.lower().startswith("ip"):
content=content.replace("ip","").strip()
data = api.ip(content)
elif content.startswith(u"航班"):
data=api.airline(content)
elif content.startswith(u"火车"):
data=api.train(content)
elif content.startswith(u"翻译"):
data=api.translator(content)
elif content.startswith(u"手机"):
data=api.mobile(content)
elif content.startswith(u"简体") or content.startswith(u"繁体"):
data=api.tradition(content)
elif content.startswith(u"汇率"):
data=api.huilv(content)
else:
data = api.weather(content)
cachedb.set(content,data)
return data if __name__ == '__main__':
path='../conf/test.yaml'
with open(path) as f:
x=yaml.load(f)
textdata = x.get('textdata')
wxlink = x.get('wxlink')
r=requests.get(wxlink)
print r.text
r=requests.post(wxlink,textdata)
print r.text
这里实现了查询航班,火车,汇率,中英文翻译,简繁体转换,查询当前IP,手机所在地的功能
https://github.com/sui84/openwrtpytest
另外pandorbox上的python安装文件为了可以运行有些改动,放在这里
Openwrt路由器上开发微信公众号应用的更多相关文章
- 苹果手机上开发微信公众号(wap)遇到的问题解决方法
1.样式 苹果 手机会自行强制css样式,比如input会变得面目全非,你可以加上input{-webkit-appearance: none;}恢复原貌! 2.jquery的live错误,苹果手机上 ...
- NodeJs 开发微信公众号(五)真实环境部署
在测试环境下开发完成代表着你离正式上线的目标不远了.接下来本章就主要谈一谈把测试环境的公众号升级为正式的公众号. 服务器和域名 目前为止我们只是在自己的电脑上完成了测试环境.真实的线上环境当然需要自己 ...
- vue+node.js+webpack开发微信公众号功能填坑——v -for循环
页面整体框架实现,实现小功能,循环出数据,整体代码是上一篇 vue+node.js+webpack开发微信公众号功能填坑--组件按需引入 修改部门代码 app.vue <yd-flexbox&g ...
- vue+node.js+webpack开发微信公众号功能填坑——组件按需引入
初次开发微信公众号,整体框架是经理搭建,小喽喽只是实现部分功能,整体页面效果 整个页面使用两个组件:布局 FlexBox,搜索框 Search,demo文档 http://vue.ydui.org/d ...
- 使用vue开发微信公众号下SPA站点的填坑之旅
原文发表于本人博客,点击进入使用vue开发微信公众号下SPA站点的填坑之旅 本文为我创业过程中,开发项目的填坑之旅.作为一个技术宅男,我的项目是做一个微信公众号,前后端全部自己搞定,不浪费国家一分钱^ ...
- Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装
在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装. ( ...
- Java开发微信公众号(二)---开启开发者模式,接入微信公众平台开发
接入微信公众平台开发,开发者需要按照如下步骤完成: 1.填写服务器配置 2.验证服务器地址的有效性 3.依据接口文档实现业务逻辑 资料准备: 1.一个可以访问的外网,即80的访问端口,因为微信公众号接 ...
- Spring Boot 开发微信公众号后台
Hello 各位小伙伴,松哥今天要和大家聊一个有意思的话题,就是使用 Spring Boot 开发微信公众号后台. 很多小伙伴可能注意到松哥的个人网站(http://www.javaboy.org)前 ...
- vue开发微信公众号--开发准备
由于工作项目的原因,需要使用vue开发微信公众号,但是这种微信公众号更多是将APP套了一个微信的壳子,除了前面的授权和微信有关系以外,其他的都和微信没多大的关系了,特此记录 开发流程 首先需要在电脑上 ...
随机推荐
- 启迪链网通证经济共同体:柏链教育&火聘online推出区块链行业人才“一门式”服务
近日,启迪链网通证经济共同体旗下两个节点成员柏链教育与火聘online,达成节点间的合作,据悉本次合作是采用共同体的生态共建模式,柏链教育与火聘online共享企业端岗位需求的大数据,然后有针对性的开 ...
- AX导出excel设置格式
今天在AX2009里面写一个导出EXCEL,没有模版,这是第一次碰到,之后写完之后发现导出的数据格式不对. 到处取经之后得到一下结果: 定义一个 Com range; SysExcelCells ...
- Relative Sort Array
Relative Sort Array Given two arrays arr1 and arr2, the elements of arr2 are distinct, and all eleme ...
- python模块之openpyxl
这是一个第三方库,可以处理xlsx格式的Excel文件.pip install openpyxl安装.如果使用Aanconda,应该自带了. 读取Excel文件 需要导入相关函数. from open ...
- Flutter Animation AnimatedBuilder
Flutter AnimatedBuilder 创建动画的widget Key key, @required Listenable animation, @required this.builder, ...
- 笔谈OpenGL ES(一)
现在图形类.视频类app越来越多,学习OpenGL ES是很有必要的,作为程序员是有必要做技术积累的.现在做播放器开发的工作,正好也涉及这块,那就好好学一学. CSDN上有套教程不错,OpenGL E ...
- ceph luminous版部署bluestore
简介 与filestore最大的不同是,bluestore可以直接读写磁盘,即对象数据是直接存放在裸设备上的,这样解决了一直被抱怨的数据双份写的问题 Bluestore直接使用一个原始分区来存放cep ...
- elementUI——主题定制
需求: 设计三套主题色+部分图标更换: 实现方式汇总: 1.传统做法,生成多套css主题包,切换link引入路径切换href实现,参考网站:http://jui.org/: <link id=& ...
- Python学习日记(四) 集合和元祖
元祖的特性:是一个只读列表.可以循环.可以切片,修改数据遵循'儿子'不能改但'孙子'可能可以改. iterable:可迭代对象(元祖.列表.字串.集合) 元祖宣告方式: tu = (1,2,3,['a ...
- 自制php操作mysql工具类(DB.class.php)
DB.class.php <?php class DB{ //主机地址 var $host; //用户名 var $username; //密码 var $password; //数据库名 va ...