2016年6月12日 星期日

Spring MVC中return ModelAndView以及return String


return ModelAndView經查詢是Spring 2.0之前版本所使用方式

如同上一個範例所寫


@RequestMapping("/hello_path")
public ModelAndView hello() {
  String message = "<h1>Hello World!</h1>";
  return new ModelAndView("hello", "message_el", message);
 }


改寫成retrun String則為


@RequestMapping("/hello_path")
public String hello(Model model){
 String message = "<h1>Hello World!</h1>";
 model.addAttribute("message_el", message);
 return "hello";
}

皆為相同作用
String是較新的做法

2016年6月9日 星期四

Spring MVC 初學

剛接觸Spring MVC
寫個簡易教學備忘一下

流程:
1.建立一個Maven專案
我是使用maven-archetype-quickstart
version 1.1
可以直接使用內建Dynamic Web Module的

2.安裝JAR檔



 <dependencies>

  <dependency>

   <groupId>org.springframework</groupId>

   <artifactId>spring-webmvc</artifactId>

   <version>4.2.6.RELEASE</version>

  </dependency>

  <dependency>

   <groupId>junit</groupId>

   <artifactId>junit</artifactId>

   <version>3.8.1</version>

   <scope>test</scope>

  </dependency>

  <dependency>

   <groupId>mysql</groupId>

   <artifactId>mysql-connector-java</artifactId>

   <version>5.1.6</version>

  </dependency>

  <dependency>

   <groupId>org.springframework</groupId>

   <artifactId>spring-jdbc</artifactId>

   <version>4.2.6.RELEASE</version>

  </dependency>

  <dependency>

   <groupId>javax.servlet</groupId>

   <artifactId>javax.servlet-api</artifactId>

   <version>3.1.0</version>

  </dependency>

  <dependency>

   <groupId>jstl</groupId>

   <artifactId>jstl</artifactId>

   <version>1.2</version>

  </dependency>

 </dependencies>





3.轉換為Dynamic Web專案(使用的archetype有內建的就跳過吧)
專案上按右鍵
Properties -> Project Facets -> Covert to faceted form... ->
打勾Dynamic Web Module  ->Apply ->OK

4.轉換為符合maven標準的資料夾格式(使用的archetype以符合就跳過)
在src/main 新增resources資料夾
在src/main 新增webapp資料夾
在src/main/webapp 新增WEB-INF資料夾
專案上按右鍵
Properties -> Deployment Assembly
Add -> Folder 選取src/main/webapp確認
Add -> Java Build Path Entries 選取Maven Dependencies確認


5.新增web.xml
放置於src/main/webapp/WEB-INF/web.xml


<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">

  <display-name>Spring MVC DEMO</display-name>

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

 

    <servlet>

        <servlet-name>dispatcher</servlet-name>

        <servlet-class>

            org.springframework.web.servlet.DispatcherServlet

        </servlet-class>

        <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

        <servlet-name>dispatcher</servlet-name>

        <url-pattern>*.do</url-pattern>

    </servlet-mapping>

 

</web-app>



6.新增dispatcher-servlet.xml
放置於src/main/webapp/WEB-INF/dispatcher-servlet.xml



<beans xmlns="http://www.springframework.org/schema/beans"

 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xsi:schemaLocation="

        http://www.springframework.org/schema/beans    

        http://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/mvc

        http://www.springframework.org/schema/mvc/spring-mvc.xsd

        http://www.springframework.org/schema/context

        http://www.springframework.org/schema/context/spring-context.xsd">



 <context:component-scan base-package="controller" />



 <bean id="viewResolver"

  class="org.springframework.web.servlet.view.UrlBasedViewResolver">

  <property name="viewClass"

   value="org.springframework.web.servlet.view.JstlView" />

  <property name="prefix" value="/WEB-INF/jsp/" />

  <property name="suffix" value=".jsp" />

 </bean>



</beans>



7.新增一個package命名為controller
在裡面放置一個Hello.java



package controller;



import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.servlet.ModelAndView;





@Controller

public class Hello { 

 

 @RequestMapping("/hello_path")

 public ModelAndView hello() {

  

  String message = "<h1>Hello World!</h1>";

  return new ModelAndView("hello", "message_el", message);

 }



}

8.在WEB-INF內新增一個資料夾命名為jsp
在jsp資料夾內放置一個hello.jsp
src/main/webapp/WEB-INF/jsp/hello.jsp


