Snake's Home

snake


  • 首頁

  • 歸檔

  • 標籤
Snake's Home

python csv模块介绍

發表於 2014-06-05 | 分類於 python

csv,即逗号分隔值(Comma-Separated Values,CSV),有时也称为字符分割值(因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。

csv是一种很常用也非常简洁方便的对大量数据存储的方式,python里面也有csv模块来对这部分内容进行处理。

1
reader(csvfile[, dialect='excel'][, fmtparam])

参数:

csvfile 需要是支持迭代(Iterator)的对象,并且每次调用next方法的返回值是字符串(string),通常的文件(file)对象,或者列表(list)对象都是适用的,如果是文件对象,打开是需要加”b”标志参数。

dialect 为分隔的风格,默认为excel风格,即逗号分隔。也支持excel-tab风格,即tab分隔。

使用例子:

1
2
3
4
5
import csv

reader = csv.reader(file('my.csv', 'rb'))
for line in reader:
print line

writer:

1
writer = csv.writer(open(targetFile,"wb"),quoting=csv.QUOTE_ALL)

第一个参数表示要写入的文件对象,具体的写入可以通过writerow和writerows函数实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
writer.writerow(["hello","anderson"])
```



```python
__author__ = 'anderson'
import csv
import re

def readcsv(file):

yourtype = raw_input("please choose the type: ")
rule = re.compile(yourtype)

with open (file, 'rb') as readfile:
spamreader = csv.reader(readfile)
for row in spamreader:
for i in range(len(row)):
1
2
3
4
5
6
7
8
9
10
11
12
13
def writecsv(self, data):
with open ('jsonfile.csv', 'a+') as csvfile:
spamwriter = csv.writer(csvfile,dialect='excel')
spamwriter.writerow(data)

def readcsv(self, file):
with open (file, 'rb') as readfile:
spamreader = csv.reader(readfile)
for row in spamreader:
line = row.split(',')
for each_line in line:
if each_line != " ":
print each_line
Snake's Home

自动化抢红包的实践

發表於 2014-04-10 | 分類於 python

最近抢红包火热,基本上是全民抢红包。
大家为了几分钱,或者优惠券,时刻候着那个点,只能说支付宝太精明了。

借鉴了别人的代码,在模拟器上跑起来了。

代码如下:

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
#!/usr/bin/pyton
#encoding=utf-8
import time
import sys

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

print('connect')
device = MonkeyRunner.waitForConnection()

#device.shell('am force-stop com.eztech.kylinlauncher')
device.shell('monkey -p com.eg.android.AlipayGphone -v 1')
print('start')
#device.startActivity(component='com.eg.android.AlipayGphone/com.alipay.android.launcher.TabLauncher')
device.shell('monkey -p com.alipay.android.launcher.TabLauncher -v 1')

w = 720
h = 1280
#raw_input("press Enter then press Ctrl+D to start!")
print('go')
while True:
for wi in xrange(100, w, w/6):
for hi in xrange(100, h, h/11):
device.drag((wi,hi),(765,1244),0.1,10)
#device.touch(wi, hi, MonkeyDevice.DOWN_AND_UP)

没有在真机上实践过。

现在缺点如下:

  1. 只是拖拽,不知道能否实现点击的功能。

  2. 点击速度太慢,模拟器上的缘故。

  3. 没有经过检验。

明天试下。

别人的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# coding: utf-8
# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection()
w = 720
h = 1280
raw_input("按 Enter后再按 Ctrl+D 后开始乱点")
print('go')
while True:
for wi in xrange(100, w, w/6):
for hi in xrange(100, h, h/11):
device.touch(wi, hi, MonkeyDevice.DOWN_AND_UP)
# Takes a screenshot
#result = device.takeSnapshot()
# Writes the screenshot to a file
#result.writeToFile('/tmp/shot1.png','png')

缺点: 很容易点到别的地方。

用monkey来实现

1
adb   shell monkey -p com.eg.android.AlipayGphone -s 500 --pct-touch 100 --ignore-crashes --ignore-timeouts --monitor-native-crashes -v -v 10000 > E:\monkey_log\java_monkey_log.txt

缺点: 完全不受控制。也很容易点到别的地方。

Snake's Home

ReportLab 实践

發表於 2014-03-22 | 分類於 python

python 生成报告, ReportLab 实践,网上找的例子,自己实践了一把。

文档

然后照着文档,例子

写成了一个:

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
from reportlab.graphics.shapes import Drawing  
from reportlab.graphics.charts.barcharts import VerticalBarChart
from urllib import urlopen
from reportlab.graphics.shapes import *
from reportlab.graphics.charts.lineplots import LinePlot
from reportlab.graphics.charts.textlabels import Label
from reportlab.graphics import renderPDF
drawing = Drawing(400, 200)
data = [(13, 5, 20),(14, 6, 21)]
bc = VerticalBarChart()
bc.x = 50
bc.y = 50
bc.height = 125
bc.width = 300
bc.data = data
bc.strokeColor = colors.black
bc.valueAxis.valueMin = 0
bc.valueAxis.valueMax = 50
bc.valueAxis.valueStep = 10
bc.categoryAxis.labels.boxAnchor ='ne'
bc.categoryAxis.labels.dx = 8
bc.categoryAxis.labels.dy = -2
bc.categoryAxis.labels.angle = 30
bc.categoryAxis.categoryNames = ['Jan-99','Feb-99','Mar-99']
drawing.add(bc)

drawing.add(String(250,150,"ss", fontSize=14,fillColor=colors.red))
renderPDF.drawToFile(drawing,'report2.pdf','API')

然后按照

学习了下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python  
import subprocess
import datetime
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
import os
def disk_report():
p = os.popen("df -h")
# print p.stdout.readlines()
return p.readlines()
def create_pdf(input, output="disk_report.pdf"):
now = datetime.datetime.today()
date = now.strftime("%Y-%m-%d %H:%M:%S")
c = canvas.Canvas(output)
textobject = c.beginText()
textobject.setTextOrigin(inch, 11*inch)
textobject.textLines('''''Disk Capcity Report: %s''' %date)
for line in input:
textobject.textLine(line.strip())
c.drawText(textobject)
c.showPage()
c.save()
report = disk_report()
create_pdf(report)

再练习:

1
2
3
4
5
6
7
8
#!/usr/bin/python  
from reportlab.pdfgen import canvas
def hello():
c = canvas.Canvas("helloworld.pdf")
c.drawString(100,100,"Hello,World")
c.showPage()
c.save()
hello()
Snake's Home

python发送mails

發表於 2014-03-12 | 分類於 python

在做持续集成时,有时会要用到邮件提醒,Jenkins自带的邮件功能有时满足不了需要,python中email模块使得处理邮件变得比较简单。

一、相关模块介绍

发送邮件主要用到了smtplib和email两个模块,这里首先就两个模块进行一下简单的介绍:
1、smtplib模块

smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])

  SMTP类构造函数,表示与SMTP服务器之间的连接,通过这个连接可以向smtp服务器发送指令,执行相关操作(如:登陆、发送邮件)。所有参数都是可选的。

