planet-venus-0~bzr116/0000755000175000017500000000000011261171700013172 5ustar poxpoxplanet-venus-0~bzr116/themes/0000755000175000017500000000000011261171712014462 5ustar poxpoxplanet-venus-0~bzr116/themes/musings/0000755000175000017500000000000011261171713016150 5ustar poxpoxplanet-venus-0~bzr116/themes/musings/personalize.js0000644000175000017500000001453011261171713021044 0ustar poxpoxvar entries = []; // list of news items var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; // event complete: stop propagation of the event function stopPropagation(event) { if (event.preventDefault) { event.preventDefault(); event.stopPropagation(); } else { event.returnValue = false; } } // scroll back to the previous article function prevArticle(event) { for (var i=entries.length; --i>=0;) { if (entries[i].anchor.offsetTop < document.documentElement.scrollTop) { window.location.hash=entries[i].anchor.id; stopPropagation(event); break; } } } // advance to the next article function nextArticle(event) { for (var i=1; i document.documentElement.scrollTop) { window.location.hash=entries[i].anchor.id; stopPropagation(event); break; } } } // process keypresses function navkey(event) { var checkbox = document.getElementById('navkeys'); if (!checkbox || !checkbox.checked) return; if (!event) event=window.event; key=event.keyCode; if (!document.documentElement) return; if (!entries[0].anchor || !entries[0].anchor.offsetTop) return; if (key == 'J'.charCodeAt(0)) nextArticle(event); if (key == 'K'.charCodeAt(0)) prevArticle(event); } // create (or reset) a cookie function createCookie(name,value,days) { if (days) { var date = new Date(); date.setTime(date.getTime()+(days*24*60*60*1000)); var expires = "; expires="+date.toGMTString(); } else expires = ""; document.cookie = name+"="+value+expires+"; path=/"; } // read a cookie function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } // each time the value of the option changes, update the cookie function selectOption() { var checkbox = document.getElementById('navkeys'); if (!checkbox) return; createCookie("navkeys", checkbox.checked?'true':'false', 365); } // add navkeys option to sidebar function addOption(event) { if (entries.length > 1 && entries[entries.length-1].parent.offsetTop > 0) { var sidebar = document.getElementById('sidebar'); if (!sidebar) return; for (var i=entries.length; --i>=0;) { var a = entries[i].anchor = document.createElement('a'); a.id = "news-" + i; entries[i].parent.insertBefore(a, entries[i].parent.firstChild); } var h2 = document.createElement('h2'); h2.appendChild(document.createTextNode('Options')); sidebar.appendChild(h2); var form = document.createElement('form'); var p = document.createElement('p'); var input = document.createElement('input'); input.type = "checkbox"; input.id = "navkeys"; p.appendChild(input); var a = document.createElement('a'); a.title = "Navigate entries"; a.appendChild(document.createTextNode('Enable ')); var code = document.createElement('code'); code.appendChild(document.createTextNode('J')); a.appendChild(code); a.appendChild(document.createTextNode(' and ')); code = document.createElement('code'); code.appendChild(document.createTextNode('K')); a.appendChild(code); a.appendChild(document.createTextNode(' keys')); p.appendChild(a); form.appendChild(p); sidebar.appendChild(form); var cookie = readCookie("navkeys"); if (cookie && cookie == 'true') input.checked = true; input.onclick = selectOption; document.onkeydown = navkey; } } // convert date to local time var localere = /^(\w+) (\d+) (\w+) \d+ 0?(\d\d?:\d\d):\d\d ([AP]M) (EST|EDT|CST|CDT|MST|MDT|PST|PDT)/; function localizeDate(element) { var date = new Date(); date.setTime(Date.parse(element.innerHTML + " GMT")); var local = date.toLocaleString(); var match = local.match(localere); if (match) { element.innerHTML = match[4] + ' ' + match[5].toLowerCase(); element.title = match[6] + " \u2014 " + match[1] + ', ' + match[3] + ' ' + match[2]; return days[date.getDay()] + ', ' + months[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear(); } else { element.title = element.innerHTML + ' GMT'; element.innerHTML = local; return days[date.getDay()] + ', ' + date.getDate() + ' ' + months[date.getMonth()] + ' ' + date.getFullYear(); } } // find entries (and localizeDates) function findEntries() { var span = document.getElementsByTagName('span'); for (var i=0; i <xsl:value-of select="atom:title"/>

,