<%@ page language="java" contentType="text/html; charset=BIG5"
    pageEncoding="BIG5"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Spring MVC Demo</title>
</head>
<body>
${message_el}
</body>
</html>

9.啟動tomcat
網址輸入
http://localhost:8080/ProjectName/hello_path.do
ProjectName看你取什麼名字就打什麼






總結一下Spring MVC的運作流程
從web.xml讀取DispatcherServlet dispatcher取的servlet-name後面加上-servert.xml就是它會去找的檔案名稱
我這邊把servlet-name取名為dispatcher所以它去尋找dispatcher-servlet.xml
之後從dispatcher-servlet.xml讀取JstlView
這邊能夠設定prefix與suffix
對應到的就是設定jsp檔案的路徑以及檔案的副檔名
以及能夠設定該去掃描哪個package
會去scan此package底下的Class檔案中的annotation
而此範例是寫了一個@Controller
告訴Spring這是一個Controller Class
底下的方法就是設置@RequestMapping
@RequestMapping對應的是網址列該打上的path
也可以加入method
@RequestMapping(value = "/hello_path", method = { RequestMethod.GET, RequestMethod.POST })
初學容易搞混web.xml設置的url-pattern與@RequestMapping的路徑有什麼不同
web.xml的url-pattern是設定怎樣的path要去找spring的dispatcher來做轉發
所以也可以在web.xml內設定專門給servlet用的路徑
本範例是使用路徑結尾為.do的交由spring mvc做轉發處理
http://localhost:8080/ProjectName/hello_path.do
看到.do便知道此request先交由spring mvc dispatcher處理
spring mvc會去比對@RequestMapping是否有value是hello_path的
於是轉交該方法來執行
此範例return為ModelAndView物件
return new ModelAndView("hello", "message", message);
ModelAndView(String viewName, String modelName, Object modelObject)
hello代表的是jsp檔名
在dispatcher-servlet.xml中我們已經設定了
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
所以spring mvc會解譯為 /WEB-INF/jsp/hello.jsp
能夠對應到server端內的資料夾路徑
modelName message_el就是帶往jsp檔案時相對應的名稱 能夠用EL $(message_el}來call massege物件
而message物件就是我們在hello方法內所寫的String message

相關檔案放在
https://gist.github.com/ripple0129/45872576a10615819c15ab81a06fdfe4

2015年12月28日 星期一

遊戲腳本撰寫紀錄

由於有網友對於遊戲的腳本製作過程有興趣

這篇也算是紀錄一下我寫手機遊戲腳本的心得

太細節的部份就不說明了

要擁有的知識可能有點雜


國際版ROB經歷了四五年總算要關閉服務了

 Rage of bahamut(rob)是一款卡牌遊戲

起源於日本的web卡牌遊戲(開發廠商為cygames)

移植到android與ios而讓卡牌遊戲成為眾多手機app廠商開發的仿效模式

遊戲本質上其實還是web

而mobage(rob代理商)有自己的登入器接口

也就是遊戲開啟後先做login的動作 輸入帳號密碼後

登入系統會配發cookie並redirrect到遊戲的web server

起先我使用bluestacks安卓模擬器來做登入動作

後來由於效能問題又改用了virtualbox直接安裝android os進去來執行

我們要自動化的第一步自然是透過程式讓app自動啟動

如何使用電腦來控制android模擬器 基本上都是使用adb這個程式來控制

adb devices #查詢電腦有無裝置連接
adb connect 192.168.56.1 #連接上位置於192.168.56.1的裝置
"""最常用的基本上就這兩個
只要連接上後續控制就是靠自動化了"""

google本身有提供一套自動化測試工具叫monkeyrunner 個人使用後感覺效能頗差

且在比對圖片時常常會掛掉

後來改用了androidviewclient這一套純python的自動化工具


#自動化連接上裝置範例

from com.dtmilano.android.adb.adbclient import AdbClient
if len(sys.argv) >= 2:
    serialno = sys.argv[1]

else:
    serialno = '.*'
print 'serialno= '+str(serialno)

device1 = AdbClient(serialno=serialno)
print 'connected'

#如果使用python script.py 192.168.56.1 這個script就會去操作192.168.56.1


連接上我們要做的事情自然就是開啟遊戲的app

事實上透過adb shell其實就能夠簡單達到了


