package org.arong.egdownloader.model; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.net.SocketTimeoutException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.swing.JDialog; import javax.swing.JTextArea; import org.apache.commons.httpclient.ConnectTimeoutException; import org.arong.egdownloader.spider.SpiderException; import org.arong.egdownloader.spider.WebClient; import org.arong.egdownloader.spider.WebClientException; import org.arong.egdownloader.ui.window.CreatingWindow; import org.arong.util.FileUtil; import org.arong.util.JsonUtil; import org.arong.util.Tracker; /*import sun.org.mozilla.javascript.internal.Context; import sun.org.mozilla.javascript.internal.Function; import sun.org.mozilla.javascript.internal.Scriptable;*/ /** * 脚本解析器 * @author dipoo * @since 2015-01-04 */ public class ScriptParser { private static ScriptEngineManager manager = new ScriptEngineManager(); private static File createScriptFile; private static File collectScriptFile; private static File downloadScriptFile; private static File searchScriptFile; public static void clearFiles(){ createScriptFile = null; collectScriptFile = null; downloadScriptFile = null; searchScriptFile = null; } public static File getCreateScriptFile(String filePath) { if(createScriptFile == null){ createScriptFile = new File(filePath); } return createScriptFile; } public static File getCollectScriptFile(String filePath) { if(collectScriptFile == null){ collectScriptFile = new File(filePath); } return collectScriptFile; } public static File getDownloadScriptFile(String filePath) { if(downloadScriptFile == null){ downloadScriptFile = new File(filePath); } return downloadScriptFile; } public static File getSearchScriptFile(String filePath) { if(searchScriptFile == null){ searchScriptFile = new File(filePath); } return searchScriptFile; } /** * 解析外部js文件并得到返回结果 * @return Object */ public static Object parseJsScript(Map<String, Object> params, File scriptFile) throws FileNotFoundException, ScriptException{ ScriptEngine engine = manager.getEngineByName("js"); if(params != null){ for(String key : params.keySet()){ engine.put(key, params.get(key)); } } Object result = engine.eval(new FileReader(scriptFile)); return result; } /** * 解析外部js文件并得到返回结果 * @return Object */ /*public static Object parseJsScriptUseRhino(File scriptFile, String function, Object[] functionArgs) throws FileNotFoundException, IOException{ //开始调用javascript函数 Context cx = Context.enter(); try { Scriptable scope = cx.initStandardObjects(); FileReader reader = new FileReader(scriptFile); cx.evaluateReader(scope, reader, "<cmd>", 1, null); Object fObj = scope.get(function, scope); if (!(fObj instanceof Function)) { System.out.println("找不到方法:" +function); } else { Function f = (Function)fObj; Object result = f.call(cx, scope, scope, functionArgs); return result; } }finally { Context.exit(); } return null; }*/ /** * 创建任务 * @throws IOException * @throws NoSuchAlgorithmException * @throws KeyManagementException */ public static Task buildTaskByJavaScript(Task task, Setting setting, JDialog window) throws SpiderException, WebClientException, ScriptException, KeyManagementException, NoSuchAlgorithmException, IOException{ CreatingWindow creatingWindow = (CreatingWindow)window; if(task.getId() == null){ task.setId(UUID.randomUUID().toString()); } String source = WebClient.getRequestUseJavaWithCookie(task.getUrl(), null, setting.getCookieInfo());//WebClient.postRequestWithCookie(task.getUrl(), setting.getCookieInfo()); Map<String, Object> param = new HashMap<String, Object>(); param.put("htmlSource", source); Task t = JsonUtil.json2bean(Task.class, parseJsScript(param, getCreateScriptFile(setting.getCreateTaskScriptPath())).toString()); //获取名称 task.setName(t.getName()); //获取子名称 task.setSubname(t.getSubname()); //获取漫画类别 task.setType(t.getType()); //获取封面路径 task.setCoverUrl(t.getCoverUrl()); //获取数目及大小 task.setTotal(t.getTotal()); task.setSize(t.getSize()); //设置下载结束索引 task.setEnd(task.getTotal()); //获取漫画语言 task.setLanguage(t.getLanguage()); Tracker.println(ScriptParser.class, task.getName()); Tracker.println(ScriptParser.class, task.getSubname()); Tracker.println(ScriptParser.class, task.getType()); Tracker.println(ScriptParser.class, task.getLanguage()); Tracker.println(ScriptParser.class, task.getTotal() + ""); Tracker.println(ScriptParser.class, task.getSize()); Tracker.println(ScriptParser.class, task.getCoverUrl()); creatingWindow.nameLabel.setText(creatingWindow.nameLabel.getText() + task.getName()); creatingWindow.subnameLabel.setText(creatingWindow.subnameLabel.getText() + task.getSubname()); creatingWindow.totalLabel.setText(creatingWindow.totalLabel.getText() + task.getTotal()); creatingWindow.sizeLabel.setText(creatingWindow.sizeLabel.getText() + task.getSize()); creatingWindow.languageLabel.setText(creatingWindow.languageLabel.getText() + task.getLanguage()); creatingWindow.nameLabel.setVisible(true); creatingWindow.subnameLabel.setVisible(true); creatingWindow.totalLabel.setVisible(true); creatingWindow.sizeLabel.setVisible(true); creatingWindow.languageLabel.setVisible(true); creatingWindow.bar.setMaximum(task.getTotal()); task.setSaveDir(task.getSaveDir() + "/" + FileUtil.filterDir(task.getName())); //获取图片集合 //计算页数(每40张一页) int page = task.getTotal() % setting.getPageCount() == 0 ? task.getTotal() / setting.getPageCount() : task.getTotal() / setting.getPageCount() + 1; List<Picture> pictures = null; int currCount = 0; for(int i = 0; i < page; i++){ if(i == page - 1){ currCount = task.getTotal();// - (page - 1) * setting.getPageCount(); }else{ currCount = (i + 1) * setting.getPageCount(); } try{ if(i == 0){ pictures = collectpictrues(source, setting.getCollectPictureScriptPath(), creatingWindow); }else{ source = WebClient.getRequestUseJavaWithCookie(task.getUrl() + "?" + setting.getPageParam() + "=" + i, null, setting.getCookieInfo());//WebClient.postRequestWithCookie(task.getUrl() + "?" + setting.getPageParam() + "=" + i, setting.getCookieInfo()); pictures.addAll(collectpictrues(source, setting.getCollectPictureScriptPath(), creatingWindow)); } }catch(Exception e){ //未采集状态 task.setStatus(TaskStatus.UNCREATED); } creatingWindow.bar.setValue(currCount); } if(pictures != null){ int i = 0; for(Picture pic : pictures){ pic.setId(UUID.randomUUID().toString()); pic.setTid(task.getId()); pic.setNum(genNum(task.getTotal(), i)); pic.setSaveAsName(setting.isSaveAsName()); i ++; } } task.setPictures(pictures); return task; } /** * 收集图片 * @return List<Picture> */ private static List<Picture> collectpictrues(String source, String scriptPath, CreatingWindow creatingWindow) throws ConnectTimeoutException, SocketTimeoutException, SpiderException, FileNotFoundException, ScriptException{ Map<String, Object> param = new HashMap<String, Object>(); param.put("htmlSource", source); Object o = parseJsScript(param, getCollectScriptFile(scriptPath)); return JsonUtil.jsonArray2beanList(Picture.class, o.toString()); } /** * 重建任务,主要重新采集语言、封面、小标题等信息 * @throws IOException * @throws NoSuchAlgorithmException * @throws KeyManagementException */ public static void rebuildTask(Task task, Setting setting) throws SpiderException, ScriptException, WebClientException, KeyManagementException, NoSuchAlgorithmException, IOException{ // if("".equals(task.getSubname()) || "".equals(task.getType()) || "".equals(task.getCoverUrl()) // ||"".equals(task.getSize()) || "".equals(task.getLanguage())){ String source = WebClient.getRequestUseJavaWithCookie(task.getUrl(), null, setting.getCookieInfo()); Map<String, Object> param = new HashMap<String, Object>(); param.put("htmlSource", source); Task t = JsonUtil.json2bean(Task.class, parseJsScript(param, getCreateScriptFile(setting.getCreateTaskScriptPath())).toString()); task.setName(t.getName()); //获取子名称 task.setSubname(t.getSubname()); //获取类别 task.setType(t.getType()); //获取封面路径 task.setCoverUrl(t.getCoverUrl()); //获取大小 task.setSize(t.getSize()); //获取漫画语言 task.setLanguage(t.getLanguage()); // } } /** * 获取图片真实下载地址 * @throws IOException * @throws NoSuchAlgorithmException * @throws KeyManagementException */ public static String getdownloadUrl(String taskName, String sourceUrl, Setting setting) throws WebClientException, KeyManagementException, NoSuchAlgorithmException, IOException{ String url = null; String source = WebClient.getRequestUseJavaWithCookie(sourceUrl, null, setting.getCookieInfo()); try { Map<String, Object> param = new HashMap<String, Object>(); param.put("htmlSource", source); param.put("down_original", setting.isDownloadOriginal());//是否下载原图 url = parseJsScript(param, getDownloadScriptFile(setting.getDownloadScriptPath())).toString(); } catch (Exception e) { e.printStackTrace(); Tracker.println(ScriptParser.class, taskName + ":getdownloadUrl异常,请检查" + setting.getDownloadScriptPath() + "脚本是否出现问题!"); return null; } Tracker.println(url); return url; } /** * 搜索漫画列表,第一个元素为分页信息字符串,格式为 count,pageCount; * 第二个元素为漫画列表JSON字符串 */ public static String[] search(String source, Setting setting) throws ConnectTimeoutException, SocketTimeoutException, FileNotFoundException, ScriptException{ Map<String, Object> param = new HashMap<String, Object>(); param.put("htmlSource", source); Object result = parseJsScript(param, getSearchScriptFile(setting.getSearchScriptPath())); return result == null ? null : result.toString().split("\\###"); } public static void testScript(String url, JTextArea resultArea, Setting setting, boolean create, boolean collect, boolean download){ String source; try { source = WebClient.getRequestUseJavaWithCookie(url, null, setting.getCookieInfo()); Map<String, Object> param = new HashMap<String, Object>(); param.put("htmlSource", source); Object result = parseJsScript(param, getCreateScriptFile(setting.getCreateTaskScriptPath())); if(result == null){ resultArea.setText(setting.getCreateTaskScriptPath() + "脚本解析出错\r\n"); return; } Task t = JsonUtil.json2bean(Task.class, result.toString()); t.setUrl(url); if(create){ //展示任务信息 resultArea.setText("---任务---\r\n" + t.getScriptMember()); } if(collect){ result = parseJsScript(param, getCollectScriptFile(setting.getCollectPictureScriptPath())); if(result == null){ resultArea.setText(setting.getCollectPictureScriptPath() + "脚本解析出错\r\n"); return; } //展示图片信息 resultArea.setText(resultArea.getText() + "\r\n---图片列表---\r\n" + result.toString()); if(download){ //展示第一张图片的真实下载地址 List<Picture> pics = JsonUtil.jsonArray2beanList(Picture.class, result.toString()); if(pics != null){ source = WebClient.getRequestUseJavaWithCookie(pics.get(0).getUrl(), null, setting.getCookieInfo()); param.put("htmlSource", source); result = parseJsScript(param, getDownloadScriptFile(setting.getDownloadScriptPath())); if(result == null){ resultArea.setText(setting.getDownloadScriptPath() + "脚本解析出错\r\n"); return; } resultArea.setText(resultArea.getText() + "\r\n---第一张图片的真实下载地址---\r\n" + result.toString()); } } }else if(download){ Object o = parseJsScript(param, getCollectScriptFile(setting.getCollectPictureScriptPath())); //展示第一张图片的真实下载地址 List<Picture> pics = JsonUtil.jsonArray2beanList(Picture.class, o.toString()); if(pics != null){ source = WebClient.getRequestUseJavaWithCookie(pics.get(0).getUrl(), null, setting.getCookieInfo()); param.put("htmlSource", source); result = parseJsScript(param, getDownloadScriptFile(setting.getDownloadScriptPath())); if(result == null){ resultArea.setText(setting.getDownloadScriptPath() + "脚本解析出错\r\n"); return; } resultArea.setText(resultArea.getText() + "\r\n---第一张图片的真实下载地址---\r\n" + result.toString()); } } } catch (ConnectTimeoutException e) { resultArea.setText(resultArea.getText() + "\r\n======异常======" + "网络连接超时"); } catch (SocketTimeoutException e) { resultArea.setText(resultArea.getText() + "\r\n======异常======" + "网络连接超时"); } catch (FileNotFoundException e) { resultArea.setText(resultArea.getText() + "\r\n======异常======" + e.getMessage()); } catch (ScriptException e) { resultArea.setText(resultArea.getText() + "\r\n======异常======" + e.getMessage()); } catch (Exception e) { resultArea.setText(resultArea.getText() + "\r\n======异常======" + e.getMessage()); } } /**public static void testScriptUseRhino(String url, JTextArea resultArea, Setting setting, boolean create, boolean collect, boolean download){ String source; try { source = WebClient.postRequestWithCookie(url, setting.getCookieInfo()); Object[] args = {source}; //Task t = JsonUtil.json2bean(Task.class, parseJsScript(param, getCreateScriptFile(setting.getCreateTaskScriptPath())).toString()); Object result = parseJsScriptUseRhino(getCreateScriptFile(setting.getCreateTaskScriptPath()),"parse", args); if(result == null){ resultArea.setText(setting.getCreateTaskScriptPath() + "脚本解析出错\r\n"); return; } Task t = JsonUtil.json2bean(Task.class, result.toString()); t.setUrl(url); if(create){ //展示任务信息 resultArea.setText("---任务---\r\n" + t.getScriptMember() + "\r\n"); } if(collect){ result = parseJsScriptUseRhino(getCollectScriptFile(setting.getCollectPictureScriptPath()),"parse", args); if(result == null){ resultArea.setText(resultArea.getText() + setting.getCollectPictureScriptPath() + "脚本解析出错\r\n"); return; } //展示图片信息 resultArea.setText(resultArea.getText() + "\r\n---图片列表---\r\n" + result.toString() + "\r\n"); if(download){ //展示第一张图片的真实下载地址 List<Picture> pics = JsonUtil.jsonArray2beanList(Picture.class, result.toString()); if(pics != null){ source = WebClient.postRequestWithCookie(pics.get(0).getUrl(), setting.getCookieInfo()); args[0] = source; result = parseJsScriptUseRhino(getDownloadScriptFile(setting.getDownloadScriptPath()),"parse", args); if(result == null){ resultArea.setText(resultArea.getText() + setting.getDownloadScriptPath() + "脚本解析出错\r\n"); return; } resultArea.setText(resultArea.getText() + "\r\n---第一张图片的真实下载地址---\r\n" + result.toString() + "\r\n"); } } }else if(download){ result = parseJsScriptUseRhino(getCollectScriptFile(setting.getCollectPictureScriptPath()),"parse", args); //展示第一张图片的真实下载地址 List<Picture> pics = JsonUtil.jsonArray2beanList(Picture.class, result.toString()); if(pics != null){ source = WebClient.postRequestWithCookie(pics.get(0).getUrl(), setting.getCookieInfo()); args[0] = source; result = parseJsScriptUseRhino(getDownloadScriptFile(setting.getDownloadScriptPath()),"parse", args); if(result == null){ resultArea.setText(resultArea.getText() + setting.getDownloadScriptPath() + "脚本解析出错\r\n"); return; } resultArea.setText(resultArea.getText() + "\r\n---第一张图片的真实下载地址---\r\n" + result.toString()); } } } catch (ConnectTimeoutException e) { resultArea.setText(resultArea.getText() + "\r\n======异常======" + "网络连接超时"); } catch (SocketTimeoutException e) { resultArea.setText(resultArea.getText() + "\r\n======异常======" + "网络连接超时"); } catch (FileNotFoundException e) { resultArea.setText(resultArea.getText() + "\r\n======异常======" + e.getMessage()); } catch (Exception e) { resultArea.setText(resultArea.getText() + "\r\n======异常======" + e.getMessage()); } }*/ /** * * @param total * @param index * @return */ public static String genNum(int total, int index){ int bit = 2; if(total <= 10){ bit = 2; }else if(total <= 100){ bit = 3; }else if(total <= 1000){ bit = 4; }else if(total <= 10000){ bit = 5; }else{ bit = 6; } String num = ""; int index_ = index + 1; for(int i = 1; i < bit - (index_ + "").length(); i++){ num += "0"; } return num + index_; } }