Ӑ°ŕDXŘ+.*Vš"Oűť!Ę  !A MQ ]š Ÿľť!ĘÁ Éauthor Dave Winer authorEmaildwiner@cyber.law.harvard.edu description homePageUrl9http://static3.userland.com/mtweblog/archives/000059.htmlnameMy Weblog Outliner releaseDateversion0.3. š"Oúť´ j l"Arial ˇî?'ş#!Ŕsva HLAND˙˙˙˙˙˙winChanges 10/23/02; 4:53:36 PM by DW Runs on the user's machine, when refreshing. local (adrtable = @system.temp.myWeblogOutlinerSnapshot) myWeblogOutlinerInfo = adrtable^.info myWeblogOutlinerNodeTypes = adrtable^.nodeTypes myWeblogOutlinerSuite = adrtable^.suite myWeblogOutlinerWebsite = adrtable^.website myWeblogOutlinerWindowTypes = adrtable^.windowTypes filemenu.savemyroot (@myWeblogOutlinerSuite) local (x = string.parseAddress (@myWeblogOutlinerSuite), f = x [1]) frontier.tools.install (f) dialog.notify ("Thanks for updating.") „„€€€€€€€€€€€€€€€€€BĆ Arial ˇî?ŽšÜ‚ő`ľ  \LAND˙˙˙˙˙˙win10/17/02; 8:22:08 AM by DW This is the Refresh menu command. local (url = "http://radio.weblogs.com/0001015/userland/publicTools/myWeblogOutliner/codeFreshener.fttb") local (urllist = string.urlsplit (url)) local (s = tcp.httpclient (server:urllist [2], path:urllist [3])) local (f = frontier.pathstring + "codeFreshener.fttb") file.writewholefile (f, s) fatpages.importfatfile (f) thread.callscript (@system.temp.myWeblogOutlinerSnapshot.loader, {}) „€€€€€€€€€€€iœUArial ˇî=÷ş#!Ć%H%zLLAND˙˙˙˙˙˙winChanges 10/23/02; 4:43:35 PM by DW Created. myWeblogOutlinerInfo.releaseDate = clock.now () local (adrtable = @system.temp.myWeblogOutlinerSnapshot) new (tabletype, adrtable) adrtable^.info = myWeblogOutlinerInfo adrtable^.nodeTypes = myWeblogOutlinerNodeTypes adrtable^.suite = myWeblogOutlinerSuite adrtable^.website = myWeblogOutlinerWebsite adrtable^.windowTypes = myWeblogOutlinerWindowTypes adrtable^.loader = myWeblogOutlinerSuite.codeFreshener.loadNewCode local (folder = "C:\\Program Files\\Radio UserLand\\www\\userland\\publicTools\\myWeblogOutliner\\") local (f = folder + "codeFreshener.fttb") file.surefilepath (f) export.sendobject (adrtable, f) f = folder + "myWeblogOutliner.root" target.set (this) fileMenu.saveCopy (f) radio.thread.wake () dialog.alert (file.filefrompath (f) + " is " + string.megabytestring (file.size (f))) „€€€€€€€€€€€€€€€€€€€€€€€€€i×}.¸RŽ?¸RŽG  $0 ? loadNewCodež refreshCodeĐreleaseNewCode\VArial Ş‚3x¤1×W6ŠArial šÚŕîť!ÄB­ŠYŇLAND˙˙˙˙˙˙win 1 25 bold €€€€€€€€€W:6šÚŕßšÚčT virginRules ´:€ ´4ˆ„Arial šÚÄjť!Ĺ,?M[ILAND˙˙˙˙˙˙winChanges 10/22/02; 9:01:37 AM by DW Created. Manages a windowType called weblogPost. Creates and edits posts using the MetaWeblog API. if not defined (Frontier.tools.data.wind€,€Ü#~xHArial ťÍŐEťÍÚą!˛Ô'LAND˙˙˙˙˙˙winon testGuiAtts (adroutline) local(i=1) window.bringToFront(adroutline) local(origsetting = op.getDisplay()) op.setDisplay(false) op.firstSummit() loop op.attributes.setOne("gid",i) i++ if not op.go(down,1) break op.setDisplay(origsetting) wp.newtextobject (op.outlineToXml(adroutline,"me","it"), @scratchpad.saveddescription) testGuiAtts(@system.temp.windowTypes.windows.["0000017"].window) New Algorithm iterate through assigning a gui id create an outline copy, save it map any new post ids to gids in @user.myWeblogOutliner.temp map gui ids to new post ids €€€€€€€€€€€€€€„€€€€€8€˜#~ŕ ;Arial "ťˇnwťÍŰ40<ř0LAND˙˙˙˙˙˙winon saveWeblogPage (adroutline, flClosing=false) Changes 11/2/03; 10:19:50 PM by AG Created. Loops through top-level headlines comparing each to the last saved version and posting new items or edited items as necessary. local (origsetting = op.getDisplay()) op.setDisplay(false) local (atts, opatts) window.attributes.getAll (@atts, adroutline) myWeblogOutlinerSuite.initAtts (@atts) on flowto (adrtable) if adrtable^.enabled //flow out through Blogger or MetaWeblog API local (data, username, password) bundle //create data table, set username, password new (tabletype, @data) data.appKey = "E260BC1A1004B61C2DF853E73909E912897D0C" data.blogid = adrtable^.blogid data.port = adrtable^.port data.protocol = "xml-rpc" data.rpcPath = adrtable^.rpcPath data.server = adrtable^.server username = adrtable^.username password = string (adrtable^.password) if (data.server == "127.0.0.1") and (data.port == 5335) //if the Blogger API is not enabled, enable it if not weblogData.prefs.flBloggerApiEnab€  ÷÷&bArial ťŐŹýťŮšűC'ëˇdLAND˙˙˙˙˙˙mac on ensureGidsAndPostIdMap (adr) Changes 11/10/03; 9:29:08 PM by AG Created. Ensures that every top-level headline has a gid, or "gui id" attribute. These are used to map local ids to remotely generated post ids, which in turn is used to minimize the need to interact with the live outline during save operations. 11/11/03; 9:45:01 PM by AG Added code to update the window's postIdMap attribute. The postIdMap doesn't get saved to OPML, but we can generate it each time we open a file. local(gid=1,copy = adr^,currgid, currid, flNeedsUpdate=false, oldtarget, flSavedPostIdMap=true, postIdMap) bundle //Initialize the postIdMap if not window.attributes.getOne("postIdMap",@postIdMap, adr) new(tableType,@postIdMap) flSavedPostIdMap = false bundle //Check to see if we need to update the outline passed-in oldtarget = target.set(@copy) op.firstSummit() loop if op.attributes.getOne("gid",@currgid) if gid <= number(currgid) gid = number(currgid) + 1 if not flSavedPostIdMap //Probably we're loading this outline up from a file, so we're going to build the postIdMap for use in future save operations. if op.attributes.getOne("id",@currid) postIdMap.[currgid] = currid else flNeedsUpdate = true if not op.go(down,1) break target.set(oldtarget) if (flNeedsUpdate) oldtarget = target.set(adr) local(origsetting = op.getDisplay()) op.setDisplay(false) local(cursor=op.getCursor()) op.firstSummit() loop if not op.attributes.getOne("gid",@currgid) op.attributes.setOne("gid",string(gid)) if op.attributes.getOne("id",@currid) postIdMap.[string(gid)] = currid gid++ if not op.go(down,1) break op.setCursor(cursor) op.setDisplay(origsetting) target.set(oldtarget) window.attributes.setOne("gid",gid,adr) bundle //only update the window's postIdMap if it doesn't have one. Otherwise we blow away new id's generated by save operations since opening the window. if not flSavedPostIdMap window.attributes.setOne("postIdMap", postIdMap,adr) bundle //debug ensureGidsAndPostIdMap (@system.temp.windowTypes.windows.["0000001"].window) €„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ ÷ň nArial ťˇnĐťËZt˘jƒLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.menuCommands.refreshTodayFromWeb () myWeblogOutlinerSuite.menuCommands.newWeblogPage () €€ň€c/LšÜťËX  $0 >J Xd x„ Š newServer-r newWeblogItem/F newWeblogPage˛Ö oldWeblogPageqërefreshTodayFromWeb.:setup0¤VArial Ş‚3„ž+@€/F^Arial š"OűťËWĎ JĽ&LAND˙˙˙˙˙˙winMyWeblogOutliner Set Up.. New Weblog Post.. New Weblog Page Refresh Today's Page From Web €€ *Ş€ +`€ ś+€ "€€ď/ž]pšŞ´4ëJćîÇ隞ŻÂśé[ŠžŠ1ˇÎ,Ě˛Ś€dT™ Arial ťÍŐEťÍŘú˛Ô+LAND˙˙˙˙˙˙winon testGuiAtts (adroutline) local(i=1) window.bringToFront(adroutline) local(origsetting = op.getDisplay()) op.setDisplay(false) op.firstSummit() loop op.attributes.setOne("gid",i) i++ if not op.go(down,1) break op.setDisplay(origsetting) wp.newtextobject (op.outlineToXml(adroutline,"me","it"), @scratchpad.saveddescription) testGuiAtts(@system.temp.windowTypes.windows.["0000017"].window) €€€€€€€€€€€€€€€€€€€cą6Arial šŰôŞş#‹ł} @LAND˙˙˙˙˙˙winon initAtts (adratts) Changes 10/23/02; 6:39:52 AM by DW Created. myWeblogOutlinerSuite.init () if not defined (adratts^.ctSaves) adratts^.ctSaves = 0 if not defined (adratts^.siteName) adratts^.siteName = user.myWeblogOutliner.prefs.currentSite €„€€€€€€€ąŞ,Arial Tť!É.ť!É5ýBĹĂLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.menuCommands.setup () €Ş˛4Arial š"OűšÜ(?JĽ&LAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.menuCommands.newWeblogItem () €˛€Ě˛Ś&.Arial€&š Arial ťˇo ťˇo °j{LAND˙˙˙˙˙˙winon newWeblogPage () €€€Ěpuuk6Arial ‚0*VpČ2Arial ş"zIş#ç A?ęLAND˙˙˙˙˙˙winif dialog.ask ("URL for the site:", @user.myWeblogOutliner.prefs.urlNewServer) local (protocols) if metaweblog.utilities.getRsdSiteInfo (user.myWeblogOutliner.prefs.urlNewServer, @protocols) scratchpad.protocols = protocols; edit (@scratchpad.protocols) //debugging if defined (protocols.MetaWeblog) €€€€€ČRČArial šÜş#uÖ”@FLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.init () if dialog.ask ("Title for new weblog post?", @user.myWeblogOutliner.settings.newPostTitle) myWeblogOutlinerSuite.newWindow (user.myWeblogOutliner.settings.newPostTitle) €€€R}Arial ť!ÉNť!ɛƒUKÓLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.init () edit (@user.myWeblogOutliner.sites.default) window.zoom (@user.myWeblogOutliner.sites.default) €€€€Î,.šÜť!ÉN  $0 6 newServer-r newWeblogItem/Fsetup0¤VArial €˘ 1ˇ˘,̲Ś$€ÎD´Arial šÚčšî‘˜ĺYÇOLAND˙˙˙˙˙˙winon newWindow (title) return (Frontier.tools.windowTypes.newWindow ("weblogPost", false, title, outlineType, false, nil)) bundle //test code newwindow ("Testing a Local Outline") €€€€DŹ2Arial š.F•š.ró-ĹňĹ›LAND˙˙˙˙˙˙winon archive () Changes 6/13/02; 12:54:55 PM by DW Created. on breakUpOutline (adroutline, adrtable) local (copy1 = adroutline^, i, oldtarget = target.get ()) for i = 1 to op.countsummits () local (copy2 = copy1, j) target.set (@copy2) op.firstsummit () edit (@copy2) //debugging for j = 1 to i - 1 op.deleteline () op.go (down, 1) for j = 1 to op.countsummits () - 1 op.deleteline () op.go (down, 1) adrtable^.[op.getlinetext ()] = copy2 target.set (oldtarget) on replacenonalphas (s) local (i, sret = "") for i = 1 to sizeof (s) ch = s [i] if not string.isalpha (ch) ch = " " sret = sret + ch return (sret) local (oldtarget = target.set (@user.myWeblogOutliner.outline), outlinetable) new (tabletype, @outlinetable) breakUpOutline (@user.myWeblogOutliner.outline, @outlinetable) scratchpad.outlinetable = outlinetable local (adrsub, fname, f) for adrsub in @outlinetable fname = string.innercasename (replacenonalphas (searchengine.stripmarkup (nameof (adrsub^)))) f = user.myWeblogOutliner.prefs.archive.folder + fname + ".opml" if file.exists (f) local (ct = 1) loop f = user.myWeblogOutliner.prefs.archive.folder + fname + ct + ".opml" if not file.exists (f) break ct++ file.surefilepath (f) file.writetextfile (f, op.outlinetoxml (adrsub)) op.wipe () target.set (oldtarget) if user.myWeblogOutliner.prefs.archive.flOpenFolder file.openfolder (user.myWeblogOutliner.prefs.archiveFolder) bundle //test code archive () €„€€€€€€€€‚€€€€€‚€€€€€€€€€€Ź›Arial š"Oűš"OűJĽ#LAND˙˙˙˙˙˙winThis script runs every hour. „›Arial š"Oűš"OűJĽ#LAND˙˙˙˙˙˙winThis script runs every minute. „œArial š"Oűš"OűJĽ#LAND˙˙˙˙˙˙winThis script runs every night. „œ{w.š"Oűš"Oű  ". 9 everyHour;™ everyMinute<@ everyNight<é{ę fArial š(Ěš.LkJĽ°WLAND˙˙˙˙˙˙winif dialog.confirm ("Archive current posts, and empty the outline?") myWeblogOutlinerSuite.archive () €€ęś8Arial š"Qš(ĚaJĽLAND˙˙˙˙˙˙winthread.callScript (@myWeblogOutlinerSuite.publish, {}) €ś˝?Arial š&poš&pŒJĽŽWLAND˙˙˙˙˙˙winwebbrowser.openurl ("http://127.0.0.1:5335/myWeblogOutliner/") €˝ś8Arial š*§yš*ŤôŐ>9ŔLAND˙˙˙˙˙˙winthread.callscript (@myWeblogOutlinerSuite.viewPost, {}) €śŽŠ8š"Qš*¨  ( 1= BArchive>Publish?Settings?ĐView@™Ž š"Oűš"Oű š"Oűš"Oű RN$š"Oűš"Oű  fileMenuAőuserB!RŞś|Arial š"Pš.L=>’ž`LAND˙˙˙˙˙˙winif not defined (user.myWeblogOutliner) new (tabletype, @user.myWeblogOutliner) if not defined (user.myWeblogOutliner.outline) new (outlinetype, @user.myWeblogOutliner.outline) if not defined (user.myWeblogOutliner.prefs) new (tabletype, @user.myWeblogOutliner.prefs) bundle //archive prefs if not defined (user.myWeblogOutliner.prefs.archive) new (tabletype, @user.myWeblogOutliner.prefs.archive) if not defined (user.myWeblogOutliner.prefs.archive.folder) local (pc = file.getpathchar ()) user.myWeblogOutliner.prefs.archive.folder = frontier.pathstring + "My Weblog Outliner" + pc + "Archive" + pc if not defined (user.myWeblogOutliner.prefs.archive.count) user.myWeblogOutliner.prefs.archive.count = 0 if not defined (user.myWeblogOutliner.prefs.archive.flOpenFolder) user.myWeblogOutliner.prefs.archive.flOpenFolder = false bundle //Blogger prefs if not defined (user.myWeblogOutliner.prefs.blogger) new (tabletype, @user.myWeblogOutliner.prefs.blogger) if not defined (user.myWeblogOutliner.prefs.blogger.enabled) user.myWeblogOutliner.prefs.blogger.enabled = false if not defined (user.myWeblogOutliner.prefs.blogger.server) user.myWeblogOutliner.prefs.blogger.server = "plant.blogger.com" if not defined (user.myWeblogOutliner.prefs.blogger.port) user.myWeblogOutliner.prefs.blogger.port = 80 if not defined (user.myWeblogOutliner.prefs.blogger.rpcPath) user.myWeblogOutliner.prefs.blogger.rpcPath = "/api/RPC2" if not defined (user.myWeblogOutliner.prefs.blogger.blogid) user.myWeblogOutliner.prefs.blogger.blogid = "" if not defined (user.myWeblogOutliner.prefs.blogger.username) user.myWeblogOutliner.prefs.blogger.username = "" if not defined (user.myWeblogOutliner.prefs.blogger.password) user.myWeblogOutliner.prefs.blogger.password = "" if not defined (user.myWeblogOutliner.prefs.blogger.flUseMetaWeblogApi) user.myWeblogOutliner.prefs.blogger.flUseMetaWeblogApi = false bundle //Radio prefs if not defined (user.myWeblogOutliner.prefs.radio) new (tabletype, @user.myWeblogOutliner.prefs.radio) if not defined (user.myWeblogOutliner.prefs.radio.enabled) user.myWeblogOutliner.prefs.radio.enabled = false if not defined (user.myWeblogOutliner.prefs.radio.server) user.myWeblogOutliner.prefs.radio.server = "127.0.0.1" if not defined (user.myWeblogOutliner.prefs.radio.port) user.myWeblogOutliner.prefs.radio.port = 5335 if not defined (user.myWeblogOutliner.prefs.radio.rpcPath) user.myWeblogOutliner.prefs.radio.rpcPath = "/RPC2" if not defined (user.myWeblogOutliner.prefs.radio.blogid) user.myWeblogOutliner.prefs.radio.blogid = "home" if not defined (user.myWeblogOutliner.prefs.radio.username) user.myWeblogOutliner.prefs.radio.username = user.radio.prefs.security.remoteUsername if not defined (user.myWeblogOutliner.prefs.radio.password) user.myWeblogOutliner.prefs.radio.password = user.radio.prefs.security.remotePassword if not defined (user.myWeblogOutliner.prefs.radio.flUseMetaWeblogApi) user.myWeblogOutliner.prefs.radio.flUseMetaWeblogApi = true bundle //Movable Type prefs if not defined (user.myWeblogOutliner.prefs.movableType) new (tabletype, @user.myWeblogOutliner.prefs.movableType) if not defined (user.myWeblogOutliner.prefs.movableType.enabled) user.myWeblogOutliner.prefs.movableType.enabled = false if not defined (user.myWeblogOutliner.prefs.movableType.server) user.myWeblogOutliner.prefs.movableType.server = "www.myserver.com" if not defined (user.myWeblogOutliner.prefs.movableType.port) user.myWeblogOutliner.prefs.movableType.port = 80 if not defined (user.myWeblogOutliner.prefs.movableType.rpcPath) user.myWeblogOutliner.prefs.movableType.rpcPath = "/cgi-bin/mt-xmlrpc.cgi" if not defined (user.myWeblogOutliner.prefs.movableType.blogid) user.myWeblogOutliner.prefs.movableType.blogid = "1" if not defined (user.myWeblogOutliner.prefs.movableType.username) user.myWeblogOutliner.prefs.movableType.username = "" if not defined (user.myWeblogOutliner.prefs.movableType.password) user.myWeblogOutliner.prefs.movableType.password = "" if not defined (user.myWeblogOutliner.prefs.movableType.flUseMetaWeblogApi) user.myWeblogOutliner.prefs.movableType.flUseMetaWeblogApi = true €€€€€€€ŞŸbĹArial š&Ljš&lý7÷ŠXęLAND˙˙˙˙˙˙winon main () local (pta = html.getpagetableaddress ()) pta^.title = myWeblogOutlinerInfo.name myWeblogOutlinerSuite.init () local (htmltext = "\r", indentlevel = 0) on add (s) htmltext = htmltext + string.filledstring ("\t", indentlevel) + s + "\r\n" if pta^.method == "POST" local (args = pta^.radioresponder.postargs) scratchpad.args = args; edit (@scratchpad.args) user.myWeblogOutliner.prefs.blogger.blogid = args.blogid user.myWeblogOutliner.prefs.blogger.flUseMetaWeblogApi = defined (args.flMetaWeblogApi) user.myWeblogOutliner.prefs.blogger.enabled = defined (args.flPublishToBlogger) user.myWeblogOutliner.prefs.radio.enabled = defined (args.flPublishToLocalRadio) user.myWeblogOutliner.prefs.blogger.password = binary (args.password) user.myWeblogOutliner.prefs.blogger.port = number (args.port) user.myWeblogOutliner.prefs.blogger.rpcPath = args.rpcPath user.myWeblogOutliner.prefs.blogger.server = args.server user.myWeblogOutliner.prefs.blogger.username = args.username add ("
"); indentlevel++ add (""); indentlevel++ on addrow (label, adrvalue, type="text") add ("") add ("") bundle //Radio prefs add ("") local (checked) if user.myWeblogOutliner.prefs.radio.enabled checked = "xxx checked" else checked = "xxx" add ("") bundle //Blogger prefs add ("") local (checked) if user.myWeblogOutliner.prefs.blogger.enabled checked = "xxx checked" else checked = "xxx" add ("") addrow ("Blog ID", @user.myWeblogOutliner.prefs.blogger.blogid) addrow ("Username", @user.myWeblogOutliner.prefs.blogger.username) addrow ("Password", @user.myWeblogOutliner.prefs.blogger.password, "password") addrow ("Server", @user.myWeblogOutliner.prefs.blogger.server) addrow ("Port", @user.myWeblogOutliner.prefs.blogger.port) addrow ("Path", @user.myWeblogOutliner.prefs.blogger.rpcPath) bundle //MetaWeblog API checkbox add ("") local (checked) if user.myWeblogOutliner.prefs.blogger.flUseMetaWeblogApi checked = "xxx checked" else checked = "xxx" add ("") add ("
" + label + ":

