现在开发环境原来越复杂,为了方便开发,让团队每个人的环境一致,最近使用docker进行打包image,发放给团队使用。

安装docker

本人使用mac,直接下载docker for mac 方便很多,其他os网上一搜一大把。so easy~!

下载images

1
2
3
4
5
6
[docker@docker-root ~]$ sudo docker pull alpine
[docker@docker-root ~]$ sudo docker pull ubuntu
[docker@docker-root ~]$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
alpine latest 3e467a6273a3 2 days ago 4.793 MB
ubuntu latest 17b6a9e179d7 5 days ago 120.7 MB

启动

1
docker run -ti -h dev --net=host -v ~/workspace/sohu:/root/workspace -w /root develop:base /bin/bash

把本地目录 ~/workspace/sohu 映射到容器 /root/workspace 目录

自定义images

先更新下源,安装几个必备工具

1
2
apt-get update
apt-get install vim curl git wget

修改阿里云源

修改成阿里云源,加快安装软件的速度

1
2
3
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak #备份
sudo vim /etc/apt/sources.list #修改
sudo apt-get update #更新列表

阿里云源

1
2
3
4
5
6
7
8
9
10
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse

python开发环境

安装工具和必备依赖

1
2
3
4
5
6
7
apt-get install gcc gdb binutils make git dstat sysstat htop curl wget
apt-get install libjpeg-dev
apt-get install net-tools
apt-get install libffi-dev
apt-get install bzip2
apt-get install libssl
apt-get install libssl-dev

如需要sqlit支持需要先装如下库,再安装python:

1
sudo apt-get install sqlite3 libsqlite3-dev

pyenv 安装

1
$ curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash

在 ~/.bashrc 中添加

1
2
3
export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

查看可安装的版本

1
$ pyenv install --list

安装指定版本

1
$ pyenv install 3.5.2 -v

更新数据库

1
$ pyenv rehash

查看当前已安装的python版本

1
2
3
4
$ pyenv versions 
* system (set by /Users/ce/workspace/sohu/.python-version)
3.5.1
sohu351

设置全局的python版本

1
2
3
4
$ pyenv global 3.5.1
$ pyenv versions
system
* 3.5.1 (set by /Users/ce/workspace/sohu/.python-version)

安装virtualenv

1
2
$ pyenv global system  切换到系统python
$ pip install virtualenv

安装virtualenvwrapper

安装 virtualenvwrapper 并让pyenv支持

1
2
$ pip install virtualenvwrapper
$ git clone https://github.com/yyuu/pyenv-virtualenvwrapper.git ~/.pyenv/plugins/pyenv-virtualenvwrapper

使用python3.5创建一个虚拟环境

1
2
3
$ pyenv global 3.5.2
$ mkvirtualenv env2
$ workon env2

Go开发环境

编译go1.3需要的参数

1
CGO_ENABLED=0 ./make.bash

ToDo……

image 字符集修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ export LANG="en_US.UTF-8"

$ sudo locale-gen "en_US.UTF-8"
Generating locales...
en_US.UTF-8... done
Generation complete.

$ sudo dpkg-reconfigure locales
Generating locales...
en_US.UTF-8... up-to-date
Generation complete.

$ locale charmap
UTF-8

syslog

如果使用syslog,需要在启动的时候做一次目录映射

1
-v /dev/log:/dev/log

保存images

1
2
3
$ docker ps                                                                                                              [17:06:10]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
111be6691cc8 c5940ba1089c "/bin/bash" 4 days ago Up 9 hours dev

把 image 中 c5940ba1089c 这个字段记住

1
docker commit c5940ba1089c develop:base  #进行保存

进行查看

1
2
3
4
5
6
 $ docker images                                                                                                          
REPOSITORY TAG IMAGE ID CREATED SIZE
develop base 5a893de95205 40 hours ago 1.87 GB
ubuntu latest 42118e3df429 9 weeks ago 124.8 MB
alpine latest 4e38e38c8ce0 3 months ago 4.799 MB
hello-world latest 690ed74de00f 11 months ago 960 B

私有仓库

查看如下文章 :

创建私有仓库

操作系统:mac OSX 10.11 或 Ubuntu 16.04
编辑器: vim、 sublime、PyCharm

python环境

版本: python3.5.1

安装工具

1. pyenv

安装 pyenv

linux:

1
2
3
4
5
$ git clone git://github.com/yyuu/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"'>> ~/.bashrc # 指明环境变量
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"'>> ~/.bashrc
$ echo 'eval"$(pyenv init -)"' >> ~/.bashrc # 开启shims and autocompletion
$ exec $SHELL -l # 重新启动shell让其生效

mac:

1
2
3
4
$ brew update
$ brew install pyenv //安装
$ brew upgrade pyenv //升级
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile //只需要执行一次即可

查看可安装的版本

1
$ pyenv install --list

安装指定版本

1
$ pyenv install 3.5.1 -v

更新数据库

1
$ pyenv rehash

查看当前已安装的python版本

1
2
3
4
$ pyenv versions 
* system (set by /Users/ce/workspace/sohu/.python-version)
3.5.1
sohu351

设置全局的python版本

1
2
3
4
$ pyenv global 3.5.1
$ pyenv versions
system
* 3.5.1 (set by /Users/ce/workspace/sohu/.python-version)

2. virtualenvwrapper

linux

1
2
$ pip install virtualenvwrapper
$ git clone https://github.com/yyuu/pyenv-virtualenvwrapper.git ~/.pyenv/plugins/pyenv-virtualenvwrapper

mac

1
2
$ pip install virtualenvwrapper
$ brew install pyenv-virtualenvwrapper

使用python3.5创建一个虚拟环境

1
2
$ mkvirtualenv env2 -p $(which python3.5)
$ workon env2

direnv

安装

1
2
3
git clone https://github.com/direnv/direnv
cd direnv
make install

配置

设置全局配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use_venv () {
export VIRTUAL_ENV = "${HOME} /.virtualenvs/${1}"
PATH_add "$VIRTUAL_ENV/bin"
}

use_vwrapper () {
source /usr/local/bin/virtualenvwrapper.sh
}

use_python() {
local python_root=$HOME/.pyenv/versions/$1
load_prefix "$python_root"
layout_python "$python_root/bin/python"
}

在项目中创建.envrc文件

1
2
3
layout python
use vwrapper
workon env2

mac快速生成干净的linux开发环境

virtualbox -> vagrant/completed -> docker-root -> docker -> … ubuntu/alpine

安装vagrant 或者去官方下载

1
2
3
4
5
brew tap caskroom/cask #if not already installed
brew install brew-cask #if not already installed
brew cask install vagrant
brew tap homebrew/completions
brew install vagrant-completion

docker-root

1
2
3
4
$ git clone https://github.com/ailispaw/docker-root
$ cd docker-root
$ make vagrant
$ make

vagrant配置文件

1
2
3
4
5
6
7
8
9
$ vagrant init
$ vim Vagrantfile
config.vm.box = "ailispaw/docker-root"
config.vm.network "forwarded_port", guest: 9999, host: 1234
config.vm.synced_folder "/Users/ce/workspace/docker/data", "/home/docker/data"
config.vm.provider "virtualbox" do |vb|
vb.memory = "512"
vb.cpus = "4"
end

启动并ssh

1
vagrant up && vagrant ssh

docker

1
2
3
4
5
6
[docker@docker-root ~]$ sudo docker pull alpine
[docker@docker-root ~]$ sudo docker pull ubuntu
[docker@docker-root ~]$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
alpine latest 3e467a6273a3 2 days ago 4.793 MB
ubuntu latest 17b6a9e179d7 5 days ago 120.7 MB

容器

1
docker create -ti -h teach --name teach -v /home/docker/data:/root/data -w /root ubuntu /bin/bash

查看所有容器

1
docker ps -a -q

删除容器

1
docker rm container_id
1
docker attach

安装必备工具

1
sudo apt-get install gcc gdb binutils make git dstat sysstat htop curl wget readelf objdump pidstat

前段时间写私信项目,这种即时消息的系统肯定是存毫秒数的。本地环境是django1.8+mysql5.6一直这么开发屡试不爽,不料到测试线上环境的时候出现了问题。

我们的线上环境数据库竟然是MariaDB10.0.16,存入datetime类型竟然惊奇的把毫秒数去掉了。由于MariaDB和mysql同出一辙我决定深入虎穴一查究竟。

本地环境没问题那就先从本地的mysql表结构看起:

这么一看为啥大问题,接着去线上数据库看看:

神奇的事情出现了datetime竟然没有长度,一顿跟DBA部门交涉最后对方似乎听懂了我的问题,然后直接就把长度6给我加上了。我一顿流汗啊,就不能给我升级下版本?这里我要说明一下mysql从5.6以后就支持了datetime存毫秒数,MariaDB也在10.1.0以后的版本进行了支持,所以我这种抱怨也是对的,无奈跨部门沟通比较困难别人给你改了长度你就用呗。