#開啟app
adb shell am start -a android.intent.action.MAIN -n com.mobage.ww.a692.Bahamut_Android/.SplashActivity
#關閉app
adb shell pm clear com.mobage.ww.a692.Bahamut_Android
"""啟動的程式名稱可能要先開eclipse觀察logcat看app的啟動流程來知道啟動時的package name
這是adb shell的使用方法,我們寫進腳本內去開啟的方式也差不多,pm clear的話同時能有清除使用者資料的功能"""

遊戲啟動後我們就開始做登入動作

#這邊我設置了一個開頭名稱為test100登入帳號,擷取封包cookie資訊登入後執行script
import time
from PIL import Image,ImageStat
from lib.sniff import sniff_rob #自己寫的擷取封包extract出cookie的module

user_name = "test"
user_num = 100
password = 12345678
delay = 1 #登入帳號之間的間隔秒數
run_script = "script" #登入後帳號所要執行的script


device1.shell("pm clear com.mobage.ww.a692.Bahamut_Android") #androidviewclient下shell的方法
time.sleep(1);
print 'Login: '+user_name+str(user_num)
print 'Password: '+ str(password)
print user_name+str(user_num)+': Run Rage of Bahamut...'
device1.shell("am start -a android.intent.action.MAIN -n com.mobage.ww.a692.Bahamut_Android/.SplashActivity")
time.sleep(5) #我是直接用等待五秒的方式等程式開啟,嚴謹點自然可以找android看有無check程式是否執行中的方法

#開啟app後要比對圖片來確認有無正常開啟app並且比對成功後開始執行登入
i=1
    while i<=8:
    picstart = Image.open("./pic/picstart.png") #用PIL開啟一個圖片
    time.sleep(1);
    picstart2=device1.takeSnapshot(reconnect=True) #利用androidviewclient takeSnapshot method擷取安卓的當前畫面
    picstart2=picstart2.transform((20,20),Image.EXTENT, (120,160,140,180)) #將當前畫面擷取出想要的部分
    print user_name+str(user_num)+': Loading'
    if device1.sameAs(picstart, picstart2, 1)== 1: #比對成功進行以下動作
        i=10 #比對成功後跳出while,由於i==9有其他動作所以用此方式跳出
        print user_name+str(user_num)+': Start to login'
        device1.touch(120,160, 'DOWN_AND_UP') #androidviewclient 模擬點取螢幕120,160的位置
        time.sleep(0.2);
        device1.touch(120,160, 'DOWN_AND_UP')
        time.sleep(0.5);
        device1.shell("input keyevent 61")#下達鍵盤TAB鍵的意思
        time.sleep(1);
        device1.type(user_name + str(user_num)) #輸入帳號
        time.sleep(1);
        device1.shell("input keyevent 61")#TAB換欄位
        device1.type(str(password)) #輸入密碼
        time.sleep(1);
        device1.shell("input keyevent 66")# 點選登入
        user=user_name+str(user_num)
        if sniff_rob(user,'01'): break #擷取出cookie
            filec = open('./cookie/'+user+'.txt','r')
            cookie = filec.read()
            if cookie == '':
                user_num = user_num -1
                break
                #將此帳號執行run_script,由於我使用windows7來跑所以有些導入程式的參數部分看起來比較複雜,也不是什麼重要的地方
                command_lines = 'python ./lib/'+run_script+'.py --'+user 
                print user+' start popen'
                args = shlex.split(command_lines)
                p = Popen(args)

    else: #比對失敗後等兩秒再比對圖片
        i=i+1
        time.sleep(2)



run_script的部分由於還蠻多種script的

都是定義遊戲中腳色要怎麼動作

包含加好友領獎勵過任務之類的

由於都是url.get url.post之類的東西也沒什麼好說明的

而擷取封包是使用scapy有興趣找相關documentation即可

這個程式其實是登入100-999個帳號

我精簡了一些不然有點太囉嗦


2015年4月28日 星期二

Scrapy 使用心得(1)


目前專案在製作一個可以快速搜索遊戲卡片的app
由於已經有相關的wiki了
所以只需要爬資料下來做好search功能

趁現在記憶猶新趕快把心得寫下提醒未來的自己XD

我所使用的環境為: python 2.7, win7 64, mongodb

目的:爬資料進去mongodb

安裝方式為:
pip install scrapy


安裝好了之後開始一個新的專案
scrapy startproject myapp

於是會建立一個
myapp資料夾


檔案結構為
myapp/
    scrapy.cfg
    myapp/
        __init__.py
        items.py
        pipelines.py
        settings.py
        spiders/
            __init__.py
            ...
