咸鱼的翻身技术

JAVA/JAVASCRIPT

Grails Day 6 Erepublik的统计工具

因为在 网页游戏 http://www.erepublik.com/en 担任某个企业的运营负责人,日常事务是负责统计玩家工作量,出具报表和发工资
由于游戏模式的固定化,所以考虑使用计算机帮我完成统计和出具报表的任务

一开始的想法是通过httpbuilder来抓取网页信息,然后将关键信息发送保存,但是由于grails和httpbuilder存在一个xml包的冲突,遂放弃

偶然间得知一个名为 greasemonkey 的fx插件,有了这个,我就可以通过js来控制其他host的dom结构,
由于是浏览器控件,没有js的安全控制,我可以将数据发送到后台,
前端部分和grails部分都比较简单,所以在数据库方面采用了mongodb..
作为一个自娱自乐的工具,已经是潮了 由于还要定时打开页面 自然要用上selenium-rc

greasemonkey的介绍 http://diveintogreasemonkey.org/toc/
mongodb的介绍 http://www.mongodb.org/display/DOCS/Home
selenium-rc插件 http://www.grails.org/Selenium+plugin

greasemonkey 的代码

访问的html页面 http://economy.erepublik.com/en/company/employees/smart-s-bread-good-/231891/46

// ==UserScript==
//
 @name           Record Erepublik Work
//
 @namespace      http://economy.erepublik.com/en/company/employees
//
 @include        http://economy.erepublik.com/en/company/employees*
//
 ==/UserScript==

var employees =  document.evaluate(
    
"//td[@class='el_employee']/div",
    document,
    
null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    
null);
var results = document.evaluate(
    
"//td[@class='el_day']",
    document,
    
null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    
null);
var results_currents = document.evaluate(
    
"//td[@class='el_day current']",
    document,
    
null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    
null);

var tokens = window.location.href.split('/')
var results = []
var summap = {company:tokens[tokens.length-2], 
              week:tokens[tokens.length
-1], 
              results: results,
              time: (
new Date()).getTime()}
for(var i=0; i<employees.snapshotLength; i++){
  
var employee = employees.snapshotItem(i)
  
var identity = employee.childNodes[1].innerHTML;
  results[results.length] 
= {id:identity,sum:0}
  
//alert(employee.childNodes[1].firstChild.innerHTML);
}
for(var j=0; j<results.snapshotLength;j++){
    
var result = results.snapshotItem(j)
    
if(result.childNodes.length > 1){
        results[parseInt(j
/6)].sum += parseInt(result.childNodes[1].innerHTML, 10)
    }
}
for(var j=0; j<results_currents.snapshotLength;j++){
    
var result = results_currents.snapshotItem(j)
    
if(result.childNodes.length > 1){
        results[j].sum 
+= parseInt(result.childNodes[1].innerHTML, 10)
    }
}

function obj2str(o){
   
var r = [];
   
if(typeof o == "string" || o == null) {
     
return o;
   }
   
if(typeof o == "object"){
     
if(!o.sort){
       r[
0]="{"
       
for(var i in o){
         r[r.length]
=i;
         r[r.length]
=":";
         r[r.length]
=obj2str(o[i]);
         r[r.length]
=",";
       }
       r[r.length
-1]="}"
     }
else{
       r[
0]="["
       
for(var i =0;i<o.length;i++){
         r[r.length]
=obj2str(o[i]);
         r[r.length]
=",";
       }
       r[r.length
-1]="]"
     }
     
return r.join("");
   }
   
return o.toString();
}

GM_xmlhttpRequest({
  method: 
"POST",
  url: 
"http://localhost:8080/erepublik/workResult/input",
  data: 
"jsonstr="+obj2str(summap),
  headers: {
    
"Content-Type""application/x-www-form-urlencoded"
  },
  onload: 
function(response) {
    console.info(response)
  }

});


grails
package erepublik

import grails.converters.JSON;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;
import com.mongodb.Mongo;

class WorkResultController {

    
static allowedMethods = [save: "POST", update: "POST", delete: "POST", input : "POST"]

    def index 
= {
        redirect(action: 
"list", params: params)
    }

