Update FeedDemon Watches with AutoIt

AutoIt FeedDemon RSS reader among others things has Watches functions. Instead of specific RSS it searches feeds for keywords and combines found items together into mashup.

It works very well except that manual input of keywords is too troublesome to create complex Watches. I wanted to create Watch integrated with Appnews internals and started to look for external keywords edit.



Watch format

I remembered that when setting up new backup routine for Cobian Backup (inspired by my computer meltdown, yeah I am still talking about that) I saw Watches saved with rest of FeedDemon settings in:

C:\Documents and Settings\[profile]\Local Settings\Application Data

That folder has bunch of files with really cryptic names and .RSSW extensions. Inside each file is XML that holds all setting for a watch, including set of keywords:

Something like this:

<watch xmlns:fd="http://www.bradsoft.com/feeddemon/xmlns/1.0/"
version="1.6" fd:feedId="D40C7E27-19C1-45FF-AE7A-3B85054531BF"
fd:autoPurgeEnabled="true" fd:autoPurgeMaxItems="50">
fd:numUnread="0" fd:numFlagged="0" fd:numTotal="50"/>
<location title="true" description="false"/><options wholeWords="true"
matchCase="false" matchAllWords="false" markReadInSourceFeed="false"/>

So after creating Watch in FeedDemon I can find it by </em> and add all <em><keyword></em> I need.</p> <h3 id="autoit">AutoIt</h3> <p>As always <a href="https://www.rarst.net/tag/autoit/">AutoIt</a> is my first choice for simple programming tasks. I decided to make a function that will:</p> <ol> <li>Find specific Watch file by Watch name.</li> <li>Change keywords in Watch as I need.</li> </ol> <h3 id="step-by-step">Step by step</h3> <p><strong>Start</strong>. Array include is needed for some functions down the road. Function declaration - takes two parameters – name of Watch to edit and array of keywords.</p> <pre><code>#include <Array.au3> Func UpdateWatch($title,$array) </code></pre><p>Set up <strong>Watches directory</strong> and stops if not found. Uses <em>@UserProfileDir</em> macros to include profile of user in path.</p> <pre><code>$path=@UserProfileDir&"\Local Settings\Application Data \FeedDemon\v1\Watches\" If Not FileExists($path) Then MsgBox(0,"","Watches directory not found") Return EndIf </code></pre><p><strong>Set up search</strong> for specific Watch. Little tricky to understand but that’s how general file search mechanics in Windows go. Change directory to Watches, try to look for files that fit <em>*.rssw</em> format, stop if not found.</p> <pre><code>FileChangeDir($path) $search=FileFindFirstFile("*.rssw") If $search=-1 Then MsgBox(0,"","Search error") Return EndIf </code></pre><p><strong>Actual search</strong>. We are going through all files, looking for the one that has title equal to what was passed to function. If nothing is found we break search and stop function.</p> <pre><code>$watch=False $pattern="<title>"&$title&"</title>" While Not $watch $file = FileFindNextFile($search) If @error Then ExitLoop If StringInStr(FileRead($file),$pattern) Then $watch=$file WEnd FileClose($search) If Not $watch Then MsgBox(0,"","Watch not found") Return EndIf </code></pre><p><strong>Keywords array preparation</strong>. For each item in array passed to function content is enclosed in keyword tags.</p> <pre><code>$s=UBound($array)-1 For $i=0 To $s $array[$i]="<keyword>"&$array[$i]&"</keyword>" Next </code></pre><p><strong>File edit</strong>. Read Watch file. Replace everything from start of keywords to the end with keywords from array. Write file back (with creating backup copy to be safe).</p> <pre><code>$xml=FileRead($watch) FileCopy($watch,$watch&".bak") $pattern="(<keyword>.*)" $replace=_ArrayToString($array,"")&"</watch>" $xml=StringRegExpReplace($xml,$pattern,$replace) FileDelete($watch) FileWrite($watch,$xml) EndFunc </code></pre><p>And all together:</p> <p><strong>Script</strong> <a href="https://www.rarst.net/script/feed_demon_updatewatch.au3">https://www.rarst.net/script/feed_demon_updatewatch.au3</a></p> <p>For results to show up in FeedDemon it must be restarted after running function.</p> <h3 id="overall">Overall</h3> <p>So instead of tedious manual input now I just feed list of program titles from <a href="http://appnews.net/">Appnews</a> managing software into Watch. Ensures that I don’t miss anything and (at times) makes me feel great when I beat software portals at update speed. :)</p> <p>What would you track with large list of keywords?</p> <h3>Related Posts</h3> <ul> <li><a href="https://www.rarst.net/software/rss-productivity/">No way out increases RSS productivity</a></li> <li><a href="https://www.rarst.net/software/newsgator/">NewsGator family of RSS readers</a></li> <li><a href="https://www.rarst.net/web/dead-rss-links-opml/">Weeding dead RSS feeds with processing OPML</a></li> <li><a href="https://www.rarst.net/software/freeware-end/">When freeware runs out of free</a></li> <li><a href="https://www.rarst.net/thoughts/1000-subscribers-milestone/">1000 subscribers milestone</a></li> </ul> </div> <nav> <ul class="pager"> <li class="previous"> <a href="https://www.rarst.net/code/cureit-updater/">« Simplify CureIt update process with AutoIt</a> </li> <li class="next"> <a href="https://www.rarst.net/software/movefile/">How to schedule file move or delete on reboot »</a> </li> </ul> </nav> </article> <section id="comments-template" class="row"> <div class="col-md-12"> <h3 id="comments-number">1 Comments</h3> </div> <div class="col-sm-11 col-md-10"> <ul class="comment-list media-list"> <li class="comment clearfix"> <article> <div class="pull-left"> <img alt="" src="https://secure.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e?s=165&d=identicon&r=g" srcset="https://secure.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e?s=330&d=identicon&r=g 2x" class="avatar avatar-165 photo" height="165" width="165" loading="lazy"/> </div> <div class="media-body"> <h4 class="media-heading comment-meta text-left"> <cite>FeedDemon gets native tool to filter feed content | Rarst.net</cite> <span class="pull-right text-muted"> <time datetime="2010-01-23T23:22:14+02:00">2010-01-23</time> <a title="Permalink" href="#comment-14267">#</a> </span> </h4> <div>[...] Filters are very similar to Watches, except they don’t create separate item in feeds tree and are applied to specified feeds [...]</div> </div> </article> </li> </ul> </div> </section> </main> </div> <footer id="footer" class="row"> <div class="col-sm-12"> <hr/> </div> <div class="col-sm-12"> <p class="credit"> © 2008–2022 <a href="https://www.rarst.net/" title="Home page">Rarst.net</a> </p> </div> </footer> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/styles/solarized_dark.min.css" integrity="sha256-Si/lZpzlGW0CtfqnOyIiWjhYoeMUIui7MyR0TxlnHss=" crossorigin="anonymous" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js" integrity="sha256-WtUXEofG2M0/YE3zVZEpwoxarqbMZ8ze89ClCdvdemQ=" crossorigin="anonymous"></script> <script type="text/javascript"> document.addEventListener("DOMContentLoaded", function () { document.querySelectorAll('pre').forEach(function (item) { hljs.highlightBlock(item) }); }); </script> </div> </body> </html>