spider資料夾內沒有檔案要自行建立spider的檔案
基本上scrapy提供許多種spider
BaseSpider:
from scrapy.spider import BaseSpider
只會爬你提供的url

CrawlSpider:
from scrapy.contrib.spiders import CrawlSpider
會爬你提供的url並把裡面的links也爬一爬

基本上我只使用過這兩種其他就不說明了

BaseSpider使用範例
我們先在spider資料夾內建立一個叫spider.py(檔名可以任意取喔)



from scrapy.spider import BaseSpider


class myappSpiders(BaseSpider): 

 

     name = 'myspider_name' #這個名字很重要喔對scrapy不熟的可能要浪費好幾分鐘在這

     allowed_domains = ['www.example.com']  #要爬的domain


     #start_urls就是爬蟲開始爬的第一個網頁,在BaseSpider中就只爬提供的這些urls
     start_urls = ['http://www.basespider.com/page1'
               ,'http://www.basespider.com/page2'
        ]

    #爬蟲從url爬完會丟到parse內你就可以從這邊設定你想取出的資料是什麼
def parse(self, response): hxs = HtmlXPathSelector(response) item = myappItem() item['item_field'] = hxs.select('//h1[@id="css_id"]/span/text()').extract() return item #這邊看到item = myappItem()與item['item_field']要先到item.py設定好 #return item會把item丟進去pipeline去處理,資料量不多其實這邊寫個file.write就好了

item.py的設定範例


from scrapy.item import Item, Field


class myappItem(Item):
    item_field = Field()

#class要跟spider.py內的myappItem同名, 每個你要抓的item_field都要來設定一下Field()




接著把terminal小黑窗目標移到scrapy.cfg同個位置
執行
scrapy crawl myspider_name
就可以開始抓囉
不要跟我一樣scrapy crawl 檔名浪費好幾分鐘阿XD

等我下次心血來潮再把後面補完QQ







2015年1月23日 星期五

Install scapy with python 2.7 in windows

參考網址
http://www.secdev.org/projects/scapy/doc/installation.html#windows 
得知需要的packages還蠻多的
不過此處列出的都是python 2.5 2.6的package links.

 2.7的找了一下

1. pywin32
http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/

2. Winpcap
http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe

3. pypcap
https://code.google.com/p/pypcap/issues/detail?id=36 

4. libdnet
http://dirk-loss.de/scapy/dnet-1.12.win32-py2.7.exe

5. pyreadline
https://pypi.python.org/pypi/pyreadline/2.0

6. scapy
http://bb.secdev.org/scapy/downloads

除了scapy要解壓縮跑python setup.py之外
剩的都是installer沒什麼安裝問題
這篇應該能夠幫助不少人省下找package的時間

2014年8月8日 星期五

演算法quine python範例

Quine演算法為程式語言經過編譯之後
執行顯示出來的內容必須與原始碼相同

wiki介紹


原本以為很難
要描述顯示出來的內容必須再新添加內容
這樣顯示的內容又會再增加
好像無解一樣

實作後發現比想像中簡單多了

python範例:

s="quine"
v="s=v=l=n='n p="
l=':"()[]+\\'
n='\n'
p='print(v[:2]+l[1]+s+l[1]+n+v[2:4]+l[1]+v+l[1]+n+v[4:6]+v[8]+l+l[7]+v[8]+n+v[6:9]+l[7]+v[9]+v[8]+n+v[11:13]+v[8]+p+v[8]+n+p)'
print(v[:2]+l[1]+s+l[1]+n+v[2:4]+l[1]+v+l[1]+n+v[4:6]+v[8]+l+l[7]+v[8]+n+v[6:9]+l[7]+v[9]+v[8]+n+v[11:13]+v[8]+p+v[8]+n+p) 

複製code執行,顯示結果將會和code一模一樣

2014年7月26日 星期六

Python for對不同datatype的測試


python的for不同於其他語言
感覺簡潔而且強大了許多
但是往往使用起來對概念的理解上也有點心虛阿XD

所以特別測試一下了解for對不同資料型別的處理方式

字串的處理:


for char in string:
  print char

會計算字串有幾個字元
有幾個字元就迴圈幾次


a = "12345"

for i in a

  print i



結果

1

2

3

4

5






列表的處理(Tuple相同):


for element in list:
  print element

會計算列表有多少個元素
有多少個元素就迴圈幾次

a = ( 'L1' , 'L2' , 'L3' , 'L4' , 'L5' ) for i in a
  print i

結果
L1
L2
L3
L4
L5


字典的處理:


for key in dictionary:
  print key

for key in dictionary
  print dictionary[key]  #印出value

有多少個key就迴圈幾次
排列的順序與key值有關
也就是會由小到大來print出來
如果key是string則會以迭代器的位置來開始印
所以想使用for在dictionary上面
最好key值使用integer較好控制
使用string為key值可能會出現非預期的錯誤



a = { 1:'a', 3:'b', 2:'c', 4:'d', 5:'e' } #注意key順序不同


for i in a


  print i





結果以key值大小排序


1

2

3

4

5



如果想要取出value值
則使用
for i in a
  print a[i]
結果以key值大小取出value值
a
c
b
d
e

2014年7月25日 星期五

正規表示式 regular expression 學習


常常看到程式中出現類似亂碼之莫名其妙的東西
譬如
^\d{3}\s(\w+)&
原來是叫正規表示式阿
也有人叫正則表達式
學名叫regular expression
總而言之就是一種字串的篩選器

regular expression常見於各種語言都會用到
也就是三不五時看到別人python內import的re

常用的部分
\d 數字
\w 任意字元含數字
\s 任意空白字元 space tab都算
{3} 乘以三次\d\d\d 等於\d{3}
( ) 擷取器 abc  a(b)c  b會被擷取出來
. 任意字元
+ 任意字串不包含自己本身
* 任意字串含自己本身
[] 就是or啦 [abc]de , ade,bde,cde都符合
[^] 就是nor啦
^ooxx&  ^開頭&結尾 嚴謹篩選,前後有東西都不合格


Regexone非常棒的教學練習網站
http://regexone.com/

基本上全部的練習做過一遍
應該就都懂了


python sys.argv[]用法


常看到python中出現sys.argv[]這東西
找了些資料總算理解了
紀錄一下備忘

sys.argv[]是python獲取命令列參數的方法
譬如我們在terminal中會輸入的指令
ls -a
-a就是命令列參數
sys.argv[0] 代表了文件的檔案名稱本身
意思就是ls
sys.argv[1] 就代表了-a

以下是參考網路的範例並修改成容易理解的方式




# -*- coding: utf-8 -*-

import sys>



>#建立一個讀取檔案的function能將檔案內容print出來

def readfile(filename): 

 '''read file and print'''

 f = file(filename)

 while True:

  line = f.readline()

  if len(line) == 0:

   break

  print line, 

 f.close()

 

#開始對sys.argv下定義

if len(sys.argv) < 2: #len小於2也就是不帶參數啦

 print 'no argument'

 sys.exit()

if sys.argv[1].startswith('--'):

 option = sys.argv[1][2:] # 取出sys.argv[1]的數值但是忽略掉'--'這兩個字元

 if option == 'version': 

  print 'Version 1.2.3'

 elif option == 'help':

  print 'help documention'

 else:

  print 'only --version --help can be used'

  sys.exit()

else:

 for filename in sys.argv[1:]: #檔案名稱於參數位置時讀取檔案

  readfile(filename)



"""

此檔案名稱為readfile.py

則可以用readfile.py --version來查詢版號

readfile.py --help來查詢help文件

readfile.py readme.txt 可以執行function

"""

2014年7月20日 星期日

AWS (Amazon Web Services) 練習django架站與linux shell的好工具


今天跟著教學申請了一個亞馬遜雲端服務帳號
http://blog.rx836.tw/blog/first-amazon-web-services/

原本一直考慮將我的windows換成ubuntu的想法可以暫停了
windows對於部分開源軟體的安裝實在是有點頭大
但是把我電腦重灌成linux使用起來可能就不是那麼方便了

AWS目前有一年免費可以使用
只要不要超過流量的話
如果真的能架出超過流量的網站(非用來大量上傳下載之類的)
我想付那個費用也是值得的

整個申請流程還算簡單
按照上面的Link做很快就能申請完成了
也速度建置了django基本的運作

目前容易卡關的小細節就是
AWS內運行的Instance並沒有對外的public IP
必須去申請一個
在左方控制那邊的 Elastic IP
申請完之後再把它allocate到你正在跑的instance就行了
不過ssh會被斷線要再重連一次
另外就是security group要設定好
不然外面連不進去也沒有用

Django的測試伺服器必須記得是使用

python mange.py runserver 0.0.0.0:8000
不設定0.0.0.0這個any ip的話
會只給本地端連線
自己的瀏覽器會無法連線過去

最後
不使用了記得到Elastic IP頁面Release IP
據說占著茅坑不拉屎會被罰錢