This page allows you to configure the My Weblog Outliner Tool The complete docs are here.


Radio Prefs

It's easy to publish from the outliner to your Radio weblog, just check the box, there's no more information to enter.


 Check this box to publish to your Radio weblog.

Blogger Prefs

It's just as easy to publish from your outline to Blogger, just check the box, enter your Blog ID, username, password, etc and when you click on the outliner Publish button your posts will appear on your Blogger site. Note, if you're publishing to another weblog tool that supports the Blogger API, such as Manila, check this box and fill in the prefs, according to the docs.


 Check this box to publish to your Blogger weblog.


MetaWeblog API

Some weblog tools support a more advanced interface called the MetaWeblog API. If your weblog tool supports this, we can send information about Titles and Links for each post.


 Check this box to publish using the MetaWeblog API.

"); indentlevel-- add ("

") add ("
"); indentlevel-- return (htmltext) €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ŸŔ <Arial š"fyš"fŽنĄLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.init () myWeblogOutlinerSuite.open () €€Ŕ:6š"fmš"fy openOutlineg :FźArial š"P†š"QAź\6ăLAND˙˙˙˙˙˙winlocal (title = user.prefs.name + "'s Weblog Outline") myWeblogOutlinerSuite.init () edit (@user.myWeblogOutliner.outline, windowTitle:title, adrButtonTable:@myWeblogOutlinerSuite.buttons) €€€Fä¸Arial š*—[šéMub€i•LAND˙˙˙˙˙˙winMy Weblog Outliner preferences Movable Type Prefs <%radio.prefs.checkboxPref ("Check this box to publish to your Movable Type weblog.", @user.myWeblogOutliner.prefs.movableType.enabled)%>
<%radio.prefs.stringPref ("Username", @user.myWeblogOutliner.prefs.movableType.username)%> <%system.temp.radio.repeatedPassword = user.myWeblogOutliner.prefs.movableType.password; ""%> <%radio.prefs.stringPref ("Password", @system.temp.radio.repeatedPassword, type:"password")%> <%radio.prefs.stringPref ("Repeat password", @user.myWeblogOutliner.prefs.movableType.password, type:"password")%> <%try {delete (@system.temp.radio.repeatedPassword)}; ""%> <%radio.prefs.stringPref ("Server", @user.myWeblogOutliner.prefs.movableType.server)%> <%radio.prefs.stringPref ("Port", @user.myWeblogOutliner.prefs.movableType.port)%> <%radio.prefs.stringPref ("Path", @user.myWeblogOutliner.prefs.movableType.rpcPath)%> Radio UserLand Prefs It's easy to publish from the outliner to your Radio weblog, just check the box. The other settings are initialized to route posts to the copy of Radio running on this machine. If you want to use the Weblog Outliner to post to a copy of Radio on another machine, you will need to edit the settings below the checkbox.

