Skype字典机器人(Java版)

有了上一篇的基础,在学习下skype的api, 就可以实现skype字典机器人功能了:-)

 

1. 下载skype java 开发包

http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/skype.tar.gz?view=tar

 

2. 将tar包里release文件夹下的jar加入到build path

 

3. 将上一篇(读取StarDict里的字典文件)用到的jar也加到build path, 同时注意配置好config.properties

 

4. 使用。

用了3个类来实现,

StarDict    根据输入的单词返回翻译结果 

WitRobot   与skype交互的类,监听输入消息,返回结果

Start        开启一个后台线程监听skype消息

 

 

 

package com.msino.dict;

import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.msino.dict.StarDictReader;
import com.msino.dict.manager.DictsManager;
import com.msino.dict.service.IDictsManager;
import com.msino.dict.service.core.Word;

/**
 * Get word info by word name
 * 
 * @author XuDong.Su
 * @version 0.1, Apr 10, 2009
 * @see com.msino.dict.StarDictReader
 */
public class StarDict {
	public static final Logger LOGGER = Logger.getLogger(StarDict.class.getName());
	
	private StarDictReader instance;
    private IDictsManager dictsManager = new DictsManager();
    private String dictsProp = dictsManager.getDictProps();

    private String dictFileDir = "";
	private String dictName = "";
	
	private HashMap<String, String> wordMap = new HashMap<String, String>();	
	
    /**
     * Default constructor.
     */
    public StarDict() {
    	// Get dictionary file directory and name
    	dictFileDir = dictsProp.substring(0, dictsProp.indexOf("||"));
    	dictName = dictsProp.substring(dictsProp.indexOf("||") + 2, dictsProp.length());
    			
        try {
            instance =  new StarDictReader(dictFileDir, dictName);
        } catch (FileNotFoundException ex) {
        	LOGGER.log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Lookup method, of class DictEngine.
     * @throws java.lang.InterruptedException Thread.sleep(long)
     */
    public String lookup(String wordName) throws InterruptedException {
    	String result = dictMap(wordName);
    	
    	// if the word exists in map, no need to research
    	if (!"".equals(result) && result != null) {
    		return result;
    	}
    	
    	try {
            Word word = null;

            long start = System.currentTimeMillis();
                        
            word = instance.lookup(wordName);
            result = word.self + ": " + word.definition;
            
            // Add word info into map
            wordMap.put(wordName, result);
            
            // For reduce memory
            if (wordMap.size() >= 5000) {
            	wordMap.clear();
            }
                       
            long end = System.currentTimeMillis();
            
            LOGGER.log(Level.INFO, word.self + ": " + word.definition);
            LOGGER.log(Level.INFO, "Space Time: " + (end - start) + "ms");
            LOGGER.log(Level.INFO, "word map size : " + wordMap.size());
            
        } catch (Exception ex) {
        	result = ex.getMessage();
        	LOGGER.log(Level.INFO, ex.getMessage());
        }
        
        return result;
    }
    
    /**
     * A cache of store has searched word
     * @param key
     * @return value
     */
    private String dictMap(String key) {
    	String value = (String) wordMap.get(key);
    	return value;
    }
}

 

package com.msino.skype;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.skype.ChatMessage;
import com.skype.ChatMessageAdapter;
import com.skype.Skype;
import com.skype.SkypeException;

import com.msino.dict.StarDict;

/**
 * Skype robot, start chat
 * 
 * @author XuDong.Su
 * @version 0.1, Apr 10, 2009
 */
public class WitRobot {
	public static final String FY = "/fy ";
	public static final String ERROR = "Sorry, you input command is not support yet, please use \"help\" or ? for more information!";
	public static final String HELP = "You can use blow command : \r\n1. Translate a word \r\n   /fy wordName \r\n2. Get help \r\n   ? or help";
	public static final String HELPCMD1 = "?";
	public static final String HELPCMD2 = "help";
	public static final String NOTFOUND = "Sorry, Not found the word.";
	
	public static final Logger LOGGER = Logger.getLogger(WitRobot.class.getName());
	
	private StarDict dict = null;
	
	public WitRobot() {
		// Initial class stardict
		dict = new StarDict();
	}
	
    public void startChat() throws Exception {
        Skype.addChatMessageListener(new ChatMessageAdapter() {
	        @Override	        
	        public void chatMessageReceived(ChatMessage receivedChatMessage) throws SkypeException {
	        	String content = "";
	        	String replyMsg = "";
	        	
	        	// Get input content
	        	content = receivedChatMessage.getContent().trim();
	            
	            if (!"".equals(content) && receivedChatMessage.getType().equals(ChatMessage.Type.SAID)) {
	            	// Get the word mean
	            	if(content.length() > 3 && FY.equals(content.substring(0, 4))) {
	            		content = content.substring(4, content.length());
	            		replyMsg = autoReplyMsg(content);
	            	} else if(HELPCMD1.equals(content) || HELPCMD2.equals(content)) {
	            		replyMsg = HELP;
	            	} else {
	            		replyMsg = ERROR;
	            	}
	            	
	            	if("".equals(replyMsg)) {
	            		replyMsg = NOTFOUND;
	            	}
	            	
	            	// reply the word's translate result
	            	receivedChatMessage.getSender().send(replyMsg);
	            	
	            }
	        }
	    });
	 }
     
    private String autoReplyMsg(String wordName) {
    	String replyMsg = "";
    	
		try {
			// Lookup word info by word name
			replyMsg = dict.lookup(wordName);
		} catch (InterruptedException e) {
			replyMsg = e.getMessage();
			LOGGER.log(Level.INFO, e.getMessage());
		}    	
		
    	return replyMsg;
    }
}

 

package com.msino.test;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.msino.skype.WitRobot;

/**
 * Test class, start a thread to listen message 
 * 
 * @author XuDong.Su
 * @version 0.1, Apr 10, 2009
 */
public class Start extends Thread {
	public static final Logger LOGGER = Logger.getLogger(Start.class.getName());
	
	public Start() {
		setDaemon(true);
		super.start();
	}

	public void run() {
		// do nothing
	}

	public void noStop() {
		try {
			Thread t = new Thread();
			synchronized (t) {
				t.wait();
			}
		} catch (InterruptedException e) {
			LOGGER.log(Level.SEVERE, null, "Wait thread error!" + e);
		}
	}

	public static void main(String[] args) throws Exception {
		
        long freeMemory = Runtime.getRuntime().freeMemory() / 1024;
        LOGGER.log(Level.INFO, "Before Free memory : " + freeMemory);
                
		Start s = new Start();
		WitRobot chat = new WitRobot();
		
		// Start chat
		chat.startChat();
		
		freeMemory = Runtime.getRuntime().freeMemory() / 1024;
		LOGGER.log(Level.INFO, "After Free memory : " + freeMemory);

		s.noStop();
	}
}

 

 

5. 运行Start类, 然后尝试向本机的skype发送消息. 如果你启动中碰到下面的错误,请将release文件夹下的swt-win32-3232.dll放到你的jave/jre/bin目录下

 

java.lang.UnsatisfiedLinkError: no swt-win32-3232 in java.library.path

.....

 

6. 演示效果:

skypedict

 

7. 疑问:

以前用openfire可以整个google talk server, 因为gtalk基于japper协议. 但skype不基于这个协议,我现在实现的方式是在本地开启一个后台线程监听skype消息, 但不知如何部署在server上,哪位大虾知道的,还请指导下,非常感谢 :-)

 

If you have any query, please feel free to contact me -- m.msino##gmail.com

 

 

 

 

 

你可能感兴趣的:(java,thread,cgi,cvs,Gmail)