`Python`标签下的文章

编程

django服务器从linux迁移到windows

教研室接了一个检察院的项目

老实说,这个项目坑爆了

一开始说可以提供一个全新的服务器,系统也是我们来定,于是,嫌弃windows的我在Linux上面很熟练的搭建起服务器来

直到…

有一天,他们的技术人员告诉我 “由于经费紧张,咱们就不能买新的服务器了,以前的服务器你想要什么系统都可以”

于是报了三个Windows Server的版本给我…

好吧,反正我也没的选,那就先看看改到windows上面有哪些改变吧?

Context 那边的服务器由于安全问题,是不允许接入外网的

所以PIP都不能用了,所以先把需要的包给下了吧,什么Django,Arrow,Python-DateUtil……

windows上面没有uwsgi,那就用FastCGI吧

想得美,我才不为了你单独去搞FastCGI呢,Django跑跑就够了!!

Nginx还是要的,不然我还得在django里面写下载接口,好在Nginx是有Windows版的 good job

等下

Windows 没有自带 Python ~~

为了保险起见,把32位的和64位的都下载下来

Context 他们是不允许使用优盘的,所以一切的一切,都只能使用刻录的光盘…

OK,前面基本都是废话,简单说,就是在Windows上面装环境啦…

代码改动?

嗯,上传文件接口,Django的Media_Root需要改个位置,当然Nginx的下载地址要改个位置,还有之前使用uwsgi的,现在得换成Django

windows的nginx貌似是不会自动选择conf/nginx.cfg,所以启动的时候还得手动写

nginx.exe -c conf/nginx.cfg

本来是用uwsgi的,那现在就直接Django启动到指定端口

python manage.pyc runserver 9999

哦哦哦,pyc文件的生成方法也很重要,毕竟这个项目xxxx,所以我还是选择不提供源代码给他们.

那就得编译一下再给他们

python -m py_compile manage.py

以此类推,把他们都编程编译过的文件

注意

linux下一个路径是
xxx/xxx/xxx

windows下一个路径是

X:\xxx\xxx

你以为修改django代码的时候就应该把

xxx/xxx/xxx 改成 X:\xxx\xxx

其实…还是

X:/xxx/xxx

本来打算写一个shell来自动安装的,现在看来,只能写成bat文件了~

由于msi的安装不会用bat来做,所以还是手动安装一下比较好

@echo "Start Unzip python packages"
Unzip Django-1.9.9.zip -d C:\
Unzip python-dateutil-patches-for-1.5 -d C:\
Unzip arrow-master -d C:\
@echo "Install Nginx"
Unzip nginx-1.11.3 -d C:\
@echo "install python packages"
python C:\Django-1.9.9\setup.py install
python C:\python-dateutil-patches-for-1.5\setup.py install
python C:\arrow-master\setup.py install
@echo "Copy Nginx configure file"
copy nginx.cfg C:\nginx-1.11.3\conf\nginx.cfg
@echo "build download folder"
md "C:\file"

在启动之前添加一些用户,然后就能启动了.

windows server还是适合使用windows自己的服务器~ASP.net

阅读剩下更多

编程

Python 处理字节流

python处理字节的点点滴滴

python有多爽,我就不说了,反正想得到的事情,基本都有办法用python来解决,当然还有一个很重要的优点: 写python不用编译~

Context

  1. 之前毕业设计做的是SMS4的实现与安全性分析.安全性分析是什么鬼?查了查书,好像是用有特征的原文来进行测试……,具体的我也忘记了.当时就琢磨,怎么样可以做一个酷炫的安全性分析呢?
  2. 公司的新产品是一款智能硬件,它会通过TCP给服务器发送指令(当然不是熟悉的HTTP请求,是传说中的字节流)

Requirement

  1. commands+re : 这个组合可以轻轻松松的提取出命令行程序的有用信息
  2. binascii : 这个东西可以轻松的产生各种各样和二进制有关或者和ascii有关的字符串
  3. struct : 超级牛逼的解包模块,瞬间把一个字节流解成元组

OK, Let’s go

commands+re

commands.output(cmd),cmd是shell命令我也不知道windows的命令可以不可以~~
这一条可以把运行结果返回出来(字符串形式)

然后用re来做正则匹配,再搭配一些split(),replace()之类的操作字符串的函数,就可以提取出一个命令行程序中有用的信息了.

binascii

binascii.b2a_hex(data)
binascii.hexlify(data)

data就是原始字符串,假设就是”abcde”
返回的也是字符串,不过是16进制的字符串”6162636465”

binascii.a2b_hex(hexstr)
binascii.unhexlify(hexstr)

这个函数就是反过来的
‘hexstr’是16进制的字符串,假定说是”6162636465”
返回的字符串就是他们所对应的ascii的字符,就是”abcde”

这有啥用嘞?

做测试!

让下位机发送一条指令可能还蛮复杂的,或者蛮浪费资源什么的,这样调试服务器代价会比较大.使用binascii来制作测试数据再好不过了.

假设下位机发送的数据是”0xaa,0xbb,0xcc,0x12,0x34,0xdd,0xee,0xff”

我们就可以模拟一条

a="aabbcc1234ddeeff"
b=asciibin.a2b_hex(a)

b就是模拟了服务器收到socket字节流.真方便

struct

收到字节流,根据协议,得知其中的8个字节是double,4个字节是float.

嗯,字节转整形还是有办法的,那么转成浮点型应该怎么转呢??

import struct吧

将python数据封装成字节流

struct.pack(format,argvs...)