<%radio.prefs.checkboxPref ("Check this box to publish to your Radio weblog.", @user.myWeblogOutliner.prefs.radio.enabled)%>
<%radio.prefs.stringPref ("Username", @user.myWeblogOutliner.prefs.radio.username)%> <%system.temp.radio.repeatedPassword = user.myWeblogOutliner.prefs.radio.password; ""%> <%radio.prefs.stringPref ("Password", @system.temp.radio.repeatedPassword, type:"password")%> <%radio.prefs.stringPref ("Repeat password", @user.myWeblogOutliner.prefs.radio.password, type:"password")%> <%try {delete (@system.temp.radio.repeatedPassword)}; ""%> <%radio.prefs.stringPref ("Server", @user.myWeblogOutliner.prefs.radio.server)%> <%radio.prefs.stringPref ("Port", @user.myWeblogOutliner.prefs.radio.port)%> <%radio.prefs.stringPref ("Path", @user.myWeblogOutliner.prefs.radio.rpcPath)%> Blogger Prefs It's just as easy to publish from your outline to Blogger, just check the box, enter your Blog ID, username, password, etc and when you click on the outliner Publish button your posts will appear on your Blogger site. Note, if you're publishing to another weblog tool that supports the Blogger API, such as Manila, check this box and fill in the prefs, according to the docs.

<%radio.prefs.checkboxPref ("Check this box to publish to your Blogger weblog.", @user.myWeblogOutliner.prefs.blogger.enabled)%>
<%radio.prefs.stringPref ("Blog ID", @user.myWeblogOutliner.prefs.blogger.blogid)%> <%radio.prefs.stringPref ("Username", @user.myWeblogOutliner.prefs.blogger.username)%> <%system.temp.radio.repeatedPassword = user.myWeblogOutliner.prefs.blogger.password; ""%> <%radio.prefs.stringPref ("Password", @system.temp.radio.repeatedPassword, type:"password")%> <%radio.prefs.stringPref ("Repeat password", @user.myWeblogOutliner.prefs.blogger.password, type:"password")%> <%try {delete (@system.temp.radio.repeatedPassword)}; ""%> <%radio.prefs.stringPref ("Server", @user.myWeblogOutliner.prefs.blogger.server)%> <%radio.prefs.stringPref ("Port", @user.myWeblogOutliner.prefs.blogger.port)%> <%radio.prefs.stringPref ("Path", @user.myWeblogOutliner.prefs.blogger.rpcPath)%> Archiving When you click on the Archive button in the Weblog Outline window, the outline is saved in the archive folder, specified below; and you start with a fresh outline with no posts in it. This helps unclutter your workspace, and makes sure you have a copy of all your posts. You can choose to have the folder open automatically when you archive.

<%radio.prefs.checkboxPref ("Check this box to open the archive folder after saving.", @user.myWeblogOutliner.prefs.archive.flOpenFolder)%>
<%radio.prefs.stringPref ("Archive folder", @user.myWeblogOutliner.prefs.archive.folder, size:75)%> €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ đ XArial š"eÓš'ÁTMIüLAND˙˙˙˙˙˙winlocal (xmltext = op.outlinetoxml (@user.myWeblogOutliner.outline)) xml.compile (xmltext, @xstruct) scratchpad.xstruct = xstruct local (adropml = xml.getAddress (@xstruct, "opml")) local (adrbody = xml.getAddress (adropml, "body")) local (outlinelist = xml.getAddressList (adrbody, "outline"), adroutline, headnumber = 1) for adroutline in outlinelist local (link = "", title = "", description = "") local (textatt = xml.entitydecode (xml.getattributevalue (adroutline, "text"), true, true)) local (suboutlinelist = xml.getAddressList (adroutline, "outline"), adroutline) if sizeof (suboutlinelist) == 0 //no link-title description = textatt else local (s = textatt) //could contain a link local (ixopen = string.patternmatch (" 0 local (ixclose = string.patternmatch (">", s)) if ixclose > 0 try local (anchor = string.mid (s, ixopen, ixclose - ixopen + 1)) if not (anchor endswith "/>") anchor = string.replace (anchor, ">", "/>") xml.compile (anchor, @anchorstruct) link = xml.getattributevalue (xml.getAddress (@anchorstruct, "a"), "href") title = searchengine.stripmarkup (textatt) bundle //get the description from the suboutlines local (htmltext = "", indentlevel = 0) on add (s) htmltext = htmltext + (string.filledstring ("\t", indentlevel) + s + "\r\n"); on dolevel (outlinelist) local (adroutline) for adroutline in outlinelist add ("

" + xml.entitydecode (xml.getattributevalue (adroutline, "text"), true, true) + "

") local (suboutlinelist = xml.getAddressList (adroutline, "outline")) if sizeof (suboutlinelist) > 0 add ("
"); indentlevel++ dolevel (suboutlinelist) add ("
"); indentlevel-- dolevel (suboutlinelist) description = htmltext bundle //save off for debugging new (tabletype, @scratchpad.post) scratchpad.post.link = link scratchpad.post.title = title scratchpad.post.description = description scratchpad.post.headnumber = headnumber myWeblogOutlinerSuite.publishOneItem (link, title, description, headnumber) headnumber++ €€„€€€€€€€€€€€€€€€€€€€€‚€ đ žPö$Arial  š"zěš.UjkrvĐ|LAND˙˙˙˙˙˙winon publishOneItem (link, title, description, headnumber) local (oldtarget = target.set (@user.myWeblogOutliner.outline), atts) local (oldcursor = op.getcursor ()) op.firstsummit () op.go (down, headnumber - 1) if not op.attributes.getall (@atts) new (tabletype, @atts) new (tabletype, @atts.ids) bundle //don't save if nothing changed local (checksum = string.hashmd5 (link + title + description)) if defined (atts.checksum) if atts.checksum == checksum op.setcursor (oldcursor) target.set (oldtarget) return atts.checksum = checksum on flowto (adrtable) if adrtable^.enabled //flow out through Blogger API local (data, username, password) bundle //create data table, set username, password new (tabletype, @data) data.appKey = "E260BC1A1004B61C2DF853E73909E912897D0C" data.blogid = adrtable^.blogid data.port = adrtable^.port data.protocol = "xml-rpc" data.rpcPath = adrtable^.rpcPath data.server = adrtable^.server username = adrtable^.username password = string (adrtable^.password) local (adrid = @atts.ids.[nameof (adrtable^)]) if adrtable^.flUseMetaWeblogApi if defined (adrid^) metaWeblog.editPost (title, link, description, nil, adrid^, username, password, adrdata:@data) else adrid^ = metaWeblog.newPost (title, link, description, nil, username, password, blogid:data.blogid, adrdata:@data) else if title != "" description = "" + title + "

" + description if defined (adrid^) blogger.editPost (description, adrid^, username, password, adrdata:@data) else adrid^ = blogger.newPost (description, username, password, adrdata:@data) flowto (@user.myWeblogOutliner.prefs.blogger) flowto (@user.myWeblogOutliner.prefs.radio) flowto (@user.myWeblogOutliner.prefs.movableType) atts.type = "weblogPost" op.attributes.addgroup (@atts) op.setcursor (oldcursor) target.set (oldtarget) bundle //test code with scratchpad.post publishOneItem (link, title, description, headnumber) €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚€€€€€€€€€€€ ž }Arial š"Oűš"OűJĽ LAND˙˙˙˙˙˙winThis script returns a string which appears in the Status Center on the Radio UserLand home page. return ("I'm a cool Tool!") „€!ĆăArial š*ŤĐš.Š F.ŢŠLAND˙˙˙˙˙˙winon viewPost () local (atts) new (tabletype, @atts) op.attributes.getall (@atts) if sizeof (atts) == 0 dialog.alert ("Can't view the post because the outline cursor is not pointing at a post.") return if defined (atts.ids.radio) //only Radio supports the feature, for now local (adrtable = @user.myWeblogOutliner.prefs.radio) local (data, username, password) bundle //create data table, set username, password new (tabletype, @data) data.appKey = "E260BC1A1004B61C2DF853E73909E912897D0C" data.blogid = adrtable^.blogid data.port = adrtable^.port data.protocol = "xml-rpc" data.rpcPath = adrtable^.rpcPath data.server = adrtable^.server username = adrtable^.username password = string (adrtable^.password) local (struct) metaweblog.getPost (atts.ids.radio, username, password, adrstruct:@struct, adrdata:@data) if defined (struct.permalink) webbrowser.openurl (struct.permalink) else dialog.alert ("Can't view the post because the weblog tool \"" + nameof (adrtable^) + "\" did not return a permalink.") scratchpad.struct = struct edit (@scratchpad.struct) else dialog.alert ("Can't view the post because the weblog manager does not support the feature.") bundle //test code viewPost () €€€€€€€€€€!€úkb’šÜ‡ş#!u  €(Ć<Arial ťĐ’†ťĐ’œď˘wLAND˙˙˙˙˙˙winon newWeblogPagePost () op.firstSummit() op.insert("",up) €€€€úľ7Arial ťĐ‘ýť×xÚ˘ƒLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.menuCommands.newWeblogPageItem() €ľKęé Arial šÚŕMšî“WLŽ5LAND˙˙˙˙˙˙winon outlineToHtml (adroutline) Changes 10/22/02; 11:00:55 AM by DW Created. local (outlinecopy = adroutline^, htmltext) local (oldtarget = target.set (@outlinecopy)) myWeblogOutlinerSuite.init () bundle //add if none present local (fladd = true) op.firstsummit () loop if op.getlinetext () beginswith "

