aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/web/js/components/Navbar.react.js69
-rw-r--r--src/web/lib/feed_utils.py13
-rw-r--r--src/web/static/css/customized-bootstrap.css38
-rw-r--r--src/web/templates/layout.html2
-rw-r--r--src/web/views/feed.py5
5 files changed, 79 insertions, 48 deletions
diff --git a/src/web/js/components/Navbar.react.js b/src/web/js/components/Navbar.react.js
index 56de178e..295b4bb6 100644
--- a/src/web/js/components/Navbar.react.js
+++ b/src/web/js/components/Navbar.react.js
@@ -5,6 +5,7 @@ var NavItem = require('react-bootstrap/lib/NavItem');
var Navbar = require('react-bootstrap/lib/Navbar');
var NavDropdown = require('react-bootstrap/lib/NavDropdown');
var MenuItem = require('react-bootstrap/lib/MenuItem');
+var Modal = require('react-bootstrap/lib/Modal');
var Button = require('react-bootstrap/lib/Button');
var Input = require('react-bootstrap/lib/Input');
@@ -13,11 +14,14 @@ var MenuStore = require('../stores/MenuStore');
JarrNavBar = React.createClass({
getInitialState: function() {
return {is_admin: MenuStore._datas.is_admin,
- crawling_method: MenuStore._datas.crawling_method};
+ crawling_method: MenuStore._datas.crawling_method,
+ showModal: false, modalType: null};
},
buttonFetch: function() {
if(this.state.is_admin && this.state.crawling_method != 'http') {
- return <NavItem eventKey={2} href="/fetch"><Glyphicon glyph="import" />Fetch</NavItem>;
+ return (<NavItem eventKey={2} href="/fetch">
+ <Glyphicon glyph="import" />Fetch
+ </NavItem>);
}
},
buttonAdmin: function() {
@@ -30,11 +34,50 @@ JarrNavBar = React.createClass({
</NavDropdown>);
}
},
+ getModel: function() {
+ var heading = null;
+ var action = null;
+ var body = null;
+ if(this.state.modalType == 'addFeed') {
+ heading = 'Add a new feed';
+ action = '/feed/bookmarklet';
+ placeholder = "Site or feed url, we'll sort it out later ;)";
+ body = <Input name="url" type="text" placeholder={placeholder} />;
+ } else {
+ heading = 'Add a new category';
+ action = '/category/create';
+ body = <Input name="name" type="text"
+ placeholder="Name, there isn't much more to it" />;
+ }
+ return (<Modal show={this.state.showModal} onHide={this.close}>
+ <form action={action} method="POST">
+ <Modal.Header closeButton>
+ <Modal.Title>{heading}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ {body}
+ </Modal.Body>
+ <Modal.Footer>
+ <Button type="submit">Add</Button>
+ </Modal.Footer>
+ </form>
+ </Modal>);
+ },
+ close: function() {
+ this.setState({showModal: false, modalType: null});
+ },
+ openAddFeed: function() {
+ this.setState({showModal: true, modalType: 'addFeed'});
+ },
+ openAddCategory: function() {
+ this.setState({showModal: true, modalType: 'addCategory'});
+ },
render: function() {
var gl_title = (<span>
<Glyphicon glyph="plus-sign" />Add a new feed
</span>);
- return (<Navbar fixedTop inverse className="navbar-custom">
+ return (<Navbar fixedTop inverse id="jarrnav">
+ {this.getModel()}
<Navbar.Header>
<Navbar.Brand>
<a href="/">JARR</a>
@@ -42,19 +85,15 @@ JarrNavBar = React.createClass({
<Navbar.Toggle />
</Navbar.Header>
<Nav pullRight>
- <Navbar.Form pullLeft>
- <form action="/feed/bookmarklet" method="GET">
- <Input name="url" type="text"
- placeholder="Add a new feed" />
- <Button type="submit">Submit</Button>
- </form>
- </Navbar.Form>
{this.buttonFetch()}
- <NavDropdown title="Feed" id="feed-mgmt-dropdown">
- <MenuItem href="/feeds/inactives">Inactive</MenuItem>
- <MenuItem href="/articles/history">History</MenuItem>
- <MenuItem href="/feeds/">All</MenuItem>
- </NavDropdown>
+ <NavItem className="jarrnavitem"
+ onClick={this.openAddFeed} href="#">
+ <Glyphicon glyph="plus-sign" />Add a new feed
+ </NavItem>
+ <NavItem className="jarrnavitem"
+ onClick={this.openAddCategory} href="#">
+ <Glyphicon glyph="plus-sign" />Add a new category
+ </NavItem>
{this.buttonAdmin()}
<NavDropdown title={<Glyphicon glyph='user' />}
id="user-dropdown">
diff --git a/src/web/lib/feed_utils.py b/src/web/lib/feed_utils.py
index 14e6b82b..80800bec 100644
--- a/src/web/lib/feed_utils.py
+++ b/src/web/lib/feed_utils.py
@@ -9,6 +9,8 @@ from web.lib.utils import try_keys, try_get_icon_url, rebuild_url
logger = logging.getLogger(__name__)
logging.captureWarnings(True)
+ACCEPTED_MIMETYPES = ('application/rss+xml', 'application/rdf+xml',
+ 'application/atom+xml', 'application/xml', 'text/xml')
def is_parsing_ok(parsed_feed):
@@ -96,8 +98,11 @@ def construct_feed_from(url=None, fp_parsed=None, feed=None, query_site=True):
del feed['icon_url']
if not feed.get('link'):
- alternates = bs_parsed.find_all(check_keys(rel=['alternate'],
- type=['application/rss+xml']))
- if len(alternates) >= 1:
- feed['link'] = rebuild_url(alternates[0].attrs['href'], feed_split)
+ for type_ in ACCEPTED_MIMETYPES:
+ alternates = bs_parsed.find_all(check_keys(
+ rel=['alternate'], type=[type_]))
+ if len(alternates) >= 1:
+ feed['link'] = rebuild_url(alternates[0].attrs['href'],
+ feed_split)
+ break
return feed
diff --git a/src/web/static/css/customized-bootstrap.css b/src/web/static/css/customized-bootstrap.css
index db789f56..ad90304d 100644
--- a/src/web/static/css/customized-bootstrap.css
+++ b/src/web/static/css/customized-bootstrap.css
@@ -8,43 +8,29 @@ div.top {
height: 0;
}
-nav.navbar-custom {
+#jarrnav {
background-color: #205081;
border: #205081;
border-radius: 0;
}
-nav.navbar-custom>div.container {
+#jarrnav>div.container {
width: 100%;
}
-nav.navbar-custom span.glyphicon {
+#jarrnav span.glyphicon {
margin-right: 5px;
}
-nav.navbar-custom button {
+#jarrnav button {
margin-left: 5px;
}
-.navbar-custom .navbar-nav > li > a {
- color: #FFFFFF;
-}
-
-.navbar-custom .navbar-nav > li > a:hover {
- background-color: #3572B0;
-}
-
-.navbar-custom .navbar-nav > .active > a,
-.navbar-nav > .active > a:hover,
-.navbar-nav > .active > a:focus {
- color: #FFFFFF;
- background-color: #3572B0;
-}
-.navbar-custom .navbar-brand {
- color: #FFFFFF;
-}
-
-.navbar-custom .navbar-nav > .open > a,
-.navbar-custom .navbar-nav > .open > a:hover,
-.navbar-custom .navbar-nav > .open > a:focus {
- color: #FFFFFF;
+#jarrnav a.navbar-brand,
+#jarrnav .jarrnavitem a,
+#jarrnav a.dropdown-toggle{
+ color: white;
+}
+#jarrnav .navbar-nav > .open > a,
+#jarrnav .navbar-nav > .open > a:hover,
+#jarrnav .navbar-nav > li > a:hover {
background-color: #3572B0;
}
a {
diff --git a/src/web/templates/layout.html b/src/web/templates/layout.html
index ac943d54..feb370e3 100644
--- a/src/web/templates/layout.html
+++ b/src/web/templates/layout.html
@@ -15,7 +15,7 @@
{% endblock %}
</head>
<body>
- <nav class="navbar navbar-inverse navbar-fixed-top navbar-custom" role="navigation">
+ <nav id="jarrnav" class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
diff --git a/src/web/views/feed.py b/src/web/views/feed.py
index 9de45a7e..959179f9 100644
--- a/src/web/views/feed.py
+++ b/src/web/views/feed.py
@@ -95,11 +95,12 @@ def reset_errors(feed_id):
return redirect(request.referrer or url_for('home'))
-@feed_bp.route('/bookmarklet', methods=['GET'])
+@feed_bp.route('/bookmarklet', methods=['GET', 'POST'])
@login_required
def bookmarklet():
feed_contr = FeedController(g.user.id)
- url = request.args.get('url', None)
+ url = (request.args if request.method == 'GET' else request.form)\
+ .get('url', None)
if not url:
flash(gettext("Couldn't add feed: url missing."), "error")
raise BadRequest("url is missing")
bgstack15