首页 > Wiz, Wiz二次开发 > WizKnowledge插件范例:自动下载博客插件

WizKnowledge插件范例:自动下载博客插件


WizKnowledge自带了一个自动下载博客的插件,利用这个插件,您可以在指定的时间,自动下载一个博客里面新发布的文章。下面是这个插件的原理介绍。

该插件在WizKnowledge安装目录下面的plugins\{6957D596-7CD9-4ddf-A129-7BD093BC5320}文件夹中。

该文件夹一共有三个文件:


首先看Plugin.ini文件,这个是插件描述文件

在Common部分,描述了插件的名称,GUID,类型(目前仅支持Normal),版本以及插件功能的数量(1)。

[Common]
AppName=Blog Downloader…
AppName_2052=博客下载器…
AppName_1028=博客下载器…
AppGUID={6957D596-7CD9-4ddf-A129-7BD093BC5320}
AppType=Normal
AppVersion=1.0
PluginCount=1

在Plugin_0部分,描述了具体的插件功能:

[Plugin_0]
Caption=Blog Downloader…
Caption_2052=博客下载器…
Caption_1028=博客下载器…
GUID={8324D9C5-46B2-4f2e-8D26-12B5B610AFF1}
HtmlDialogFileName=BlogDownloader.htm
HtmlDialogTitle=Blog Downloader
HtmlDialogTitle_2052=博客下载器
HtmlDialogTitle_1028=博客下载器
HtmlDialogWidth=500
HtmlDialogHeight=630
Type=HtmlDialog
BeginGroup=0

这部分描述了插件的功能,是一个Html对话框类型的插件。同时制定了Html文件名:BlogDownloader.htm。

Strings部分,是插件的字符串资源,主要是为了支持多语言。

然后是BlogDownloader.htm文件。这个就是插件功能的界面部分,用户点击“博客下载器”这个菜单后,WizKnowledge会显示一个Html对话框。Html对话框里面的内容,就是这个Html文件。

这个Html界面如下:

其中都是一些标准的html表单控件,例如编辑框,复选框,下拉框。比较特殊的一个就是WizKnowledge目录树。这个目录树,是一个ActiveX控件,可以显示WizKnowledge数据库里面的目录。

Html代码如下:

                <object id=”folder” classid=”clsid:26C7C9DF-8814-4FB5-925A-C720E75C924A” width=”300″ height=”250″>
                </object>
其中26C7C9DF-8814-4FB5-925A-C720E75C924A就是WizKnowledge目录树的ActiveX控件的class id。

用户的操作,以及插件的功能实现,都在通过html里面的脚本实现的