接着我就做了测试竟然发现还是存不了毫秒,但是惊奇的发现毫秒的位数都是用0补全的,举个例子:

1
2
2015-09-10 13:56:01.542410  # 我想要的数据
2015-09-10 13:56:01.000000 # 现实的数据

现实就是这么残酷,我打开了django DEBUG模式,看到sql中的毫秒数本来就没有,那我在线上数据库使用sql带着毫秒数写入一条数据测试了一下,惊奇的发现竟然可以保存毫秒数,那意思就是说线上的数据库经过对dateime长度的修改其实是可以存毫秒数的,只是现在django不知道怎么处理的竟然没有存入。本着对自己负责任的心里,我决定看下django源码了解他是如何实现的:

1
2
3
4
5
6
@cached_property
def data_types(self):
if self.features.supports_microsecond_precision:
return dict(self._data_types, DateTimeField='datetime(6)', TimeField='time(6)')
else:
return self._data_types

这段代码我看到了让人欣喜的datetime(6)这么说只要是self.features.supports_microsecond_precisionTrue那么就会支持毫秒数,那我们接着往下看找到这个方法

1
2
3
4
5
@cached_property
def supports_microsecond_precision(self):
# See https://github.com/farcepest/MySQLdb1/issues/24 for the reason
# about requiring MySQLdb 1.2.5
return self.connection.mysql_version >= (5, 6, 4) and Database.version_info >= (1, 2, 5)

从段代码就能看出来了,丫判断了mysq版本是不是大于5.6.4且Database(import MySQLdb as Database 其实就是连接驱动)大于1.2.5如果都大于那就支持,不大于就不支持很阴险啊,因为我们线上MariaDB10.0.16其实跟mysql5.5左右的版本是对应的所以肯定不支持啊。那就得想个比较淫荡的方便,所以在线上配置文件中加入如下代码:

1
2
from django.db.backends.mysql.base import DatabaseFeatures
DatabaseFeatures.supports_microsecond_precision = True

这样强制让等于True就会支持毫秒。搞定,收工!


说起celery搞python的程序员并不陌生,一般做队列任务之类的总是会用到。最近公司新项目用到类似队列的场景但是还要求定时完成,所以一下想到了celery马上搞起来。

看了资料做了需求分析,celery本身能完成队列和异步任务的功能,也有crontab但是如果做复杂的定时任务并不好控制,相对复杂。django-celery里面的定时任务功能可以通过后台控制,通过封装好的models也可以进行修改非常好。正好我们项目就是用的django所以直接django搞起来

安装

安装不用多说直接pip就搞定, the我们使用的是github上的development版本,与相依赖的是celery==3.1.18

1
2
pip install git+https://github.com/celery/django-celery.git
pip install celery==3.1.18 # 如果出现依赖问题那就安装

django设置

在settings.py中配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import djcelery
djcelery.setup_loader()
# BROKER_URL = 'django://' # 直接使用django做broker生产环境不建议,建议使用redis或者rabbitMQ
BROKER_URL = 'redis://:auth@127.0.0.1:22222/0' # broker使用reids
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler' # 定时任务
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
CELERY_ENABLE_UTC = False # 不是用UTC
CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_TASK_RESULT_EXPIRES = 10 #任务结果的时效时间
CELERYD_LOG_FILE = BASE_DIR + "/logs/celery/celery.log" # log路径
CELERYBEAT_LOG_FILE = BASE_DIR + "/logs/celery/beat.log" # beat log路径
CELERY_ACCEPT_CONTENT = ['pickle', 'json', 'msgpack', 'yaml'] # 允许的格式

...
INSTALLED_APPS = (
...
'djcelery',
'kombu.transport.django',
...
)

第一二项是必须的,
在INSTALLED_APPS中添加的djcelery是必须的. kombu.transport.django则是基于Django的broker,如果使用redis就不需要了。

最后创建Celery所需的数据表(django1.8):

1
python manage.py migrate

创建一个task

正如前面所说的, 一个task就是一个Pyhton function. 但Celery需要知道这一function是task, 因此我们可以使用celery自带的装饰器decorator: @task. 在django app目录中创建taske.py:

1
2
3
4
5
from celery import task

@task()
def add(x, y):
return x + y

当settings.py中的djcelery.setup_loader()运行时, Celery便会查看所有INSTALLED_APPS中app目录中的tasks.py文件, 找到标记为task的function, 并将它们注册为celery task.