host:smtp服务器主机名

port:smtp服务的端口,默认是25;如果在创建SMTP对象的时候提供了这两个参数,在初始化的时候会自动调用connect方法去连接服务器。

 smtplib模块还提供了SMTP_SSL类和LMTP类,对它们的操作与SMTP基本一致。

 smtplib.SMTP提供的方法:

SMTP.set_debuglevel(level):设置是否为调试模式。默认为False,即非调试模式,表示不输出任何调试信息。

SMTP.connect([host[, port]]):连接到指定的smtp服务器。参数分别表示smpt主机和端口。注意: 也可以在host参数中指定端口号(如:smpt.yeah.net:25),这样就没必要给出port参数。

SMTP.docmd(cmd[, argstring]):向smtp服务器发送指令。可选参数argstring表示指令的参数。

SMTP.helo([hostname]) :使用"helo"指令向服务器确认身份。相当于告诉smtp服务器“我是谁”。

SMTP.has_extn(name):判断指定名称在服务器邮件列表中是否存在。出于安全考虑,smtp服务器往往屏蔽了该指令。

SMTP.verify(address) :判断指定邮件地址是否在服务器中存在。出于安全考虑,smtp服务器往往屏蔽了该指令。

SMTP.login(user, password) :登陆到smtp服务器。现在几乎所有的smtp服务器,都必须在验证用户信息合法之后才允许发送邮件。

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]) :发送邮件。这里要注意一下第三个参数,msg是字符串,表示邮件。我们知道邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意msg的格式。这个格式就是smtp协议中定义的格式。

SMTP.quit() :断开与smtp服务器的连接,相当于发送"quit"指令。(很多程序中都用到了smtp.close(),具体与quit的区别google了一下,也没找到答案。)

2、email模块