<script language=“JavaScript” type=“text/javascript”>
    //
    function formatInt(val)    //格式化整数,主要是用来生成日期类型的目录
    {
        if (val < 10)
            return “0″ + val;
        else
            return “” + val;
    }
    //
    function OnFolderSelChanged() {        //当用户更改了选中的文件夹(目录树ActiveX控件),在html里面,动态显示用户选择的目录。
        var selectedFolder = folder.SelectedFolder;    //选中的文件夹
        if (selectedFolder != null
            && textBlogName.value != null
            && textBlogName.value != “”) {    //如果不为空
            labelSaveToResult.innerHTML = “<strong>” + selectedFolder.Location + textBlogName.value + “/</strong>”;    //显示用户的选择的目录
        }
    }    
    //
    var objApp = new ActiveXObject(“WizExplorer.WizExplorerApp”);            //获得当前正在运行WizExplorer实例
    var objCommon = new ActiveXObject(“WizKMControls.WizCommonUI”);    //一个通用的函数库
    var database = objApp.Database;    //获得WizExplorer正在打开的数据库
    //
    var appGUID = objApp.GetPluginAppGUID(document);    //获得当前插件的App GUID,也可以直接通过Plugin.ini获得。
    //
    for (var i = 0; i < 24; i++) {    //添加24小时定时下载下拉框
        var optionTime1 = document.createElement(“OPTION”);
        optionTime1.value = formatInt(i) + “:00″;
        optionTime1.text = optionTime1.value;
        selectTime.add(optionTime1);
        //
        var optionTime2 = document.createElement(“OPTION”);
        optionTime2.value = formatInt(i) + “:00″;
        optionTime2.text = optionTime2.value;
        selectTime.add(optionTime2);
    }
    //
    var settings_meta = “Plugin_BlogDownloader”;    //用户录入的信息保存在数据库中,以便下次直接显示用户上次输入的信息。这个变量设置了保存信息的位置,类似于ini文件的section。
    //
    textBlogName.value = database.Meta(settings_meta, “BlogName”) ;    //从已经保存的记录中初始化博客名称
    textRssFeedURL.value = database.Meta(settings_meta, “RssFeedURL”);    //博客URL
    checkAddToTaskScheduler.checked = database.Meta(settings_meta, “AddToTaskScheduler”);    //是否添加到计划任务
    var downloadTime = database.Meta(settings_meta, “AutoDownloadTime”);    //自动下载的时间
    if (downloadTime == null || downloadTime == “”)
        downloadTime = “12:00″;
    selectTime.value = downloadTime;
    if (selectTime.selectedIndex == -1)
        selectTime = 24;
    //
    var saveContentOnly = database.Meta(settings_meta, “SaveContentOnly”);    //是否只保存正文
    if (saveContentOnly == null || saveContentOnly == “” || saveContentOnly == “1″)
        checkSaveContentOnly.checked = true;
    //
    if (textBlogName.value == null || textBlogName.value == “”) {
        textBlogName.value = objApp.LoadPluginString(appGUID, “WizBrotherBlogName”);
    }
    if (textRssFeedURL.value == null || textRssFeedURL.value == “”) {
        textRssFeedURL.value = objApp.LoadPluginString(appGUID, “WizBrotherBlogFeedURL”);
    }
    //
    folder.Database = database;    //初始化目录树
    folder.StateSection = “Folder_Plugin_BlogDownloader”;    //设置目录树的记录状态
    folder.Border = true;    //设置显示边框
    folder.OnSelChanged = OnFolderSelChanged;    //响应用户选择目录事件
    //
    objApp.PluginLocalizeHtmlDialog(document);        //本地化html对话框
    //
    function CloseDialog(ret) {    //当用户点击确定或者取消按钮的时候,关闭对话框
        if (ret == 1) {    //如果用户点击了确定按钮,检查用户录入的信息
            if (textBlogName.value == null || textBlogName.value == “”) {
                alert(objApp.LoadPluginString(appGUID, “EnterBlogName”));
                textBlogName.focus();
                return;
            }
            if (textRssFeedURL.value == null || textRssFeedURL.value == “”) {
                alert(objApp.LoadPluginString(appGUID, “EnterRssFeedURL”));
                textRssFeedURL.focus();
                return;
            }
            //
            var selectedFolder = folder.SelectedFolder;
            if (selectedFolder == null){
                alert(objApp.LoadPluginString(appGUID, “SelectFolder”));
                return;
            }
            //
            var pluginPath = objApp.AppPath + “plugins\\” + appGUID + “\\”;    //获得插件的路径
            var scriptTemplateFileName = pluginPath + “BlogDownloader.js”;    //BlogDownloader.js是一个下载Blog的脚本模板
            //
            var scriptText = objCommon.LoadTextFromFile(scriptTemplateFileName);    //加载脚本模板
            //
            scriptText = scriptText.replace(“%blog_name%”, textBlogName.value);    //替换模板里面的博客名称
            scriptText = scriptText.replace(“%rss_feed_url%”, textRssFeedURL.value.replace(/\\/g, “\\\\”));    //替换模板里面的rss种子
            scriptText = scriptText.replace(“%save_to%”, selectedFolder.Location);    //替换博客中的选中的文件夹location
            scriptText = scriptText.replace(“%database_path%”, database.DatabasePath.replace(/\\/g, “\\\\”));    //替换模板中的数据库路径
            scriptText = scriptText.replace(“%save_content_only%”, checkSaveContentOnly.checked ? “1″ : “0″);    //替换模板中的是否保存正文的参数
            //
            var scriptFileName = objApp.DataStore + “BlogDownloaderScripts\\Download “ + textBlogName.value + “.js”;    //设置利用模板生成的新的脚本文件的文件名
            //
            objCommon.SaveTextToFile(scriptFileName, scriptText, “”);    //保存成脚本文件
            //
            var exeFileName = objCommon.GetSpecialFolder(“SystemFolder”) + “wscript.exe”;    //获得wscript文件名
            //
            objCommon.RunExe(exeFileName, “\”" + scriptFileName + “\”", false);    //执行脚本
            //
            database.Meta(settings_meta, “BlogName”) = textBlogName.value;        //保存用户录入的信息
            database.Meta(settings_meta, “RssFeedURL”) = textRssFeedURL.value;
            database.Meta(settings_meta, “AddToTaskScheduler”) = checkAddToTaskScheduler.checked ? “1″ : “0″;
            database.Meta(settings_meta, “AutoDownloadTime”) = selectTime.value;
            database.Meta(settings_meta, “SaveContentOnly”) = checkSaveContentOnly.checked ? “1″ : “0″;
            //
            if (checkAddToTaskScheduler.checked) {    //如果用户选择了添加到计划任务,则将加入js计划任务中。
                var schtasksFileName = objCommon.GetSpecialFolder(“SystemFolder”) + “schtasks.exe”;   
                var schtasksParams = “/Create /TN \”WizBrother\\BlogDownloader\\Download “ + textBlogName.value + “\” /SC DAILY /ST “ + selectTime.value + “:00 /TR \”‘” + scriptFileName + “‘\”";
                objCommon.RunExe(schtasksFileName, schtasksParams, false);
            }
        }
        //
        objApp.Window.CloseHtmlDialog(document, ret);    //关闭对话框
    }  
</script>    

BlogDownloader.js文件

这是一个下载博客的模板文件,在BlogDownloader.Htm里面,使用用户录入的信息替换模板中的变量,然后生成一个真正的js文件。

