home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 September / PCWorld_2008-09_cd.bin / komunikace / kmeleon / K-Meleon1.1.3en-US.exe / chrome / newsfox.jar / content / newsfox / opml.js < prev    next >
Text File  |  2007-09-29  |  16KB  |  484 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is NewsFox.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Andy Frank <andy@andyfrank.com>.
  18.  * Portions created by the Initial Developer are Copyright (C) 2005-2007
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  *   Andrey Gromyko <andrey@gromyko.name>
  23.  *   Ron Pruitt <wa84it@gmail.com>
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the LGPL or the GPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. const BACKUPS = "backups";
  40. const NUMBACKUP = 5;
  41.  
  42. var numNewFeed = 0;
  43. var fromBackup = true;
  44. var opmlStack = new Array();
  45. var stackIndex = 0;
  46.  
  47. ////////////////////////////////////////////////////////////////
  48. // Export OPML
  49. ////////////////////////////////////////////////////////////////
  50.  
  51. function exportOpml()
  52. {
  53.   var picker = Components.classes["@mozilla.org/filepicker;1"].
  54.     createInstance(Components.interfaces.nsIFilePicker);
  55.   picker.init(window, "Export OPML", picker.modeSave);
  56.   picker.appendFilter("OPML Files (*.xml, *.opml)", "*.xml;*.opml");
  57.   picker.appendFilters(picker.filterAll);
  58.   picker.defaultString = "newsfox.opml";
  59.   
  60.   var result = picker.show();
  61.   if(result == picker.returnOK || result == picker.returnReplace)
  62.     {
  63.         var file = picker.file;
  64.         if(file.exists()) file.remove(true);
  65.         file.create(file.NORMAL_FILE_TYPE, 0666);
  66.         expOpml(file,true);
  67.     }
  68. }
  69.  
  70. function expOpml(file,report)
  71. {
  72.     try 
  73.     {
  74.         var srcTemplate =  '<?xml version="1.0" encoding="UTF-8"?>';
  75.         srcTemplate += "<opml version=\"1.0\">\n";
  76.         srcTemplate += "<head>\n\t<title>NewsFox OPML Export</title>\n";
  77.         var currentDate = new Date();
  78.         srcTemplate += "\t<dateModified>" + currentDate.toString() + "</dateModified>\n";
  79.         srcTemplate += "</head>\n";
  80.         srcTemplate += "<body/>\n</opml>";
  81.  
  82.         var opmlDoc = new DOMParser().parseFromString(srcTemplate, "text/xml");
  83.         var opmlBody = opmlDoc.getElementsByTagName("body")[0];
  84.  
  85.         var groupNode, feedNode, feed;
  86.         for (var i=0; i<gFdGroup.length; i++)
  87.         {
  88.             groupNode = opmlDoc.createElement("outline");
  89.             groupNode.setAttribute("text",gFdGroup[i].title);
  90.             if (gFdGroup[i].search)
  91.             {
  92.                 var srchdat = gFdGroup[i].srchdat;
  93.                 groupNode.setAttribute("type","NFsearch");
  94.                 groupNode.setAttribute("NFflagged",srchdat.flagged);
  95.                 groupNode.setAttribute("NFunread",srchdat.unread);
  96.                 groupNode.setAttribute("NFtext",srchdat.text);
  97.                 groupNode.setAttribute("NFtextflags",srchdat.textflags);
  98.                 groupNode.setAttribute("NFstartTime",srchdat.startTime);
  99.                 groupNode.setAttribute("NFendTime",srchdat.endTime);
  100.             }
  101.             else
  102.                 groupNode.setAttribute("type","NFgroup");
  103.             opmlBody.appendChild(groupNode);
  104.             for (var j=0; j<gFdGroup[i].list.length; j++)
  105.             {
  106.                 feed = gFmodel.get(gFdGroup[i].list[j]);
  107.                 feedNode = opmlDoc.createElement("outline");
  108.                 feedNode.setAttribute("type","rss");
  109.                 feedNode.setAttribute("text",feed.getDisplayName());
  110.                 feedNode.setAttribute("xmlUrl",feed.url);
  111.                 feedNode.setAttribute("htmlUrl",feed.homepage);
  112.                 feedNode.setAttribute("NFuid",feed.uid);
  113.                 feedNode.setAttribute("NFdeleteOld",feed.deleteOld);
  114.                 feedNode.setAttribute("NFdeleteUnread",!feed.dontDeleteUnread);
  115.                 feedNode.setAttribute("NFautoCheck",feed.autoCheck);
  116.                 feedNode.setAttribute("NFstyle",feed.style);
  117.                 groupNode.appendChild(feedNode);
  118.             }
  119.         }  
  120.  
  121.         var opmlSource = new XMLSerializer().serializeToString(opmlDoc);
  122.         var unicodeConverter = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].getService(Components.interfaces.nsIScriptableUnicodeConverter);
  123.         unicodeConverter.charset = "UTF-8";
  124.         opmlSource = unicodeConverter.ConvertFromUnicode(opmlSource);
  125.  
  126.       var out = Components.classes['@mozilla.org/network/file-output-stream;1'].
  127.         createInstance(Components.interfaces.nsIFileOutputStream);
  128.       out.init(file, 2, 0x200, false); // open as "write only"
  129.       
  130.         println(out, opmlSource);
  131.       out.close();
  132.  
  133.         const NF_SB = document.getElementById("newsfox-string-bundle");
  134.         var rpt = NF_SB.getString('opmlexport');  
  135.       if (report) alert(rpt);
  136.     } 
  137.     catch (err) 
  138.     {
  139.       if (report) alert("Export failed: " + err);
  140.     }
  141. }
  142.  
  143. function backupOpml()
  144. {
  145.     var now = new Date();
  146.     var nowFilename = getBackupFilename(now);
  147.     var file = getProfileDir();
  148.     file.append(BACKUPS);
  149.     if (!file.exists()) file.create(file.DIRECTORY_TYPE, 0750);
  150.     file.append(nowFilename);
  151.     if(file.exists())
  152.         return;
  153.     else
  154.     {
  155.         var backupDir = getProfileDir();
  156.         backupDir.append(BACKUPS);
  157.         var backupEnum = backupDir.directoryEntries;
  158.         var dirFiles = new Array();
  159.         var i = 0;
  160.         while (backupEnum.hasMoreElements())
  161.             dirFiles[i++] = backupEnum.getNext().QueryInterface(Components.interfaces.nsILocalFile);
  162.         for (i=0; i<dirFiles.length-(NUMBACKUP-1); i++)
  163.             dirFiles[i].remove(false);
  164.         file.create(file.NORMAL_FILE_TYPE, 0666);
  165.         expOpml(file,false);
  166.     }
  167. }
  168.  
  169. function getBackupFilename(date)
  170. {
  171.     var year = date.getFullYear();
  172.     var month = date.getMonth() + 1;
  173.     month = (month < 10 ? "0" : "") + month;
  174.     var date1 = date.getDate();
  175.     date1 = (date1 < 10 ? "0" : "") + date1;
  176.     var filename = "newsfox-"+year+"-"+month+"-"+date1+".opml";
  177.     return filename;
  178. }
  179.  
  180. ////////////////////////////////////////////////////////////////
  181. // Import OPML
  182. ////////////////////////////////////////////////////////////////
  183.  
  184. function restoreBackup()
  185. {
  186.     importOpml(true,true,false);
  187. }
  188.  
  189. function importOpml(fromBackup,fromFile,removeDir)
  190. {
  191.     if (removeDir)
  192.     {
  193.         for (var i=gFmodel.size()-1; i>=0; i--)
  194.             deleteFeedFromDisk(gFmodel.get(i));
  195.         makeNewModels();
  196.         var feedtree = document.getElementById("newsfox.feedTree");
  197.         feedtree.view = new FeedTreeModel();
  198.     }
  199.     if (!fromFile) // from URL
  200.     {
  201.         const NF_SB = document.getElementById("newsfox-string-bundle");
  202.         var prmpt = NF_SB.getString('opmlhttpimportprompt');
  203.         var url = window.prompt(prmpt,"http://","Import OPML");
  204.         if (url) impOpml(url,fromBackup);
  205.         return;
  206.     }
  207.   var picker = Components.classes["@mozilla.org/filepicker;1"].
  208.     createInstance(Components.interfaces.nsIFilePicker);
  209.     if (fromBackup)
  210.     {
  211.         var backupDir = getProfileDir();
  212.         backupDir.append(BACKUPS);
  213.         picker.displayDirectory = backupDir;
  214.     }
  215.   picker.init(window, "Import OPML", picker.modeOpen);
  216.   picker.appendFilter("OPML Files (*.xml, *.opml)", "*.xml;*.opml");
  217.   picker.appendFilters(picker.filterAll);
  218.  
  219.   if(picker.show() == picker.returnOK)
  220.     {
  221.         var nsIPH = Components.classes["@mozilla.org/network/protocol;1?name=file"].createInstance(Components.interfaces.nsIFileProtocolHandler);
  222.         var url = nsIPH.getURLSpecFromFile(picker.file);
  223.         impOpml(url,fromBackup);
  224.     }
  225. }
  226.  
  227. function makeNewModels()
  228. {
  229.   var arttree = document.getElementById("newsfox.articleTree");
  230.     gCollect = new EmptyCollection();
  231.     arttree.view = null;  
  232.     arttree.view = new ArticleTreeModel();
  233.   var file = getProfileDir();
  234.   file.append("master.xml");
  235.     if (file.exists()) file.remove(false);
  236.   file = getProfileDir();
  237.   file.append("master_index.xml");
  238.     if (file.exists()) file.remove(false);
  239.   file = getProfileDir();
  240.   file.append("master_group.xml");
  241.     if (file.exists()) file.remove(false);
  242.     gFmodel = new FdModel();
  243.     gFdGroup = new Array();
  244.     gIdx = new Indexes();
  245.     loadModels();
  246. }
  247.  
  248. function impOpml(url,fromBackup)
  249.     try 
  250.     {
  251.         loadingTooltip(true);
  252.         if (fromBackup) makeNewModels();
  253.  
  254.         var fix = Components.classes['@mozilla.org/docshell/urifixup;1'].getService(Components.interfaces.nsIURIFixup);
  255.         url = fix.createFixupURI(url, fix.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP);
  256.  
  257.         // Locks up browser - not sure why - same code as file.js
  258.         //var xml = document.implementation.createDocument("","",null);
  259.         //xml.async = false;
  260.         //xml.load(url.spec);
  261.       
  262.         var req = new XMLHttpRequest();
  263.         req.open("GET", url.spec, false);
  264.         req.overrideMimeType("application/xml");
  265.         req.send(null);
  266.         var xml = req.responseXML;
  267.  
  268.     opmlStack = xml.getElementsByTagName("outline");
  269.         numNewFeed = 0;
  270.         stackIndex = 0;
  271.         setTimeout(addOpmlFeed,1);  // adds new feeds and then groups
  272.     }
  273.     catch (err)
  274.     {
  275.         alert("Import failed: " + err);
  276.     }
  277. }
  278.  
  279. function addOpmlFeed()
  280. {
  281.     if (stackIndex == opmlStack.length)
  282.     {
  283.         addOpmlGroups();
  284.         return;
  285.     }
  286.     setPmeter((100*stackIndex)/opmlStack.length);
  287.     var kid = opmlStack[stackIndex];
  288.     var isNew, url, j, uid;
  289.     url = kid.getAttribute("xmlUrl");
  290.     if (url != null)
  291.     {
  292.         isNew = true;
  293.         for (j=0; j<gFmodel.size(); j++)
  294.             if (url == gFmodel.get(j).url)
  295.             {
  296.                 isNew = false;
  297.                 kid.setAttribute("newsfox",j);
  298.             }
  299.         if (isNew)
  300.         {
  301.             var feed = createNewFeed(gFmodel, url, false, false);
  302.             kid.setAttribute("newsfox",gFmodel.size()-1);
  303.             var uid = kid.getAttribute("NFuid");
  304.             var ktext = kid.getAttribute("text");
  305.             if (ktext != null) feed.customName = ktext;
  306.             var khome = kid.getAttribute("htmlUrl");
  307.             if (khome != null) feed.homepage = khome;
  308.             if (uid != null)
  309.             {
  310.                 feed.deleteOld = false;
  311.                 if (kid.getAttribute("NFdeleteOld") == "true")
  312.                     feed.deleteOld = !feed.deleteOld;
  313.                 feed.dontDeleteUnread = false;
  314.                 if (kid.getAttribute("NFdeleteUnread") == "false")
  315.                     feed.dontDeleteUnread = !feed.dontDeleteUnread;
  316.                 feed.autoCheck = false;
  317.                 if (kid.getAttribute("NFautoCheck") == "true")
  318.                     feed.autoCheck = !feed.autoCheck;
  319.                 feed.style = kid.getAttribute("NFstyle");
  320.             }
  321.             if (fromBackup && uid != null)
  322.             {
  323.             // has to be unique if from an *unmodified* Newsfox file
  324.                 var uniq = true;
  325.                 for (j=0; j<gFmodel.size(); j++)
  326.                     if (uid == gFmodel.get(j).uid) uniq = false;
  327.                 if (uniq) feed.uid = feed.defaultName = uid;
  328.             }
  329.             numNewFeed++;
  330.         }
  331.     }
  332.     stackIndex++;
  333.     setTimeout(addOpmlFeed,1);
  334. }
  335.  
  336. function addOpmlGroups()
  337. {
  338.     try
  339.     {
  340.         var grpKids, feedNumber, grp, num;
  341.         var numNewGrp = 0;
  342.         for (i=0; i<opmlStack.length; i++)
  343.         {
  344.             var grptype = opmlStack[i].getAttribute("type");
  345.             if (grptype == "rss") continue;
  346.             grp = new FeedGroup();
  347.             if (grptype == "NFgroup")
  348.                 grp.search = false;
  349.             else if (grptype == "NFsearch")
  350.             {
  351.                 grp.search = true;
  352.                 grp.srchdat.flagged = opmlStack[i].getAttribute("NFflagged");
  353.                 grp.srchdat.unread = opmlStack[i].getAttribute("NFunread");
  354.                 grp.srchdat.text = opmlStack[i].getAttribute("NFtext");
  355.                 grp.srchdat.textflags = opmlStack[i].getAttribute("NFtextflags");
  356.                 grp.srchdat.startTime = opmlStack[i].getAttribute("NFstartTime");
  357.                 grp.srchdat.endTime = opmlStack[i].getAttribute("NFendTime");
  358.             }
  359.             grp.title = opmlStack[i].getAttribute("text");
  360.             grpKids = opmlStack[i].getElementsByTagName("outline");
  361.             for (j=0; j<grpKids.length; j++)
  362.             {
  363.                 feedNumber = grpKids[j].getAttribute("newsfox");
  364.         if (feedNumber == null) continue;
  365.                 grp.list.push(feedNumber);
  366.             }
  367.             isNew = true;
  368.             if (!grp.search)
  369.             {
  370.                 for (j=0; j<gFdGroup.length; j++)
  371.                     if (grp.title == gFdGroup[j].title)
  372.                         if (grp.list.length == gFdGroup[j].list.length)
  373.                         {
  374.                             isNew = false;
  375.                             for (var k=0; k<grp.list.length; k++)
  376.                                 if (grp.list[k] != gFdGroup[j].list[k]) isNew = true;
  377.                         }
  378.             }
  379.  
  380.             if (isNew)
  381.             {
  382.                 num = gFdGroup.length;
  383.                 gFdGroup.push(grp);
  384.                 gIdx.fdgp.push(num);
  385.                 gIdx.feed.push(-1);
  386.                 gIdx.catg.push(0);
  387.                 gIdx.open.push(false);
  388.                 numNewGrp++;
  389.             }
  390.         }
  391.         var feedtree = document.getElementById("newsfox.feedTree");
  392.         var fRow = feedtree.treeBoxObject.getFirstVisibleRow();
  393.         feedtree.view = new FeedTreeModel();
  394.         if (fromBackup)
  395.         {
  396.             feedtree.view.selection.select(0);
  397.             markFlaggedUnread(false,false);
  398.         }
  399.         else
  400.         {
  401.             feedtree.view.selection.select(-1);
  402.         feedtree.treeBoxObject.scrollToRow(fRow);
  403.         }
  404.         saveModels();
  405.         setPmeter(0);
  406.         loadingTooltip(false);
  407.         const NF_SB = document.getElementById("newsfox-string-bundle");
  408.         if (opmlStack.length == 0)
  409.         {
  410.             var rptfail = NF_SB.getString('opmlfail');
  411.             alert(rptfail);
  412.         }
  413.         else
  414.         {
  415.             var rpt = NF_SB.getString('opmlimport');
  416.             var rptnfeed = NF_SB.getString('opmlnewfeeds');
  417.             var rptngroup = NF_SB.getString('opmlnewgroups');
  418.       alert(rpt + "\n\n" + numNewFeed + " " + rptnfeed + "\n" + numNewGrp + " " + rptngroup);
  419.         }
  420.     }
  421.     catch (err)
  422.     {
  423.         alert("Import failed: " + err);
  424.     }
  425. }
  426.  
  427. ////////////////////////////////////////////////////////////////
  428. // Export RSS
  429. ////////////////////////////////////////////////////////////////
  430.  
  431. function exportRSS()
  432. {
  433.   var picker = Components.classes["@mozilla.org/filepicker;1"].
  434.     createInstance(Components.interfaces.nsIFilePicker);
  435.   picker.init(window, "Export to RSS", picker.modeSave);
  436.   picker.appendFilter("XML Files (*.xml)", "*.xml");
  437.   picker.appendFilters(picker.filterAll);
  438.   picker.defaultString = "rss.xml";
  439.   
  440.   var result = picker.show();
  441.   if(result == picker.returnOK || result == picker.returnReplace)
  442.     {
  443.         var file = picker.file;
  444.         if(file.exists()) file.remove(true);
  445.         file.create(file.NORMAL_FILE_TYPE, 0666);
  446.  
  447.         var out = openOutputStream(file, 0x02 | 0x08 | 0x20);
  448.         println(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
  449.         println(out, "<rss version=\"2.0\">\n\t<channel>");
  450.         var title = "<![CDATA[Newsfox: " + toUTF8(gCollect.getTitle()) + "]]>";
  451.         println(out, "\t\t<title>" + title + "</title>");
  452.         println(out, "\t\t<link>file:///" + file.path.replace(/\\/g,"\/") + "</link>");
  453.         println(out, "\t\t<description>" + title + "</description>");
  454.         var now = new Date().toUTCString();
  455.         println(out, "\t\t<lastBuildDate>" + now + "</lastBuildDate>");
  456.         println(out, "\t\t<generator>Newsfox " + VERSION + "</generator>");
  457.         for (var i=0; i<gCollect.size(); i++)
  458.         {
  459.             var art = gCollect.get(i);
  460.             println(out, "\t\t<item>");
  461.             println(out, "\t\t\t<title><![CDATA[" + toUTF8(art.title) + "]]></title>");
  462.             println(out, "\t\t\t<link><![CDATA[" + art.link + "]]></link>");
  463.             if (art.id)
  464.                 println(out, "\t\t\t<guid><![CDATA[" + art.id + "]]></guid>");
  465.             println(out, "\t\t\t<pubDate>" + art.date.toUTCString() + "</pubDate>");
  466.             if (art.category != "")
  467.                 println(out, "\t\t\t<category><![CDATA[" + toUTF8(art.category) + "]]></category>");
  468.             var feed = gCollect.getFeed(i);
  469.             if (feed.url.substring(0,5) == "http:")
  470.                 println(out, "\t\t\t<source url=\"" + encodeHTML(feed.url) + "\"><![CDATA[" + toUTF8(feed.getDisplayName()) + "]]></source>");
  471.             println(out, "\t\t\t<description><![CDATA[" + toUTF8(art.body) + "]]></description>");
  472.             for (var j=0; j<art.enclosures.length; j++)
  473.             {
  474.                 var enc = art.enclosures[j];
  475.                 println(out, "\t\t\t<enclosure url=\"" + encodeHTML(enc.url) + "\" type=\"" + encodeHTML(enc.type) + "\" length=\"" + encodeHTML(enc.length) + "\"/>");
  476.             }
  477.             println(out, "\t\t</item>");
  478.         }
  479.         println(out, "\t</channel>\n</rss>");
  480.         out.close();
  481.     }
  482. }
  483.