将function标注为task并不会妨碍他们的正常执行. 你还是可以像平时那样调用它: z = add(1, 2).

执行task

让我们以一个简单的例子作为开始. 例如我们希望在用户发出request后异步执行该task, 马上返回response, 从而不阻塞该request, 使用户有一个流畅的访问过程. 那么, 我们可以使用.delay, 例如在在views.py的一个view中:

1
2
3
4
from myapp.tasks import add
...
add.delay(2, 2)
...

Celery会将task加入到queue中, 并马上返回. 而在一旁待命的worker看到该task后, 便会按照设定执行它, 并将他从queue中移除. 而worker则会执行以下代码:

1
2
3
import myapp.tasks.add

myapp.tasks.add(2, 2)

启动

启动worker

正如之前说到的, 我们需要worker来执行task. 以下是在开发环境中的如何启动worker:

首先启动terminal, 如同开发django项目一样, 激活virtualenv, 切换到django项目目录. 然后启动django自带web服务器: python manage.py runserver.

然后启动worker:

1
python manage.py celery worker --loglevel=info

此时, worker将会在该terminal中运行, 并显示输出结果.

启动task

打开新的terminal, 激活virtualenv, 并切换到django项目目录:

$ python manage.py shell
>>> from myapp.tasks import add
>>> add.delay(2, 2)

此时, 你可以在worker窗口中看到worker执行该task:

1
2
[2014-10-07 08:47:08,076: INFO/MainProcess] Got task from broker: myapp.tasks.add[e080e047-b2a2-43a7-af74-d7d9d98b02fc]
[2014-10-07 08:47:08,299: INFO/MainProcess] Task myapp.tasks.add[e080e047-b2a2-43a7-af74-d7d9d98b02fc] succeeded in 0.183349132538s: 4

定时任务

好了,简单的任务我们已经调通,下面我们还是来看定时任务怎么弄。
首先新建一个文件task.py(名字可以随便取)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import datetime
import json
from djcelery import models as celery_models
from django.utils import timezone

def create_task(name, task, task_args, crontab_time):
'''
创建任务
name # 任务名字
task # 执行的任务 "myapp.tasks.add"
task_args # 任务参数 {"x":1, "Y":1}
crontab_time # 定时任务时间 格式:
{
'month_of_year': 9 # 月份
'day_of_month': 5 # 日期
'hour': 01 # 小时
'minute':05 # 分钟
}

'''

# task任务, created是否定时创建
task, created = celery_models.PeriodicTask.objects.get_or_create(
name=name,
task=task)
# 获取 crontab
crontab = celery_models.CrontabSchedule.objects.filter(
**crontab_time).first()
if crontab is None:
# 如果没有就创建,有的话就继续复用之前的crontab
crontab = celery_models.CrontabSchedule.objects.create(
**crontab_time)
task.crontab = crontab # 设置crontab
task.enabled = True # 开启task
task.kwargs = json.dumps(task_args) # 传入task参数
expiration = timezone.now() + datetime.timedelta(day=1)
task.expires = expiration # 设置任务过期时间为现在时间的一天以后
task.save()
return True


def disable_task(name):
'''
关闭任务
'''

try:
task = celery_models.PeriodicTask.objects.get(name=name)
task.enabled = False # 设置关闭
task.save()
return True
except celery_models.PeriodicTask.DoesNotExist:
return True

启动beat

执行定时任务时, Celery会通过celerybeat进程来完成. Celerybeat会保持运行, 一旦到了某一定时任务需要执行时, Celerybeat便将其加入到queue中. 不像worker进程, Celerybeat只有需要一个即可.

启动:

1
python manage.py celery beat --loglevel=info

其实还有一种简单的启动方式worker和beat一起启动:

1
python manage.py celery worker --loglevel=info --beat

将定期任务储存在django数据库中. 即是在django和celery都运行的状态, 这一方式也可以让我们方便的修改定时任务. 我们只需要设置settings.py中的一项便能开启这一方式:

1
2
# settings.py
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'

然后我们便可以通过django admin的/admin/djcelery/periodictask/添加定期任务了.
也可以直接使用刚才我写的脚本在自己的代码逻辑中自己增加和禁用定时任务

定时删除

可能大家用了一段时间就会想到,很多任务都是一次执行完就不需要,留在数据库里就是垃圾数据了有没有办法清除。方法肯定有因为django-celery本身就有定时任务功能我们加个任务就解决了。好我们看代码:
在django app目录中打开taske.py加入如下代码