emial模块用来处理邮件消息,包括MIME和其他基于RFC 2822 的消息文档。使用这些模块来定义邮件的内容,是非常简单的。其包括的类有(更加详细的介绍可见:http://docs.python.org/library/email.mime.html):

class email.mime.base.MIMEBase(_maintype, _subtype, **_params):这是MIME的一个基类。一般不需要在使用时创建实例。其中_maintype是内容类型,如text或者image。_subtype是内容的minor type 类型,如plain或者gif。 **_params是一个字典,直接传递给Message.add_header()。

class email.mime.multipart.MIMEMultipart([_subtype[, boundary[, _subparts[, _params]]]]:MIMEBase的一个子类,多个MIME对象的集合,_subtype默认值为mixed。boundary是MIMEMultipart的边界,默认边界是可数的。

class email.mime.application.MIMEApplication(_data[, _subtype[, _encoder[, **_params]]]):MIMEMultipart的一个子类。

class email.mime.audio. MIMEAudio(_audiodata[, _subtype[, _encoder[, **_params]]]): MIME音频对象

class email.mime.image.MIMEImage(_imagedata[, _subtype[, _encoder[, **_params]]]):MIME二进制文件对象。

class email.mime.message.MIMEMessage(_msg[, _subtype]):具体的一个message实例,使用方法如下:

msg=mail.Message.Message() #一个实例
msg[‘to’]=’XXX@XXX.com’ #发送到哪里
msg[‘from’]=’YYY@YYYY.com’ #自己的邮件地址
msg[‘date’]=’2012-3-16’ #时间日期
msg[‘subject’]=’hello world’ #邮件主题

class email.mime.text.MIMEText(_text[, _subtype[, _charset]]):MIME文本对象,其中_text是邮件内容,_subtype邮件类型,可以是text/plain(普通文本邮件),html/plain(html邮件),  _charset编码,可以是gb2312等等。

二、几种邮件的具体实现代码

1、普通文本邮件

普通文本邮件发送的实现,关键是要将MIMEText中_subtype设置为plain。首先导入smtplib和mimetext。创建smtplib.smtp实例,connect邮件smtp服务器,login后发送,具体代码如下:(python2.7下实现)

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
# -*- coding: UTF-8 -*-
'''
发送txt文本邮件
Anderson
'''

import smtplib
from email.mime.text import MIMEText
#mailto_list=[YYY@YYY.com]
mailto_list=['luck@163.com']
mail_host="smtp.XXX.cn" #设置服务器
mail_user="anderson@XXX.cn" #用户名
mail_pass="123456" #口令
mail_postfix="XXX.cn" #发件箱的后缀

def send_mail(to_list,sub,content):
me="hello"+"<"+mail_user+"@"+mail_postfix+">"
msg = MIMEText(content,_subtype='plain',_charset='gb2312')
msg['Subject'] = sub
msg['From'] = me
msg['To'] = ";".join(to_list)
try:
server = smtplib.SMTP()
server.connect(mail_host)
server.login(mail_user,mail_pass)
server.sendmail(me, to_list, msg.as_string())
server.close()
return True
except Exception, e:
print str(e)
return False
if __name__ == '__main__':
if send_mail(mailto_list,"hello","hello world!"):
print "发送成功"
else:
print "发送失败"

2、html邮件的发送

与text邮件不同之处就是将将MIMEText中_subtype设置为html。具体代码如下:(python2.7下实现)

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
    # -*- coding: utf-8 -*-
'''
发送html文本邮件
Anderson
'''

import smtplib
from email.mime.text import MIMEText
mailto_list=["luck@163.com"]
mail_host="smtp.XXX.cn" #设置服务器
mail_user="anderson@XXX.cn" #用户名
mail_pass="123456" #口令
mail_postfix="XXX.cn" #发件箱的后缀

def send_mail(to_list,sub,content): #to_list:收件人;sub:主题;content:邮件内容
me="hello"+"<"+mail_user+"@"+mail_postfix+">" #这里的hello可以任意设置,收到信后,将按照设置显示
msg = MIMEText(content,_subtype='html',_charset='gb2312') #创建一个实例,这里设置为html格式邮件
msg['Subject'] = sub #设置主题
msg['From'] = me
msg['To'] = ";".join(to_list)
try:
s = smtplib.SMTP()
s.connect(mail_host) #连接smtp服务器
s.login(mail_user,mail_pass) #登陆服务器
s.sendmail(me, to_list, msg.as_string()) #发送邮件
s.close()
return True
except Exception, e:
print str(e)
return False
if __name__ == '__main__':
if send_mail(mailto_list,"hello",u"<a href='http://www.yiban.cn'>链接</a>"):
print "发送成功"
else:
print "发送失败"

3、发送带附件的邮件

发送带附件的邮件,首先要创建MIMEMultipart()实例,然后构造附件,如果有多个附件,可依次构造,最后利用smtplib.smtp发送。

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
# -*- coding: cp936 -*-
'''
发送带附件邮件
Anderson
'''


from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib

#创建一个带附件的实例
msg = MIMEMultipart()

#构造附件1
att1 = MIMEText(open('C:\\Users\\wftang\\Desktop\\New folder\\mail1.py', 'rb').read(), 'base64', 'gb2312')
att1["Content-Type"] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="123.doc"'#这里的filename可以任意写,写什么名字,邮件中显示什么名字
msg.attach(att1)

#构造附件2
att2 = MIMEText(open('C:\\Users\\wftang\\Desktop\\New folder\\mail1.py', 'rb').read(), 'base64', 'gb2312')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="124.txt"'
msg.attach(att2)

#加邮件头
msg['to'] = 'anderson@163.com'
msg['from'] = 'luck@163.com'
msg['subject'] = 'hello world'
#发送邮件
try:
server = smtplib.SMTP()
server.connect('smtp.163.com')
server.login('luck@163.com','****')#XXX为用户名,XXXXX为密码
server.sendmail(msg['from'], msg['to'],msg.as_string())
server.quit()
print '发送成功'
except Exception, e:
print str(e)

4、利用MIMEimage发送图片

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
# -*- coding: cp936 -*-
import smtplib
import mimetypes
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage

def AutoSendMail():
msg = MIMEMultipart()
msg['From'] = "luck@163.com"
msg['To'] = "anderson@163.com"
msg['Subject'] = "hello world"


txt = MIMEText("这是中文的邮件内容哦",'plain','gb2312')
msg.attach(txt)


file1 = "C:\\Users\\anderson\\Desktop\\ssssa.jpg"
image = MIMEImage(open(file1,'rb').read())
image.add_header('Content-ID','<image1>')
msg.attach(image)


server = smtplib.SMTP()
server.connect('smtp.163.com')
server.login('lucklly@163.com','allen888')
server.sendmail(msg['From'],msg['To'],msg.as_string())
server.quit()

if __name__ == "__main__":
AutoSendMail()
Snake's Home

python尝试monkey收集crash

發表於 2014-03-05 | 分類於 python

曾今花了点时间研究的 monkey 测试,感觉Monkey太不可控了,不停的点击,crash一个接着一个。看Log也看得眼花,好不容易找到一个FATAL ERROR, 开发却说没什么用。

Monkey 命令看似简单,就那么一行,可是参数组合起来,就强大了。

Monkey经常点了系统的控件。恒温告诉我有黑白名单。后面试用了一下,果然不会点到系统中去了。

可以直接用:

1
2
3
adb shell getprop "ro.product.model"
adb shell getprop "ro.build.version.releasel"
adb shell getprop "ro.product.brand"

来获
/system/build.prop 里面的信息。(何老师教的。)

翠花,上脚本:

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#encoding:utf-8  
import os
import time
import re

packageName="com.XXX.app"
logdir=r"d:\jenkins"
remote_path=r"\\10.21.101.100\XXXX\build\android"

#os.popen('adb shell cat /system/build.prop >D:\jenkins\phone.text')
os.system('adb shell cat /system/build.prop >D:\jenkins\phone.text')

f = r"D:\jenkins\phone.text"


def getcmd(cmd):
f = open(cmd,"r")
lines = f.readlines()
for line in lines:

line=line.split('=')
if (line[0]=='ro.build.version.release'):
version = line[1]
if (line[0]=='ro.product.model'):
model = line[1]
if (line[0]=='ro.product.brand'):
brand = line[1]
return version,model,brand


version,model,brand=getcmd(f)

print version,model,brand
os.remove(f)

#print "使用Logcat清空Phone中log"
os.popen("adb logcat -c")

#print"暂停2秒..."
print "wait"
time.sleep(2)
#os.popen("adb shell monkey -p com.XXX.app -s 500 -v -v 1000")

#print"强制关闭准备测试的APP"
print "a"
#commd="adb shell am force-stop %s" %(packageName)
#os.popen(commd)
now1 = time.strftime('%m-%d-%H_%M_%S', time.localtime(time.time()))
#newfname="%sCircle-debug.apk"%(now1)
#newfpath="%s/%s"%(output_path,newfname)
#oldfpath="%s/%s"%(output_path,oldname)
#os.rename(oldfpath, newfpath)
#print"开始执行Monkey命令"

monkeylogname=logdir+"\\"+now1+"monkey.log"
print monkeylogname
cmd="adb shell monkey -p com.XXX.app -s 500 --ignore-timeouts --monitor-native-crashes -v -v 10000 >>%s" %(monkeylogname)
os.popen(cmd)

#print"手机截屏"

os.popen("adb shell screencap -p /sdcard/monkey_run.png")

#print"拷贝截屏图片至电脑"

cmd1="adb pull /sdcard/monkey_run.png %s" %(logdir)
os.popen(cmd1)

print "gai ming"
oldname=logdir+"\\"+r"monkey_run.png"
if (os.path.exists(oldname)):
print "file is exist"
else:
print "file isn't exist"
print oldname
newname=logdir+"\\"+now1+r"monkey.png"
print newname
os.rename(oldname, newname)

#print"使用Logcat导出日志"

logcatname=logdir+"\\"+now1+r"logcat.log"
cmd2="adb logcat -d >%s" %(logcatname)
os.popen(cmd2)

#print"导出traces文件"

tracesname=logdir+"\\"+now1+r"traces.log"
cmd3="adb shell cat /data/anr/traces.txt>%s" %(tracesname)
os.popen(cmd3)

######################
#获取error
######################

NullPointer="java.lang.NullPointerException"
IllegalState="java.lang.IllegalStateException"
IllegalArgument="java.lang.IllegalArgumentException"
ArrayIndexOutOfBounds="java.lang.ArrayIndexOutOfBoundsException"
RuntimeException="java.lang.RuntimeException"
SecurityException="java.lang.SecurityException"

def geterror():
f = open(logcatname,"r")
lines = f.readlines()
errfile="%s\error.log" %(remote_path)
fr = open(errfile,"a")
fr.write(now1)
fr.write("\n")
fr.write(version)
fr.write("\n")
fr.write(model)
fr.write("\n")
fr.write(brand)
fr.write("\n")

count=0
for line in lines:
if ( re.findall(NullPointer,line) or re.findall(IllegalState,line) or re.findall(IllegalArgument,line) or re.findall(ArrayIndexOutOfBounds,line) or re.findall(RuntimeException,line) or re.findall(SecurityException,line) ):
a=lines.index(line)
count +=1
for var in range(a,a+22):
print lines[var]
fr.write(lines[var])
fr.write("\n")
f.close()
fr.close()
return count


number=geterror()
print number

脚本是写出来了,也能发现一些有用的crash。
但是,开发不Fix。。。

要是哪天能做一个监控系统就好了。
结合线上线下,就不会有这么多Crash了。

本文发表在: testerhome

Snake's Home

初学monkeyrunner

發表於 2014-02-22 | 分類於 python

现在的工作的重心渐渐从Web转到Mobile上来了。根据网上的例子,在公司产品上体验了一把MokeyRunner

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/pyton
#encoding=utf-8
import time
import sys

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

now=time.strftime("%Y-%m-%d-%H-%M-%S")
logpath="D:\\log\\"
name=sys.argv[0].split("\\")
filename=name[len(name)-1]

log=open(logpath+filename[0:-3]+"-log"+now+".txt",'w')

device = MonkeyRunner.waitForConnection()
print('connected')
MonkeyRunner.sleep(3)
log.write("连接成功...\n")

device.installPackage('../platform-tools/weather.apk')
print('install')
MonkeyRunner.sleep(3)
log.write("安装成功...\n")

#device.shell('am force-stop com.eztech.kylinlauncher')
device.shell('monkey -p com.XXX.app -v 1')

#device.startActivity(component='com.eztech.kylinlauncher/com.eztech.kylinlauncher.MainActivity')
device.startActivity(component ="com.XXX.app/com.XXX.app.activity.WelcomeActivity")

MonkeyRunner.sleep(10)

device.touch(137,205,'DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.touch(346,200,'DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.touch(186,304,'DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.touch(234,202,'DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.touch(562,205,'DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.touch(27,90,'DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.touch(609,197,'DOWN_AND_UP')
MonkeyRunner.sleep(2)

device.press('KEYCODE_DPAD_UP','DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.press('KEYCODE_DPAD_UP','DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.press('KEYCODE_DPAD_RIGHT','DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.press('KEYCODE_DPAD_RIGHT','DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.press('KEYCODE_DPAD_RIGHT','DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.press('KEYCODE_DPAD_LEFT','DOWN_AND_UP')
MonkeyRunner.sleep(2)
device.press('KEYCODE_DPAD_RIGHT','DOWN_AND_UP')
MonkeyRunner.sleep(5)
device.press("KEYCODE_DPAD_CENTER","DOWN_AND_UP")
MonkeyRunner.sleep(10)
device.press('KEYCODE_DPAD_DOWN','DOWN_AND_UP')
MonkeyRunner.sleep(3)
device.press('KEYCODE_BACK ','DOWN_AND_UP')
MonkeyRunner.sleep(3)
#点击发送的位置
#device.touch(324,73,'DOWN_AND_UP')
device.touch(388,298,'DOWN_AND_UP')
MonkeyRunner.sleep(10)
print('touch')
log.write("我点!...\n")
#移动第一个便签的位置到最后面去,参数是:一个起始点坐标,一个终点坐标,移动的时间,移动的步骤
#device.drag((232,235),(216,472),3,2)
device.drag((314,248),(314,360),4,3)
MonkeyRunner.sleep(3)
print('drag')
log.write("我拽!...\n")
#截图
result = device.takeSnapshot()
#保存截图
result.writeToFile('./pic0012.png','png')
#取电脑中的需要对比的截图
resultTrue=MonkeyRunner.loadImageFromFile('C:\\SDK\\adt-bundle-windows-x86_64-20140321\\sdk\\tools\\picture\\pic001.png')
log.write("对比截图...\n")
#compare pictures with the same is 90%
#对比截图,看相似度能否达到9成
if(result.sameAs(resultTrue,0.9)):
#print the message
print("compare success")
#write message to log
log.write("对比成功...\n")
else:
#print the failed message
print("compare failed")
log.write("对比失败,图片相似度没有达到90%...\n")

device.removePackage('com.moji.mjweather')
print ('uninstall Success!')
log.write("卸载成功...\n")
#回到主界面
device.press('KEYCODE_HOME ','DOWN_AND_UP')
MonkeyRunner.sleep(3)
print('back to home ')
log.write("结束!...\n")

跑完了以后,感觉这工具不太好用。
1: 取坐标这个是硬伤。兼容性难做到。
2: 靠图片相似度对比,这个太不准了。

Snake's Home

用selenium实现的流程自动化

發表於 2014-01-27 | 分類於 python

这是在某厂负责的第一个项目,是公司内部做的一个OA系统,主要是各种流程,请假,审批等等。
开发起来并不复杂,但是流程特别多,业务比较复杂,项目还没结束的时候,团队人都走没了。

当时测试时间被压缩得很紧,基本功能没啥问题后,就写了个脚本来覆盖各个流程。
这也是这个公司的第一个自动化测试项目和敏捷项目。
虽然功劳都被人拿走了,但是这个项目还是很成功的。

auto.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#encoding:utf-8
# coding:gb2312
from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver.common.action_chains import ActionChains
import time,re,sys,os
import csv

class OAtest():
currentpath=os.getcwd()
logpath=currentpath+"\\Log"
casepath=currentpath+"\\Case"
tablepath=currentpath+"\\Table"
if not os.path.exists(logpath) :
os.mkdir("Log")
print logpath
logname = time.strftime(r"%Y-%m-%d_%H-%M",time.localtime())
print logname
filename=logpath + "\\" + logname+"log.txt"
print filename
logline=open(filename,"w+")
#logline.write('If you are happy')

def setUp(self):
self.dr = webdriver.Chrome()
#self.dr = webdriver.Ie()
self.url = 'http://10.21.168.170/index'
print u"现在开始登陆..."
self.logline.write("现在开始登陆...\n")
def login(self,name):
print "Now Logging is %s" %(name)
self.logline.write("现在登陆的账号是 %s \n" %(name))
dr = self.dr
dr.get(self.url)
time.sleep(1)
dr.find_element_by_id('UserForm_username').send_keys(name)
dr.find_element_by_id('UserForm_password').send_keys('1')
dr.find_element_by_name('yt0').click()
# errormsg = dr.find_element_by_class_name("errorSummary")
#if errormsg.is_displayed() == True:
# print u"用户名密码不匹配,请检查用户名或密码!\n"
time.sleep(1)
dr.maximize_window()


def creatleaveprogress(self,mingzi):
dr = self.dr
frame = dr.find_element_by_xpath("/html/frameset/frameset").find_element_by_tag_name("frame")
dr.switch_to_frame(frame)
print u"现在进入流程"
dr.find_element_by_xpath('/html/body/div[1]/div/ul/li[2]/div[1]/a').click()
self.logline.write("现在进入新建流程...\n")
print u"现在进入新建流程"
dr.find_element_by_xpath('/html/body/div[1]/div/ul/li[2]/div[3]/p[1]/a').click()
print u"点中了新建流程按钮"
time.sleep(1)
dr.switch_to_default_content()
# dr.switch_to_frame("Main")
frame1 = dr.find_element_by_xpath("/html/frameset/frameset/frameset").find_element_by_tag_name("frame")
dr.switch_to_frame(frame1)
print u"转入到流程页面"
self.logline.write("转入到流程页面...\n")
# element=dr.find_element_by_xpath('/html/body/div/div/div[2]/ul[3]/li[3]/p[1]/a')
#开始读table表了
filelist=os.listdir(self.tablepath)
print filelist
print mingzi
rule=re.compile(mingzi)
filelist1=",".join(filelist)
if rule.findall(filelist1):
print rule.findall(filelist1)
print u"有这张表"
else:
print u"找不到张表"
#my_file= 'C:\\Users\\Lenovo\\Desktop\\aa\\aa.csv'
myfile = self.tablepath + "\\"+mingzi + ".csv"
print myfile
data=csv.reader(file(myfile,'rb'))
print data
#for user in data:
# print user
# table2 = list(data)
i=0
for table1 in data:
if i==0:
element=dr.find_element_by_xpath(table1[0])
print u"打开创建流程页面"
element.click()
print u"现在申请的是:%s"%(element.text)
print "title of current page is %s" %(dr.title)
print "url of current page is %s" %(dr.current_url)
else:
dr.switch_to_default_content()
# now_handle = dr.current_window_handle
for handle in dr.window_handles:
dr.switch_to_window(handle)
print "title of current page is %s" %(dr.title)
print "url of current page is %s" %(dr.current_url)
# print "url of current page is %s" %(dr.current_window_handle)
#for table1 in data:
# print table1
print "The value is %s,%s"%(table1[0],table1[1])
dr.find_element_by_xpath(table1[0]).send_keys(table1[1])
i=i+1
title = dr.find_element_by_xpath('//table/tbody/tr[1]/td[2]/div').text
print "The title is %s \n" %title
dr.find_element_by_id('submit_request').click()
currenttime = time.strftime(r"%Y-%m-%d_%H:%M:%S",time.localtime())
print "Time is %s"%currenttime
# dr.get_screenshot_as_file('baidu.png')
time.sleep(1)
try:
alert = dr.switch_to_alert()
alert.accept()
except:
print 'no alerts display'

#filename = title + currenttime
return title

def banjie(self,biaoti,flag=1):
dr = self.dr
print u"传过来的参数是%s"%biaoti
print u"现在flag的值是%s"%flag
frame = dr.find_element_by_xpath("/html/frameset/frameset").find_element_by_tag_name("frame")
dr.switch_to_frame(frame)
print u"现在进入流程"
dr.find_element_by_xpath('/html/body/div[1]/div/ul/li[2]/div[1]/a').click()
if flag==0:
print u"现在进入我的待办"
self.logline.write("现在进入我的待办...\n")
dr.find_element_by_xpath('/html/body/div[1]/div/ul/li[2]/div[3]/p[2]/a').click()
else:
print u"现在进入我的办结"
self.logline.write("现在进入我的办结...\n")
dr.find_element_by_xpath('/html/body/div[1]/div/ul/li[2]/div[3]/p[4]/a').click()
print u"点中"
time.sleep(1)
dr.switch_to_default_content()
# dr.switch_to_frame("Main")
frame1 = dr.find_element_by_xpath("/html/frameset/frameset/frameset").find_element_by_tag_name("frame")
dr.switch_to_frame(frame1)
print u"转入到我的办结页面"
self.logline.write("转入到我的办结页面...\n")
# dr.find_element_by_xpath('/html/body/div/div/div[2]/ul[3]/li[3]/p[1]/a').click()

xiaobiaoti = dr.find_element_by_xpath('/html/body/div/div/table/tbody/tr[1]/td[4]/a')
# assert(biaoti,xiaobiaoti.text)
pngname1=self.logpath+"\\"+self.logname+biaoti+"progress.png"
pngname2=self.logpath+"\\"+self.logname+biaoti+"detail.png"
if (biaoti == xiaobiaoti.text):
print u"找到了 %s" %biaoti
xiaobiaoti.click()
print u"打开请求 %s" %biaoti
for handle in dr.window_handles:
dr.switch_to_window(handle)
time.sleep(1)
dr.get_screenshot_as_file(pngname2)
dr.close()
else:
print u"没有找到 %s,请查看你的设置或流程,谢谢!\n" %biaoti
#xiaobiaoti.click()
for handle in dr.window_handles:
dr.switch_to_window(handle)
dr.get_screenshot_as_file(pngname1)
time.sleep(2)

def approveleaveprogress(self,biaoti,flag=1):
dr = self.dr
print u"传过来的参数是%s"%biaoti
print u"现在flag的值是%s"%flag
frame = dr.find_element_by_xpath("/html/frameset/frameset").find_element_by_tag_name("frame")
# driver.switch_to_frame(frame)
dr.switch_to_frame(frame)
# dr.switch_to_frame("Left")
print u"现在进入frame"
# add = driver.find_element_by_css_selector('input.add')
# SearchButton = driver.find_element_by_css_selector('input.add1')
# progressbutton = dr.find_element_by_xpath('/html/body/div[1]/div/ul/li[2]/div[1]/a')
dr.find_element_by_xpath('/html/body/div[1]/div/ul/li[3]/div[1]/a').click()
time.sleep(1)
print u"现在进入事宜"
dr.find_element_by_xpath('/html/body/div[1]/div/ul/li[3]/div[3]/p[1]/a').click()
time.sleep(1)
print u"打开了待办事宜"
self.logline.write("打开了待办事宜...\n")
dr.switch_to_default_content()
frame1 = dr.find_element_by_xpath("/html/frameset/frameset/frameset").find_element_by_tag_name("frame")
# driver.switch_to_frame(frame)
dr.switch_to_frame(frame1)
print u"现在进入到 frame11"
self.logline.write("现在进入到 frame11...\n")
# inputs = dr.find_elements_by_tag_name('td')
# for input in inputs:
# if input.text == 'biaoti':
# print"Find the progress"
# input.click()
# break
#dr.find_element_by_xpath('/html/body/div/div/table/tbody/tr[1]/td[3]/a').click()
xiaobiaoti = dr.find_element_by_xpath('/html/body/div/div/table/tbody/tr[1]/td[3]/a')
# assert(biaoti,xiaobiaoti.text)
if (biaoti == xiaobiaoti.text):
print u"在待办事宜中找到了 %s" %biaoti
xiaobiaoti.click()
print u"打开请求 %s" %biaoti
else:
print u"在待办事宜中没找到 %s,请查看你的设置或流程,谢谢!\n" %biaoti
#xiaobiaoti.click()
time.sleep(3)
print "Now I open the page"
print "title of current page is %s" %(dr.title)
print "url of current page is %s" %(dr.current_url)
for handle in dr.window_handles:
dr.switch_to_window(handle)
print "title of current page is %s" %(dr.title)
print "url of current page is %s" %(dr.current_url)
print "url of current page is %s" %(dr.current_window_handle)
if flag==0:
dr.find_element_by_id('submit_back').click()
print u"请求%s被退回"%(biaoti)
else:
dr.find_element_by_id('submit_request').click()
print u"批准请求%s"%(biaoti)
time.sleep(1)
try:
alert = dr.switch_to_alert()
alert.accept()
except:
print 'no alerts display'

#def rejectprogress(self):


def tearDown(self):
self.dr.quit()



#if __name__ == "__main__":
# unittest.main()

t = OAtest()

print 'now start to create a request'
t.setUp()

t.login(10000386)
ss=t.creatleaveprogress()
print "return value is %s" %ss
t.tearDown()

time.sleep(5)

print 'now start to approve a request'
t.setUp()
t.login(10000410)
t.approveleaveprogress(ss)
t.tearDown()

leavetime = dr.find_element_by_xpath('//table/tbody/tr[6]/td[2]/div/input')
backtime = dr.find_element_by_xpath('//table/tbody/tr[7]/td[2]/div/input')
leaveday = dr.find_element_by_xpath('//table/tbody/tr[11]/td[2]/div/input')
leavereason = dr.find_element_by_xpath('//table/tbody/tr[12]/td[2]/div/textarea')



leavetime.send_keys("2014-07-09 00:00:00")
backtime.send_keys("2014-07-10 00:00:00")
leaveday.send_keys("1")
leavereason.send_keys(u"回家")

path.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#encode=utf-8
import os,sys,re

a=os.getcwd()+"\\Table"
print a
list=os.listdir(a)
print list
print type(list)
arry=",".join(list)
print arry
print type(arry)
r=r'\w+\.csv'
a=re.compile(r)
print a
list=a.findall(arry)
print list

for i in list:
print i
i=i.split(".")
print i[0]

把case写到一个文件里面,维护起来方便。

reader.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
52
#coding=utf-8
import csv
import re,sys,os

my_file= 'C:\\Users\\Lenovo\\Desktop\\aa\\dd.csv'
typelist =[]
data=csv.reader(file(my_file,'rb'))
i = 0
for user in data:
print user
typelist.append(user[0])
i=i+1
print typelist
typeli="".join(typelist)
print i+1

#yourfile='C:\\Users\\Lenovo\\Desktop\\aa\\dd.txt'
#data=csv.reader(file(yourfile,'rb'))
source=open(r"C:\\Users\\Lenovo\\Desktop\\aa\\dd.txt","r")
data=source.readlines()
source.close()
j=0
k=0
for pro in data:
print "the list is %s" %pro
# pro="".join(pro)
#print "the list change to %s" %pro
pro=pro.strip("\n")
index=pro.find(':')
print index
pro=pro.split(':')
head=pro[0]
print head
tail=pro[1]
print tail
#r=r'\d'
rule=re.compile(r'^\D')
#print rule.findall(head)
if rule.findall(head):
if re.findall(head,typeli):
print u"在csv文件中有匹配"
print u"行号是"
j=j+1
#登陆等操作
#创建新表
else:
print u"请新建流程的表路径,或者检查你的类型"
else:
print "The case %s is skip " %head
k=k+1
print u"跑过的case %d" %j
print u"跳过的case %d" %k

弄成一个可执行的工具,这样就可以脱离python环境。

setup.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#-*-coding: UTF-8-*-
from distutils.core import setup
import py2exe
# Powered by ***
INCLUDES = []
options = {"py2exe" :
{"compressed" : 1,
"optimize" : 2,
"includes" : INCLUDES,
"dll_excludes": ["mswsock.dll", "powrprof.dll","w9xpopen.exe"] }}
setup(
name = "OA Helper",
version = '1.0',
options = options,
description = "Please contact with Anderson if you have any problems,Q:117732865",
zipfile=None,
console=[{"script": "file.py", "icon_resources": [(1, "logo.ico")] }],
)

因为时间很紧,脚本没有做太多的优化,也没有结果报表啥的,主要是给自己看的,就随意了很多。

Snake's Home

Hexo更换主题

發表於 2013-12-10 | 分類於 建站

默认的主题太大众了。
我打算选一个iceman,简单简约。iceman

更多主题 https://github.com/hexojs/hexo/wiki/Themes

英文说明是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Install: 这里注意下你执行命令的文件夹,首先需要在cd themes 中执行clone
$ git clone https://github.com/wizicer/iceman.git themes/iceman

Install dependence
$ npm install hexo-renderer-ejs --save
$ npm install hexo-renderer-stylus --save
$ npm install hexo-renderer-marked --save

Iceman requires Hexo 2.4.5 and above.
Enable: Modify theme setting in blog folder _config.yml to iceman .

Update:
cd themes/iceman
git pull

please backup your _config.yml file before update.

Configuration:

Modify settings in /themes/iceman/_config.yml .
  1. 将Git Shell 切到Hexo目录下,然后执行下面的命令,将pacman下载到 themes/pacman 目录下。
    $ git clone https://github.com/A-limon/pacman.git themes/pacman

  2. 修改你的博客根目录/D/Hexo下的config.yml配置文件中的theme属性,将其设置为pacman。

  3. 更新pacman主题

cd themes/pacman

git pull

NOTE:先备份_config.yml 文件后再升级

换过几个主题,最后选择了 next
参照

Next|官网

Next|主题设定

Next|第三方服务

Next|github

其他

md文件发布问题

在md文件中写中文,发布后会出现乱码的情况,另存为时改为“UTF-8”即可。

图片

对于本地图片,需要在source目录下面新建一个目录images,然后把图片放到目录中。

Markdown语法

1
![这是一张图片](/images/fens.me.png)

比如post的layout默认是hexo\scaffolds\post.md

1
2
3
4
title: { { title } }
date: { { date } }
tags:
---

我想添加categories,以免每次手工输入,只需要修改这个文件添加一行,如下:

1
2
3
4
5
title: { { title } }
date: { { date } }
categories:
tags:
---

添加照片,很简单,只需要在你的文章*.md文件的头上添加photos项即可,然后一行行添加你要展示的照片:

1
2
3
4
5
6
7
layout: photo
title: 我的阅历
date: 2085-01-16 07:33:44
tags: [hexo]
photos:
- http://bruce.u.qiniudn.com/2013/11/27/reading/photos-0.jpg
- http://bruce.u.qiniudn.com/2013/11/27/reading/photos-1.jpg

不想每次都手动添加怎么办?同样的,打开您的hexo\scaffolds\photo.md

1
2
3
4
5
6
7
layout: { { layout } }
title: { { title } }
date: { { date } }
tags:
photos:
-
---

然后每次可以执行带layout的new命令生成照片文章:

1
hexo new photo "photoPostName" #新建照片文章
Snake's Home

Hexo小试牛刀

發表於 2013-12-03 | 分類於 建站

Hexo: 独立博客新玩法

首先Hexo是一款基于Node.js的静态博客,它是由台湾的一位大学生写出来的,支持很多主题和Markdown,很多人都在使用。

我的理解,按照MarkDown的语法规则,免费的将自己网页部署到代码托管网站上去。Hexo就是这样一套自动生成网页的框架。
对于喜欢写独立博客的来说,是一个福音。不需要域名,服务器,备案等,就可以拥有自己的网站。

我记得以前是用jeklly托管到github上,我弄过,但是没坚持下来。
当知道有Hexo的时候,也写过一些。但是由于众所周知的原因,github经常打不开,导致部署常常出错,所以也没有坚持下来。
前段时间发现上github速度又可以了,打算重新在弄弄,坚持写下去。

1. 本地搭建

几条命令:


$ npm install -g hexo
$ mkdir Hexo
$ cd Hexo
$ hexo init
$ npm install

这样就安装完成了,NodeJs的安装,网上有很多的资料。

2. Start Server

在/Hexo下执行

1
2
$ hexo server
[info] Hexo is running at http://localhost:4000/. Press Ctrl + c to stop.

在浏览器中打开 http://localhost:4000/, 你就可以看到生成的博客了。

3. Create a new post

在/Hexo下执行

1
2
$ hexo new "your article name"
[info] File Created at \Hexo\source\_posts\your-article-name.md

4. Generate static files

$ hexo generate

it will generate file at the folder \Hexo\public\

5. Edit files

如果要更改文件,到\Hexo\source_posts 用markdown 语法编辑一下。
如果要删除,到这个目录下删除不想要的文章。
然后更新

1
2
3
hexo g == hexo generate <!--生成-->
hexo s == hexo server <!--启动服务来预览-->
hexo d == hexo deploy <!--部署-->

6. Deploy to github

1.建立与你用户名对应的仓库,仓库名必须为[your_user_name.github.io]

2.SSH

请参照 hexo重置ssh

3.配置config.yml

部署到Github前需要配置_config.yml文件,首先找到下面的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#Deployment
##Docs: http://hexo.io/docs/deployment.html
deploy:
type:
```
然后将它们修改为

``` bash
# Deployment
## Docs: http://hexo.io/docs/deployment.html
deploy:
type: github
repository: git@github.com:snake/snake.github.io.git
branch: master

NOTE1:

Repository:必须是SSH形式的url(git@github.com:snake/snake.github.io.git),而不能是HTTPS形式的url(https://github.com/snake/snake.github.io.git),否则会出现错误。

NOTE2:

如果你是为一个项目制作网站,那么需要把branch设置为gh-pages。

4. Deploy

1
$ hexo deploy

7. 测试

当部署完成后,在浏览器中打开http://snake.github.io/(https://snake.github.io/) ,正常显示网页,表明部署成功。

8. 总结:部署步骤

每次部署的步骤,可按以下三步来进行。

1
2
3
hexo clean
hexo generate
hexo deploy

9. 总结:本地调试

在执行下面的命令后,

1
2
$ hexo g #生成
$ hexo s #启动本地服务,进行文章预览调试

浏览器输入http://localhost:4000,
查看搭建效果。此后的每次变更_config.yml 文件或者新建文件都可以先用此命令调试,尤其是当你想调试新添加的主题时。

可以用简化的一条命令
hexo s -g

常用命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
hexo new "postName" #新建文章
hexo new page "pageName" #新建页面
hexo generate #生成静态页面至public目录
hexo server #开启预览访问端口(默认端口4000,'ctrl + c'关闭server)
hexo deploy #将.deploy目录部署到GitHub
hexo help # 查看帮助
hexo version #查看Hexo的版本

命令的简写为:
hexo n == hexo new
hexo g == hexo generate
hexo s == hexo server
hexo d == hexo deploy
1…67
Snake

Snake

不要被困难击倒,除非你躺着睡大觉

69 文章
17 分類
57 標籤
© 2017 Snake
由 Hexo 強力驅動
主題 - NexT.Muse