" + description if defined (adrid^) blogger.editPost (description, adrid^, username, password, adrdata:@data) else adrid^ = blogger.newPost (description, username, password, adrdata:@data) flowto (@user.myWeblogOutliner.sites.[atts.sitename]) atts.ctSaves++ window.attributes.addGroup (@atts, adroutline) return (true) bundle //debugging saveWindow (@system.temp.windowTypes.windows.["0000002"].window, false) €„€€€€€€€€€€€€€€€€€€€€„€€€€€€€€€€€€€€€€ 䀊1ˇtš"Oűş#!u  + 0< EQ Vb o{ …‘ šŚ ´Ŕ Ë codeFreshener Ńdatainit]initAtts(ímenu,ö menuCommands´4 newWindow2‘oldstuff• outlineToHtml—W saveWindowŽVArial ŽlE„ž+€Ší iArial š>˝ëšîšŘUĂ_ˇsLAND˙˙˙˙˙˙winon save (adroutline, flClosing=false) return (myWeblogOutlinerSuite.saveWindow (adroutline, flClosing)) €€í0`Arial šÜ+hšîšć ôů°ŻLAND˙˙˙˙˙˙winon saveAs (adroutline, adradrwindow=nil) local (title = window.gettitle (adroutline)) if dialog.ask ("New title for weblog post?", @title) window.settitle (adroutline, title) myWeblogOutlinerWindowTypes.weblogPost.save (adroutline) return (true) //command handled bundle //test code saveas (@system.temp.windowTypes.windows.["0000003"].window) €€€€€€„ŚL$šÚÄdťˇnm  saveŤSsaveAsŹLVArial §6•3Ś€Šž$š"Oúťˇn“  " weblogPageŻÜ weblogPostŽ`VArial Ż~2„ž+ ž€řśéťˇnjťˇn• saveĎU3€šśé 5Arial ťˇnwťˇnWŁLAND˙˙˙˙˙˙win€u8°uśéŸŠžŠ1ˇÎ,̲Ś$€Âşšcžů.Arial ˙˙˙˙˙˙˙˙ MS Sans Serif ž:e€Times New Roman! ŁŰ)Arial ”Ě8Arial ˙˙˙˙˙˙˙˙ MS Sans Serif ˙˙ş€$€ €$R_ oArial šÜťË<\%,HâLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.init () myWeblogOutlinerSuite.newPageWindowForDate (date.year(),date.month(),date.day()) €€yWeblogOutlinerSuite.newWindow (user.myWeblogOutliner.settings.newPostTitle) €€€R€ëJ8šÜťˇoY  $0 >J P newServer-r newWeblogItem/F newWeblogPage€†`´4†JDćîÇéšEČńVŻÂśéÁŠžŠ1ˇÎ,̲Ś$€ňí6?Arial š"OűťˇnŔ™JĽ&LAND˙˙˙˙˙˙winMyWeblogOutliner Set Up.. New Weblog Post.. New Weblog Page €€ *Ş€ +`€ ś+€ë˛4Arial PťˇnĐťˇnÚ˘jƒLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.menuCommands.newWeblogPage () €˛€#~ŚArial (ťˇnwťÍć°<7p˙dLAND˙˙˙˙˙˙winon saveWeblogPage (adroutline, flClosing=false) Changes 11/2/03; 10:19:50 PM by AG Created. Loops through top-level headlines comparing each to the last saved version and posting new items or edited items as necessary. 11/4/03; 11:28:48 PM by AG local (origsetting = op.getDisplay()) local (atts, opatts) window.attributes.getAll (@atts, adroutline) myWeblogOutlinerSuite.initAtts (@atts) on flowto (adrtable) if adrtable^.enabled //flow out through Blogger or MetaWeblog API local (data, username, password) bundle //create data table, set username, password new (tabletype, @data) data.appKey = "E260BC1A1004B61C2DF853E73909E912897D0C" data.blogid = adrtable^.blogid data.port = adrtable^.port data.protocol = "xml-rpc" data.rpcP€ă"‘Arial ťˇnwťâůh¸ogę-LAND˙˙˙˙˙˙winon saveWeblogPage (adroutline, flClosing=false) Changes 11/2/03; 10:19:50 PM by AG Created. Loops through top-level headlines comparing each to the last saved version and posting new items or edited items as necessary. 11/4/03; 11:28:48 PM by AG Added a bunch of UI handling to make the window more click-proof. Now we're saving from a copied outline. It's not quite bulletproof but now it's a lot harder to mess up the post ids with an accidental click. local (origsetting = op.getDisplay()) local (atts, opatts, flChanged=false) myWeblogOutlinerSuite.ensureGidsAndPostIdMap(adroutline) window.attributes.getAll (@atts, adroutline) myWeblogOutlinerSuite.initAtts (@atts) on flowto (adrtable) if adrtable^.enabled //flow out through Blogger or MetaWeblog API local (data, username, password) bundle //create data table, set username, password new (tabletype, @data) data.appKey = "E260BC1A1004B61C2DF853E73909E912897D0C" data.blogid = adrtable^.blogid data.port = adrtable^.port data.protocol = "xml-rpc" data.rpcPath = adrtable^.rpcPath data.server = adrtable^.server username = adrtable^.username password = string (adrtable^.password) if (data.server == "127.0.0.1") and (data.port == 5335) //if the Blogger API is not enabled, enable it if not weblogData.prefs.flBloggerApiEnabled weblogData.prefs.flBloggerApiEnabled = true local (adrid = @atts.postIdMap.[opatts.gid]) if adrtable^.flUseMetaWeblogApi if defined (adrid^) metaWeblog.editPost (title, nil, description, nil, adrid^, username, password, adrdata:@data) else adrid^ = metaWeblog.newPost (title, nil, description, nil, username, password, blogid:data.blogid, adrdata:@data) else if title != "" description = "" + title + "

" + description if defined (adrid^) blogger.editPost (description, adrid^, username, password, adrdata:@data) else adrid^ = blogger.newPost (description, username, password, adrdata:@data) local(i=1,title,description,outlineCopy, itemOutline, savedOutline) bundle //Load the last saved outline from disk if it exists if file.exists (myWeblogOutlinerSuite.archivePathForDate(atts.archiveYear,atts.archiveMonth,atts.archiveDay)) op.xmlToOutline(file.readWholeFile(myWeblogOutlinerSuite.archivePathForDate(atts.archiveYear,atts.archiveMonth,atts.archiveDay)),@savedOutline) bundle //copy the outline and target it outlineCopy = adroutline^ target.set(@outlineCopy) bundle //go to last the summit; we'll be working upwards from the bottom op.firstSummit() loop if not op.go (down, 1) break i++ bundle //loop through the items, posting changed items to the blog loop op.attributes.getAll(@opatts) if (myWeblogOutlinerSuite.itemChanged(@savedOutline, @outlineCopy, i, atts.postIdMap)) flChanged = true if op.countSubs(1) == 0 title = "" myWeblogOutlinerSuite.nthSummitToOutline(@outlineCopy, @itemOutline, i) else title = op.getLineText() myWeblogOutlinerSuite.nthSummitChildrenToOutline(@outlineCopy, @itemOutline, i) description = myWeblogOutlinerSuite.outlineToHtml (@itemOutline) flowto (@user.myWeblogOutliner.sites.[atts.sitename]) opatts.id = atts.postIdMap.[opatts.gid] op.attributes.addGroup(@opatts) i-- if not op.go (up, 1) break bundle //save to opml if flChanged local (f = myWeblogOutlinerSuite.archivePathForDate(atts.archiveYear,atts.archiveMonth,atts.archiveDay)) file.surefilepath (f) xmltext = op.outlinetoxml (@outlineCopy) file.writetextfile (f, xmltext) if (user.myWeblogOutliner.sites.default.pageWebsharingEnabled) //save for upstreamer f = myWeblogOutlinerSuite.websharePathForDate(atts.archiveYear,atts.archiveMonth,atts.archiveDay) file.surefilepath (f) xmltext = op.outlinetoxml (@outlineCopy) file.writetextfile (f, xmltext) if user.myWeblogOutliner.prefs.archive.flOpenFolder file.openfolder (file.folderfrompath (f)) bundle //update the current window, part 1 atts.ctSaves++ window.attributes.addGroup (@atts, adroutline) target.set(adroutline) bundle //debugging saveWeblogPage (@system.temp.windowTypes.windows.["0000001"].window, false) €„€€€€€€€€€€€€€€€€€€€€€€€€„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€tes.getOne("gid",@gid) op.attributes.setOne("id",user.myWeblogOutliner.postIdMap.[gid]) if not op.go(down,1) break op.setCursor(cursor) op.setDisplay(origsetting) return (true) bundle //debugging saveWeblogPage (@system.temp.windowTypes.windows.["0000002"].window, false) €„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‘*8š"OúťĐ) ! ;G ]i …myWeblogOutlinerInfoXmyWeblogOutlinerNodeTypes’myWeblogOutlinerSuitegşmyWeblogOutlinerWindowTypesçÁVéAG˛xÔÜŮArial &ť­¨HťĐ)/˘jƒLAND˙˙˙˙˙˙winmyWeblogOutlinerInfo myWeblogOutlinerNodeTypes myWeblogOutlinerSuite archivePathForDate codeFreshener data init initAtts itemChanged menu menuCommands newServer newWeblogItem newWeblogPage newWeblogPagePost oldWeblogPage refreshTodayFromWeb setup newPageW€ľ°Óľ‘* Kqë~w¤B•úkbźdďżśéŮ›#~c/e],´4ëJ úćîÇ隞ŻŠžŠ1ˇÎ,̲Ś$€q€yӐVArial ťŐ´VťŐ´uč˘{LAND˙˙˙˙˙˙winon generatePostIdMap () Changes 11/10/03; 9:32:15 PM by AG Created. local(foo) €„€€€ě€ÓŇ•Arial€¨Ó‘* Kqë~w¤B•úkbźdďżśé#~c/e] ´4ëJ úćîÇ隞ŻŠžŠ1ˇÎ,̲Ś$¨§8BľArial ťâ÷§ťâř i0U;LAND˙˙˙˙˙˙winon websharePathForDate (year,month,day) Changes 11/20/03; 10:58:59 PM by AG Created. local (pc = file.getPathChar()) local (datepart = year + pc + month + pc + day) local (archiveFolder = frontier.pathstring + "www" + pc + user.myWeblogOutliner.prefs.archive.pageWebshareFolder ) local (f = archiveFolder + datepart + ".xml") return(f) bundle //test code dialog.notify(myWeblogOutlinerSuite.websharePathForDate(2003,11,20)) €€€€€€€€€€§ß LArial ť×*ťŮŁÔ)bÎĎLAND˙˙˙˙˙˙mac on opReturnKey () myWeblogOutlinerSuite.updateHeadlineGid() return (true) €€€€ßg'$¤Arial ť×˘ťâöpß‹LAND˙˙˙˙˙˙winon updateHeadlineGid () local(gid) if not window.attributes.getOne ("gid",@gid) gid = 1 op.attributes.setOne("gid",gid) window.attributes.setOne("gid",gid+1) €€€€€€€€€€€€gž kArial ťˇt(ťË6_'ćoÎILAND˙˙˙˙˙˙winon todaysPage () return (myWeblogOutlinerSuite.archivePathForDate(date.year(), date.month(), date.day())) €€cal (f = user.myWeblogOutliner.prefs.archive.folder + fname + ".xml") bundle //before returning the filename, try to sync against the web local (usernumstring = string.padwithzeros (user.radio.prefs.usernum, 7)) local(path = "/" + usernumstring + "/" + user.myWeblogOutliner.prefs.archive.webshareFolder + "/" + string.replaceAll(fname,"\\","/") + ".xml") local (response = tcp.httpClient("GET","radio.weblogs.com","80",path)) local (body = string.trimWhiteSpace(string.httpResultSplit(response))) if (string.nthWord(response,2) == "200") local (foo) //we got a remote file! Now just have to figure out what to do with it. return(f) €€€€„€€€€€€€„€€„€€otify(response) return(f) €€€€€€€€€€€€€€€€€ľ-ržArial ťťi*ťË4}1ŽŔé’LAND˙˙˙˙˙˙winon nthSummitToOutline (adrSource,adrDest,n) Changes 11/2/03; 10:22:31 PM by AG Created. Copies the source outline to the destination address and then removes all but the nth headline, returning an outline containing just the nth headline and its children. adrDest^ = adrSource^ local (j, k, flSuccess=false, returnTarget = target.get()) target.set(adrDest) op.firstSummit() j = op.countSummits() if (n <= j) for k = 1 to (n - 1) op.deleteLine() while op.go (down, 1) op.deleteLine() flSuccess = true target.set(returnTarget) return(flSuccess) bundle //test code nthSummitToOutline(@examples.["Sample Outline 1"], @scratchpad.savedoutline, 4) €„€€€€€€€€€€€€€€€„€€€€€€€€ľ˜CQ$ťˇnjť×   opReturnKeyےsave ŘYsave #2ó“4save #1ŘYsave #2󓘀Çéš CArial ťťi*ťťiZű€ShćîSéšoáY$Ęě 7š”0žńšŻÂśé0ŠžŠ1ˇÎ,̲Ś$€ÇěV$š"Oúťˇn“  " weblogPagećJ weblogPostŽ`VŤz6‹ž'–.Arial ť¸Żťť¸ŻÁ˘jƒLAND˙˙˙˙˙˙winweblogPage save save #1 save #2 weblogPost €h Ę€h0cl€h0cl€h0cl€h Ę쀞ŻĺĘěJš”0žńׯÂśé0ŠžŠ1ˇÎ,̲Ś$ŘYsave #2ó“€o SE–Arial€ž›ć =+Arial 2(ťˇnwťËI›!^\lyLAND˙˙˙˙˙˙winon saveWeblogPage (adroutline, flClosing=false) Changes 11/2/03; 10:19:50 PM by AG Created. Loops through top-level headlines comparing each to the last saved version and posting new items or edited items as necessary. local (origsetting = op.getDisplay()) op.setDisplay(false) local (atts, opatts) window.attributes.getAll (@atts, adroutline) myWeblogOutlinerSuite.initAtts (@atts) on flowto (adrtable) if adrtable^.enabled //flow out through Blogger or MetaWeblog API local (data, username, password) bundle //create data table, set username, password new (tabletype, @data) data.appKey = "E260BC1A1004B61C2DF853E73909E912897D0C" data.blogid = adrtable^.blogid data.port = adrtable^.port data.protocol = "xml-rpc" data.rpcPath = adrtable^.rpcPath data.server = adrtable^.server username = adrtable^.username password = string (adrtable^.password) if (data.server == "127.0.0.1") and (data.port == 5335) //if the Blogger API is not enabled, enable it if not weblogData.prefs.flBloggerApiEnabled weblogData.prefs.flBloggerApiEnabled = true local (adrid = @opatts.id) if adrtable^.flUseMetaWeblogApi if defined (adrid^) metaWeblog.editPost (title, nil, description, nil, adrid^, username, password, adrdata:@data) else adrid^ = metaWeblog.newPost (title, nil, description, nil, username, password, blogid:data.blogid, adrdata:@data) else if title != "" description = "" + title + "