2014年7月18日 星期五

git 心得整理


Git是使用於版本控制的程式
GitHub是著名的Git網站也就是repository

Git有提供git shell能透過command line直接對repository下達clone push pull等等的命令
Git shell documentation
http://git-scm.com/docs/git-shell.html

Git shell使用ssh遠端加密操作
也就是自己電腦需要有private_key而public_key需要置放於repository
簡單的來說public_key就是鎖
private_key就是鑰匙
你可以將public_key放在很多repository
自己的電腦只要有private_key就能夠遠端登入每個有public_key的repository
產生key的方法為
開啟git shell輸入以下指令

ssh-keygen -t rsa -C "username@emailhost"
之後將private_key放置於program files\Git\bin內
並將public_key打開複製裡面的文字放置到github的產生SSH內

GitHub Default Storage的path如果為C:\abc\
repository專案名稱為def.git
則對應到C:\abc\def\ 資料夾內
下載方式為

git clone https://github.com/username/def.git

這張用小畫家畫的概念圖對新手應該有非常大的幫助



剩的就靠全中文的教學網站
Documentation正體中文

2014年7月14日 星期一

準備不夠?做就是在準備了!


我朋友說想去學英文會話

希望能夠跑國外路線的業務

依照我所認識的他

英文會話能力並不算太差

至少溝通上應該不會有問題才是


我跟他說

語言能力沒有環境下不練習就會退化

何必去學會話能力

認真去跑國外業務會話能力不就能夠提升了嗎?

我們總是希望在別人能表現自己最優秀的一面

但事實上你要如何去達到完美

現在世界變化如此迅速

等你練習到完美時或許環境又改變了

現在這個世界需要的是目的為導向

我相信國外的客戶不會因為你語言能力強大就跟你下訂單

既然目的是國外客戶的業務

語言不過是溝通的工具

不需要達到完美

能夠明確的表達產品的功能即可

說一口流利的英文的確是有加分作用

但我想那在客戶願不願意下訂單的影響是非常小的

重要的還是在於產品的功能與價格以及業務誠不誠實



當然許多事情有不同的目的

特別是一次性決定勝負的項目

譬如考試、面試、表演

這時自然準備就重要了許多囉

2014年7月11日 星期五

丟掉Monkeyrunner投向AndroidViewClient的懷抱吧!


Monkeyrunner是一套android device自動化測試的工具

腳本使用jython語言

詳細的介紹如下:
http://developer.android.com/tools/help/monkeyrunner_concepts.html

不過由於monkeydevice的takeSnapshot method丟出exception的機率太高

導致我不得不放棄monkeyrunner轉向AndroidViewClient

AndroidViewClient是純python語言寫成

原始碼在此
https://github.com/dtmilano/AndroidViewClient
Download

安裝方式為
windows內環境變數加上
變數:
ANDROID_VIEW_CLIENT_HOME
值:
C:\AndroidViewClient-master\AndroidViewClient\src

之後就能夠直接於python內調用了

連接上deivce並screenshot的範例腳本


from com.dtmilano.android.adb.adbclient import AdbClient

if len(sys.argv) >= 2:
    serialno = sys.argv[1]
else:
    serialno = '.*'

device = AdbClient(serialno=serialno)
img = device.takeSnapshot()




另外monkeyimage的功能必須使用PIL (Python Image Library)來替代
http://www.pythonware.com/products/pil/
讀取電腦中的picimg圖片與拍screenshot之後切圖下來的picimg2作比對的腳本
     

        #Monkeyrunner
picimp = MonkeyRunner.loadImageFromFile('./pic/picimp.png')
picimp2=device1.takeSnapshot()
picimp2=picimp2.getSubImage((300,660,150,70))
        if picimp.sameAs(picimp2) == 1:
     
        #AndroidViewClient with PIL
picimp = Image.open("../pic/picimp.png")
picimp2= device1.takeSnapshot(reconnect=True)
picimp2= picimp2.transform((150,60),Image.EXTENT, (300,660,450,720))
        if device1.sameAs(picimp, picimp2, 1)== 1:


整體來說
AndroidViewClient效率高出Monkeyrunner許多
而且takesnapshot也不像monkeydevice一樣太多的出錯
目前實測沒有出錯過
如果要跑長時間的測試有包含到takesnapshot
使用AndroidViewClient會好上許多

