Skip to content

Commit

Permalink
Issue #6: initial implementation for feed autodiscovery.
Browse files Browse the repository at this point in the history
  • Loading branch information
passiomatic committed Mar 6, 2015
1 parent 3aaf21c commit e1eb56d
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 31 deletions.
2 changes: 0 additions & 2 deletions coldsweat/fetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ def fetch_feed(self):

def parse_feed(self, data):

#feed = self.feed

soup = feedparser.parse(data)
# Got parsing error?
if hasattr(soup, 'bozo') and soup.bozo:
Expand Down
2 changes: 1 addition & 1 deletion coldsweat/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def alert(message):
except ValueError:
return text
return u'<div class="alert alert--%s">%s</div>' % (klass.lower(), text)

def run_tests():

#t = datetime.utcnow()
Expand Down
51 changes: 42 additions & 9 deletions coldsweat/frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@
from controllers import *
from utilities import *
from fetcher import *

from markup import *
from session import SessionMiddleware

import filters

from plugins import trigger_event, load_plugins

ENTRIES_PER_PAGE = 30
Expand Down Expand Up @@ -332,21 +330,28 @@ def feed_enable(self, feed_id):
return self.redirect_after_post('%s/feeds/' % self.application_url)


@form(r'^/feeds/add$')
@form(r'^/feeds/add/1$')
@login_required
def feed_add(self):
def feed_add_1(self):
form_message = ''
groups = self.get_groups()

# URL could be passed via a GET (bookmarklet) or POST
self_link = self.request.params.get('self_link', '').strip()

#@@TODO: Allow specify domain.com w/out scheme

if self.request.method == 'GET':
return self.respond_with_template('_feed_add_wizard_1.html', locals())

# Handle POST

group_id = int(self.request.POST.get('group', 0))

if not validate_url(self_link):
form_message = u'ERROR Error, specify a valid web address'
return self.respond_with_template('_feed_add_wizard_1.html', locals())

try:
response = fetch_url(self_link)
except RequestException, exc:
Expand All @@ -356,21 +361,49 @@ def feed_add(self):
#form_message = u'ERROR Error, a network error occured'
#return self.respond_with_template('_feed_add_wizard_1.html', locals())

if not sniff_feed(response.text):
links = find_feed_links(response.text)
return self.respond_with_template('_feed_add_wizard_2.html', locals())

# It's a feed

#@@TODO: add plugin events
feed = self.add_feed_from_url(self_link, fetch_data=False)
ff = Fetcher(feed)
ff.parse_feed(response.text)

return self._add_subscription(feed, group_id)


@POST(r'^/feeds/add/2$')
@login_required
def feed_add_2(self):

self_link = self.request.POST.get('self_link', '')
group_id = int(self.request.POST.get('group', 0))

#@@TODO: handle multiple feed subscription
# urls = self.request.POST.getall('feeds')
# for url in urls:
# pass

feed = self.add_feed_from_url(self_link, fetch_data=True)
return self._add_subscription(feed, group_id)


def _add_subscription(self, feed, group_id):
if group_id:
group = Group.get(Group.id == group_id)
else:
group = Group.get(Group.title == Group.DEFAULT_GROUP)
group = Group.get(Group.title == Group.DEFAULT_GROUP)

feed = self.add_feed_from_url(self_link, fetch_data=True)
subscription = self.add_subscription(feed, group)
if subscription:
self.alert_message = u'SUCCESS Feed has been added to <i>%s</i> group' % group.title
else:
self.alert_message = u'INFO Feed is already in <i>%s</i> group' % group.title
return self.respond_with_script('_modal_done.js', {'location': '%s/?feed=%d' % (self.application_url, feed.id)})

return self.respond_with_script('_modal_done.js', {'location': '%s/?feed=%d' % (self.application_url, feed.id)})

@GET(r'^/fever/?$')
def fever(self):
Expand Down
14 changes: 3 additions & 11 deletions coldsweat/markup.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ def start_link(self, attrs):
return

#@@TODO: check if it's relative URL before join
self.links.append(urlparse.urljoin(self.base_url, d['href']))
url, title = urlparse.urljoin(self.base_url, d['href']), d['title'] if 'title' in d else u''
self.links.append((url, title))


class Scrubber(BaseProcessor):
Expand Down Expand Up @@ -240,23 +241,14 @@ def _parse(parser, data):

# Link discovery functions

def find_feed_links(data, base_url):
def find_feed_links(data, base_url=''):
'''
Return the feed links found for the page
'''
p = FeedLinkFinder(base_url)
_parse(p, data)
return p.links