var BLOG_NAME = “%blog_name%”;    //博客名称
var RSS_URL = “%rss_feed_url%”;        //rss种子URL
var SAVE_TO = “%save_to%”;        //保存文件夹
var DATABASE_PATH = “%database_path%”;    //数据库文件夹
var SAVE_CONTENT_ONLY = “%save_content_only%”;    //是否只保存正文
//
var objDatabase = new ActiveXObject(“WizKMCore.WizDatabase”);        //创建数据库对象
objDatabase.Open(DATABASE_PATH);    //打开数据库
//
function jsAlert(msg) {
    var objShell = new ActiveXObject(“WScript.Shell”); 
    return objShell.Popup(msg, 10000, “WizKnowledge”, 0);
}
function formatInt(val) {
    if (val < 10)
        return “0″ + val;
    else
        return “” + val;
}
//利用MSXml获得RSS节点
function getRssItemNodes() {
    var objXml = new ActiveXObject(“MSXML.DOMDocument”);
    objXml.async = false;
    if (!objXml.load(RSS_URL)) {
        jsAlert(“Can not download: “ + RSS_URL)
        return null;
    }
    //
    var channelNode = objXml.selectSingleNode(“/rss/channel”);
    if (channelNode == null) {
        jsAlert(“\”" + RSS_URL + “\” is not a valid rss feed”);
        return null;
    }
    //
    return channelNode.childNodes;
}
//获得保存网页的flag
function getUpdateDocumentFlags() {
    var wizUpdateDocumentSaveSel = 0×0001;
    var wizUpdateDocumentIncludeScript = 0×0002;
    var wizUpdateDocumentShowProgress = 0×0004;
    var wizUpdateDocumentSaveContentOnly = 0×0008;
    var wizUpdateDocumentSaveTextOnly = 0×0010;
    var wizUpdateDocumentDonotDownloadFile = 0×0020;
    var wizUpdateDocumentAllowAutoGetContent = 0×0040;
    //是否只保存正文
    var flag = 0;
    if (SAVE_CONTENT_ONLY == “1″)
        flag |= wizUpdateDocumentSaveContentOnly;
    return flag;
}
//获得当前日期
var myDate = new Date();
var year = myDate.getFullYear();
var month = myDate.getMonth() + 1;
var day = myDate.getDate();
//保存的博客所在的文件夹
var document_location = SAVE_TO + BLOG_NAME + “/” + year + formatInt(month) + “/”;
//获得RSS里面链接
var arrayLinks = new Array();
//
var nodes = getRssItemNodes();
if (nodes != null) {
    for (var i = nodes.length - 1; i >= 0; i) {
        var node = nodes[i];
        //
        if (node.nodeType != 1)
            continue;
        //
        if (node.nodeName != “item”)
            continue;
        //
        var linkNode = node.selectSingleNode(“link”);
        if (null == linkNode)
            continue;
        //
        //
        var link = linkNode.text;
        if (link == null || link.length == 0)
            continue;
        //
        try {
            //从数据库中通过URL查询,如果已经保存过,就不再重新保存
            var documents = objDatabase.DocumentsFromURL(link);
            if (documents != null && documents.Count > 0)
                continue;
        }
        catch (e) {
        }
        //
        var titleNode = node.selectSingleNode(“title”);
        var title = null;
        if (titleNode != null)
            title = titleNode.text;
        if (title == null)
            title = “”;
        //
        arrayLinks.push(link);
        arrayLinks.push(title);
    }
}
//
//下载任务
if (arrayLinks.length > 0) {
    var objDownloader = new ActiveXObject(“WizKMControls.WizBatchDownloader”);    //创建批量下载网页的对象
    //
    var flags = getUpdateDocumentFlags();
    //
    for (var i = 0; i < arrayLinks.length; i += 2) {
        var link = arrayLinks[i];
        var title = arrayLinks[i + 1];
        //添加任务
        if (title.length == 0) {
            objDownloader.AddJob(DATABASE_PATH, document_location, link, “”, flags, true, true);
        }
        else {
            objDownloader.AddJob(DATABASE_PATH, document_location, link, title, flags, true, true);
        }
    }
    //显示下载窗口,并且自动开始下载。
    objDownloader.ShowWindow(true);
}

通过上面的描述,我们可以看到WizKnowledge的二次开发能力是非常的强大。


分类: Wiz, Wiz二次开发 标签:
  1. 屎壳郎
    2010年1月30日06:15 | #1

    强大无比,希望WizK越来越强大

  2. Knight
    2010年6月5日03:23 | #2

    很好很强大,个人认为Wiz唯有2点美中不足
    一就是就是视图了,虽然界面很漂亮,但是仅大纲视图(分类列和搜索列)占用太大空间,导致正文显示的面板太小,而对于频繁切换页面的人来说,全屏太不方便,所以建议作者改进一下视图,最好能切换成树状管理发刚模式
    还有一个是编辑窗口和显示窗口独立,能嵌入到显示窗口就好了

  1. 本文目前尚无任何 trackbacks 和 pingbacks.

Spam Protection by WP-SpamFree