├── example.cron ├── favicon.gif ├── favicon.ico ├── favicon.png ├── favicon.psd ├── icon-hires.png ├── icon-normal.png ├── apple-touch-icon.png ├── apple-touch-icon-76x76.png ├── apple-touch-icon-120x120.png ├── apple-touch-icon-152x152.png ├── apple-touch-icon-180x180.png ├── README.md ├── feedcourt.js ├── feedlist.txt ├── feedcourt.css ├── parsefeeds.py └── LICENSE /example.cron: -------------------------------------------------------------------------------- 1 | cd ~/feedcourt; ./env/bin/python ./parsefeeds.py 2 | -------------------------------------------------------------------------------- /favicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/favicon.gif -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/favicon.ico -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/favicon.png -------------------------------------------------------------------------------- /favicon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/favicon.psd -------------------------------------------------------------------------------- /icon-hires.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/icon-hires.png -------------------------------------------------------------------------------- /icon-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/icon-normal.png -------------------------------------------------------------------------------- /apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/apple-touch-icon.png -------------------------------------------------------------------------------- /apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bendybendy/feedcourt/HEAD/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Feed Court 2 | 3 | I dearly loved the wall of text aggregator [Popurls](http://web.archive.org/web/20151031011257/http://popurls.com/), until they started messing with it, forcing in images and dropping customization. It didn't seem to hard to create a clone of my own, so that's what this project is: a dead simple server-side web app that grabs RSS feeds and puts them on a page. 4 | 5 | The index.html is generated by a cron'd python script that reads a list of rss feeds. Vanilla javascript creates an event to expand div to see more text. That's about it for now. 6 | 7 | ## Active Demo 8 | 9 | [http://feedcourt.bendonnelly.com/](http://feedcourt.bendonnelly.com/) 10 | 11 | ## Requires 12 | [Python feedparser](http://pythonhosted.org/feedparser/introduction.html) 13 | 14 | -------------------------------------------------------------------------------- /feedcourt.js: -------------------------------------------------------------------------------- 1 | function pagelinks(){ 2 | var morelinks = document.getElementsByClassName('more') 3 | for (var i = 0 ; i < morelinks.length ; i++){ 4 | console.log("making links"); 5 | l = morelinks[i]; 6 | l.addEventListener('click',function(){ 7 | if (this.innerHTML == "less") { 8 | this.parentElement.parentElement.style.height = "30em"; 9 | this.innerHTML = "more"; 10 | }else { 11 | this.parentElement.parentElement.style.height = "auto"; 12 | this.innerHTML = "less"; 13 | } 14 | }); 15 | } 16 | } 17 | function convertUTCDateToLocalDate(date) { 18 | var newDate = new Date(date.getTime()+date.getTimezoneOffset()*60*1000); 19 | 20 | var offset = date.getTimezoneOffset() / 60; 21 | var hours = date.getHours(); 22 | newDate.setHours(hours - offset); 23 | return newDate; 24 | } 25 | function utctolocal(){ 26 | var lastup = document.getElementById("utcupdate").innerHTML; 27 | var offsetlastup = convertUTCDateToLocalDate(new Date(lastup)); 28 | document.getElementById("utcupdate").innerHTML = offsetlastup.toString().replace(/GMT.[0-9]*/g,""); 29 | 30 | } 31 | function loadroutine(){ 32 | utctolocal(); 33 | pagelinks(); 34 | } 35 | -------------------------------------------------------------------------------- /feedlist.txt: -------------------------------------------------------------------------------- 1 | http://feeds.feedburner.com/Metafilter 2 | https://news.ycombinator.com/rss 3 | https://www.techmeme.com/feed.xml 4 | http://feeds.feedburner.com/AskMetafilter 5 | http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml 6 | http://feeds.feedburner.com/TheAtlantic 7 | https://www.reddit.com/r/bullcity.rss 8 | http://www.newyorker.com/feed/everything 9 | http://fivethirtyeight.com/all/feed 10 | http://stackexchange.com/feeds/questions 11 | http://gis.stackexchange.com/feeds 12 | http://serverfault.com/feeds 13 | https://www.reddit.com/r/AskHistorians.rss 14 | https://www.reddit.com/r/ArchivePorn.rss 15 | https://www.reddit.com/r/ArtefactPorn.rss 16 | https://www.reddit.com/r/linguistics.rss 17 | https://www.reddit.com/r/philosophy.rss 18 | https://www.reddit.com/r/AskACountry.rss 19 | https://www.reddit.com/r/commandline.rss 20 | https://www.reddit.com/r/osxterminal.rss 21 | https://www.reddit.com/r/unixporn.rss 22 | https://hazlitt.net/rss.xml 23 | http://longform.org/feed.rss 24 | http://feeds.feedburner.com/mefi/Projects 25 | http://www.nytimes.com/services/xml/rss/nyt/Science.xml 26 | http://feeds.nytimes.com/nyt/rss/Technology 27 | http://www.nytimes.com/services/xml/rss/nyt/Arts.xml 28 | https://www.reddit.com/r/MapPorn.rss 29 | https://www.reddit.com/r/Geography.rss 30 | https://publicdomainreview.org/feed/ 31 | https://www.aldaily.com/feed 32 | https://dustedmagazine.tumblr.com/rss 33 | https://www.avclub.com/rss 34 | http://thequietus.com/feed 35 | http://feeds.feedburner.com/seriouseatsfeaturesvideos 36 | https://pitchfork.com/rss/reviews/albums/ 37 | http://deals.kinja.com/rss 38 | https://lifehacker.com/rss 39 | https://www.reddit.com/.rss?feed=5818ede8174bea3c164b1669a88c82ee57dba26c&user=bendybendy 40 | http://feeds.pinboard.in/rss/popular/wikipedia 41 | http://feeds.pinboard.in/rss/recent/?textify=1 42 | http://feeds.pinboard.in/rss/popular/?textify=1 43 | -------------------------------------------------------------------------------- /feedcourt.css: -------------------------------------------------------------------------------- 1 | h1, h2, body, p { 2 | font-family: sans-serif; 3 | color: #fefefe; 4 | font-size: 12; 5 | } 6 | .section_head h2 { 7 | max-width: 14rem; 8 | } 9 | a, h2 a:visited { 10 | color: #aeaeae; 11 | text-decoration: none; 12 | } 13 | a:visited { 14 | color: #333; 15 | } 16 | body { 17 | background-color: #010101; 18 | color: #efefef; 19 | } 20 | #footer, 21 | #header, 22 | #wrapper { 23 | margin-left:auto; 24 | margin-right: auto; 25 | } 26 | #jumblewrapper, 27 | #wrapper { 28 | padding: 0 1em; 29 | } 30 | #jumblewrapper { 31 | line-height: 1.24rem; 32 | padding: 0 1.5rem; 33 | max-width: 40rem; 34 | } 35 | 36 | #footer, 37 | #header { 38 | display: inline-block; 39 | padding: 0.5em 1em 0 2em; 40 | width: auto; 41 | } 42 | #header p { 43 | position: absolute; 44 | left: 9em; 45 | top: 0.85em; 46 | text-transform: lowercase; 47 | } 48 | #footer, 49 | #header h1, p{ 50 | color: #de4e1c;; 51 | } 52 | .sorter { 53 | font-weight: 800; 54 | } 55 | .sorter a, 56 | .sorter a:visited{ 57 | color: green; 58 | } 59 | .section { 60 | position: relative; 61 | display: inline-block; 62 | vertical-align: top; 63 | height: 30em; 64 | overflow: hidden; 65 | width: 26em; 66 | border: 1px dotted #444; 67 | padding: 1.1em; 68 | margin: 0.6em 0 0.8em 1.2em; 69 | } 70 | .section_head { 71 | width: auto; 72 | } 73 | .more { 74 | width: 2rem; 75 | border: 1px solid #333; 76 | padding: 0 0.3rem 0.1rem 0.3rem; 77 | position: absolute; 78 | right: 1rem; 79 | top:1.4rem; 80 | text-align: center; 81 | font-variant: small-caps; 82 | } 83 | .entry { 84 | border-bottom: 1px solid #333; 85 | padding: 0.2em 0; 86 | max-width: 25em; 87 | margin-left:auto; 88 | margin-right:auto; 89 | 90 | } 91 | .jumblesite a:hover, 92 | .jumble a:hover, 93 | .section_head h2 a:hover, 94 | .entry a:hover { 95 | color: #efefee; 96 | } 97 | @media only screen and (max-device-width: 812px){ 98 | .jumblewrapper, 99 | .wrapper, 100 | .section { 101 | padding: 0; 102 | } 103 | 104 | .more { 105 | right: 2.7rem; 106 | font-size: larger; 107 | color: green; 108 | } 109 | 110 | #header p { 111 | position: unset; 112 | font-size: 2rem; 113 | } 114 | 115 | #jumblewrapper { 116 | line-height: 3rem; 117 | max-width: 88%; 118 | margin-left: auto; 119 | margin-right: auto; 120 | } 121 | 122 | } 123 | @media only screen and (max-device-width: 480px) { 124 | /* mobile styles */ 125 | h1 , h2, body, p { 126 | font-size: xx-large; 127 | } 128 | .entry { 129 | padding: 0.9em 0; 130 | border-bottom: 1px solid #666; 131 | } 132 | .entry:hover { 133 | background-color: #441111;; 134 | } 135 | .entry:hover a:visited { 136 | color: #fefefe; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /parsefeeds.py: -------------------------------------------------------------------------------- 1 | import feedparser 2 | import datetime 3 | from random import shuffle 4 | 5 | import re 6 | 7 | feedlist = open("feedlist.txt", 'r') 8 | #now = datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M%p") 9 | now = datetime.datetime.utcnow().isoformat() 10 | 11 | pattern = re.compile('[\W_]+') 12 | 13 | output = """ 14 |
| a wall of text rss aggregator | updated: %s | 30 | """ %now 31 | 32 | #init list for jumbling entries 33 | all_entries = [] 34 | # make a copy of the header for the jumble page 35 | joutput = output 36 | 37 | #start the wrapper divs and header 38 | output +=" jumble