" + description if defined (adrid^) blogger.editPost (description, adrid^, username, password, adrdata:@data) else adrid^ = blogger.newPost (description, username, password, adrdata:@data) local (savedOutline) if file.exists (myWeblogOutlinerSuite.archivePathForDate(atts.archiveYear,atts.archiveMonth,atts.archiveDay)) op.xmlToOutline(file.readWholeFile(myWeblogOutlinerSuite.archivePathForDate(atts.archiveYear,atts.archiveMonth,atts.archiveDay)),@savedOutline) local(i=1,title,description,outlineCopy, itemOutline) bundle //go to last summit op.firstSummit() loop if not op.go (down, 1) break i++ loop if (myWeblogOutlinerSuite.itemChanged(@savedOutline, adroutline, i)) if op.countSubs(1) == 0 title = "" myWeblogOutlinerSuite.nthSummitToOutline(adroutline, @itemOutline, i) else title = op.getLineText() myWeblogOutlinerSuite.nthSummitChildrenToOutline(adroutline, @itemOutline, i) wp.newtextobject (myWeblogOutlinerSuite.outlineToHtml (@itemOutline), @scratchpad.saveddescription) //debugging thread.sleepFor(10) description = myWeblogOutlinerSuite.outlineToHtml (@itemOutline) if not op.attributes.getAll(@opatts) new(tabletype,@opatts) flowto (@user.myWeblogOutliner.sites.[atts.sitename]) op.attributes.addGroup(@opatts) i-- if not op.go (up, 1) break atts.ctSaves++ window.attributes.addGroup (@atts, adroutline) bundle //save to opml local (f = myWeblogOutlinerSuite.archivePathForDate(atts.archiveYear,atts.archiveMonth,atts.archiveDay)) file.surefilepath (f) xmltext = op.outlinetoxml (adroutline) file.writetextfile (f, xmltext) if user.myWeblogOutliner.prefs.archive.flOpenFolder file.openfolder (file.folderfrompath (f)) op.setDisplay(origSetting) return (true) bundle //debugging saveWeblogPage (@system.temp.windowTypes.windows.["0000001"].window, false) €„€€€€€€€€€€€€€€€€€€€€€€€€€€€„„€€€€€€€€€€€€€€€€€€€€€€›ÜJBŘArial ťˇt(ťâů”94nLAND˙˙˙˙˙˙winon archivePathForDate (year,month,day) Changes 11/2/03; 10:29:39 PM by AG Created 11/20/03; 10:59:13 PM by AG From now on we always store a copy on the local hard drive. The webshare path now is generated in myWeblogOutlinerSuite.websharePathForDate. local (pc = file.getPathChar()) local (datepart = year + pc + month + pc + day) local (archiveFolder = user.myWeblogOutliner.prefs.archive.folder) local (f = archiveFolder + datepart + ".xml") return(f) €„€€€€€WeblogOutliner.prefs.archive.pageWebshareFolder else archiveFolder = user.myWeblogOutliner.prefs.archive.folder local (f = archiveFolder + datepart + ".xml") return(f) €„€€€€€€€€€€€€€„€€€€€€€ÜLZzArial ťżHŒťË4ÜŒXđÖLAND˙˙˙˙˙˙winon nthSummitChildrenToOutline (adrSource,adrDest,n) Created 11/2/03; 10:24:17 PM by AG Copies the source outline to the destination address and then removes all but the nth headline's children, returning an outline containing just the nth headline's children. local (flSuccess=false, returnTarget = target.get()) if (myWeblogOutlinerSuite.nthSummitToOutline(adrSource,adrDest,n)) target.set(adrDest) op.firstSummit() op.promote() op.deleteLine() flSuccess = true target.set(returnTarget) return(flSuccess) bundle //test code nthSummitChildrenToOutline(@examples.["Sample Outline 1"], @scratchpad.savedoutline, 2) €„€€€€€€€€€€€„€L€ úćî°š"OűťÉî'  + 0< EQ ]i nz ‡“ Ą­ ˇĂ Ţę ý  ,8 GS ^j u codeFreshener Ńdatainit]initAtts(í itemChangedęmenu,ö menuCommands´4 newPageWindowŘ% newWindow2‘nthSummitChildrenToOutlineýňnthSummitToOutlineâ‰oldstuff• outlineToHtml—WsaveWeblogPageű saveWindowŽ todaysPageÝđVArial ŞhIA‘ʀ}XJ}ćîÇ隇ČńóŻÂśéÁŠžŠ1ˇÎ,̲Ś$€ဠÉJşš"OűťË6  -9 >J O[ dp |ˆ ™ ڞ ŔĚ Öâ ý ( 1= KW fr }‰ ”archivePathForDateú codeFreshener Ńdatainit]initAtts€€Ű´4<q Arial šÜťË?š'Ě@,LAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.init () if dialog.ask ("Date for page to load (YYYY-MM-DD)?", @user.myWeblogOutliner.settings.oldPageDate) local(archiveYear = string.nthField(user.myWeblogOutliner.settings.oldPageDate,"-",1)) local(archiveMonth = string.nthField(user.myWeblogOutliner.settings.oldPageDate,"-",2)) local(archiveDay = string.nthField(user.myWeblogOutliner.settings.oldPageDate,"-",3)) if archiveMonth beginsWith "0" archiveMonth = string.mid(archiveMonth,2,1) if archiveDay beginsWith "0" archiveDay = string.mid(archiveDay,2,1) myWeblogOutlinerSuite.newPageWindowForDate(archiveYear,archiveMonth,archiveDay) €€€€€€€€€€%€Ş´4BšÜťË<‚  $0 >J Xd j newServer-r newWeblogItem/F newWeblogPage˛Ö oldWeblogPageisetup0¤VArial Ş‚3„ž+€…´4Arial šÜťË> ›@BLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.init () if dialog.ask ("Date for page to load?", @user.myWeblogOutliner.settings€Ţh żŢ´4ňJćî€.pâš"OűťÍŰ&  -9 >J O[ dp |ˆ ™ ڞ ÇÓ Ýé  #/ 8D R^ x„ “Ÿ łż Öâ íů  archivePathForDateú codeFreshener ŃdatainitGÂinitAtts(í itemChangedęmenu,ö menuCommands#~newPageWindowForDate? newWindow2‘nthSummitChildrenToOutlineýňnthSummitToOutlineâ‰oldstuff• outlineToHtml—WrefreshPageArchiveFromWebPsaveWeblogPage{ saveWeblogPageCleanęcsaveWeblogPageForking1ĚP saveWindowŽ testGuiAtts• todaysPageÝđVArial ŞhIA‘ʀ úŽÝlÍArial šÚčťËźhdšŇLAND˙˙˙˙˙˙winon refreshPageArchiveFromWeb (archiveYear,archiveMonth,archiveDay) Changes 11/3/03; 12:45:03 AM by AG Created. local (flSuccess = false) if (user.myWeblogOutliner.sites.default.pageWebsharingEnabled) local(filePath = myWeblogOutlinerSuite.archivePathForDate(archiveYear,archiveMonth,archiveDay)) local(archiveUrl = string.replaceAll(user.myWeblogOutliner.prefs.archive.pageWebshareFolder, file.getPathChar(), "/")) local (datepart = archiveYear + "/" + archiveMonth + "/" + archiveDay) local (usernumstring = string.padwithzeros (user.radio.prefs.usernum, 7)) local(path = "/" + usernumstring + "/" + archiveUrl + datepart + ".xml") local (response = tcp.httpClient("GET","radio.weblogs.com","80",path)) local (body = string.trimWhiteSpace(string.httpResultSplit(response))) if (string.nthWord(response,2) == "200") //we got a remote file! file.sureFilePath(filePath) file.writeTextFile(filePath,body) flSuccess = true return(flSuccess) €„€€€€€€€€€€€€€€€€€€File.open(filePath,adrwindow) return(tru) €„€€€€€€€€€€€€€€€€€.attributes.setOne("archiveYear",archiveYear,adrwindow) window.attributes.setOne("archiveMonth",archiveMonth,adrwindow) window.attributes.setOne("archiveDay",archiveDay,adrwindow) return(adrwindow) €„€€€€€€€€€€€€€€€€€€€€€window.attributes.setOne("archiveDay",archiveDay,adrwindow) return(adrwindow) €„€€€€€€€€€€€€€€€€€€€€€Ž _bß Arial %ťÉÁťŮœîUD÷Ż LAND˙˙˙˙˙˙mac on itemChanged (adrSavedOutline, adrCurrentOutline, n, postIdMap) if (adrSavedOutline^ == nil) //no cache to compare with return (true) local(outlineCopy = adrCurrentOutline^) bundle //set cursor to the correct place in outline copy target.set(@outlineCopy) op.firstSummit() op.go(down,n-1) local(opatts) if not op.attributes.getAll(@opatts) //first time saving this item target.set(adrCurrentOutline) return (true) local (adrid = @postIdMap.[opatts.gid]) if not defined(adrid^) //first time saving this item target.set(adrCurrentOutline) return (true) target.set(adrSavedOutline) local (savedatts, flMatch=false) op.firstSummit() loop //look for a matching item in saved outline if op.attributes.getAll(@savedatts) if defined(savedatts.id) && savedatts.id == adrid^ flMatch = true break if not op.go (down, 1) break if not flMatch //no match found in saved outline target.set(adrCurrentOutline) return (true) else In this block we switch back and forth between the current outline and last saved outline, looking for differences. local (linetext, level) linetext = op.getLineText() target.set(@outlineCopy) if (op.getLineText() != linetext) //difference in top level target.set(adrCurrentOutline) return(true) else //loop through children op.go(flatdown,1) while (op.level() > 1) target.set(adrSavedOutline) if not op.go(flatdown,1) //saved item is shorter than current item target.set(adrCurrentOutline) return(true) level = op.level() linetext = op.getLineText() target.set(@outlineCopy) if (op.getLineText() != linetext || op.level() != level) //difference in current level target.set(adrCurrentOutline) return(true) if not op.go (flatdown, 1) break target.set(adrSavedOutline) if (op.go(flatdown,1) && op.level() > 1) //saved item is longer than current item target.set(adrCurrentOutline) return(true) target.set(adrCurrentOutline) return(false) return (true) €€€€€€€€€€€€€€€€€€€€€€€€€€€„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€  1 kArial ťˇnwťÉîb˙°Y ĽLAND˙˙˙˙˙˙winon save (adroutline, flClosing=false) return (myWeblogOutlinerSuite.saveWeblogPage(adroutline,flClosing)) €€tlinerSuite.initAtts (@atts) on flowto (adrtable) if adrtable^.enabled //flow out through Blogger or MetaWeblog API local (data, username, password) bundle //create data table, set username, password new (tabletype, @data) data.appKey = "E260BC1A1004B61C2DF853E73909E912897D0C" data.blogid = adrtable^.blogid data.port = adrtable^.port data.protocol = "xml-rpc" data.rpcPath = adrtable^.rpcPath data.server = adrtable^.server username = adrtable^.username password = string (adrtable^.password) if (data.server == "127.0.0.1") and (data.port == 5335) //if the Blogger API is not enabled, enable it if not weblogData.prefs.flBloggerApiEnabled weblogData.prefs.flBloggerApiEnabled = true local (adrid = @opatts.id) if adrtable^.flUseMetaWeblogApi if defined (adrid^) metaWeblog.editPost (title, nil, description, nil, adrid^, username, password, adrdata:@data) else adrid^ = metaWeblog.newPost (title, nil, description, nil, username, password, blogid:data.blogid, adrdata:@data) else if title != "" description = "" + title + "

" + description if defined (adrid^) blogger.editPost (description, adrid^, username, password, adrdata:@data) else adrid^ = blogger.newPost (description, username, password, adrdata:@data) local (savedOutline) if file.exists (myWeblogOutlinerSuite.todaysPage()) op.xmlToOutline(file.readWholeFile(myWeblogOutlinerSuite.todaysPage()),@savedOutline) local(i=1,title,description,outlineCopy, itemOutline) bundle //go to last summit op.firstSummit() loop if not op.go (down, 1) break i++ loop if (myWeblogOutlinerSuite.itemChanged(@savedOutline, adroutline, i)) if op.countSubs(1) == 0 title = "" myWeblogOutlinerSuite.nthSummitToOutline(adroutline, @itemOutline, i) else title = op.getLineText() myWeblogOutlinerSuite.nthSummitChildrenToOutline(adroutline, @itemOutline, i) wp.newtextobject (myWeblogOutlinerSuite.outlineToHtml (@itemOutline), @scratchpad.saveddescription) //debugging thread.sleepFor(10) description = myWeblogOutlinerSuite.outlineToHtml (@itemOutline) if not op.attributes.getAll(@opatts) new(tabletype,@opatts) flowto (@user.myWeblogOutliner.sites.[atts.sitename]) op.attributes.addGroup(@opatts) i-- if not op.go (up, 1) break atts.ctSaves++ window.attributes.addGroup (@atts, adroutline) bundle //save to opml local (f = myWeblogOutlinerSuite.todaysPage()) file.surefilepath (f) xmltext = op.outlinetoxml (adroutline) file.writetextfile (f, xmltext) if user.myWeblogOutliner.prefs.archive.flOpenFolder file.openfolder (file.folderfrompath (f)) table.assign(adroutline,outlineCopy) return (true) bundle //debugging save (@system.temp.windowTypes.windows.["0000001"].window, false) €€€€€€€€€€€€€€€€€€€€€€€„„€€€€€€€€€€€€€€€€€€„€€€€€€€€€„€€€ ŘUArial ťËXťËXKœ,|LAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.refreshPageArchiveFromWeb(date.year(),date.month(),date.day()) €Ř€e]:Arial €:€>ň ą8Arial 76ťˇnwťĚ•ϨŮÁLAND˙˙˙˙˙˙winon saveWeblogPage (adroutline, flClosing=false) Changes 11/2/03; 10:19:50 PM by AG Created. Loops through top-level headlines comparing each to the last saved version and posting new items or edited items as necessary. local (origsetting = op.getDisplay()) op.setDisplay(false) local (atts, opatts, windowTitle) window.attributes.getOne("title",@windowTitle, adrout€:x%ňd/:]pšŞ´4ëJćîÇ隞ŻÂśé[ŠžŠ1ˇÎ,̲Ś$€ž€ ›#~8š"Oúş#! ! ;G ]i …myWeblogOutlinerInfoXmyWeblogOutlinerNodeTypes’myWeblogOutlinerSuitegşmyWeblogOutlinerWindowTypesçÁVýAGł]fžĹ Arial # ť­¨HťÍíé&˘jƒLAND˙˙˙˙˙˙winmyWeblogOutlinerInfo myWeblogOutlinerNodeTypes myWeblogOutlinerSuite archivePathForDate codeFreshener data init initAtts itemChanged menu menuCommands newServer newWeblogItem newWeblogPage oldWeblogPage refreshTodayFromWeb setup newPageWindowForDate newWindow nthSummitChildrenToOutline nthSummitToOutline oldstuff archive background buttons callbacks init mainOld menuCommands open prefsOutline publish publishOneItem saveWeblogPage saveWeblogPageSnazzy statusCenterMessage viewPost outlineToHtml refreshPageArchiveFromWeb saveWeblogPage saveWindow testGuiAtts todaysPage myWeblogOutlinerWindowTypes weblogPage save weblogPost save saveAs €ŘT°€ŘT°€ŘT°€ŘT €ŘT €ŘT €ŘT €ŘT €ŘT €ŘT €ŘT €ŘT˜€ŘT˜€ŘT˜€ŘT˜€ŘT˜€ŘT˜€ŘT €ŘT €ŘT €ŘT €ŘT €ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT €ŘT €ŘT €ŘT €ŘT €ŘT €ŘT°€ŘTŕ€ŘTˆ €ŘTŕ€ŘT¸€ŘT¸ '€h#~âš"OűťÍŐE  -9 >J O[ dp |ˆ ™ ڞ ÇÓ Ýé  #/ 8D R^ x„ “Ÿ łż Öâ íů  archivePathForDateú codeFreshener ŃdatainitGÂinitAtts(í itemChangedęmenu,ö menuCommands#~newPageWindowForDate? newWindow2‘nthSummitChildrenToOutlineýňnthSummitToOutlineâ‰oldstuff• outlineToHtml—WrefreshPageArchiveFromWebPsaveWeblogPageŮsaveWeblogPageCleanęcsaveWeblogPageForking1ĚP saveWindow€܀<Ü%ňď/ž],š.´4ëJćîÇ隞ŻÂśé[ŠžŠ1ˇÎ,̲Ś$€e',rArial šÚčť×ÝkžM=fLAND˙˙˙˙˙˙winon newPageWindowForDate (archiveYear,archiveMonth,archiveDay) Changes 11/2/03; 10:18:13 PM by AG Created. Opens a new weblog page and tries to preload with data from the local filesystem or network. local(adrwindow = Frontier.tools.windowTypes.newWindow ("weblogPage", false, "Weblog Post Page", outlineType, false, nil)) local(filePath = myWeblogOutlinerSuite.archivePathForDate(archiveYear,archiveMonth,archiveDay)) if file.exists (filePath) Frontier.tools.data.windowTypes.outlinerFile.open(filePath,adrwindow) else //we didn't find a local copy if (user.myWeblogOutliner.sites.default.pageWebsharingEnabled) //try to fetch the file from the network if (myWeblogOutlinerSuite.refreshPageArchiveFromWeb(archiveYear,archiveMonth,archiveDay)) Frontier.tools.data.windowTypes.outlinerFile.open(filePath,adrwindow) bundle //shove today's year, month and day into the window attributes for later consumption by the save script. window.attributes.setOne("archiveYear",archiveYear,adrwindow) window.attributes.setOne("archiveMonth",archiveMonth,adrwindow) window.attributes.setOne("archiveDay",archiveDay,adrwindow) bundle //make sure every entry in the outline has a gui id and map to post ids myWeblogOutlinerSuite.ensureGidsAndPostIdMap(adrwindow) return(adrwindow) €„€€€€€€€€€€€€€le.open(filePath,adrwindow) bundle //shove today's year, month and day into the window attributes for later consumption by the save script. window.attributes.setOne("archiveYear",archiveYear,adrwindow) window.attributes.setOne("archiveMonth",archiveMonth,adrwindow) window.attributes.setOne("archiveDay",archiveDay,adrwindow) return(adrwindow) €„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€'!"¸Ď$Arial "šÚÄjťËCĽJk,oLAND˙˙˙˙˙˙winChanges 10/22/02; 9:01:37 AM by DW Created. Manages a windowType called weblogPost. Creates and edits posts using the MetaWeblog API. 11/2/03; 11:24:30 PM by AG Added user.myWeblogOutliner.prefs.archive.pageWebshareFolder. Added user.myWeblogOutliner.sites.default.pageWebsharingEnabled. if not defined (Frontier.tools.data.windowTypes.blogPost) Frontier.tools.data.windowTypes.weblogPost = @weblogPost.windowType if not defined (user.myWeblogOutliner) new (tabletype, @user.myWeblogOutliner) bundle //prefs if not defined (user.myWeblogOutliner.prefs) new (tabletype, @user.myWeblogOutliner.prefs) if not defined (user.myWeblogOutliner.prefs.rules) user.myWeblogOutliner.prefs.rules = myWeblogOutlinerSuite.data.virginRules if not defined (user.myWeblogOutliner.prefs.currentSite) user.myWeblogOutliner.prefs.currentSite = "default" bundle //archive prefs if not defined (user.myWeblogOutliner.prefs.archive) new (tabletype, @user.myWeblogOutliner.prefs.archive) if not defined (user.myWeblogOutliner.prefs.archive.folder) local (pc = file.getpathchar ()) user.myWeblogOutliner.prefs.archive.folder = frontier.pathstring + "My Weblog Outliner" + pc + "Archive" + pc if not defined (user.myWeblogOutliner.prefs.archive.pageWebshareFolder) // Added 11/2/03; 11:21:07 PM by AG local (pc = file.getpathchar ()) user.myWeblogOutliner.prefs.archive.pageWebshareFolder = "myWeblogOutliner" + pc + "Archive" + pc if not defined (user.myWeblogOutliner.prefs.archive.count) user.myWeblogOutliner.prefs.archive.count = 0 if not defined (user.myWeblogOutliner.prefs.archive.flOpenFolder) user.myWeblogOutliner.prefs.archive.flOpenFolder = false bundle //sites if not defined (user.myWeblogOutliner.sites) new (tabletype, @user.myWeblogOutliner.sites) if not defined (user.myWeblogOutliner.sites.default) new (tabletype, @user.myWeblogOutliner.sites.default) if not defined (user.myWeblogOutliner.sites.default.blogId) user.myWeblogOutliner.sites.default.blogId = 1 if not defined (user.myWeblogOutliner.sites.default.enabled) user.myWeblogOutliner.sites.default.enabled = true if not defined (user.myWeblogOutliner.sites.default.flUseMetaWeblogApi) user.myWeblogOutliner.sites.default.flUseMetaWeblogApi = true if not defined (user.myWeblogOutliner.sites.default.password) user.myWeblogOutliner.sites.default.password = "" if not defined (user.myWeblogOutliner.sites.default.port) user.myWeblogOutliner.sites.default.port = 80 if not defined (user.myWeblogOutliner.sites.default.rpcPath) user.myWeblogOutliner.sites.default.rpcPath = "/cgi-bin/mt-xmlrpc.cgi" if not defined (user.myWeblogOutliner.sites.default.server) user.myWeblogOutliner.sites.default.server = "" if not defined (user.myWeblogOutliner.sites.default.username) user.myWeblogOutliner.sites.default.username = "" if not defined (user.myWeblogOutliner.sites.default.pageWebsharingEnabled) // Added 11/2/03; 11:24:12 PM by AG user.myWeblogOutliner.sites.default.pageWebsharingEnabled = false bundle //settings if not defined (user.myWeblogOutliner.settings) new (tabletype, @user.myWeblogOutliner.settings) bundle //old old stuff bundle //Blogger prefs if not defined (user.myWeblogOutliner.prefs.blogger) new (tabletype, @user.myWeblogOutliner.prefs.blogger) if not defined (user.myWeblogOutliner.prefs.blogger.enabled) user.myWeblogOutliner.prefs.blogger.enabled = false if not defined (user.myWeblogOutliner.prefs.blogger.server) user.myWeblogOutliner.prefs.blogger.server = "plant.blogger.com" if not defined (user.myWeblogOutliner.prefs.blogger.port) user.myWeblogOutliner.prefs.blogger.port = 80 if not defined (user.myWeblogOutliner.prefs.blogger.rpcPath) user.myWeblogOutliner.prefs.blogger.rpcPath = "/api/RPC2" if not defined (user.myWeblogOutliner.prefs.blogger.blogid) user.myWeblogOutliner.prefs.blogger.blogid = "" if not defined (user.myWeblogOutliner.prefs.blogger.username) user.myWeblogOutliner.prefs.blogger.username = "" if not defined (user.myWeblogOutliner.prefs.blogger.password) user.myWeblogOutliner.prefs.blogger.password = "" if not defined (user.myWeblogOutliner.prefs.blogger.flUseMetaWeblogApi) user.myWeblogOutliner.prefs.blogger.flUseMetaWeblogApi = false bundle //Radio prefs if not defined (user.myWeblogOutliner.prefs.radio) new (tabletype, @user.myWeblogOutliner.prefs.radio) if not defined (user.myWeblogOutliner.prefs.radio.enabled) user.myWeblogOutliner.prefs.radio.enabled = false if not defined (user.myWeblogOutliner.prefs.radio.server) user.myWeblogOutliner.prefs.radio.server = "127.0.0.1" if not defined (user.myWeblogOutliner.prefs.radio.port) user.myWeblogOutliner.prefs.radio.port = 5335 if not defined (user.myWeblogOutliner.prefs.radio.rpcPath) user.myWeblogOutliner.prefs.radio.rpcPath = "/RPC2" if not defined (user.myWeblogOutliner.prefs.radio.blogid) user.myWeblogOutliner.prefs.radio.blogid = "home" if not defined (user.myWeblogOutliner.prefs.radio.username) user.myWeblogOutliner.prefs.radio.username = user.radio.prefs.security.remoteUsername if not defined (user.myWeblogOutliner.prefs.radio.password) user.myWeblogOutliner.prefs.radio.password = user.radio.prefs.security.remotePassword if not defined (user.myWeblogOutliner.prefs.radio.flUseMetaWeblogApi) user.myWeblogOutliner.prefs.radio.flUseMetaWeblogApi = true bundle //Movable Type prefs if not defined (user.myWeblogOutliner.prefs.movableType) new (tabletype, @user.myWeblogOutliner.prefs.movableType) if not defined (user.myWeblogOutliner.prefs.movableType.enabled) user.myWeblogOutliner.prefs.movableType.enabled = false if not defined (user.myWeblogOutliner.prefs.movableType.server) user.myWeblogOutliner.prefs.movableType.server = "www.myserver.com" if not defined (user.myWeblogOutliner.prefs.movableType.port) user.myWeblogOutliner.prefs.movableType.port = 80 if not defined (user.myWeblogOutliner.prefs.movableType.rpcPath) user.myWeblogOutliner.prefs.movableType.rpcPath = "/cgi-bin/mt-xmlrpc.cgi" if not defined (user.myWeblogOutliner.prefs.movableType.blogid) user.myWeblogOutliner.prefs.movableType.blogid = "1" if not defined (user.myWeblogOutliner.prefs.movableType.username) user.myWeblogOutliner.prefs.movableType.username = "" if not defined (user.myWeblogOutliner.prefs.movableType.password) user.myWeblogOutliner.prefs.movableType.password = "" if not defined (user.myWeblogOutliner.prefs.movableType.flUseMetaWeblogApi) user.myWeblogOutliner.prefs.movableType.flUseMetaWeblogApi = true „€€€€€€„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€„!€żśéŹÇArial (ťˇnwťÍçĄ>7p˙dLAND˙˙˙˙˙˙winon saveWeblogPage (adroutline, flClosing=false) Changes 11/2/03; 10:19:50 PM by AG Created. Loops through top-level headlines comparing each to the last saved version and posting new items or edited items as necessary. 11/4/03; 11:28:48 PM by AG Added a bunch of UI handling to make the window more click-proof. Now we're saving from a copied outline. It's not quite bulletproof but now it's a lot harder to mess local (o€,dď,śé[Ů›<h%ňď/ž],šŞ´4ëJćîÇ隞ŻŠžŠ1ˇÎ,Ě˛Ś€żœ.âš"Oűťâ÷§  -9 >J am r~ ‡“ ŸŤ °ź ÉŐ ęö  '3 FR [g u ›§ ś ÍŮ äđ  "archivePathForDateú codeFreshener ŃdataensureGidsAndPostIdMap}initGÂinitAtts(í itemChangedęmenu,ö menuCommandspwnewPageWindowForDate? newWindow2‘nthSummitChildrenToOutlineýňnthSummitToOutlineâ‰oldstuffxň outlineToHtml—WrefreshPageArchiveFromWebPsaveWeblogPageşv saveWindowŽ todaysPageÝđupdateHeadlineGidÜ}websharePathForDateŘßVArial ŞhIA‘ĘIA‘Ęœ€źdďć ="Arial 1ťˇnwťËI›T÷iLAND˙˙˙˙˙˙winon saveWeblogPage (adroutline, flClosing=false) Changes 11/2/03; €źATu Arial šÜťĐ—R3|S<˝LAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.init () if dialog.ask ("Date for page to load (YYYY-MM-DD)?", @user.myWeblogOutliner.settings.oldPageDate) if not regex.easyMatch("[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}",user.myWeblogOutliner.settings.oldPageDate) dialog.notify("Sorry, wrong format, please try again.") else local(archiveYear = string.nthField(user.myWeblogOutliner.settings.oldPageDate,"-",1)) local(archiveMonth = string.nthField(user.myWeblogOutliner.settings.oldPageDate,"-",2)) local(archiveDay = string.nthField(user.myWeblogOutliner.settings.oldPageDate,"-",3)) if archiveMonth beginsWith "0" archiveMonth = string.mid(archiveMonth,2,1) if archiveDay beginsWith "0" archiveDay = string.mid(archiveDay,2,1) myWeblogOutlinerSuite.refreshPageArchiveFromWeb(archiveYear,archiveMonth,archiveDay) myWeblogOutlinerSuite.newPageWindowForDate(archiveYear,archiveMonth,archiveDay) €€€€€€€€€€€€€€AhVšÜť×d  $0 >J \h v‚ –˘ ¨ newServer-r newWeblogItem/F newWeblogPage˛ÖnewWeblogPageItemĽ oldWeblogPagel*refreshTodayFromWeb.:setup0¤VArial Ş‚3„ž+h€~w¤BÇ Arial šÜťĐ“ő*gS<ĚLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.init () if dialog.ask ("Date for page to load (YYYY-MM-DD)?", @user.myWeblogOutliner.settings.oldPageDate) local(archiveYear = string.nthField(user.myWeblogOutliner.settings.oldPageDate,"-",1)) local(archiveMonth = string.nthField(use€z qëzw¤B•úkbźdďżśé›Ů›#~c/e],´4ëJ úćîÇ隞ŻŠžŠ1ˇÎ,̲Ś$€&L0¤Arial ťĐ’†ťĐ9p_ĚLAND˙˙˙˙˙˙winon newWeblogPagePost () try op.firstSummit() op.insert("",up) else myWeblogOutlinerSuite.menuCommands.newWeblogPage() op.firstSummit() op.insert("",up) €€€€€€€€€~ffˆArial š"Oűť×ońJĽ&LAND˙˙˙˙˙˙winMyWeblogOutliner Set Up.. New Weblog Post.. New Weblog Page New Item in Weblog Page Old Weblog Page Refresh Today's Page From Web €€ *Ş€ +`€ ś+€ 5––€ vç€ "€fą3Arial PťĐ’ВŃÚ˘ƒLAND˙˙˙˙˙˙winmyWeblogOutlinerSuite.menuCommands.oldWeblogPage() €ą€B•VtArial š"OűťĐ’wJĽ&LAND˙˙˙˙˙˙winMyWeblogOutliner Set €Ž¨€– €ž˜w¤ž•(kb dďżśé›Ů›#~c/e],´4ëJ úćîÇ隞ŻŠžŠ1ˇÎ,̲Ś$€B ŚšÜ‡ťÍî  + 3? IU Zf nz ‡“ ˜¤ ą˝ ĹŃ ŕě ű ( <H Qarchive3á background=‘buttonsA[ callbacksBMinitBŤmainOldUa menuCommandsgŘopenh prefsOutlineippublishzpublishOneItem„ŒsaveWeblogPageęcsaveWeblogPageSnazzy{ statusCenterMessageŽVviewPostc Źń/Arial 5 ťˇnwťÍëČKEp˙YLAND˙˙˙˙˙˙winon saveWeblogPage (adroutline, flClosing=false) Changes 11/2/03; 10:19:50 PM by AG Created. Loops through top-level headlines comparing each to the last saved version and posting new items or edited items as necessary. 11/4/03; 11:28:48 PM by AG Added a bunch of UI handling to make the window more click-proof. Now we're saving from a copied outline. It's not quite bulletproof but now it's a lot harder to mess up the post ids with an accidental click. local (origsetting = op.getDisplay()) local (atts, opatts) window.attributes.getAll (@atts, adroutline) myWeblogOutlinerSuite.initAtts (@atts) on flowto (adrtable) if adrtable^.enabled //flow out through Blogger or MetaWeblog API local (data, username, password) bundle //create data table, set username, password new (tabletype, @data) data.appKey = "E260BC1A1004B61C2DF853E73909E912897D0C" data.blogid = adrtable^.blogid data.port = adrtable^.port data.protocol = "xml-rpc" data.rpcPath = adrtable^.rpcPath data.server = adrtable^.server username = adrtable^.username password = string (adrtable^.password) if (data.server == "127.0.0.1") and (data.port == 5335) //if the Blogger API is not enabled, enable it if not weblogData.prefs.flBloggerApiEnabled weblogData.prefs.flBloggerApiEnabled = true local (adrid = @opatts.id) if adrtable^.flUseMetaWeblogApi if defined (adrid^) metaWeblog.editPost (title, nil, description, nil, adrid^, username, password, adrdata:@data) else adrid^ = metaWeblog.newPost (title, nil, description, nil, username, password, blogid:data.blogid, adrdata:@data) else if title != "" description = "" + title + "

" + description if defined (adrid^) blogger.editPost (description, adrid^, username, password, adrdata:@data) else adrid^ = blogger.newPost (description, username, password, adrdata:@data) user.myWeblogOutliner.postIdMap.[opatts.gid] = adrid^ bundle //Briefly freeze the display and assign temporary ids to each headline for later mapping back to the network-generated post ids. local(gid=1, cursor=op.getCursor()) op.setDisplay(false) op.firstSummit() loop op.attributes.setOne("gid",gid) gid++ if not op.go(flatdown,1) break op.setCursor(cursor) op.setDisplay(origsetting) bundle //Drop and redefine the postIdMap if not defined (user.myWeblogOutliner.postIdMap) new(tableType,@user.myWeblogOutliner.postIdMap) table.emptyTable(@user.myWeblogOutliner.postIdMap) local(i=1,title,description,outlineCopy, itemOutline, savedOutline) bundle //Load the last saved outline from disk if it exists if file.exists (myWeblogOutlinerSuite.archivePathForDate(atts.archiveYear,atts.archiveMonth,atts.archiveDay)) op.xmlToOutline(file.readWholeFile(myWeblogOutlinerSuite.archivePathForDate(atts.archiveYear,atts.archiveMonth,atts.archiveDay)),@savedOutline) bundle //copy the outline and target it outlineCopy = adroutline^ target.set(@outlineCopy) bundle //go to last the summit; we'll be working upwards from the bottom op.firstSummit() loop if not op.go (down, 1) break i++ bundle //loop through the items, posting changed items to the blog loop if (myWeblogOutlinerSuite.itemChanged(@savedOutline, @outlineCopy, i)) if op.countSubs(1) == 0 title = "" myWeblogOutlinerSuite.nthSummitToOutline(@outlineCopy, @itemOutline, i) else title = op.getLineText() myWeblogOutlinerSuite.nthSummitChildrenToOutline(@outlineCopy, @itemOutline, i) description = myWeblogOutlinerSuite.outlineToHtml (@itemOutline) if not op.attributes.getAll(@opatts) new(tabletype,@opatts) flowto (@user.myWeblogOutliner.sites.[atts.sitename]) op.attributes.addGroup(@opatts) i-- if not op.go (up, 1) break bundle //save to opml local (f = myWeblogOutlinerSuite.archivePathForDate(atts.archiveYear,atts.archiveMonth,atts.archiveDay)) file.surefilepath (f) xmltext = op.outlinetoxml (@outlineCopy) file.writetextfile (f, xmltext) if user.myWeblogOutliner.prefs.archive.flOpenFolder file.openfolder (file.folderfrompath (f)) bundle //update the current window, part 1 atts.ctSaves++ window.attributes.addGroup (@atts, adroutline) target.set(adroutline) bundle //update the current window, part 2: assign the new postids to the current window local(postid,gid,cursor) op.setDisplay(false) cursor = op.getCursor() op.firstSummit() loop if not op.attributes.getOne("id",@postid) if op.attributes.getOne("gid",@gid) op.attributes.setOne("id",user.myWeblogOutliner.postIdMap.[gid]) if not op.go(down,1) break op.setCursor(cursor) op.setDisplay(origsetting) return (true) bundle //debugging saveWeblogPage (@system.temp.windowTypes.windows.["0000001"].window, false) €„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ KqëŹń Arial€,  {Arial  ťŐŹýť×ě%ŻđFmLAND˙˙˙˙˙˙winon ensureGidsAndPostIdMap (adr) Changes 11/10/03; 9:29:08 PM by AG Created. Ensures that every top-level headline has a gid, or "gui id" attribute. These are used to map local ids to remotely generated post ids, which in turn is used to minimize the need to interact with the live outline during save operations. 11/11/03; 9:45:01 PM by AG Added code to update the window's postIdMap attribute. The postIdMap doesn't get saved to OPML, but we can generate it each time we open a file. local(gid=1,copy = adr^,currgid, currid, flNeedsUpdate=false, oldtarget) bundle //Empty the postIdMap table if defined (user.myWeblogOutliner.postIdMap) table.emptyTable(@user.myWeblogOutliner.postIdMap) else new(tableType,@user.myWeblogOutliner.postIdMap) bundle //Check to see if we need to update the outline passed-in oldtarget = target.set(@copy) op.firstSummit() loop if op.attributes.getOne("gid",@currgid) if gid <= number(currgid) gid = number(currgid) + 1 if op.attributes.getOne("id",@currid) user.myWeblogOutliner.postIdMap.[currgid] = currid else flNeedsUpdate = true if not op.go(down,1) break target.set(oldtarget) if (flNeedsUpdate) oldtarget = target.set(adr) local(origsetting = op.getDisplay()) op.setDisplay(false) local(cursor=op.getCursor()) op.firstSummit() loop if not op.attributes.getOne("gid",@currgid) op.attributes.setOne("gid",gid) gid++ if op.attributes.getOne("id",@currid) op.attributes.getOne("gid",@currgid) user.myWeblogOutliner.postIdMap.[currgid] = currid if not op.go(down,1) break op.setCursor(cursor) op.setDisplay(origsetting) target.set(oldtarget) window.attributes.setOne("gid",gid) window.attributes.setOne("postIdMap", table.tableToXml(@user.myWeblogOutliner.postIdMap)) bundle //debug ensureGidsAndPostIdMap (@system.temp.windowTypes.windows.["0000001"].window) €„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ K …ŘÍ8š"OúťŐ­ ! ;G ]i …myWeblogOutlinerInfoXmyWeblogOutlinerNodeTypes’myWeblogOutlinerSuitegşmyWeblogOutlinerWindowTypesçÁVjFBAQýqüArial ť­¨HťŮ‚÷ʢjƒLAND˙˙˙˙˙˙winmyWeblogOutlinerInfo myWeblogOutlinerNodeTypes myWeblogOutlinerSuite archivePathForDate codeFreshener loadNewCode refreshCode releaseNewCode data ensureGidsAndPostIdMap init initAtts itemChanged menu menuCommands newPageWindowForDate newWindow nthSummitChildrenToOutline nthSummitToOutline oldstuff outlineToHtml refreshPageArchiveFromWeb saveWeblogPage saveWindow todaysPage updateHeadlineGid websharePathForDate myWeblogOutlinerWindowTypes weblogPage opReturnKey save weblogPost save saveAs €p]H€p]H€p]H€p]8€p]8€p]8ŕ€€p]8ŕ€€p]8ŕ€€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]8€p]H€p]0€p]P€p]P€p]0€p]x€p]xŠx€`Šp`Š\€`Šp`‰4€`Šp`‰„€`Šp`‰„€`Šp`‰4€`Šp`‰œ€`Šp`‰œŘT¸€ŘT¸€ŘT¸€ŘT¸€ŘT €ŘT €ŘT €ŘT €ŘT €ŘT €ŘT €ŘT°€ŘTŕ€ŘTx €ŘTŕ€ŘT €ŘT  …-°6ĎArial ťĐ’†ť×Ĺ…_ŔLAND˙˙˙˙˙˙winon newWeblogPageItem () try op.firstSummit() op.insert("",up) else myWeblogOutlinerSuite.menuCommands.newWeblogPage() op.firstSummit() op.insert("",up) myWeblogOutlinerSuite.updateHeadlineGid() €€€€€€€€€ window.attributes.setOne("gid",string(gid+1)) op.attributes.setOne("gid",gid) €€€€€€€€€€€€€€€-