1
2
3
4
5
6
7
8
9
10
11
from djcelery import models as celery_models
from django.utils import timezone

@task()
def delete():
'''
删除任务
从models中过滤出过期时间小于现在的时间然后删除
'''

return celery_models.PeriodicTask.objects.filter(
expires__lt=timezone.now()).delete()

大家都记得创建任务脚本里设置了 expires 1天以后过期,这样在filter的时候就能当做条件把过期的任务找到并且删除。

然后我们在django-admin中把这个任务加到定时任务中:

名字为del,任务是myapp.taks.delete,定时为每天的5点执行(crontab的格式,不熟悉的大家可以搜索学习下linux crontab格式)

参考

http://www.weiguda.com/blog/73/
http://my.oschina.net/kinegratii/blog/292395#OSC_h2_10

最近项目中总是跟java配合,我一个写python的程序员,面对有复杂数据结构的java代码转换成python代码,确实是一大难题,有时候或多或少会留有一点坑,看来有空还得看看java基础。这不今天又开始让我们连接kafka啦。公司的kafka跟zookeeper做了群集,连接比较麻烦,具体如何使用,java那面做的封装我也看不到,所以只能通过简单的沟通。

开始

开始肯定去找python连接kafka的标准库,kafka-pythonpykafka 前者使用的人多是比较成熟的库,后者是Samsa的升级版本,在网上到文章在python连接并使用kafka 使用samsa连接zookeeper然后使用kafka Cluster很能满足我的需求,在pykafka的例子中也看到了zk的支持,而kafka-python并没有zk的支持,所以选择了pykafka做为连接库

概念问题

kafaka和zookeeper的群集,使用samsa的时候生产者和消费者都连接了zookeeper,但是我跟峰云(大数据大牛,运维屌丝逆转)沟通,他们使用的时候是生产者直接连接kafaka服务器列表,消费者才用zookeeper。这也解决了我看pykafka文档,只有消费者才连接zookeeper的困惑,所以问题解决,直接按照文档搞起。

生产者

1
2
3
4
5
6
>>> from pykafka import KafkaClient
>>> client = KafkaClient(hosts="192.168.1.1:9092, 192.168.1.2:9092") # 可接受多个Client这是重点
>>> client.topics # 查看所有topic
>>> topic = client.topics['my.test'] # 选择一个topic
>>> producer = topic.get_producer()
>>> producer.produce(['test message ' + str(i ** 2) for i in range(4)]) # 加了个str官方的例子py2.7跑不过

消费者

1
2
3
4
5
>>> balanced_consumer = topic.get_balanced_consumer(
consumer_group='testgroup',
auto_commit_enable=True, # 设置为Flase的时候不需要添加 consumer_group
zookeeper_connect='myZkClusterNode1.com:2181,myZkClusterNode2.com:2181/myZkChroot' # 这里就是连接多个zk
)

1
2
3
4
5
6
7
def _chk_ipaddr(ipaddr):
IP_PATTERN = '^((0|[1-9]\d?|[0-1]\d{2}|2[0-4]\d|25[0-5])\.){3}(0|[1-9]\d?|[0-1]\d{2}|2[0-4]\d|25[0-5])$'
if not ipaddr:
return False

ipcheck = re.compile(IP_PATTERN, re.I)
return True if ipcheck.match(ipaddr) else False

最近公司业务上涨,报警频频发生,刚买的短信接口已经用一半了,这么下去肯定不是办法。现在都是移动互联网时代了,肯定得想点新办法,看着手机我想起了微信,这货要是能实现报警,问题不就解决了么?

我抱着试一试的态度,在网上查找了一下,结果病就治好了…… 呃…… 电视广告看多了。 在网上查到了微信实现报警的方案,以我的理解分两种:

1.公众号,公众号使用模板信息可以给用户发送10w调每天的信息
2.企业号,给员工无限制的发送信息:

企业号的功能:

企业号适用于企业与员工或上下游供应链之间的沟通。

1、企业可以主动发消息给员工,消息量不受限制。

2、企业号出现在微信会话列表首层,在通讯录中有单独的分类。

3、可以自定义菜单。

4、拥有多个子号。

5、更加关注与安全,需要双方认证。

作为一个强迫症控,那肯定得用企业号啊,这里需要老板的支持,企业号不是自己能申请的,还好我老板高瞻远瞩,已经申请好了。(嘻嘻,希望老板能看到)

对企业号进行配置:

扫描二维码进行登录:https://qy.weixin.qq.com/
登陆

配置企业号

登陆以后新建应用:
创建新应用

输入应用名称为监控报警就新建了一个叫做监控报警的应用,新建完成后,进入【应用中心】查看应用id, 这里后面要用。

设置管理员:

指定应用的管理员。点击设置 -> 权限管理 -> 管理 -> 新建管理组 -> 添加管理员和权限。然后就会获得corpid 和 sceret。这里后面也要用。

开发

1、阅读开发文档。文档位置:微信开发文档

我只读了建立连接、管理通讯录、发送消息。好了,发个报警够了,很简单。

2、建立连接获取access_token。

这个token是一个有有效时间的密钥用于后续操作认证。

Https请求方式: GET

https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=id&corpsecret=secrect

正常情况下就会反馈一个json并得到access_token

根据文档获取玩access_token后就可以发送消息了。

我写的脚本代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env python
# coding:utf-8
import sys
import urllib2
import time
import json
import requests

reload(sys)
sys.setdefaultencoding('utf-8')

title = sys.argv[2] # 位置参数获取title 适用于zabbix
content = sys.argv[3] # 位置参数获取content 适用于zabbix

class Token(object):
# 获取token
def __init__(self, corpid, corpsecret):
self.baseurl = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}'.format(
corpid, corpsecret)
self.expire_time = sys.maxint

def get_token(self):
if self.expire_time > time.time():
request = urllib2.Request(self.baseurl)
response = urllib2.urlopen(request)
ret = response.read().strip()
ret = json.loads(ret)
if 'errcode' in ret.keys():
print >> ret['errmsg'], sys.stderr
sys.exit(1)
self.expire_time = time.time() + ret['expires_in']
self.access_token = ret['access_token']
return self.access_token

def send_msg(title, content):
# 发送消息
corpid = "" # 填写自己应用的
corpsecret = "" # 填写自己应用的
qs_token = Token(corpid=corpid, corpsecret=corpsecret).get_token()
url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={0}".format(
qs_token)
payload = {
"touser": "user1|user2",
"msgtype": "text",
"agentid": "3",
"text": {
"content": "标题:{0}\n 内容:{1}".format(title, content)

},
"safe": "0"
}
ret = requests.post(url, data=json.dumps(payload, ensure_ascii=False))
print ret.json()

if __name__ == '__main__':
# print title, content
send_msg(title, content)

参考文章:

微信公众平台企业号用于监控报警探究(python版本)

最近在研究华为防火墙,要搞个web版的程序来控制防火墙,那底层就需要用telnet或者snmp来控制设置,今天先共享下telnet的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#coding=utf-8
import telnetlib
import re
import time

HOST = '192.168.1.231'
user = 'admin'
password = 'admin'

tn = telnetlib.Telnet(HOST)
# tn.set_debuglevel(2) #开启调试模式

tn.expect([re.compile(b"Username:"),]) #用正则匹配Username
tn.write(user + "\n") #匹配成功,输入user
tn.expect([re.compile(b"Password:"),]) #同上
tn.write(password + "\n") #同上
time.sleep(.1)

tn.read_until("<HWJC.HL-DDoS.SDA>") #如果读到<HWJC.HL-DDoS.SDA>提示符,执行下面命令
tn.write("display clock\n") #输入命令
tn.read_until("display clock") #如果读到"display clock",执行下面命令,这里的操作是在后面获取返回值的时候排除"display clock"这一行数据
time.sleep(.1) #延时以确保下调命令能读到数据
print tn.read_very_eager() #打印执行"display clock"的返回值
# tn.write("quit\n") #退出
# print tn.read_all() #获取全部返回值
tn.close() #关闭连接

在大家看到这门课程的时候,这个视频已经让我传到51cto的学院上了,之前一直用七牛云存储做视频存放,结果超过免费标准,收费了然后给我账号封了,我很无奈所以想找个新的放视频的地方,最好是优酷,结果优酷审核总是很慢,所以我就选择了51cto。但是想观看51cto的这个课程需要花费5金币来购买,5金币也就是5元人民币,这也是我经过深思熟虑的事,一是这样会让我录制视频更有动力,二是大家看起来也会更珍惜。所以还是希望大家多少支持吧。毕竟大家看到我这幻灯片做的都对得起这个价格,哈哈哈……

共享你的代码(二)课程知识点:

  • 新需求
  • 改变API后,兼容老用户
  • 增加参数,满足新老用户

视频地址:请点击 共享你的代码(二)