planet-venus-0~bzr116/themes/musings/images/0000755000175000017500000000000011261171713017415 5ustar poxpoxplanet-venus-0~bzr116/themes/musings/default.css0000644000175000017500000001454111261171713020313 0ustar poxpox/* * Written by Stefano Mazzocchi */ /* ----------------------------- Global Definitions -------------------- */ body { margin: 0px; padding: 0px; color: #222; background-color: #fff; quotes: "\201C" "\201E" "\2018" "\2019"; } a:link { color: #222; } a:visited { color: #555; } a[rel~='license'] { text-decoration: none; } h1 { font-size: 1.75em; text-transform: uppercase; letter-spacing: 0.25em; padding: 10px; margin: 0px 0px 0px 0px; color: #FFF; font-weight: normal; background-color: #036; border-bottom: 2px solid #bbb } /* ----------------------------- Sidebar --------------------------- */ #sidebar { float: right; top: 150px; right: 0px; width: 11em; background-color: white; padding: 0px 10px 20px 0px; margin: 0px 0px 20px 20px; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; } #sidebar h2 { letter-spacing: 0.15em; text-transform: uppercase; font-size: .9em; background-color: #BCD; color: #222; font-weight: bold; padding: 3px 0px 2px 4px; margin: 15px 0px 5px 10px; border: 1px solid #ccc; } #sidebar p { font-size: .8em; padding-left: 20px; padding-right: 5px; } #sidebar ul { font-family: sans-serif; margin-left: 5px; padding-left: 25px; } #sidebar li { margin-left: 0px; text-indent: -15px; list-style-type: none; font-size: .8em; line-height: 1.2em; } #sidebar ul li a { text-decoration: none; } #sidebar ul li a:hover { text-decoration: underline; } #sidebar img { border: 0; } #sidebar dl { font-size: .8em; padding-left: 1.0em; } #sidebar dl ul { padding-left: 1em; } #sidebar dt { margin-top: 1em; font-weight: bold; padding-left: 1.0em; } #sidebar dd { margin-left: 2.5em; } #sidebar .message { cursor: help; border-bottom: 1px dashed red; } #sidebar a:active, #sidebar a:hover { color: #FFCC66; } #sidebar a.message:hover { cursor: help; background-color: #ffD0D0; color:#000; border: 1px dashed red !important; text-decoration: none !important; } #sidebar dl a { text-decoration:none; } /* ----------------------------- Body ---------------------------- */ #body { margin-top: 10px; } .admin { text-align: right; } #body h2.date { text-transform: none; font-size: 1em; color: #222; font-weight: bold; text-align: right; border-top: 1px solid #ccc; background-color: #BCD; border-bottom: 1px solid #ccc; padding: 3px 15px 2px 5px; max-width:43em; margin: 0; } /* ----------------------------- News ---------------------------- */ .news { margin: 30px 10px 30px 10px; clear: left; max-width: 50em; } .news h3 { margin: 0 0 .5em 0; padding: 0px; font-size: 1.5em; } .news h3 a { color:#036; text-decoration:none; } .news .content { margin: 5px 5px 5px 15px; padding: 0px 1em 1em 1em; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; border-right: 1px solid #ccc; line-height: 1.5em; font-size: 1em; font-family: sans-serif; max-width:40em; } .news .links { } .news .permalink { text-align: right; } .news .icon { height: 1em; width: 1em; border: 0; bottom: 0; } /* ----------------------------- News Content ---------------------------- */ .news .content p { line-height: 1.2em; } .news .content img { margin: 5px; } .news .content blockquote { margin: 10px 35px 10px 35px; padding: 5px; } .news .content pre { font-family: monospace; border: 1px solid #ddd; padding: 10px; margin: 10px 20px 10px 20px; background-color: #f8f8f8; overflow: auto; } .news .content code { font-family: monospace; } .news .content ul, .news .content ol { margin: 5px 35px 5px 35px; padding: 5px; counter-reset: item; } .news .content ul > ul, .news .content ul > ol, .news .content ol > ul, .news .content ol > ol { margin: 0px 0px 0px 35px; padding: 0px; } .news .content li { padding: 1px; line-height: 1.2em; } .news code { font-family: large; } .news .content :link, .news .content :visited { text-decoration: none; font-weight:bold; color:#036; } .news .content p:hover a, .news .content dt:hover a, .news .content dd:hover a, .news .content li:hover a { text-decoration: underline; } .news :link:active, .news :visited:active, .news :link:hover, .news :visited:hover { color: #FFCC66; } /* --------------------------- Accomodations ----------------------- */ /* Cosmic Variance */ .alignright { float:right; } .alignleft { float:left; } img.alignright { padding: 4px; margin: 0 0 2px 7px; display: inline; } img.centered { display: block; margin-left: auto; margin-right: auto; } /* Backreaction */ div.content:hover a, div.permalink:hover a { text-decoration:underline; } /* Musings/String Coffee Table */ math[display=block] {overflow:auto;} math { white-space: nowrap } .numberedEq span, .eqno {float:right} merror {display:inline;font-size:1em;} img.mathlogo, img.svglogo { float:right; border:0 } .footnote {font-size: .9em} .update h4 { display:inline; font-size:1em; font-weight:bold; } table.plaintable {border-collapse:collapse;} .plaintable td {border:1px solid #000; padding: 3px;} .plaintable th {padding: 3px;} .plaintable caption { font-weight: bold; font-size:1.1em; text-align:center; margin-left:30px; } .centeredfigure { position:relative; margin:auto; text-align:center; } .figurecaption {color:#630;} /* Bosker Blog */ p.center {text-align:center} /* boing boing */ br { clear: none !important; } /* engadget */ h6 { clear: left !important; } /* cadenhead */ p.sourcecode { font-family: monospace; border: 1px solid #ddd; padding: 10px; margin: 10px 20px 10px 20px; background-color: #f8f8f8; overflow: auto; } /* programmableweb */ .imgRight { float: right; } /* gizmodo */ img.left { float: left; } /* gizmodo */ img.right { float: right; } /* gizmodo */ img.center { display: block; margin-left: auto; margin-right: auto; } /* wikipedia */ table { width: auto !important; } /* del.icio.us */ .delicious-tags { font-size: .8em; text-align: right; } /* ----------------------------- Footer ---------------------------- */ #footer { padding: 0px; margin: 30px 0px 50px 50px; } #footer p { padding: 2px 2px 2px 5px; background-color: #ccc; border-top: 1px solid #aaa; border-bottom: 1px solid #aaa; border-left: 1px solid #aaa; letter-spacing: 0.15em; text-transform: uppercase; text-align: left; } planet-venus-0~bzr116/themes/musings/config.ini0000644000175000017500000000044311261171712020116 0ustar poxpox[Planet] template_files: atom.xml.xslt foafroll.xml.xslt opml.xml.xslt index.html.xslt template_directories: ../common bill_of_materials: default.css personalize.js images/feed-icon-10x10.png images/opml.png images/foaf.png images/venus.png images/venus.ico planet-venus-0~bzr116/themes/mobile/0000755000175000017500000000000011261171712015731 5ustar poxpoxplanet-venus-0~bzr116/themes/mobile/mobile.html.xslt0000644000175000017500000001471011261171712021062 0ustar poxpox <xsl:value-of select="atom:title"/>

Subscriptions

,

content
planet-venus-0~bzr116/themes/mobile/config.ini0000644000175000017500000000074611261171712017706 0ustar poxpox# In addition to the outputs produced by the 'asf' theme, this one adds # a 'mobile' version. For best results, this needs to be combined with # the 'excerpt.py' filter. [Planet] template_files: atom.xml.xslt foafroll.xml.xslt index.html.xslt mobile.html.xslt opml.xml.xslt validate.html.xslt template_directories: ../asf ../common bill_of_materials: default.css personalize.js images/feed-icon-10x10.png images/opml.png images/foaf.png images/venus.png planet-venus-0~bzr116/themes/genshi_fancy/0000755000175000017500000000000011261171711017116 5ustar poxpoxplanet-venus-0~bzr116/themes/genshi_fancy/planet.css0000644000175000017500000000400111261171711021106 0ustar poxpoxbody { border-right: 1px solid black; margin-right: 200px; padding-left: 20px; padding-right: 20px; } h1 { margin-top: 0px; padding-top: 20px; font-family: "Bitstream Vera Sans", sans-serif; font-weight: normal; letter-spacing: -2px; text-transform: lowercase; text-align: right; color: grey; } .admin { text-align: right; } h2 { font-family: "Bitstream Vera Sans", sans-serif; font-weight: normal; color: #200080; margin-left: -20px; } h3 { font-family: "Bitstream Vera Sans", sans-serif; font-weight: normal; background-color: #a0c0ff; border: 1px solid #5080b0; padding: 4px; } h3 a { text-decoration: none; color: inherit; } h4 { font-family: "Bitstream Vera Sans", sans-serif; font-weight: bold; } h4 a { text-decoration: none; color: inherit; } img.face { float: right; margin-top: -3em; } .entry { margin-bottom: 2em; } .entry .date { font-family: "Bitstream Vera Sans", sans-serif; color: grey; } .entry .date a { text-decoration: none; color: inherit; } .sidebar { position: absolute; top: 0px; right: 0px; width: 200px; margin-left: 0px; margin-right: 0px; padding-right: 0px; padding-top: 20px; padding-left: 0px; font-family: "Bitstream Vera Sans", sans-serif; font-size: 85%; } .sidebar h2 { font-size: 110%; font-weight: bold; color: black; padding-left: 5px; margin-left: 0px; } .sidebar ul { padding-left: 1em; margin-left: 0px; list-style-type: none; } .sidebar ul li:hover { color: grey; } .sidebar ul li a { text-decoration: none; } .sidebar ul li a:hover { text-decoration: underline; } .sidebar ul li a img { border: 0; } .sidebar p { border-top: 1px solid grey; margin-top: 30px; padding-top: 10px; padding-left: 5px; } .sidebar .message { cursor: help; border-bottom: 1px dashed red; } .sidebar a.message:hover { cursor: help; background-color: #ff0000; color: #ffffff !important; text-decoration: none !important; } a:hover { text-decoration: underline !important; color: blue !important; } planet-venus-0~bzr116/themes/genshi_fancy/index.html.genshi0000644000175000017500000000646111261171711022376 0ustar poxpox $feed.config.name

$feed.config.name

$entry.new_date

$entry.source.config.name

$entry.title_detail.stream

${entry.content[0].stream} ${entry.summary_detail.stream}

by $entry.author_detail.name at $entry.updated

planet-venus-0~bzr116/themes/genshi_fancy/config.ini0000644000175000017500000000054111261171711021064 0ustar poxpox# This theme reimplements the classic "fancy" htmltmpl using genshi [Planet] template_files: atom.xml.xslt foafroll.xml.xslt index.html.genshi opml.xml.xslt rss10.xml.tmpl rss20.xml.tmpl template_directories: ../common ../classic_fancy bill_of_materials: planet.css images/feed-icon-10x10.png images/logo.png images/venus.png planet-venus-0~bzr116/themes/django/0000755000175000017500000000000011261171710015722 5ustar poxpoxplanet-venus-0~bzr116/themes/django/index.html.dj0000644000175000017500000000211611261171710020313 0ustar poxpox {{ name }}

{{ name }}

last updated by Venus on {{ date }} on behalf of {{ author_name }}

Feeds

    {% for channel in Channels %}
  • {{ channel.title }} by {{ channel.author_name }}
  • {% endfor %}
{% for item in Items %} {% ifchanged item.channel_name %}

{{ item.channel_name }}

{% endifchanged %}
{% if item.title %}

{{ item.title }}

{% endif %} {{ item.content }}

by {{ item.channel_author }} on {{ item.date }} · permalink

{% endfor %} planet-venus-0~bzr116/themes/django/config.ini0000644000175000017500000000026511261171710017673 0ustar poxpox# This theme is an example Planet Venus theme using the # Django template engine. [Planet] template_files: index.html.dj template_directories: bill_of_materials: bland.css planet-venus-0~bzr116/themes/django/bland.css0000644000175000017500000000101111261171710017505 0ustar poxpoxbody { margin: 50px 60px; font-family: Georgia, Times New Roman, serif; } h1 { font: normal 4em Georgia, serif; color: #900; margin-bottom: 0px; } .updated, .entry-tools { font: .8em Verdana, Arial, sans-serif; margin-bottom: 2em; } #channels { float: right; width: 30%; padding: 20px; margin: 20px; margin-top: 0px; border: 1px solid #FC6; background: #FFC; } #channels h2 { margin-top: 0px; } #channels ul { margin-bottom: 0px; } .entry { border-top: 1px solid #CCC; padding-top: 1em; } planet-venus-0~bzr116/themes/common/0000755000175000017500000000000011261171707015756 5ustar poxpoxplanet-venus-0~bzr116/themes/common/validate.html.xslt0000644000175000017500000001332411261171707021431 0ustar poxpox <xsl:value-of select="atom:title"/>
Name Format Notes
rss_0_90 rss_0_91 rss_0_91 rss_1_0 rss_0_90 rss_0_90 rss_2_0 rss_2_0 atom_0_3 atom_1_0 atom_1_0 background-color:#FCC http://feedvalidator.org/check?url= http://www.validome.org/rss-atom/validate? viewSourceCode=1&version= &url= message
planet-venus-0~bzr116/themes/common/rss20.xml.tmpl0000644000175000017500000000203711261171707020426 0ustar poxpox <TMPL_VAR name> en - <TMPL_VAR channel_name ESCAPE="HTML"><TMPL_IF title>: <TMPL_VAR title_plain ESCAPE="HTML"></TMPL_IF> () " length="" type=""/> planet-venus-0~bzr116/themes/common/rss10.xml.tmpl0000644000175000017500000000215011261171707020421 0ustar poxpox "> <TMPL_VAR name ESCAPE="HTML"> - " /> "> <TMPL_VAR channel_name ESCAPE="HTML"><TMPL_IF title>: <TMPL_VAR title_plain ESCAPE="HTML"></TMPL_IF> planet-venus-0~bzr116/themes/common/opml.xml.xslt0000644000175000017500000000320011261171706020432 0ustar poxpox <xsl:value-of select="atom:title"/> planet-venus-0~bzr116/themes/common/images/0000755000175000017500000000000011261171706017222 5ustar poxpoxplanet-venus-0~bzr116/themes/common/images/venus.png0000644000175000017500000000107211261171706021070 0ustar poxpoxPNG  IHDRPtEXtSoftwareGraphicConverter5]HIDATxbHa?3O~fҧp=?$d(B0o2ITNT߿߿ȁ4qfawqJyr[֌*\= cûn q=%Ft,_k^zGګ{YFӂK VYZ.W.ޙ[;bd5-k3פ}j<?q颕WFl4cts,L6Xӯ3PcüfQ azxᬮ85M>gJ%S45<cMv*{yzw.ݳiqmq+MW=t|5 ØI?Z)ӘQZڋ Lݻi@ۗPH8K7+$0Z CSvweTG/w.pP(FtOIENDB`planet-venus-0~bzr116/themes/common/images/venus.ico0000644000175000017500000000157611261171706021067 0ustar poxpoxh( Ler2L\2[n3lQ~Odo)Rc+Zp&Oa&_w$p*._>Zf$KZ,^u3y+`y'Xn(i)z82TXnw*Xo1s589(]s.cx.z,>:v-Vf4w8:?A:1Zn;4cs>~<64~@\h(Sg8{;6AL?:=2~/t,u0x_9Zf)Wk,f|2s5{DDB84//&'lLtFbn'Yl.i~5x1|;=<=1-0.*Yo L`(a{.l0r7{;6583*+v$j#GU"Qf'ax/q1z1,*+(&&+hj Oe#Wl \q'g2t/+% u!nv\)l(o&o,t.z&~!{ z#x_w21=;($/zx{KHPqt~dTbplanet-venus-0~bzr116/themes/common/images/tcosm11.gif0000644000175000017500000000031311261171705021174 0ustar poxpoxGIF89a nJfAo7X.M!8ӑެы; c<`a9a:igAಠψЉyXךdDmI5453!, H-@"~oa_m(QCc%j AlNY<1p<*g"G8.D̄ ;planet-venus-0~bzr116/themes/common/images/planet.png0000644000175000017500000000065211261171705021215 0ustar poxpoxPNG  IHDRPDxPLTE!!",+.9;QPOTPPnSTyXUjWWq^`egakfffhdrcjjn|qpvifqqzqrs{}z|w|~yxd pHYs  ~tIME--Y)IDATxڭ  ďTLk2s/dѫ\VB(m.+-%+6PuO(ujh66]jZ:W&Gq ]3t*|r(NUb6/;4Gp9Jf@kGjM!qF¡6" @=MOnl[c_-9wGo,{ Ղ)bxIENDB`planet-venus-0~bzr116/themes/common/images/opml.png0000644000175000017500000000144411261171705020701 0ustar poxpoxPNG  IHDR# PLTE󧩅KH-)id563332111ZQfff41cc億﫦칺߄雛嫧uq)">8半OK}zB;lh"ᘗ 1)YW쐎'¾!便OKCC" sn跸1+{t{|73a\馦IHꉆ<8! "TSicA@4* 펎ﶶIA1!wvkl'!ddPRA9~sn86cR歭 b\ǽ pHYsHHFk>JIDATm O` CPa:q0Q97qEtSA+C`<~ߤiIH{mԲ0-+VhVŇBL-0j_ :clO}`e>Dɠi֖5Y%Uzb L#򼪺'2٧P|lOG4#r[%3ƪ }G4E({LF@DF¶Lݶ-܎WJgN7ۿtFl4 e8y4’=# dbŽwZG`Ts9_HJjayIENDB`planet-venus-0~bzr116/themes/common/images/logo.png0000644000175000017500000001244511261171704020674 0ustar poxpoxPNG  IHDR4 pHYsgRtIME ; f9$tEXtCommentLEAD Technologies Inc. V1.01~Ѓ IDATx]vzaKH8۵ϽgmĢHWku_ Hkq{!y=JqG.[_Tyݦ}݂s_`n--w1ٺ߻My|^(]~˽l 迃 l[kB꿺j&`oD r"OM @~$kq+?P>/+-3EDm,=XSR  X'˅Pya6i] Ի2,XI@Pr7|fQO J?(>.pMc~$*Dp[0[> <]QD.gg4ސ@C8$; ('6LtC!r-g2!d1; 0 R޻VrIu d0pE#/A;:Ĵ~ưS?*(,Z C@PFqqPiW sp# ;БC-“?4Vg.ھM'A:30fM᜛RUE|Fq8Gr쫍;DSh`h~`&P %`'Te8X9o[fI Ȕu~.80$7r{ -&!'2Jq09 x_Rogb*pF^G z2 5hpw8_Ror!pj|.7ՖA6XX?E0'>AX3UaYypW?%Ugd~\f# CL_l|pk~{t0p7{"A-(1LvH2_g gZ@LƁ3"LR/PÙ^VhV^~{JG'QPlh1#ڢ^ƜznxPrs. {bF7`t 6EY( VaqmH8pLv@ {%9Ӕ:e+ГXL$߯anTv O=c0=`nLzD!Yg42THp;2BdOuP-SC:zm¾T 2!oeC 5Ĩ0cs7Z 6xz!2,EmmPS6 M"N1S_@.[Eg[ O₁\;Y "Uz xQS6 MrYbL.|P9Ѫh5U =d9Ъlc(-ٚgqeq𠎻# H Dt|ʏ-#ȈHtx:.x]SF'в\JyQB5|Ka.mʈ2~V4kDs *t2v>XLG2/X`M1QdCAI3IP3bXFs9hI֟tRܟ4wr /!,,ӂ.'y Wr8u={] 3<=pDcrɘ5MS:g(kHf 5/ꆁܻh JMPݑ}.6A]pJk ~x2x-)۸Q0g<_.BVLbfoD^y4)(p":_P ֏s]?'5 qOkht:!#BsX f"ά2 qL3 #g4TJU8r2*J3䪄wΦBIM@?=ʶ0/ELȜ\PI}e&I\ E}eP-"m|jw#an|%3BF/j;*WF+dOB".Cʣ Qp%]Eߪiҹ34$S㬞jYR99~+%c[3pNk++OMdFXʶ L/,sڮ(63ݥ ?y=ˡ2-N Hb fܔ]dűcX dR/1#1E#.TwG-1kЬ% Fdl:"sHH3ĚmS_;О3P.a j[w6(‡g2XdcH[|$F8cn$QXv,\T0L[>֗W>SP&퇬+;_\[~*CjֲgicZ+$%m9oA΋KQDKfpiƹFf(sF :Jӛ ,#W+g}5 !IreiFb4|mk-د f1ۯ氂֘T9I7<Xtʊ;:03R]A f"2[; M0v;uGM #Ъ3 V08DvxrL7ؙ~p$<(ye1E+;erd›os*Cb.c$@:T[%Zvs\Y-&) =fn%%}YrAb9C*mPᴷز*wz0ս d&kZ|D*d/>@*䊲f"Ϲ'"=b+":C`J{NPjĔakoffR5uzZ1})(z# ZLҗ }Mudy+g͉6Co1.k "vVZmҲ`dߢ1¤ HSLSʏX1Ei3ϼ FX:MF0E+ }zI2~: zԮǦɼl&W !i܍65;Uc#|E,9FZ-Y{@ B "%.s~ԼVW5F f >Vx8k%Pٱ9\JymDFD-M=rUcʥ@MEoTcqBYTt[lTIV W7a8~(ּ3rQAO}nD`#N;h9,82@1?S5"cÊ0b$68K(HLL3+u'0Y\gSn  $&sGɑͿȟ,&9:& S*3r Lj1Y[3]W􁘉AO(P lx|!(t:Ye5CpO0ou!2Aݝ21-Jb(.8+*HN%7jX@6mŜA#nș Ph?Ѻ)@BxUWDsL7=\Ai<~>}Ja ,+i3E- &WHPYUXT΍ŷ9 +c2Myl93Uipi_3Xhfko,rӮ3)7A*ߺ b\m3Fԓӥ*/9U2P#IVA"ZL5 A.6iIViL˦2Rg5±\єkQMz?[.lT;HT?Oԃ˚zBgiU(g 5!0de񕙷Tf2S03,N6Shu[cD!48V_>R;,8nc0uڹeuBݳ*PzoT*`tpnӒ5}ؘP?ӳD$?d;b`h\}MmπPZ:NfUV|3I$\ovoI&=ov 2mB=Z.lYWz}Ag:>JwX=eX<@dQ0cyd$LĝS(]ܞCB*u}` n6XO,F3AlT[KvpḇΠGm` ʄfdMXbZ,QIDATcXؘw͚5Z\\Zka:75"e"bRaR :U)B+XX0Dr:;qJkkjKGͶ_ðt"Ece M,+-M e89ՂB̫+PQS]jg4icVz0_^dՒu j%4$ZYM.fX1|" z`bcfeX?\E>830e55  V.c^ R@66 ~mIENDB`planet-venus-0~bzr116/themes/common/images/feed-icon-10x10.png0000644000175000017500000000072511261171704022332 0ustar poxpoxPNG  IHDR 2ϽgAMA7tEXtSoftwareAdobe ImageReadyqe<gIDATx,;HQ{gf]|cZ @j!>l+VAIvIH@( X`h(U|kuvgޛ]|9#&ĝ?rD( |}fT\MA1:|Aa w#'>,`1F-4ҽs;n[QhmEnhdxvz9œno-aDn*󊷳qzevWyde (+^h]Hd5K{Mؠ]=d4Nchh'?rsahC F 0e&IENDB`planet-venus-0~bzr116/themes/common/foafroll.xml.xslt0000644000175000017500000000270211261171703021272 0ustar poxpox planet-venus-0~bzr116/themes/common/atom.xml.xslt0000644000175000017500000000507511261171703020434 0ustar poxpox no planet-venus-0~bzr116/themes/classic_fancy/0000755000175000017500000000000011261171703017263 5ustar poxpoxplanet-venus-0~bzr116/themes/classic_fancy/planet.css0000644000175000017500000000400111261171703021253 0ustar poxpoxbody { border-right: 1px solid black; margin-right: 200px; padding-left: 20px; padding-right: 20px; } h1 { margin-top: 0px; padding-top: 20px; font-family: "Bitstream Vera Sans", sans-serif; font-weight: normal; letter-spacing: -2px; text-transform: lowercase; text-align: right; color: grey; } .admin { text-align: right; } h2 { font-family: "Bitstream Vera Sans", sans-serif; font-weight: normal; color: #200080; margin-left: -20px; } h3 { font-family: "Bitstream Vera Sans", sans-serif; font-weight: normal; background-color: #a0c0ff; border: 1px solid #5080b0; padding: 4px; } h3 a { text-decoration: none; color: inherit; } h4 { font-family: "Bitstream Vera Sans", sans-serif; font-weight: bold; } h4 a { text-decoration: none; color: inherit; } img.face { float: right; margin-top: -3em; } .entry { margin-bottom: 2em; } .entry .date { font-family: "Bitstream Vera Sans", sans-serif; color: grey; } .entry .date a { text-decoration: none; color: inherit; } .sidebar { position: absolute; top: 0px; right: 0px; width: 200px; margin-left: 0px; margin-right: 0px; padding-right: 0px; padding-top: 20px; padding-left: 0px; font-family: "Bitstream Vera Sans", sans-serif; font-size: 85%; } .sidebar h2 { font-size: 110%; font-weight: bold; color: black; padding-left: 5px; margin-left: 0px; } .sidebar ul { padding-left: 1em; margin-left: 0px; list-style-type: none; } .sidebar ul li:hover { color: grey; } .sidebar ul li a { text-decoration: none; } .sidebar ul li a:hover { text-decoration: underline; } .sidebar ul li a img { border: 0; } .sidebar p { border-top: 1px solid grey; margin-top: 30px; padding-top: 10px; padding-left: 5px; } .sidebar .message { cursor: help; border-bottom: 1px dashed red; } .sidebar a.message:hover { cursor: help; background-color: #ff0000; color: #ffffff !important; text-decoration: none !important; } a:hover { text-decoration: underline !important; color: blue !important; } planet-venus-0~bzr116/themes/classic_fancy/index.html.tmpl0000644000175000017500000001052211261171702022232 0ustar poxpox ### Fancy Planet HTML template. ### ### When combined with the stylesheet and images in the output/ directory ### of the Planet source, this gives you a much prettier result than the ### default examples template and demonstrates how to use the config file ### to support things like faces ### ### For documentation on the more boring template elements, see ### examples/config.ini and examples/index.html.tmpl in the Planet source. <TMPL_VAR name> "> " title="" type="application/+xml">

### End
### End

### End
### Planet provides template variables for *all* configuration options for ### the channel (and defaults), even if it doesn't know about them. We ### exploit this here to add hackergotchi faces to our channels. Planet ### doesn't know about the "face", "facewidth" and "faceheight" configuration ### variables, but makes them available to us anyway.

" title="">

" width="" height="" alt="">
lang=""> lang="">">
lang="">
### Planet also makes available all of the information from the feed ### that it can. Use the 'planet-cache' tool on the cache file for ### a particular feed to find out what additional keys it supports. ### Comment extra fields are 'author' and 'category' which we ### demonstrate below.

">by at under

### End
### End
planet-venus-0~bzr116/themes/classic_fancy/config.ini0000644000175000017500000000062011261171702021226 0ustar poxpox# This theme is based on the one contained in Planet V2.0. It demonstrates # that one can mix the use of htmltmpl and xslt templates. [Planet] template_files: atom.xml.xslt foafroll.xml.xslt index.html.tmpl opml.xml.xslt rss10.xml.tmpl rss20.xml.tmpl template_directories: ../common bill_of_materials: planet.css images/feed-icon-10x10.png images/logo.png images/planet.png planet-venus-0~bzr116/themes/asf/0000755000175000017500000000000011261171702015232 5ustar poxpoxplanet-venus-0~bzr116/themes/asf/personalize.js0000644000175000017500000002273011261171702020127 0ustar poxpoxvar entries = []; // list of news items var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; // event complete: stop propagation of the event function stopPropagation(event) { if (event.preventDefault) { event.preventDefault(); event.stopPropagation(); } else { event.returnValue = false; } } // scroll back to the previous article function prevArticle(event) { var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; for (var i=entries.length; --i>=0;) { if (!entries[i].anchor) continue; if (entries[i].anchor.offsetTop < scrollTop) { window.location.hash=entries[i].anchor.id; stopPropagation(event); break; } } } // advance to the next article function nextArticle(event) { var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; for (var i=1; iscrollTop) { window.location.hash=entries[i].anchor.id; stopPropagation(event); break; } } } // process keypresses function navkey(event) { var checkbox = document.getElementById('navkeys'); if (!checkbox || !checkbox.checked) return; if (!event) event=window.event; if (event.originalTarget && event.originalTarget.nodeName.toLowerCase() == 'input' && event.originalTarget.id != 'navkeys') return; if (!document.documentElement) return; if (!entries[0].anchor || !entries[0].anchor.offsetTop) return; key=event.keyCode; if (key == 'J'.charCodeAt(0)) nextArticle(event); if (key == 'K'.charCodeAt(0)) prevArticle(event); } // create (or reset) a cookie function createCookie(name,value,days) { if (days) { var date = new Date(); date.setTime(date.getTime()+(days*24*60*60*1000)); var expires = "; expires="+date.toGMTString(); } else expires = ""; document.cookie = name+"="+value+expires+"; path=/"; } // read a cookie function readCookie(name) { var nameEQ = name + "="; if (!document.cookie) return; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } // each time the value of the option changes, update the cookie function selectOption() { var checkbox = document.getElementById('navkeys'); if (!checkbox) return; createCookie("navkeys", checkbox.checked?'true':'false', 365); } // add navkeys option to sidebar function addOption(event) { var sidebar = document.getElementById('sidebar'); if (!sidebar) return; var h2 = null; for (var i=entries.length; --i>=0;) { if (document.getElementById("news-" + i)) break; if (entries[i].parent.offsetTop > 0) { var a = entries[i].anchor = document.createElement('a'); a.id = "news-" + i; entries[i].parent.insertBefore(a, entries[i].parent.firstChild); if (h2 == null) h2 = document.createElement('h2'); } } if (h2 != null && !document.getElementById("navkeys")) { h2.appendChild(document.createTextNode('Options')); sidebar.appendChild(h2); var form = document.createElement('form'); var p = document.createElement('p'); var input = document.createElement('input'); input.type = "checkbox"; input.id = "navkeys"; p.appendChild(input); var a = document.createElement('a'); a.title = "Navigate entries"; a.appendChild(document.createTextNode('Enable ')); var code = document.createElement('code'); code.appendChild(document.createTextNode('J')); a.appendChild(code); a.appendChild(document.createTextNode(' and ')); code = document.createElement('code'); code.appendChild(document.createTextNode('K')); a.appendChild(code); a.appendChild(document.createTextNode(' keys')); p.appendChild(a); form.appendChild(p); sidebar.appendChild(form); var cookie = readCookie("navkeys"); if (cookie && cookie == 'true') input.checked = true; input.onclick = selectOption; document.onkeydown = navkey; } } // Parse an HTML5-liberalized version of RFC 3339 datetime values Date.parseRFC3339 = function (string) { var date=new Date(); date.setTime(0); var match = string.match(/(\d{4})-(\d\d)-(\d\d)\s*(?:[\sT]\s*(\d\d):(\d\d)(?::(\d\d))?(\.\d*)?\s*(Z|([-+])(\d\d):(\d\d))?)?/); if (!match) return; if (match[2]) match[2]--; if (match[7]) match[7] = (match[7]+'000').substring(1,4); var field = [null,'FullYear','Month','Date','Hours','Minutes','Seconds','Milliseconds']; for (var i=1; i<=7; i++) if (match[i]) date['setUTC'+field[i]](match[i]); if (match[9]) date.setTime(date.getTime()+ (match[9]=='-'?1:-1)*(match[10]*3600000+match[11]*60000) ); return date.getTime(); } // convert datetime to local date var localere = /^(\w+) (\d+) (\w+) \d+ 0?(\d\d?:\d\d):\d\d ([AP]M) (EST|EDT|CST|CDT|MST|MDT|PST|PDT)/; function localizeDate(element) { var date = new Date(); date.setTime(Date.parseRFC3339(element.getAttribute('datetime'))); if (!date.getTime()) return; var local = date.toLocaleString(); if (element.parentNode.nodeName == 'a') local = date.toLocaleTimeString(); var match = local.match(localere); if (match) { /* Firefox */ element.innerHTML = match[4] + ' ' + match[5].toLowerCase(); element.title = match[6] + " \u2014 " + match[1] + ', ' + match[3] + ' ' + match[2]; return days[date.getDay()] + ', ' + months[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear(); } else { local = local.replace(/ GMT(-\d\d\d\d) \(.*\)$/, ''); /* Webkit */ element.title = element.innerHTML + ' GMT'; element.innerHTML = local; return days[date.getDay()] + ', ' + date.getDate() + ' ' + months[date.getMonth()] + ' ' + date.getFullYear(); } } // find entries (and localizeDates) function findEntries() { var times = document.getElementsByTagName('time'); for (var i=0; i <!DOCTYPE html> <xsl:value-of select="atom:title"/>

Footnotes

content
planet-venus-0~bzr116/themes/asf/default.css0000644000175000017500000001772311261171701017401 0ustar poxpox/* * Originally written by Stefano Mazzocchi * Adapted by Sam Ruby */ /* ----------------------------- Global Definitions -------------------- */ body { margin: 0px; padding: 0px; color: #222; background-color: #fff; quotes: "\201C" "\201E" "\2018" "\2019"; } a:link { color: #222; } a:visited { color: #555; } a:hover { color: #000; } a:active { } a:focus { } a.inactive { color: #558; } a.rising { font-weight: bold; } a[rel~='license'] { text-decoration: none; } body > h1 { font-size: x-large; text-transform: uppercase; letter-spacing: 0.25em; padding: 10px; margin: 0px 0px 0px 0px; color: #889; font-family: Sans-Serif; font-weight: bold; font-style: italic; background-color: #eee; border-bottom: 2px solid #ccd; } /* ----------------------------- Sidebar --------------------------- */ #sidebar { float: right; top: 150px; right: 0px; width: 210px; background-color: white; padding: 0px 0px 10px 0px; margin: 0px 0px 20px 20px; border-left: 2px solid #ccd; border-bottom: 2px solid #ccd; -webkit-border-bottom-left-radius: 1em; -moz-border-radius: 0 0 0 1em; } #sidebar h2 { letter-spacing: 0.15em; text-transform: uppercase; font-size: x-small; color: #666; font-weight: normal; padding: 2px 0px 2px 12px; margin: 15px 0px 5px 10px; border-top: 1px solid #ccc; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; -webkit-border-top-left-radius: 6px; -webkit-border-bottom-left-radius: 6px; -moz-border-radius: 6px 0 0 6px; } #sidebar h2 a img { margin-bottom: 4px; vertical-align: middle; } #sidebar p { font-size: x-small; padding-left: 20px; padding-right: 5px; } #sidebar ul { font-family: sans-serif; margin-left: 5px; padding-left: 25px; } #sidebar li { margin-left: 0px; text-indent: -15px; list-style-type: none; font-size: x-small; } #sidebar ul li a { text-decoration: none; } #sidebar ul li a:hover { text-decoration: underline; } #sidebar ul li a:visited { color: #000; } #sidebar ul li ul { display: none; } #sidebar ul li { position: relative; } #sidebar ul li:hover ul { background-color: #EEE; -webkit-border-radius: 0.5em; -moz-border-radius: 0.5em; border: 2px solid #BBB; color:#000; display: block; margin-left: -300px; margin-right: 115px; padding: 10px; padding-left: 25px; position: absolute; right: 80px; top: -12px; z-index: 1; } #sidebar img { margin-top: 2px; border: 0; } #sidebar dl { font-size: x-small; padding-left: 1.0em; } #sidebar dl ul { padding-left: 1em; } #sidebar dt { margin-top: 1em; font-weight: bold; padding-left: 1.0em; } #sidebar dd { margin-left: 2.5em; } #sidebar .message { cursor: help; border-bottom: 1px dashed red; } #sidebar a.message:hover { cursor: help; background-color: #ffD0D0; border: 1px dashed red !important; text-decoration: none !important; } #sidebar input[name=q] { padding-left: 0.5em; border: 1px solid #ccd; -webkit-border-radius: 0.8em; -moz-border-radius: 0.8em; width: 12.5em; margin: 4px 0 0 24px; } /* ---------------------------- Footer --------------------------- */ #footer ul { margin: 0 20px 0 -25px; padding: 0; } #footer li { margin: 0; padding: 0; list-style: none; display: inline; } #footer ul li ul { display: none; } #footer img { display: none; } /* ----------------------------- Body ---------------------------- */ #body { margin-top: 10px; margin-right: 210px; } .admin { text-align: right; } #body > h2 { float: right; min-width: 25%; -webkit-border-top-left-radius: 0.5em; -webkit-border-bottom-left-radius: 0.5em; -moz-border-radius: 0.5em 0 0 0.5em; text-transform: none; font-size: medium; color: #667; font-weight: bold; text-align: center; border: 2px solid #ccd; background-color: #eee; padding: 1px 1.5em 1px 1.5em; margin: -0.2em -22px 0 0; } /* ----------------------------- News ---------------------------- */ .news { margin: 30px 10px 30px 10px; clear: left; } .news > h3 { text-indent: -10px; margin: 12px; padding: 0px; font-size: medium; } .news > h3 > a:first-child { margin-left: 10px } .news > h3 > a:first-child:before { content: '⌘'; font-family: Code2000; color: #D70; margin-left: -18px; margin-right: 2px; text-decoration: none; } img.icon { height: 16px; width: 16px; margin-left: -8px; margin-bottom: -2px; margin-right: 3px; } .news .content { margin: 5px 5px 5px 15px; padding: 0px 5px 0px 5px; border-left: 1px solid #ccc; line-height: 1.2em; font-size: small; font-family: sans-serif; } .news .links { } .news .permalink { text-align: right; } /* ----------------------------- News Content ---------------------------- */ .news .content p { line-height: 1.2em; } .news .content img { margin: 5px; } .news .content blockquote { margin: 10px 35px 10px 35px; padding: 5px; } .news .content pre { font-family: monospace; font-size: medium; font-weight: bold; border: 1px solid #ddd; padding: 10px; margin: 10px 20px 10px 20px; background-color: #f8f8f8; overflow: auto; } .news .content ul, .news .content ol { margin: 5px 35px 5px 35px; padding: 5px; counter-reset: item; } .news .content ul > ul, .news .content ul > ol, .news .content ol > ul, .news .content ol > ol { margin: 0px 0px 0px 35px; padding: 0px; } .news .content li { padding: 1px; line-height: 1.2em; } .news code { font-family: monospace; font-size: medium; font-weight: bold; } .news .content a { text-decoration: none; color: #000; border-bottom: 1px dotted #777; margin: 0px 2px 0px 2px; padding: 1px 1px 1px 1px; } .news .content a:hover { border: 1px dotted #000; background-color: #eee; padding: 1px 2px 1px 2px; margin: 0px; } .news .content a:active { background-color: #ccc !important; position: relative; top: 1px; left: 1px; padding: 1px 2px 1px 2px; margin: 0px; } .news .content a:focus { border: 1px solid #fff !important; background-color: #ccc !important; padding: 1px 2px 1px 2px; margin: 0px; } /* --------------------------- Accomodations ----------------------- */ /* boing boing */ br { clear: none !important; } /* engadget */ p { clear: none !important; } /* cadenhead */ p.sourcecode { font-family: monospace; font-size: medium; font-weight: bold; border: 1px solid #ddd; padding: 10px; margin: 10px 20px 10px 20px; background-color: #f8f8f8; overflow: auto; } /* cadenhead */ span.sourcecode { font-family: monospace; font-size: medium; font-weight: bold; font-size: large; background-color: #f8f8f8; } /* hsivonen */ ul p, ol p { margin-top: 0.3em; margin-bottom: 0.3em; } /* programmableweb */ .imgRight { float: right; } /* gizmodo */ img.left { float: left; } /* gizmodo */ img.right { float: right; } /* gizmodo */ img.center { display: block; margin-left: auto; margin-right: auto; } /* wikipedia */ table { width: auto !important; } /* del.icio.us */ .delicious-tags { font-size: x-small; text-align: right; } /* musings */ img.mathlogo, img.svglogo { float: right; border: 0; } math { white-space: nowrap; } math[display=block] { overflow: auto; } .numberedEq span, .eqno { float: right; } /* sutor */ img.post-img-right { float:right; } /* niall */ img.floatright { float: right; } /* jason kolb */ .FeaturedPost > li { list-style-type: none; background-color: #f8f8f8; } /* Tantek */ ul.tags,ul.tags li,h4.tags { display:inline; font-size: x-small } ul.tags a:link, ul.tags a:visited { color:green } a[rel='tag'] img { border: 0; } /* DiveIntoMark */ .framed { float: none; } /* BurningBird */ .update:before { content: 'Update'; font-weight: bold; } .update { margin: 2em; padding: 0 1em 0 1em; background: #eee; border: 1px solid #aaa; } /* ----------------------------- Footer ---------------------------- */ #footer { padding: 0px; margin: 30px 0px 50px 50px; } #footer p { padding: 2px 2px 2px 5px; background-color: #ccc; border-top: 1px solid #aaa; border-bottom: 1px solid #aaa; border-left: 1px solid #aaa; letter-spacing: 0.15em; text-transform: uppercase; text-align: left; } planet-venus-0~bzr116/themes/asf/config.ini0000644000175000017500000000066611261171701017207 0ustar poxpox# This theme is based on the one originally developed by Stefano Mazzocci # for planetapache.org, and modified by Sam Ruby for planet.intertwingly.net [Planet] template_files: atom.xml.xslt foafroll.xml.xslt index.html.xslt opml.xml.xslt validate.html.xslt template_directories: ../common bill_of_materials: default.css personalize.js images/feed-icon-10x10.png images/opml.png images/foaf.png images/venus.png planet-venus-0~bzr116/tests/0000755000175000017500000000000011261171700014334 5ustar poxpoxplanet-venus-0~bzr116/tests/test_themes.py0000644000175000017500000000350411261171700017234 0ustar poxpox#!/usr/bin/env python import unittest from planet import config from os.path import split class ThemesTest(unittest.TestCase): def setUp(self): config.load('tests/data/config/themed.ini') # template directories def test_template_directories(self): self.assertEqual(['foo', 'bar', 'asf', 'config', 'common'], [split(dir)[1] for dir in config.template_directories()]) # administrivia def test_template(self): self.assertEqual(1, len([1 for file in config.template_files() if file == 'index.html.xslt'])) def test_feeds(self): feeds = config.subscriptions() feeds.sort() self.assertEqual(['feed1', 'feed2'], feeds) # planet wide configuration def test_name(self): self.assertEqual('Test Configuration', config.name()) def test_link(self): self.assertEqual('', config.link()) # per template configuration def test_days_per_page(self): self.assertEqual(7, config.days_per_page('index.html.xslt')) self.assertEqual(0, config.days_per_page('atom.xml.xslt')) def test_items_per_page(self): self.assertEqual(50, config.items_per_page('index.html.xslt')) self.assertEqual(50, config.items_per_page('atom.xml.xslt')) def test_encoding(self): self.assertEqual('utf-8', config.encoding('index.html.xslt')) self.assertEqual('utf-8', config.encoding('atom.xml.xslt')) # dictionaries def test_feed_options(self): self.assertEqual('one', config.feed_options('feed1')['name']) self.assertEqual('two', config.feed_options('feed2')['name']) def test_template_options(self): option = config.template_options('index.html.xslt') self.assertEqual('7', option['days_per_page']) self.assertEqual('50', option['items_per_page']) planet-venus-0~bzr116/tests/test_subconfig.py0000644000175000017500000000031711261171700017725 0ustar poxpox#!/usr/bin/env python from test_config_csv import ConfigCsvTest from planet import config class SubConfigTest(ConfigCsvTest): def setUp(self): config.load('tests/data/config/rlist-config.ini') planet-venus-0~bzr116/tests/test_splice.py0000644000175000017500000000245411261171700017231 0ustar poxpox#!/usr/bin/env python import unittest from planet.splice import splice, config configfile = 'tests/data/splice/config.ini' class SpliceTest(unittest.TestCase): def test_splice(self): config.load(configfile) doc = splice() self.assertEqual(12,len(doc.getElementsByTagName('entry'))) self.assertEqual(4,len(doc.getElementsByTagName('planet:source'))) self.assertEqual(16,len(doc.getElementsByTagName('planet:name'))) self.assertEqual('test planet', doc.getElementsByTagName('title')[0].firstChild.nodeValue) def test_splice_unsub(self): config.load(configfile) config.parser.remove_section('tests/data/spider/testfeed2.atom') doc = splice() self.assertEqual(8,len(doc.getElementsByTagName('entry'))) self.assertEqual(3,len(doc.getElementsByTagName('planet:source'))) self.assertEqual(11,len(doc.getElementsByTagName('planet:name'))) def test_splice_new_feed_items(self): config.load(configfile) config.parser.set('Planet','new_feed_items','3') doc = splice() self.assertEqual(9,len(doc.getElementsByTagName('entry'))) self.assertEqual(4,len(doc.getElementsByTagName('planet:source'))) self.assertEqual(13,len(doc.getElementsByTagName('planet:name'))) planet-venus-0~bzr116/tests/test_spider.py0000644000175000017500000001334011261171677017251 0ustar poxpox#!/usr/bin/env python import unittest, os, glob, calendar, shutil, time from planet.spider import filename, spiderPlanet, writeCache from planet import feedparser, config import planet workdir = 'tests/work/spider/cache' testfeed = 'tests/data/spider/testfeed%s.atom' configfile = 'tests/data/spider/config.ini' class SpiderTest(unittest.TestCase): def setUp(self): # silence errors self.original_logger = planet.logger planet.getLogger('CRITICAL',None) try: os.makedirs(workdir) except: self.tearDown() os.makedirs(workdir) def tearDown(self): shutil.rmtree(workdir) os.removedirs(os.path.split(workdir)[0]) planet.logger = self.original_logger def test_filename(self): self.assertEqual(os.path.join('.', 'example.com,index.html'), filename('.', 'http://example.com/index.html')) self.assertEqual(os.path.join('.', 'planet.intertwingly.net,2006,testfeed1,1'), filename('.', u'tag:planet.intertwingly.net,2006:testfeed1,1')) self.assertEqual(os.path.join('.', '00000000-0000-0000-0000-000000000000'), filename('.', u'urn:uuid:00000000-0000-0000-0000-000000000000')) # Requires Python 2.3 try: import encodings.idna except: return self.assertEqual(os.path.join('.', 'xn--8ws00zhy3a.com'), filename('.', u'http://www.\u8a79\u59c6\u65af.com/')) def spiderFeed(self, feed_uri): feed_info = feedparser.parse('') data = feedparser.parse(feed_uri) writeCache(feed_uri, feed_info, data) def verify_spiderFeed(self): files = glob.glob(workdir+"/*") files.sort() # verify that exactly four files + one sources dir were produced self.assertEqual(5, len(files)) # verify that the file names are as expected self.assertTrue(os.path.join(workdir, 'planet.intertwingly.net,2006,testfeed1,1') in files) # verify that the file timestamps match atom:updated data = feedparser.parse(files[2]) self.assertEqual(['application/atom+xml'], [link.type for link in data.entries[0].source.links if link.rel=='self']) self.assertEqual('one', data.entries[0].source.planet_name) self.assertEqual('2006-01-03T00:00:00Z', data.entries[0].updated) self.assertEqual(os.stat(files[2]).st_mtime, calendar.timegm(data.entries[0].updated_parsed)) def test_spiderFeed(self): config.load(configfile) self.spiderFeed(testfeed % '1b') self.verify_spiderFeed() def test_spiderFeed_retroactive_filter(self): config.load(configfile) self.spiderFeed(testfeed % '1b') self.assertEqual(5, len(glob.glob(workdir+"/*"))) config.parser.set('Planet', 'filter', 'two') self.spiderFeed(testfeed % '1b') self.assertEqual(1, len(glob.glob(workdir+"/*"))) def test_spiderUpdate(self): config.load(configfile) self.spiderFeed(testfeed % '1a') self.spiderFeed(testfeed % '1b') self.verify_spiderFeed() def test_spiderFeedUpdatedEntries(self): config.load(configfile) self.spiderFeed(testfeed % '4') self.assertEqual(2, len(glob.glob(workdir+"/*"))) data = feedparser.parse(workdir + '/planet.intertwingly.net,2006,testfeed4') self.assertEqual(u'three', data.entries[0].content[0].value) def verify_spiderPlanet(self): files = glob.glob(workdir+"/*") # verify that exactly eight files + 1 source dir were produced self.assertEqual(14, len(files)) # verify that the file names are as expected self.assertTrue(os.path.join(workdir, 'planet.intertwingly.net,2006,testfeed1,1') in files) self.assertTrue(os.path.join(workdir, 'planet.intertwingly.net,2006,testfeed2,1') in files) data = feedparser.parse(workdir + '/planet.intertwingly.net,2006,testfeed3,1') self.assertEqual(['application/rss+xml'], [link.type for link in data.entries[0].source.links if link.rel=='self']) self.assertEqual('three', data.entries[0].source.author_detail.name) self.assertEqual('three', data.entries[0].source['planet_css-id']) def test_spiderPlanet(self): config.load(configfile) spiderPlanet() self.verify_spiderPlanet() def test_spiderThreads(self): config.load(configfile.replace('config','threaded')) _PORT = config.parser.getint('Planet','test_port') log = [] from SimpleHTTPServer import SimpleHTTPRequestHandler class TestRequestHandler(SimpleHTTPRequestHandler): def log_message(self, format, *args): log.append(args) from threading import Thread class TestServerThread(Thread): def __init__(self): self.ready = 0 self.done = 0 Thread.__init__(self) def run(self): from BaseHTTPServer import HTTPServer httpd = HTTPServer(('',_PORT), TestRequestHandler) self.ready = 1 while not self.done: httpd.handle_request() httpd = TestServerThread() httpd.start() while not httpd.ready: time.sleep(0.1) try: spiderPlanet() finally: httpd.done = 1 import urllib urllib.urlopen('http://127.0.0.1:%d/' % _PORT).read() status = [int(rec[1]) for rec in log if str(rec[0]).startswith('GET ')] status.sort() self.assertEqual([200,200,200,200,404], status) self.verify_spiderPlanet() planet-venus-0~bzr116/tests/test_scrub.py0000644000175000017500000001056011261171677017102 0ustar poxpox#!/usr/bin/env python import unittest, StringIO, time from copy import deepcopy from planet.scrub import scrub from planet import feedparser, config feed = ''' F&ouml;o ignoreme F&ouml;o %d-12-31T23:59:59Z F&ouml;o F&ouml;o F&ouml;o F&ouml;o ''' % (time.gmtime()[0] + 1) configData = ''' [testfeed] ignore_in_feed = future_dates = name_type = html title_type = html summary_type = html content_type = html ''' class ScrubTest(unittest.TestCase): def test_scrub_ignore(self): base = feedparser.parse(feed) self.assertTrue(base.entries[0].has_key('author')) self.assertTrue(base.entries[0].has_key('author_detail')) self.assertTrue(base.entries[0].has_key('id')) self.assertTrue(base.entries[0].has_key('updated')) self.assertTrue(base.entries[0].has_key('updated_parsed')) self.assertTrue(base.entries[0].summary_detail.has_key('language')) config.parser.readfp(StringIO.StringIO(configData)) config.parser.set('testfeed', 'ignore_in_feed', 'author id updated xml:lang') data = deepcopy(base) scrub('testfeed', data) self.assertFalse(data.entries[0].has_key('author')) self.assertFalse(data.entries[0].has_key('author_detail')) self.assertFalse(data.entries[0].has_key('id')) self.assertFalse(data.entries[0].has_key('updated')) self.assertFalse(data.entries[0].has_key('updated_parsed')) self.assertFalse(data.entries[0].summary_detail.has_key('language')) def test_scrub_type(self): base = feedparser.parse(feed) self.assertEqual('Föo', base.feed.author_detail.name) config.parser.readfp(StringIO.StringIO(configData)) data = deepcopy(base) scrub('testfeed', data) self.assertEqual('F\xc3\xb6o', data.feed.author_detail.name) self.assertEqual('F\xc3\xb6o', data.entries[0].author_detail.name) self.assertEqual('F\xc3\xb6o', data.entries[0].source.author_detail.name) self.assertEqual('text/html', data.entries[0].title_detail.type) self.assertEqual('text/html', data.entries[0].summary_detail.type) self.assertEqual('text/html', data.entries[0].content[0].type) def test_scrub_future(self): base = feedparser.parse(feed) self.assertEqual(1, len(base.entries)) self.assertTrue(base.entries[0].has_key('updated')) config.parser.readfp(StringIO.StringIO(configData)) config.parser.set('testfeed', 'future_dates', 'ignore_date') data = deepcopy(base) scrub('testfeed', data) self.assertFalse(data.entries[0].has_key('updated')) config.parser.set('testfeed', 'future_dates', 'ignore_entry') data = deepcopy(base) scrub('testfeed', data) self.assertEqual(0, len(data.entries)) def test_scrub_xmlbase(self): base = feedparser.parse(feed) self.assertEqual('http://example.com/', base.entries[0].title_detail.base) config.parser.readfp(StringIO.StringIO(configData)) config.parser.set('testfeed', 'xml_base', 'feed_alternate') data = deepcopy(base) scrub('testfeed', data) self.assertEqual('http://example.com/feed/', data.entries[0].title_detail.base) config.parser.set('testfeed', 'xml_base', 'entry_alternate') data = deepcopy(base) scrub('testfeed', data) self.assertEqual('http://example.com/entry/1/', data.entries[0].title_detail.base) config.parser.set('testfeed', 'xml_base', 'base/') data = deepcopy(base) scrub('testfeed', data) self.assertEqual('http://example.com/base/', data.entries[0].title_detail.base) config.parser.set('testfeed', 'xml_base', 'http://example.org/data/') data = deepcopy(base) scrub('testfeed', data) self.assertEqual('http://example.org/data/', data.entries[0].title_detail.base) planet-venus-0~bzr116/tests/test_rlists.py0000644000175000017500000000270511261171677017306 0ustar poxpox#!/usr/bin/env python import unittest, os, shutil from planet import config, opml from os.path import split from glob import glob from ConfigParser import ConfigParser workdir = os.path.join('tests', 'work', 'config', 'cache') class ReadingListTest(unittest.TestCase): def setUp(self): config.load('tests/data/config/rlist.ini') def tearDown(self): shutil.rmtree(workdir) os.removedirs(os.path.split(workdir)[0]) # administrivia def test_feeds(self): feeds = [split(feed)[1] for feed in config.subscriptions()] feeds.sort() self.assertEqual(['testfeed0.atom', 'testfeed1a.atom', 'testfeed2.atom', 'testfeed3.rss'], feeds) # dictionaries def test_feed_options(self): feeds = dict([(split(feed)[1],feed) for feed in config.subscriptions()]) feed1 = feeds['testfeed1a.atom'] self.assertEqual('one', config.feed_options(feed1)['name']) feed2 = feeds['testfeed2.atom'] self.assertEqual('two', config.feed_options(feed2)['name']) # dictionaries def test_cache(self): cache = glob(os.path.join(workdir,'lists','*')) self.assertEqual(1,len(cache)) parser = ConfigParser() parser.read(cache[0]) feeds = [split(feed)[1] for feed in parser.sections()] feeds.sort() self.assertEqual(['opml.xml', 'testfeed0.atom', 'testfeed1a.atom', 'testfeed2.atom', 'testfeed3.rss'], feeds) planet-venus-0~bzr116/tests/test_reconstitute.py0000644000175000017500000000323311261171676020512 0ustar poxpox#!/usr/bin/env python import unittest, os, sys, glob, new, re, StringIO, time from planet import feedparser from planet.reconstitute import reconstitute from planet.scrub import scrub testfiles = 'tests/data/reconstitute/%s.xml' class ReconstituteTest(unittest.TestCase): desc_re = re.compile("Description:\s*(.*?)\s*Expect:\s*(.*)\s*-->") simple_re = re.compile("^(\S+) == (u?'[^']*'|\([0-9, ]+\))$") def eval(self, name): # read the test case try: testcase = open(testfiles % name) data = testcase.read() description, expect = self.desc_re.search(data).groups() testcase.close() except: raise RuntimeError, "can't parse %s" % name # parse and reconstitute to a string work = StringIO.StringIO() results = feedparser.parse(data) scrub(testfiles%name, results) reconstitute(results, results.entries[0]).writexml(work) # verify the results results = feedparser.parse(work.getvalue().encode('utf-8')) self.assertFalse(results.bozo, 'xml is well formed') if not self.simple_re.match(expect): self.assertTrue(eval(expect, results.entries[0]), expect) else: lhs, rhs = self.simple_re.match(expect).groups() self.assertEqual(eval(rhs), eval(lhs, results.entries[0])) # build a test method for each test file for testcase in glob.glob(testfiles % '*'): root = os.path.splitext(os.path.basename(testcase))[0] func = lambda self, name=root: self.eval(name) method = new.instancemethod(func, None, ReconstituteTest) setattr(ReconstituteTest, "test_" + root, method) planet-venus-0~bzr116/tests/test_opml.py0000644000175000017500000001620311261171676016732 0ustar poxpox#!/usr/bin/env python import unittest from planet.opml import opml2config from ConfigParser import ConfigParser class OpmlTest(unittest.TestCase): """ Test the opml2config function """ def setUp(self): self.config = ConfigParser() # # Element # def test_outline_element(self): opml2config('''''', self.config) self.assertEqual('sample feed', self.config.get("http://example.com/feed.xml", 'name')) def test_wrong_element(self): opml2config('''''', self.config) self.assertFalse(self.config.has_section("http://example.com/feed.xml")) def test_illformed_xml_before(self): opml2config(''' ''', self.config) self.assertEqual('sample feed', self.config.get("http://example.com/feed.xml", 'name')) def test_illformed_xml_after(self): opml2config(''' ''', self.config) self.assertEqual('sample feed', self.config.get("http://example.com/feed.xml", 'name')) # # Type # def test_type_missing(self): opml2config('''''', self.config) self.assertEqual('sample feed', self.config.get("http://example.com/feed.xml", 'name')) def test_type_uppercase(self): opml2config('''''', self.config) self.assertEqual('sample feed', self.config.get("http://example.com/feed.xml", 'name')) def test_type_atom(self): opml2config('''''', self.config) self.assertEqual('sample feed', self.config.get("http://example.com/feed.xml", 'name')) def test_wrong_type(self): opml2config('''''', self.config) self.assertFalse(self.config.has_section("http://example.com/feed.xml")) def test_WordPress_link_manager(self): # http://www.wasab.dk/morten/blog/archives/2006/10/22/wp-venus opml2config('''''', self.config) self.assertEqual('sample feed', self.config.get("http://example.com/feed.xml", 'name')) # # xmlUrl # def test_xmlurl_wrong_case(self): opml2config('''''', self.config) self.assertEqual('sample feed', self.config.get("http://example.com/feed.xml", 'name')) def test_missing_xmlUrl(self): opml2config('''''', self.config) self.assertFalse(self.config.has_section("http://example.com/feed.xml")) def test_blank_xmlUrl(self): opml2config('''''', self.config) self.assertFalse(self.config.has_section("")) # # text # def test_title_attribute(self): opml2config('''''', self.config) self.assertEqual('sample feed', self.config.get("http://example.com/feed.xml", 'name')) def test_missing_text(self): opml2config('''''', self.config) self.assertFalse(self.config.has_section("http://example.com/feed.xml")) def test_blank_text_no_title(self): opml2config('''''', self.config) self.assertFalse(self.config.has_section("http://example.com/feed.xml")) def test_blank_text_with_title(self): opml2config('''''', self.config) self.assertEqual('sample feed', self.config.get("http://example.com/feed.xml", 'name')) def test_blank_text_blank_title(self): opml2config('''''', self.config) self.assertFalse(self.config.has_section("http://example.com/feed.xml")) def test_text_utf8(self): opml2config('''''', self.config) self.assertEqual('Se\xc3\xb1or Frog\xe2\x80\x99s', self.config.get("http://example.com/feed.xml", 'name')) def test_text_win_1252(self): opml2config('''''', self.config) self.assertEqual('Se\xc3\xb1or Frog\xe2\x80\x99s', self.config.get("http://example.com/feed.xml", 'name')) def test_text_entity(self): opml2config('''''', self.config) self.assertEqual('Se\xc3\xb1or Frog\xe2\x80\x99s', self.config.get("http://example.com/feed.xml", 'name')) def test_text_double_escaped(self): opml2config('''''', self.config) self.assertEqual('Se\xc3\xb1or Frog\xe2\x80\x99s', self.config.get("http://example.com/feed.xml", 'name')) if __name__ == '__main__': unittest.main() planet-venus-0~bzr116/tests/test_idindex.py0000644000175000017500000000512611261171675017410 0ustar poxpox#!/usr/bin/env python import unittest, planet from planet import idindex, config class idIndexTest(unittest.TestCase): def setUp(self): # silence errors self.original_logger = planet.logger planet.getLogger('CRITICAL',None) def tearDown(self): idindex.destroy() planet.logger = self.original_logger def test_unicode(self): from planet.spider import filename index = idindex.create() iri = 'http://www.\xe8\xa9\xb9\xe5\xa7\x86\xe6\x96\xaf.com/' index[filename('', iri)] = 'data' index[filename('', iri.decode('utf-8'))] = 'data' index[filename('', u'1234')] = 'data' index.close() def test_index_spider(self): import test_spider config.load(test_spider.configfile) index = idindex.create() self.assertEqual(0, len(index)) index.close() from planet.spider import spiderPlanet try: spiderPlanet() index = idindex.open() self.assertEqual(12, len(index)) self.assertEqual('tag:planet.intertwingly.net,2006:testfeed1', index['planet.intertwingly.net,2006,testfeed1,1']) self.assertEqual('http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss', index['planet.intertwingly.net,2006,testfeed3,1']) index.close() finally: import os, shutil shutil.rmtree(test_spider.workdir) os.removedirs(os.path.split(test_spider.workdir)[0]) def test_index_splice(self): import test_splice config.load(test_splice.configfile) index = idindex.create() self.assertEqual(12, len(index)) self.assertEqual('tag:planet.intertwingly.net,2006:testfeed1', index['planet.intertwingly.net,2006,testfeed1,1']) self.assertEqual('http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss', index['planet.intertwingly.net,2006,testfeed3,1']) for key in index.keys(): value = index[key] if value.find('testfeed2')>0: index[key] = value.swapcase() index.close() from planet.splice import splice doc = splice() self.assertEqual(8,len(doc.getElementsByTagName('entry'))) self.assertEqual(4,len(doc.getElementsByTagName('planet:source'))) self.assertEqual(12,len(doc.getElementsByTagName('planet:name'))) try: module = 'dbhash' except ImportError: planet.logger.warn("dbhash is not available => can't test id index") for method in dir(idIndexTest): if method.startswith('test_'): delattr(idIndexTest,method) planet-venus-0~bzr116/tests/test_foaf.py0000644000175000017500000001053411261171675016676 0ustar poxpox#!/usr/bin/env python import unittest, os, shutil from planet.foaf import foaf2config from ConfigParser import ConfigParser from planet import config, logger workdir = 'tests/work/config/cache' blogroll = 'http://journal.dajobe.org/journal/2003/07/semblogs/bloggers.rdf' testfeed = "http://dannyayers.com/feed/rdf" test_foaf_document = ''' Danny Ayers Raw Blog by Danny Ayers '''.strip() class FoafTest(unittest.TestCase): """ Test the foaf2config function """ def setUp(self): self.config = ConfigParser() self.config.add_section(blogroll) def tearDown(self): if os.path.exists(workdir): shutil.rmtree(workdir) os.removedirs(os.path.split(workdir)[0]) # # Tests # def test_foaf_document(self): foaf2config(test_foaf_document, self.config) self.assertEqual('Danny Ayers', self.config.get(testfeed, 'name')) def test_no_foaf_name(self): test = test_foaf_document.replace('foaf:name','foaf:title') foaf2config(test, self.config) self.assertEqual('Raw Blog by Danny Ayers', self.config.get(testfeed, 'name')) def test_no_weblog(self): test = test_foaf_document.replace('rdfs:seeAlso','rdfs:seealso') foaf2config(test, self.config) self.assertFalse(self.config.has_section(testfeed)) def test_invalid_xml_before(self): test = '\n' + test_foaf_document foaf2config(test, self.config) self.assertFalse(self.config.has_section(testfeed)) def test_invalid_xml_after(self): test = test_foaf_document.strip()[:-1] foaf2config(test, self.config) self.assertEqual('Danny Ayers', self.config.get(testfeed, 'name')) def test_online_accounts(self): config.load('tests/data/config/foaf.ini') feeds = config.subscriptions() feeds.sort() self.assertEqual(['http://api.flickr.com/services/feeds/' + 'photos_public.gne?id=77366516@N00', 'http://del.icio.us/rss/eliast', 'http://torrez.us/feed/rdf'], feeds) def test_multiple_subscriptions(self): config.load('tests/data/config/foaf-multiple.ini') self.assertEqual(2,len(config.reading_lists())) feeds = config.subscriptions() feeds.sort() self.assertEqual(5,len(feeds)) self.assertEqual(['http://api.flickr.com/services/feeds/' + 'photos_public.gne?id=77366516@N00', 'http://api.flickr.com/services/feeds/' + 'photos_public.gne?id=SOMEID', 'http://del.icio.us/rss/SOMEID', 'http://del.icio.us/rss/eliast', 'http://torrez.us/feed/rdf'], feeds) def test_recursive(self): config.load('tests/data/config/foaf-deep.ini') feeds = config.subscriptions() feeds.sort() self.assertEqual(['http://api.flickr.com/services/feeds/photos_public.gne?id=77366516@N00', 'http://del.icio.us/rss/eliast', 'http://del.icio.us/rss/leef', 'http://del.icio.us/rss/rubys', 'http://intertwingly.net/blog/atom.xml', 'http://thefigtrees.net/lee/life/atom.xml', 'http://torrez.us/feed/rdf'], feeds) # these tests only make sense if libRDF is installed try: import RDF except: logger.warn("Redland RDF is not available => can't test FOAF reading lists") for key in FoafTest.__dict__.keys(): if key.startswith('test_'): delattr(FoafTest, key) if __name__ == '__main__': unittest.main() planet-venus-0~bzr116/tests/test_filters.py0000644000175000017500000001524011261171675017432 0ustar poxpox#!/usr/bin/env python import unittest, xml.dom.minidom from planet import shell, config, logger class FilterTests(unittest.TestCase): def test_coral_cdn(self): testfile = 'tests/data/filter/coral_cdn.xml' filter = 'coral_cdn_filter.py' output = shell.run(filter, open(testfile).read(), mode="filter") dom = xml.dom.minidom.parseString(output) imgsrcs = [img.getAttribute('src') for img in dom.getElementsByTagName('img')] self.assertEqual('http://example.com.nyud.net:8080/foo.png', imgsrcs[0]) self.assertEqual('http://example.com.1234.nyud.net:8080/foo.png', imgsrcs[1]) self.assertEqual('http://u:p@example.com.nyud.net:8080/foo.png', imgsrcs[2]) self.assertEqual('http://u:p@example.com.1234.nyud.net:8080/foo.png', imgsrcs[3]) def test_excerpt_images1(self): config.load('tests/data/filter/excerpt-images.ini') self.verify_images() def test_excerpt_images2(self): config.load('tests/data/filter/excerpt-images2.ini') self.verify_images() def verify_images(self): testfile = 'tests/data/filter/excerpt-images.xml' output = open(testfile).read() for filter in config.filters(): output = shell.run(filter, output, mode="filter") dom = xml.dom.minidom.parseString(output) excerpt = dom.getElementsByTagName('planet:excerpt')[0] anchors = excerpt.getElementsByTagName('a') hrefs = [a.getAttribute('href') for a in anchors] texts = [a.lastChild.nodeValue for a in anchors] self.assertEqual(['inner','outer1','outer2'], hrefs) self.assertEqual(['bar','bar',''], texts) def test_excerpt_lorem_ipsum(self): testfile = 'tests/data/filter/excerpt-lorem-ipsum.xml' config.load('tests/data/filter/excerpt-lorem-ipsum.ini') output = open(testfile).read() for filter in config.filters(): output = shell.run(filter, output, mode="filter") dom = xml.dom.minidom.parseString(output) excerpt = dom.getElementsByTagName('planet:excerpt')[0] self.assertEqual(u'Lorem ipsum dolor sit amet, consectetuer ' + u'adipiscing elit. Nullam velit. Vivamus tincidunt, erat ' + u'in \u2026', excerpt.firstChild.firstChild.nodeValue) def test_excerpt_lorem_ipsum_summary(self): testfile = 'tests/data/filter/excerpt-lorem-ipsum.xml' config.load('tests/data/filter/excerpt-lorem-ipsum.ini') config.parser.set('excerpt.py', 'target', 'atom:summary') output = open(testfile).read() for filter in config.filters(): output = shell.run(filter, output, mode="filter") dom = xml.dom.minidom.parseString(output) excerpt = dom.getElementsByTagName('summary')[0] self.assertEqual(u'Lorem ipsum dolor sit amet, consectetuer ' + u'adipiscing elit. Nullam velit. Vivamus tincidunt, erat ' + u'in \u2026', excerpt.firstChild.firstChild.nodeValue) def test_stripAd_yahoo(self): testfile = 'tests/data/filter/stripAd-yahoo.xml' config.load('tests/data/filter/stripAd-yahoo.ini') output = open(testfile).read() for filter in config.filters(): output = shell.run(filter, output, mode="filter") dom = xml.dom.minidom.parseString(output) excerpt = dom.getElementsByTagName('content')[0] self.assertEqual(u'before--after', excerpt.firstChild.firstChild.nodeValue) def test_xpath_filter1(self): config.load('tests/data/filter/xpath-sifter.ini') self.verify_xpath() def test_xpath_filter2(self): config.load('tests/data/filter/xpath-sifter2.ini') self.verify_xpath() def verify_xpath(self): testfile = 'tests/data/filter/category-one.xml' output = open(testfile).read() for filter in config.filters(): output = shell.run(filter, output, mode="filter") self.assertEqual('', output) testfile = 'tests/data/filter/category-two.xml' output = open(testfile).read() for filter in config.filters(): output = shell.run(filter, output, mode="filter") self.assertNotEqual('', output) def test_regexp_filter(self): config.load('tests/data/filter/regexp-sifter.ini') testfile = 'tests/data/filter/category-one.xml' output = open(testfile).read() for filter in config.filters(): output = shell.run(filter, output, mode="filter") self.assertEqual('', output) testfile = 'tests/data/filter/category-two.xml' output = open(testfile).read() for filter in config.filters(): output = shell.run(filter, output, mode="filter") self.assertNotEqual('', output) def test_regexp_filter2(self): config.load('tests/data/filter/regexp-sifter2.ini') testfile = 'tests/data/filter/category-one.xml' output = open(testfile).read() for filter in config.filters(): output = shell.run(filter, output, mode="filter") self.assertNotEqual('', output) testfile = 'tests/data/filter/category-two.xml' output = open(testfile).read() for filter in config.filters(): output = shell.run(filter, output, mode="filter") self.assertEqual('', output) def test_xhtml2html_filter(self): testfile = 'tests/data/filter/index.html' filter = 'xhtml2html.plugin?quote_attr_values=True' output = shell.run(filter, open(testfile).read(), mode="filter") self.assertTrue(output.find('/>')<0) self.assertTrue(output.find('')>=0) try: from subprocess import Popen, PIPE _no_sed = True if _no_sed: try: # Python 2.5 bug 1704790 workaround (alas, Unix only) import commands if commands.getstatusoutput('sed --version')[0]==0: _no_sed = False except: pass if _no_sed: try: sed = Popen(['sed','--version'],stdout=PIPE,stderr=PIPE) sed.communicate() if sed.returncode == 0: _no_sed = False except WindowsError: pass if _no_sed: logger.warn("sed is not available => can't test stripAd_yahoo") del FilterTests.test_stripAd_yahoo try: import libxml2 except: logger.warn("libxml2 is not available => can't test xpath_sifter") del FilterTests.test_xpath_filter1 del FilterTests.test_xpath_filter2 except ImportError: logger.warn("Popen is not available => can't test standard filters") for method in dir(FilterTests): if method.startswith('test_'): delattr(FilterTests,method) planet-venus-0~bzr116/tests/test_filter_xslt.py0000644000175000017500000000327211261171674020322 0ustar poxpox#!/usr/bin/env python import unittest, xml.dom.minidom from planet import shell, config, logger class XsltFilterTests(unittest.TestCase): def test_xslt_filter(self): config.load('tests/data/filter/translate.ini') testfile = 'tests/data/filter/category-one.xml' input = open(testfile).read() output = shell.run(config.filters()[0], input, mode="filter") dom = xml.dom.minidom.parseString(output) catterm = dom.getElementsByTagName('category')[0].getAttribute('term') self.assertEqual('OnE', catterm) def test_addsearch_filter(self): testfile = 'tests/data/filter/index.html' filter = 'addsearch.xslt' output = shell.run(filter, open(testfile).read(), mode="filter") self.assertTrue(output.find('

Search

')>=0) self.assertTrue(output.find('
')>=0) self.assertTrue(output.find(' href="http://planet.intertwingly.net/opensearchdescription.xml"')>=0) self.assertTrue(output.find('')>=0) try: import libxslt except: try: try: # Python 2.5 bug 1704790 workaround (alas, Unix only) import commands if commands.getstatusoutput('xsltproc --version')[0] != 0: raise ImportError except: from subprocess import Popen, PIPE xsltproc=Popen(['xsltproc','--version'],stdout=PIPE,stderr=PIPE) xsltproc.communicate() if xsltproc.returncode != 0: raise ImportError except: logger.warn("libxslt is not available => can't test xslt filters") del XsltFilterTests.test_xslt_filter del XsltFilterTests.test_addsearch_filter planet-venus-0~bzr116/tests/test_filter_tmpl.py0000644000175000017500000000472411261171674020307 0ustar poxpox#!/usr/bin/env python import unittest, os, sys, glob, new, re, StringIO, time from planet import config from planet.shell import tmpl testfiles = 'tests/data/filter/tmpl/%s.%s' class FilterTmplTest(unittest.TestCase): desc_feed_re = re.compile("Description:\s*(.*?)\s*Expect:\s*(.*)\s*-->") desc_config_re = re.compile(";\s*Description:\s*(.*?)\s*;\s*Expect:\s*(.*)") simple_re = re.compile("^(\S+) == (u?'[^']*'|\([0-9, ]+\))$") def eval_feed(self, name): # read the test case try: testcase = open(testfiles % (name,'xml')) data = testcase.read() description, expect = self.desc_feed_re.search(data).groups() testcase.close() except: raise RuntimeError, "can't parse %s" % name # map to template info results = tmpl.template_info(data) # verify the results if not self.simple_re.match(expect): self.assertTrue(eval(expect, results), expect) else: lhs, rhs = self.simple_re.match(expect).groups() self.assertEqual(eval(rhs), eval(lhs, results)) def eval_config(self, name): # read the test case try: testcase = open(testfiles % (name,'ini')) data = testcase.read() description, expect = self.desc_config_re.search(data).groups() testcase.close() except: raise RuntimeError, "can't parse %s" % name # map to template info config.load(testfiles % (name,'ini')) results = tmpl.template_info("") # verify the results if not self.simple_re.match(expect): self.assertTrue(eval(expect, results), expect) else: lhs, rhs = self.simple_re.match(expect).groups() self.assertEqual(eval(rhs), eval(lhs, results)) # build a test method for each xml test file for testcase in glob.glob(testfiles % ('*','xml')): root = os.path.splitext(os.path.basename(testcase))[0] func = lambda self, name=root: self.eval_feed(name) method = new.instancemethod(func, None, FilterTmplTest) setattr(FilterTmplTest, "test_" + root, method) # build a test method for each ini test file for testcase in glob.glob(testfiles % ('*','ini')): root = os.path.splitext(os.path.basename(testcase))[0] func = lambda self, name=root: self.eval_config(name) method = new.instancemethod(func, None, FilterTmplTest) setattr(FilterTmplTest, "test_" + root, method) planet-venus-0~bzr116/tests/test_filter_genshi.py0000644000175000017500000000152511261171674020604 0ustar poxpox#!/usr/bin/env python import unittest, xml.dom.minidom from planet import shell, config, logger class GenshiFilterTests(unittest.TestCase): def test_addsearch_filter(self): testfile = 'tests/data/filter/index.html' filter = 'addsearch.genshi' output = shell.run(filter, open(testfile).read(), mode="filter") self.assertTrue(output.find('

Search

')>=0) self.assertTrue(output.find('
')>=0) self.assertTrue(output.find(' href="http://planet.intertwingly.net/opensearchdescription.xml"')>=0) self.assertTrue(output.find('')>=0) try: import genshi except: logger.warn("Genshi is not available => can't test genshi filters") for method in dir(GenshiFilterTests): if method.startswith('test_'): delattr(GenshiFilterTests,method) planet-venus-0~bzr116/tests/test_filter_django.py0000644000175000017500000000310411261171673020563 0ustar poxpox#!/usr/bin/env python import os.path import unittest, xml.dom.minidom, datetime from planet import config, logger from planet.shell import dj class DjangoFilterTests(unittest.TestCase): def test_django_filter(self): config.load('tests/data/filter/django/test.ini') results = dj.tmpl.template_info("") self.assertEqual(results['name'], 'Django on Venus') def test_django_date_type(self): config.load('tests/data/filter/django/test.ini') results = dj.tmpl.template_info("") self.assertEqual(type(results['date']), datetime.datetime) def test_django_entry_title(self): config.load('tests/data/filter/django/test.ini') feed = open('tests/data/filter/django/test.xml') input = feed.read(); feed.close() results = dj.run( os.path.realpath('tests/data/filter/django/title.html.dj'), input) self.assertEqual(results, "\xc2\xa1Atom-Powered Robots Run Amok!\n") def test_django_config_context(self): config.load('tests/data/filter/django/test.ini') feed = open('tests/data/filter/django/test.xml') input = feed.read(); feed.close() results = dj.run( os.path.realpath('tests/data/filter/django/config.html.dj'), input) self.assertEqual(results, "Django on Venus\n") try: from django.conf import settings except ImportError: logger.warn("Django is not available => can't test django filters") for method in dir(DjangoFilterTests): if method.startswith('test_'): delattr(DjangoFilterTests,method) planet-venus-0~bzr116/tests/test_expunge.py0000644000175000017500000000612211261171673017432 0ustar poxpox#!/usr/bin/env python import unittest, os, glob, shutil, time from planet.spider import filename from planet import feedparser, config from planet.expunge import expungeCache from xml.dom import minidom import planet workdir = 'tests/work/expunge/cache' sourcesdir = 'tests/work/expunge/cache/sources' testentries = 'tests/data/expunge/test*.entry' testfeeds = 'tests/data/expunge/test*.atom' configfile = 'tests/data/expunge/config.ini' class ExpungeTest(unittest.TestCase): def setUp(self): # silence errors self.original_logger = planet.logger planet.getLogger('CRITICAL',None) try: os.makedirs(workdir) os.makedirs(sourcesdir) except: self.tearDown() os.makedirs(workdir) os.makedirs(sourcesdir) def tearDown(self): shutil.rmtree(workdir) os.removedirs(os.path.split(workdir)[0]) planet.logger = self.original_logger def test_expunge(self): config.load(configfile) # create test entries in cache with correct timestamp for entry in glob.glob(testentries): e=minidom.parse(entry) e.normalize() eid = e.getElementsByTagName('id') efile = filename(workdir, eid[0].childNodes[0].nodeValue) eupdated = e.getElementsByTagName('updated')[0].childNodes[0].nodeValue emtime = time.mktime(feedparser._parse_date_w3dtf(eupdated)) if not eid or not eupdated: continue shutil.copyfile(entry, efile) os.utime(efile, (emtime, emtime)) # create test feeds in cache sources = config.cache_sources_directory() for feed in glob.glob(testfeeds): f=minidom.parse(feed) f.normalize() fid = f.getElementsByTagName('id') if not fid: continue ffile = filename(sources, fid[0].childNodes[0].nodeValue) shutil.copyfile(feed, ffile) # verify that exactly nine entries + one source dir were produced files = glob.glob(workdir+"/*") self.assertEqual(10, len(files)) # verify that exactly four feeds were produced in source dir files = glob.glob(sources+"/*") self.assertEqual(4, len(files)) # expunge... expungeCache() # verify that five entries and one source dir are left files = glob.glob(workdir+"/*") self.assertEqual(6, len(files)) # verify that the right five entries are left self.assertTrue(os.path.join(workdir, 'bzr.mfd-consult.dk,2007,venus-expunge-test1,1') in files) self.assertTrue(os.path.join(workdir, 'bzr.mfd-consult.dk,2007,venus-expunge-test2,1') in files) self.assertTrue(os.path.join(workdir, 'bzr.mfd-consult.dk,2007,venus-expunge-test3,3') in files) self.assertTrue(os.path.join(workdir, 'bzr.mfd-consult.dk,2007,venus-expunge-test4,2') in files) self.assertTrue(os.path.join(workdir, 'bzr.mfd-consult.dk,2007,venus-expunge-test4,3') in files) planet-venus-0~bzr116/tests/test_docs.py0000644000175000017500000000077411261171673016716 0ustar poxpox#!/usr/bin/env python import unittest, os from xml.dom import minidom from glob import glob class DocsTest(unittest.TestCase): def test_well_formed(self): for doc in glob('docs/*'): if os.path.isdir(doc): continue if doc.endswith('.css') or doc.endswith('.js'): continue try: minidom.parse(doc) except: self.fail('Not well formed: ' + doc); break else: self.assertTrue(True); planet-venus-0~bzr116/tests/test_config_csv.py0000644000175000017500000000124011261171672020072 0ustar poxpox#!/usr/bin/env python import os, shutil, unittest from planet import config workdir = os.path.join('tests', 'work', 'config', 'cache') class ConfigCsvTest(unittest.TestCase): def setUp(self): config.load('tests/data/config/rlist-csv.ini') def tearDown(self): shutil.rmtree(workdir) os.removedirs(os.path.split(workdir)[0]) # administrivia def test_feeds(self): feeds = config.subscriptions() feeds.sort() self.assertEqual(['feed1', 'feed2'], feeds) def test_filters(self): self.assertEqual(['foo','bar'], config.filters('feed2')) self.assertEqual(['foo'], config.filters('feed1')) planet-venus-0~bzr116/tests/test_config.py0000644000175000017500000000376711261171672017237 0ustar poxpox#!/usr/bin/env python import unittest from planet import config class ConfigTest(unittest.TestCase): def setUp(self): config.load('tests/data/config/basic.ini') # administrivia def test_template(self): self.assertEqual(['index.html.tmpl', 'atom.xml.tmpl'], config.template_files()) def test_feeds(self): feeds = config.subscriptions() feeds.sort() self.assertEqual(['feed1', 'feed2'], feeds) def test_feed(self): self.assertEqual('http://example.com/atom.xml', config.feed()) self.assertEqual('atom', config.feedtype()) # planet wide configuration def test_name(self): self.assertEqual('Test Configuration', config.name()) def test_link(self): self.assertEqual('http://example.com/', config.link()) # per template configuration def test_days_per_page(self): self.assertEqual(7, config.days_per_page('index.html.tmpl')) self.assertEqual(0, config.days_per_page('atom.xml.tmpl')) def test_items_per_page(self): self.assertEqual(50, config.items_per_page('index.html.tmpl')) self.assertEqual(50, config.items_per_page('atom.xml.tmpl')) def test_encoding(self): self.assertEqual('utf-8', config.encoding('index.html.tmpl')) self.assertEqual('utf-8', config.encoding('atom.xml.tmpl')) # dictionaries def test_feed_options(self): self.assertEqual('one', config.feed_options('feed1')['name']) self.assertEqual('two', config.feed_options('feed2')['name']) def test_template_options(self): option = config.template_options('index.html.tmpl') self.assertEqual('7', option['days_per_page']) self.assertEqual('50', option['items_per_page']) def test_filters(self): self.assertEqual(['foo','bar'], config.filters('feed2')) self.assertEqual(['foo'], config.filters('feed1')) # ints def test_timeout(self): self.assertEqual(30, config.feed_timeout()) planet-venus-0~bzr116/tests/test_apply.py0000644000175000017500000001066611261171672017113 0ustar poxpox#!/usr/bin/env python import unittest, os, shutil from planet import config, splice, logger from xml.dom import minidom workdir = 'tests/work/apply' configfile = 'tests/data/apply/config-%s.ini' testfeed = 'tests/data/apply/feed.xml' class ApplyTest(unittest.TestCase): def setUp(self): testfile = open(testfeed) self.feeddata = testfile.read() testfile.close() try: os.makedirs(workdir) except: self.tearDown() os.makedirs(workdir) def tearDown(self): shutil.rmtree(os.path.split(workdir)[0]) def apply_asf(self): splice.apply(self.feeddata) # verify that selected files are there for file in ['index.html', 'default.css', 'images/foaf.png']: path = os.path.join(workdir, file) self.assertTrue(os.path.exists(path)) self.assertTrue(os.stat(path).st_size > 0, file + ' has size 0') # verify that index.html is well formed, has content, and xml:lang html = open(os.path.join(workdir, 'index.html')) doc = minidom.parse(html) list = [] content = lang = 0 for div in doc.getElementsByTagName('div'): if div.getAttribute('class') != 'content': continue content += 1 if div.getAttribute('xml:lang') == 'en-us': lang += 1 html.close() self.assertEqual(12, content) self.assertEqual(3, lang) def test_apply_asf(self): config.load(configfile % 'asf') self.apply_asf() def test_apply_classic_fancy(self): config.load(configfile % 'fancy') self.apply_fancy() def test_apply_genshi_fancy(self): config.load(configfile % 'genshi') self.apply_fancy() def test_apply_filter_html(self): config.load(configfile % 'html') self.apply_asf() output = open(os.path.join(workdir, 'index.html')).read() self.assertTrue(output.find('/>')>=0) output = open(os.path.join(workdir, 'index.html4')).read() self.assertTrue(output.find('/>')<0) def test_apply_filter_mememe(self): config.load(configfile % 'mememe') self.apply_fancy() output = open(os.path.join(workdir, 'index.html')).read() self.assertTrue(output.find('