将字节流解析成python数据类型

struct.unpack(format,string)

format很有意思,简单说就是解析规则.

比如解析成float,就写’f’

解析成double,就写成’d’

那么一个数据流里面既有float又有double怎么办呢?

嗯,截取字符串嘛!

struct.unpack('f',s1[0:4])
struct.unpack('d',s1[4:12])

哈哈,我一开始也是这样写的,后面章鱼兄跟我说,format里面可以写很多东西

struct.unpack('fd',s1)

这个会直接返回(r1,r2),其中r1就是那个float,r2就是那个double

真的好方便

附表一张

format 类型
f float
d double
c char
i int
l long
3s 长度为3的字符串
4s 长度为4的字符串
5s 长度为5的字符串

至于struct.pack()嘛,既然format都有了,那么应该不难理解了,在python里面试一试就明白了

阅读剩下更多

编程

微信服务号的消息处理

新产品会和微信公众号有交互,所以就来尝尝鲜,做一做微信公众号的各种东西.

首先:注册,认证,bla bla bla,设置一堆东西

在获得了开发权限之后,就可以仔细阅读开发文档了.

和微信的交互有两种:

  1. 服务器给微信发送消息
  2. 微信给服务器发送消息

说说他们的区别.

服务器给微信发消息,很方便,发表单格式的就行了,微信回复的是json格式的

微信服务器主动给服务器发消息,就很恶心了.

  1. 如果在配置页面设置了消息模式是加密的,那么收到了微信的消息之后需要先对包进行解密,才能得知微信发送的消息的确切内容.
  2. 微信的每次请求,都需要按照和它一样的变态格式回复.
  3. 还得验证验证消息到底是不是微信发的~

先来看看微信给服务器发的是什么样子的东西

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[this is a test]]></Content>
 <MsgId>1234567890123456</MsgId>
 </xml>

哦,这个是没加密的,加密的更难看…

应该用正则来提取内容吧,我把他们都写了出来,方便方便

REGEX_TOUSERNAME = r'\<ToUserName\>\<\!\[CDATA\[(.*)\]\]\>\<\/ToUserName\>'
REGEX_FROMUSERNAME = r'\<FromUserName\>\<\!\[CDATA\[(.*)\]\]\>\<\/FromUserName\>'
REGEX_MSGTYPE = r'\<MsgType\>\<\!\[CDATA\[(.*)\]\]\>\<\/MsgType\>'
REGEX_EVENT = r'\<Event\>\<\!\[CDATA\[(.*)\]\]\>\<\/Event\>'
REGEX_EVENT_KEY = r'\<EventKey\>\<\!\[CDATA\[(.*)\]\]\>\<\/EventKey\>'
REGEX_SCANTYPE = r'\<ScanType\>\<\!\[CDATA\[(.*)\]\]\>\<\/ScanType\>'
REGEX_SCANRESULT = r'\<ScanResult\>\<\!\[CDATA\[(.*)\]\]\>\<\/ScanResult\>'
REGEX_CREATETIME = r'\<CreateTime\>(.*)\<\/CreateTime\>'
REGEX_CONTENT = r'\<Content\>\<\!\[CDATA\[(.*)\]\]\>\<\/Content\>'

还傻乎乎的搞了个类来解析这坨东西

class wechat_xml_object(object):
    def __init__(self, xml):
        self.origin = str(xml)

    @property
    def toUserName(self):
        return self.returnValueForKey(REGEX_TOUSERNAME)

    @property
    def fromUserName(self):
        return self.returnValueForKey(REGEX_FROMUSERNAME)

    @property
    def msgType(self):
        return self.returnValueForKey(REGEX_MSGTYPE)

    @property
    def event(self):
        return self.returnValueForKey(REGEX_EVENT)

    @property
    def eventKey(self):
        return self.returnValueForKey(REGEX_EVENT_KEY)

    @property
    def scanType(self):
        return self.returnValueForKey(REGEX_SCANTYPE)

    @property
    def scanResult(self):
        return self.returnValueForKey(REGEX_SCANRESULT)

    @property
    def createTime(self):
        return self.returnValueForKey(REGEX_CREATETIME)

    @property
    def content(self):
        return self.returnValueForKey(REGEX_CONTENT)

    def returnValueForKey(self, regex):
        match = re.search(regex,self.origin)
        if match:
            return match.group(1)
        else:
            return None

虽然我知道有kissXML这种神器,但是我得装……

上面是把明文的XML解包出来,现在我们把想回复的数据给封装起来

class wechat_xml_builder(object):
    def __init__(self, data_type):
        self.type = data_type
        self.content = ''
        self.contains = []

    def addObject(self, key, value, data_mark):
        if key in self.contains:
            return False
        if data_mark:
            self.content += '<{0}><![CDATA[{1}]]></{2}>'.format(key, value, key)
        else:
            self.content += '<{0}>{1}</{2}>'.format(key, value, key)
        self.contains.append(key)
        return True

    def add_default_from(self, dictionary):
        fromUser = dictionary['toUser']
        openid = dictionary['openid']
        createTime = dictionary['createTime']
        self.addObject('ToUserName', openid, True)
        self.addObject('FromUserName', fromUser, True)
        self.addObject('CreateTime', createTime, False)

    def exportString(self):
        return '<xml>' + self.content + '</xml>'

我感觉这个类用起来还是蛮简单的.

至于说加密和解密,微信还是很良心的提供了一个库,可以直接操作.

下次再整理一下微信开发中其他的坑儿吧

阅读剩下更多

返回顶部