def find_feed_link(data, base_url):
'''
Return the first feed link found
'''
links = find_feed_links(data, base_url)
if links:
return links[0]
return None

def sniff_feed(data):
data = data.lower()
if data.count('<html'):
Expand Down
6 changes: 3 additions & 3 deletions coldsweat/templates/_feed_add_wizard_1.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{{def render_form}}
<form action="{{application_url}}/feeds/add" data-ajax-post method="POST">
<form action="{{application_url}}/feeds/add/1" data-ajax-post method="POST">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-times-circle"></i></button>
<h3>Add Feed Subscription</h3>
</div>
<div class="modal-body">
{{form_message|alert}}
<label for="self-link-field">Web address (URL) for the feed</label>
<input type="text" id="field-self-link" autofocus name="self_link" required size="40" value="{{self_link}}">
<label for="self-link-field">Web address (URL) for the site or feed</label>
<input type="text" id="field-self-link" autofocus name="self_link" required size="40" value="{{self_link}}" placeholder="http://">
{{if length(groups) > 1}}
<label>Add to group <select name="group">
{{for g in groups}}
Expand Down
30 changes: 30 additions & 0 deletions coldsweat/templates/_feed_add_wizard_2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<form action="{{application_url}}/feeds/add/2" data-ajax-post method="POST">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-times-circle"></i></button>
<h3>Add Feed Subscription</h3>
</div>
{{if links}}
<div class="modal-body">
{{form_message|alert}}
<p>Coldsweat found the following feed(s) for {{self_link|friendly_url}}:</p>
{{for loop, link in looper(links)}}
{{py:url, title = link}}
<label>
<input type="radio" {{if loop.first}}checked{{endif}} name="self_link" value="{{url|html}}"> {{title|html}} <code>{{url|html}}</code>
</label>
{{endfor}}
<input type="hidden" name="group" value="{{group_id}}">
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Subscribe</button>
</div>
{{else}}
<div class="modal-body">
{{form_message|alert}}
<p>Coldsweat could not find any feed for {{self_link|friendly_url}}.</p>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" class="btn btn-primary">Close</button>
</div>
{{endif}}
</form>
2 changes: 1 addition & 1 deletion coldsweat/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</li>
{{endif}}
<li class="sep filter-feeds"><a data-toggle="tooltip" data-placement="right" title="Subscribed feeds (4 key)" href="{{application_url}}/feeds/"><i class="fa fa-rss fa-fw"></i></a></li>
<li><a data-toggle="tooltip" class="add-trigger" href="{{application_url}}/feeds/add" data-placement="right" title="Add feed subscription" data-remote-modal="modal-add-subscription"><i class="fa fa-plus-square fa-fw"></i></a></li>
<li><a data-toggle="tooltip" class="add-trigger" href="{{application_url}}/feeds/add/1" data-placement="right" title="Add feed subscription" data-remote-modal="modal-add-subscription"><i class="fa fa-plus-square fa-fw"></i></a></li>
<li class="sep"><li class="dropdown"><a data-toggle="dropdown" href="#"><i class="fa fa-user fa-fw"></i></a>
<ul class="dropdown-menu" role="menu">
<li><a href="{{application_url}}/profile" data-remote-modal>Your profile</a>
Expand Down
12 changes: 9 additions & 3 deletions coldsweat/tests/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@
'''

from os import path
from ..markup import find_feed_link
from ..markup import find_feed_links

def find_feed_link(data, base_url):
links = find_feed_links(data, base_url)
if links:
return links[0]
return None

def run_tests():

# Figure out current dir
Expand All @@ -23,9 +29,9 @@ def run_tests():

for filename, expected_url in test_files:
with open(path.join(test_dir, filename)) as f:
url = find_feed_link(f.read(), 'http://example.com')
url, title = find_feed_link(f.read(), 'http://example.com')
assert url == expected_url
print 'Found', url, '(OK)'
print 'Found', url, title, '(OK)'

if __name__ == '__main__':
run_tests()
Expand Down
2 changes: 1 addition & 1 deletion coldsweat/tests/discovery/xhtml.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<title>XHTML Transitional document</title>
<link rel="stylesheet" href="./somestyle.css /">
<link rel="shortcut icon" href="./favicon.ico" />
<link rel="alternate" type="application/rss+xml" title="RSS" href="http://somedomain.com/articles.xml" />
<link rel="alternate" type="application/rss+xml" href="http://somedomain.com/articles.xml" />
<link rel="alternate" type="text/xml" title="Comment RSS" href="http://somedomain.com/comments.xml" />

<meta http-equiv="refresh" content="300" />
Expand Down

0 comments on commit e1eb56d

Please sign in to comment.