補充:
monkeyrunner下的read()與python的read()不太一樣
我的python file.read()讀不出tshark所擷取的封包資訊
反而monkeyrunner下使用的file.read()就能夠讀取出來
估計是monkeyrunner使用java的直譯器的關係

2014年7月9日 星期三

網路的發展是否將能夠傳送觸覺嗅覺與味覺呢?


N年前網路從貝爾實驗室發明出來之後(詳細歷史自行查閱吧XD)

一直發展至今

網路對於多數人已經是每天不可或缺生活要件

網路提供的便利性無遠弗屆

但一直以來Output都是影像與聲音

許多方面的應用不單單是只有影像或聲音就足夠的

我想這也是目前實體店面能夠持續生存的最大原因

就好比網路購買的物品來說

我們總是希望在電腦前面就能夠真實地感受到布料的觸覺

也希望在電腦前面就能夠決定這瓶香水適不適合自己

也想知道明天將寄送來的餅乾會不會吃一口就丟掉

但至今似乎還沒有適合的 solution來解決這部分的問題


一言以蔽之

科技還沒有進步到如此的階段

你相信未來我們在電腦前面(或許未來根本已經不需要電腦)

能夠接受到觸覺嗅覺與味覺嗎?

我相信是遲早的事情

3D列印已經能夠將物品的形狀透過網路來傳輸了

還有什麼是不能靠網路來傳輸的?

或許一件usb裝置搭載香料混合器就能夠產生不同的氣味

或許未來氣味也有類似RGB三原色的RGB三原味

僅需要提供數值就能透過裝置產生不同的氣味

或許有個裝置能產生不同味道只要你將它含在口中(不是這麼衛生就是了)

或許材料工程突破製造出能夠變換各種不同質感的物體

當然所有東西都必須數位化了

都需要制定規範了

未來的發展真的是能夠無限的想像


當人類對於腦部的研究夠透徹又如何?

所有的感官知覺要被操控接收就太過於簡單了

或許嗅覺檔案是直接去影響腦中分析嗅覺的區域來達到效果

其他部位的感官亦同

人體身上也有許多的 Input / Output

如果不要透過人體的Input直接將檔案傳送至腦部

所有的世界都將會不同

這部分的構想過去的小說電影都有提到了

魔鬼總動員+攔截記憶碼

但如果這一切真的發生了

我想這世界將會有許多的成癮者

希望自己永遠活在虛擬感官的接收中

再也不要醒過來



2014年7月7日 星期一

Runas 解決windows 7 batch script 權限問題的好幫手


今天在處理tshark.bat時卡在windows 7權限問題

tshark.bat內容:


tshark pppoes and host xx.xx.xx.xx

不斷的permission denied.

加入runas 能夠設定跑此bat檔的用戶是誰

不過較麻煩的是windows 7內至少要有兩名用戶否則無法使用

所以必須創立新的使用者帳戶

並且新增密碼


runas /user:tshark /savecred "C:\program files\wireshark\tshark.exe pppoes and host xx.xx.xx"

如果沒有/savecred則每次執行bat檔都要輸入一次密碼

有加入/savecred則第一次需要輸入之後就不需要輸入了


Python 檔案內搜索固定位置字串並取代文字




#欲寫入文字
number = 123


filea = open("abc.xml", "r+")          #開啟檔案,須以r+讀寫模式
fileaString = filea.read()                    #將檔案讀成字串
idFilter = 'Name="ID" Value='         #搜索檔案內特定的文字
idPosition = fileaString.find(idFilter)  #抓出檔案內特定的文字位置
filea.seek(idPosition+33,0)               #將當前檔案讀寫位置設定到想要改寫的地方
filea.write(str(user_num))                  #將字串寫入,整數需要先更改成字串
filea.close()                                       #關閉檔案


範例:

abc.txt檔案內容:

123456789
abcdefghijklmnop


filea = open("abc.txt", "r+")
fileaString = filea.read()
idFilter = 'cde'
idPosition = fileaString.find(idFilter)
filea.seek(idPosition,0)
filea.write('GUNGUNGUN')  
filea.close()

輸出結果:

123456789
aGUNGUNGUNklmnop

2014年7月1日 星期二

Wireshark tcpdump capture filter doesn't work


一直以來嘗試wireshark抓取封包只能利用Filter.

Capture Filter設上條件之後就抓不到任何封包了

原來是因為pppoe的關係

pppoe的封包檔頭與一般IP封包不同

所以capture filter設上條件會將pppoe給過濾掉

Capture Filter的設置方式為

pppoes and host xx.xx.xx.xx

