From 64964d2fcfa73e18b1316d788bacd11e2180bb7d Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Sun, 31 Jan 2016 18:59:36 +0100 Subject: handling errors from one page app --- src/conf.py | 4 +++- src/web/js/actions/MenuActions.js | 2 ++ src/web/js/actions/RightPanelActions.js | 9 +++++++++ src/web/js/components/Menu.react.js | 8 ++++---- src/web/js/components/RightPanel.react.js | 32 +++++++++++++++++++++++++++++++ src/web/js/stores/MenuStore.js | 4 +++- src/web/models/feed.py | 1 + src/web/views/feed.py | 8 +++----- src/web/views/views.py | 2 ++ 9 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/conf.py b/src/conf.py index 7db65fd1..8acdeef6 100644 --- a/src/conf.py +++ b/src/conf.py @@ -92,7 +92,9 @@ USER_AGENT = config.get('crawler', 'user_agent') RESOLVE_ARTICLE_URL = config.getboolean('crawler', 'resolve_article_url') DEFAULT_MAX_ERROR = config.getint('crawler', - 'default_max_error') + 'default_max_error') +ERROR_THRESHOLD = int(DEFAULT_MAX_ERROR / 2) + CRAWLING_METHOD = config.get('crawler', 'crawling_method') LOG_LEVEL = {'debug': logging.DEBUG, diff --git a/src/web/js/actions/MenuActions.js b/src/web/js/actions/MenuActions.js index fa30474e..027a3d37 100644 --- a/src/web/js/actions/MenuActions.js +++ b/src/web/js/actions/MenuActions.js @@ -12,6 +12,8 @@ var MenuActions = { feeds: payload.feeds, categories: payload.categories, is_admin: payload.is_admin, + max_error: payload.max_error, + error_threshold: payload.error_threshold, crawling_method: payload.crawling_method, all_unread_count: payload.all_unread_count, }); diff --git a/src/web/js/actions/RightPanelActions.js b/src/web/js/actions/RightPanelActions.js index 838690d1..489abae4 100644 --- a/src/web/js/actions/RightPanelActions.js +++ b/src/web/js/actions/RightPanelActions.js @@ -28,6 +28,15 @@ var RightPanelActions = { delObj: function(id, obj_type, fields) { this._apiReq('DELETE', id, obj_type, null, MenuActions.reload); }, + resetErrors: function(feed_id) { + jquery.ajax({type: 'GET', + url: "feed/reset_errors/" + feed_id, + success: function() { + MenuActions.reload(); + }, + }); + + }, }; module.exports = RightPanelActions; diff --git a/src/web/js/components/Menu.react.js b/src/web/js/components/Menu.react.js index ad28015c..b68a84eb 100644 --- a/src/web/js/components/Menu.react.js +++ b/src/web/js/components/Menu.react.js @@ -32,9 +32,9 @@ var FeedItem = React.createClass({ if(this.props.active) { classes += " bg-primary"; } - if(this.props.error_count >= 6) { + if(this.props.error_count >= MenuStore._datas.max_error) { classes += " bg-danger"; - } else if(this.props.error_count > 3) { + } else if(this.props.error_count > MenuStore._datas.error_threshold) { classes += " bg-warning"; } var title = {this.props.title}; @@ -97,7 +97,7 @@ var CategoryGroup = React.createClass({ var feeds = this.props.feeds.filter(function(feed) { if (filter == 'unread' && feed.unread <= 0) { return false; - } else if (filter == 'error' && feed.error_count <= 3) { + } else if (filter == 'error' && feed.error_count <= MenuStore._datas.error_threshold) { return false; } return true; @@ -201,7 +201,7 @@ var Menu = React.createClass({ var feeds = []; var unread = 0; this.state.categories[cat_id].feeds.map(function(feed_id) { - if(this.state.feeds[feed_id].error_count > 3) { + if(this.state.feeds[feed_id].error_count > MenuStore._datas.error_threshold) { feed_in_error = true; } unread += this.state.feeds[feed_id].unread; diff --git a/src/web/js/components/RightPanel.react.js b/src/web/js/components/RightPanel.react.js index 009b40df..bf352a61 100644 --- a/src/web/js/components/RightPanel.react.js +++ b/src/web/js/components/RightPanel.react.js @@ -247,7 +247,38 @@ var Feed = React.createClass({
Category
{content}
); }, + getErrorFields: function() { + if(this.props.obj.error_count < MenuStore._datas.error_threshold) { + return; + } + if(this.props.obj.error_count < MenuStore._datas.max_error) { + return (
+
State
+
The download of this feed has encountered some problems. However its error counter will be reinitialized at the next successful retrieving.
+
Last error
+
{this.props.obj.last_error}
+
); + } + return (
+
State
+
That feed has encountered too much consecutive errors and won't be retrieved anymore.
+ +
Last error
+
{this.props.obj.last_error}
+
+ +
+
); + }, + resetErrors: function() { + var obj = this.state.obj; + obj.error_count = 0; + this.setState({obj: obj}, function() { + RightPanelActions.resetErrors(this.props.obj.id); + }.bind(this)); + }, getBody: function() { return (
@@ -260,6 +291,7 @@ var Feed = React.createClass({ text={this.props.obj.last_retrieved} />
+ {this.getErrorFields()} {this.getCategorySelect()} {this.getCore()} {this.getFilterRows()} diff --git a/src/web/js/stores/MenuStore.js b/src/web/js/stores/MenuStore.js index b8f50fd9..a68b24de 100644 --- a/src/web/js/stores/MenuStore.js +++ b/src/web/js/stores/MenuStore.js @@ -9,7 +9,7 @@ var MenuStore = assign({}, EventEmitter.prototype, { _datas: {filter: 'all', feeds: {}, categories: {}, active_type: null, active_id: null, is_admin: false, crawling_method: 'classic', - all_unread_count: 0}, + all_unread_count: 0, max_error: 0, error_threshold: 0}, getAll: function() { return this._datas; }, @@ -47,6 +47,8 @@ MenuStore.dispatchToken = JarrDispatcher.register(function(action) { MenuStore._datas['feeds'] = action.feeds; MenuStore._datas['categories'] = action.categories; MenuStore._datas['is_admin'] = action.is_admin; + MenuStore._datas['max_error'] = action.max_error; + MenuStore._datas['error_threshold'] = action.error_threshold; MenuStore._datas['crawling_method'] = action.crawling_method; MenuStore._datas['all_unread_count'] = action.all_unread_count; MenuStore.emitChange(); diff --git a/src/web/models/feed.py b/src/web/models/feed.py index c5fcbe4c..7768ee50 100644 --- a/src/web/models/feed.py +++ b/src/web/models/feed.py @@ -77,6 +77,7 @@ class Feed(db.Model): "filters": self.filters, "icon_url": self.icon_url, "error_count": self.error_count, + "last_error": self.last_error, "created_date": self.created_date, "last_modified": self.last_modified, "last_retrieved": self.last_retrieved} diff --git a/src/web/views/feed.py b/src/web/views/feed.py index 959179f9..1b6c8654 100644 --- a/src/web/views/feed.py +++ b/src/web/views/feed.py @@ -88,11 +88,9 @@ def delete(feed_id=None): @login_required def reset_errors(feed_id): feed_contr = FeedController(g.user.id) - feed = feed_contr.get(id=feed_id) - feed_contr.update({'id': feed_id}, {'error_count': 0, 'last_error': ''}) - flash(gettext('Feed %(feed_title)r successfully updated.', - feed_title=feed.title), 'success') - return redirect(request.referrer or url_for('home')) + feed_contr.update({'id': feed_id}, + {'error_count': 0, 'last_error': ''}) + return '' @feed_bp.route('/bookmarklet', methods=['GET', 'POST']) diff --git a/src/web/views/views.py b/src/web/views/views.py index e09d2696..0ae37a8d 100644 --- a/src/web/views/views.py +++ b/src/web/views/views.py @@ -263,6 +263,8 @@ def get_menu(): categories[feed['category_id']]['feeds'].append(feed_id) return jsonify(**{'feeds': feeds, 'categories': categories, 'crawling_method': conf.CRAWLING_METHOD, + 'max_error': conf.DEFAULT_MAX_ERROR, + 'error_threshold': conf.ERROR_THRESHOLD, 'is_admin': g.user.is_admin(), 'all_unread_count': sum(unread.values())}) -- cgit