Openwrt路由器上开发微信公众号应用

Posted 白马酒凉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Openwrt路由器上开发微信公众号应用相关的知识,希望对你有一定的参考价值。

利用nohup命令创建启动服务

[root@PandoraBox:/mnt/sda1/projects/openwrtpytest/utils]#opkg -d usb install /mn
t/sda1/ipk/coreutils_8.16-1_ramips_24kec.ipk
Installing coreutils (8.16-1) to usb...
Configuring coreutils.
[root@PandoraBox:/mnt/sda1/projects/openwrtpytest/utils]#opkg -d usb install /mn
t/sda1/ipk/coreutils-nohup_8.16-1_ramips_24kec.ipk
Installing coreutils-nohup (8.16-1) to usb...
Configuring coreutils-nohup.

后面的&是后台运行
Linux shell中有三种输入输出,分别为标准输入,标准输出,错误输出,分别对应0,1,2

ps命令无法看到nohup的job,用jobs -l
 

用nohup执行python程序时,print无法输出
nohup python test.py > nohup.out 2>&1 &
发现nohup.out中显示不出来python程序中print的东西。
这是因为python的输出有缓冲,导致nohup.out并不能够马上看到输出。
python 有个-u参数,使得python不启用缓冲。
nohup python -u test.py > nohup.out 2>&1 &
 
创建启动服务
/etc/init.d/wechat
#!/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   

  

chmod 777 /etc/init.d/wechat
启动
/etc/init.d/wechat start

注意wechat里面的\\r\\n要换成linux下的\\n,不然会出错

如果重复启动后报错端口被占用,要先把原先的进程杀掉

error: [Errno 125] Address already in use
[root@PandoraBox:/mnt/sda1/projects/openwrtpytest/utils]#netstat -atpn | grep 8001
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8001 0.0.0.0:* LISTEN 2626/python

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,手机所在地的功能
代码放在github上
https://github.com/sui84/openwrtpytest

另外pandorbox上的python安装文件为了可以运行有些改动,放在这里
https://github.com/sui84/PandorboxPython27
 

以上是关于Openwrt路由器上开发微信公众号应用的主要内容,如果未能解决你的问题,请参考以下文章

教你3分钟快速开发微信公众号[订阅号][服务号]

教你3分钟快速开发微信公众号[订阅号][服务号]

C#开发微信门户及应用(26)-公众号微信素材管理

如何使用jsp开发微信公众平台,或者使用java语言开发公众平台

NodeJs 开发微信公众号准备工作

开发微信公众号后台,原来这么简单?[微信公众号开发]