就能夠作用囉



而tcpdump抓取pppoe封包的方式為

tcpdump ether[0x0c:2] == 0x8864

不過試了老半天依舊無法將host條件或-s給加進去阿

還是無法取得http header資訊

希望有高手幫忙解答了


2014/7/7補充

tcpdump無法解決pppoe的問題

改使用tshark總算成功了

tshark pppoes and host 123.123.123.123 and port 80


2014年6月30日 星期一

pwntcha安裝心得

由於有辨識captcha的需求
在網路上找到pwntcha開源套件

沒有編譯過原始碼經驗的我當然是困難重重

根據網路的資料來查找

看樣子使用Linux來編譯是會簡單許多

搞了一整天

利用VirtualBox安裝ubuntu 14.04 LTS

過程有點繁複

包含使用virtualbox guest addtion建立主客體之間的共用資料夾

(
簡短說明:
1.使用virtualbox 裝置->共用資料夾->新增出一個裝置(D_DRIVE)
2.於客體Linux內建立一個share資料夾(/home/ripple/share)
3.終端機輸入
mount -t vboxsf "裝置名稱" "掛載於Linux的path"
mount -t vboxsf D_DRIVE /home/ripple/share
)

開始安裝許多必要的套件(於編譯之前必定先安裝否則編譯將失敗)
切換至終端機 ctrl+alt+F2 或 ctrl+alt+T

sudo apt-get install libsdl1.2-dev libsdl1.2debian
sudo apt-get install libsdl1.2-dev (relatively large, 10M
sudo apt-get install libsdl-image1.2-dev
sudo apt-get install libsdl-mixer1.2-dev
sudo apt-get install libsdl-ttf2.0-dev
sudo apt-get install libsdl-gfx1.2-dev
sudo apt-get install libimlib2
sudo apt-get install libimlib2-dev
sudo apt-get install subversioin
Svn co svn :/ / svn.zoy.org / caca / pwntcha / trunk pwntcha
. / bootstrap
好的陣亡在這個步驟
說需要automake 1.5或以上的版本
sudo apt-get install automake autoconf
也都安裝好了就是無法./bootstrap

山不轉路轉
馬上抓了Fedora 20安裝(幾年不見都出到20了= =)
於virtualbox內安裝失敗
原因不明再次放棄
改安裝CentOS 6.5
有了先前安裝經驗
共用資料夾一下就建立好了
CentOS 比較麻煩阿repo內只有SDL1.2
libsdl-image
libsdl-image-devel
libsdl-mixer
libsdl-mixer-devel
都要從網路找rpm安裝
rpm -Uvh "rpm-package"
全部都安裝好後
到pwntcha的根資料夾
./bootstrap
./configure
make
make install
好的大功告成
cd /pwntcha/src
mkdir share
cd ..
開始搬資料到share資料夾內才可以開始用
ls -al 屬於資料夾的都要搬
(xanga,vbulletin,tickets,ticketmaster,slashdot,scode,phpbb,paypal)
cp -r xanga ./share
cp -r vbulletin ./share
...省略

總算是可以使用了
使用方式
pwntcha "圖片名"
啥~解不出來XD
再仔細閱讀
http://caca.zoy.org/wiki/PWNtcha
我要解的是屬於hoke
原來These captchas can currently not be defeated by PWNtcha
沒讀到這一行文字
看到圖片就高潮的下場就是白忙一場呢

2014年6月29日 星期日

這是一個起步


其實一直以來就覺得該開一個部落格了
原因無他
只是想要有個能夠備份自己所學習知識的工具罷了
過幾年後回頭審慎自己所寫的文章
再想想自己進步了多少

也可以在這邊抒發一些想法與心得
比起在Facebook內發些心得感想
然後開始與想法有出入的路人或交情甚薄的網友互相嘴砲
發文在這邊來的自由地多

有許多的東西想要學習
多數是程式設計方面
我一直深信專業不會賺錢
知識才能夠賺錢
或許有人反駁專業能領多少多少K
事實上不過是種薪水罷了
在我眼裡
賺錢不是一個月領多少K
而是你所擁有的的知識的連結能夠為你創造多少財富
學習程式設計也只是為了興趣
或許在學習的途中
能夠看見這些知識如何為我帶來財富

現階段的工作需求
所以主要以學習
python
monkeyrunner
Linux bash shell
C++
原本想學的arduino暫時先擱在一旁了
還有好多好多想學的東西
Java JavaScript C#
資訊真的是學不完