    def input 
= {
        def resultsum 
= JSON.parse(params.jsonstr)
        
        def m 
= new Mongo()
        
        def db 
= m.getDB("erepublik")
        def coll 
= db.getCollection("work")
        
        
//coll.drop()
        
        BasicDBObject query 
= new BasicDBObject();
        query.put(
"week", resultsum.week);
        query.put(
"company", resultsum.company);
        
        def findone 
= coll.findOne(query);
        
        
if(findone){
            println 
'update'
            coll.update(findone , resultsum as BasicDBObject)
        }
else{
            println 
'insert'
            coll.insert(resultsum as BasicDBObject)
        }
        
        
/*DBCursor cur = coll.find();

        while(cur.hasNext()) {
            System.out.println(cur.next());
        }
*/
        
        render 
0    
    }
    
    def list 
= {
        def results 
= [] 
        def m 
= new Mongo()
        def db 
= m.getDB("erepublik")
        def coll 
= db.getCollection("work")
        
        [workResultInstanceList: coll.find(), workResultInstanceTotal: coll.find().count()]
    }

    def create 
= {
        def workResultInstance 
= new WorkResult()
        workResultInstance.properties 
= params
        
return [workResultInstance: workResultInstance]
    }

    def save 
= {
        def workResultInstance 
= new WorkResult(params)
        
if (workResultInstance.save(flush: true)) {
            flash.message 
= "${message(code: 'default.created.message', args: [message(code: 'workResult.label', default: 'WorkResult'), workResultInstance.id])}"
            redirect(action: 
"show", id: workResultInstance.id)
        }
        
else {
            render(view: 
"create", model: [workResultInstance: workResultInstance])
        }
    }

    def show 
= {
        def workResultInstance 
= WorkResult.get(params.id)
        
if (!workResultInstance) {
            flash.message 
= "${message(code: 'default.not.found.message', args: [message(code: 'workResult.label', default: 'WorkResult'), params.id])}"
            redirect(action: 
"list")
        }
        
else {
            [workResultInstance: workResultInstance]
        }
    }

    def edit 
= {
        def workResultInstance 
= WorkResult.get(params.id)
        
if (!workResultInstance) {
            flash.message 
= "${message(code: 'default.not.found.message', args: [message(code: 'workResult.label', default: 'WorkResult'), params.id])}"
            redirect(action: 
"list")
        }
        
else {
            
return [workResultInstance: workResultInstance]
        }
    }

    def update 
= {
        def workResultInstance 
= WorkResult.get(params.id)
        
if (workResultInstance) {
            
if (params.version) {
                def version 
= params.version.toLong()
                
if (workResultInstance.version > version) {
                    
                    workResultInstance.errors.rejectValue(
"version""default.optimistic.locking.failure", [message(code: 'workResult.label'default'WorkResult')] as Object[], "Another user has updated this WorkResult while you were editing")
                    render(view: 
"edit", model: [workResultInstance: workResultInstance])
                    
return
                }
            }
            workResultInstance.properties 
= params
            
if (!workResultInstance.hasErrors() && workResultInstance.save(flush: true)) {
                flash.message 
= "${message(code: 'default.updated.message', args: [message(code: 'workResult.label', default: 'WorkResult'), workResultInstance.id])}"
                redirect(action: 
"show", id: workResultInstance.id)
            }
            
else {
                render(view: 
"edit", model: [workResultInstance: workResultInstance])
            }
        }
        
else {
            flash.message 
= "${message(code: 'default.not.found.message', args: [message(code: 'workResult.label', default: 'WorkResult'), params.id])}"
            redirect(action: 
"list")
        }
    }

    def delete 
= {
        def workResultInstance 
= WorkResult.get(params.id)
        
if (workResultInstance) {
            
try {
                workResultInstance.delete(flush: 
true)
                flash.message 
= "${message(code: 'default.deleted.message', args: [message(code: 'workResult.label', default: 'WorkResult'), params.id])}"
                redirect(action: 
"list")
            }
            
catch (org.springframework.dao.DataIntegrityViolationException e) {
                flash.message 
= "${message(code: 'default.not.deleted.message', args: [message(code: 'workResult.label', default: 'WorkResult'), params.id])}"
                redirect(action: 
"show", id: params.id)
            }
        }
        
else {
            flash.message 
= "${message(code: 'default.not.found.message', args: [message(code: 'workResult.label', default: 'WorkResult'), params.id])}"
            redirect(action: 
"list")
        }
    }
}


posted on 2010-11-19 01:06 hopesfish 阅读(287) 评论(0)  编辑 收藏 引用 所属分类: grails

只有注册用户登录后才能发表评论。