v/pol
1
0
mirror of https://github.com/taroved/pol synced 2025-05-28 03:50:08 -07:00

fixed feed generator problem + several immprovements

This commit is contained in:
Alexandr Nesterenko 2016-07-11 13:40:40 -07:00
parent ce8432fb55
commit a53952b9f0
8 changed files with 394 additions and 23 deletions

12
feed.py
View File

@ -42,10 +42,11 @@ def element_to_string(element):
s = [element.text] if element.text else []
for sub_element in element:
s.append(etree.tostring(sub_element))
s.append(element.tail)
if element.tail:
s.append(element.tail)
return ''.join(s)
def _buildFeed(response, feed_config):
def _buildFeed(response, feed_config):
tree = response.selector._root.getroottree()
# get data from html
@ -57,9 +58,9 @@ def _buildFeed(response, feed_config):
element = node.xpath(feed_config['fields'][field_name])
if element:
item[field_name] = element_to_string(element[0])
items.append(item)
if len(item) == len(feed_config['fields']): # all fields are required
items.append(item)
#import pdb; pdb.set_trace()
#build feed
feed = Rss201rev2Feed(
title='Polite Pol: ' + feed_config['uri'],
@ -92,7 +93,8 @@ def _downloadDone(response_str, request=None, page_factory=None, feed_config=Non
request.finish()
def _downloadError(error, request=None, page_factory=None):
request.write('Downloader error: ' + error.value)
request.write('Downloader error: ' + error.getErrorMessage())
request.write('Traceback: ' + error.getTraceback())
request.finish()
def startFeedRequest(request, feed_id):

View File

@ -104,11 +104,14 @@ def get_selection_tag_ids(item_tag_ids, html_json):
# get fork path
fork_path = [tag[I_TAGNAME] for tag in fork_stack]
# console log
print 'Fork path: /'+'/'.join(fork_path)
# get pathes for items
fork_len = len(fork_path) - 1
selection_pathes = {name:_build_path(parent_stacks[name][fork_len:]) for name in parent_stacks}
# console log
for name in selection_pathes:
print name + ': ' + '/'.join([repr(p) for p in selection_pathes[name]])
# get fork tags
fork_tags = _find_tags_by_tag_names(html_json, fork_path)
@ -154,6 +157,9 @@ def build_xpathes_for_items(item_tag_ids, html_json):
feed_xpath = '/' + '/'.join(fork_path)
item_xpathes = {}
for name in selection_pathes:
item_xpathes[name] = '/'.join([repr(path_item) for path_item in selection_pathes[name]])
if selection_pathes[name]:
item_xpathes[name] = '/'.join([repr(path_item) for path_item in selection_pathes[name]])
else:
item_xpathes[name] = '.'
return [feed_xpath, item_xpathes]

View File

@ -0,0 +1,193 @@
/*!
* jQuery Browser Plugin 0.1.0
* https://github.com/gabceb/jquery-browser-plugin
*
* Original jquery-browser code Copyright 2005, 2015 jQuery Foundation, Inc. and other contributors
* http://jquery.org/license
*
* Modifications Copyright 2015 Gabriel Cebrian
* https://github.com/gabceb
*
* Released under the MIT license
*
* Date: 05-07-2015
*/
/*global window: false */
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], function ($) {
return factory($);
});
} else if (typeof module === 'object' && typeof module.exports === 'object') {
// Node-like environment
module.exports = factory(require('jquery'));
} else {
// Browser globals
factory(window.jQuery);
}
}(function(jQuery) {
"use strict";
function uaMatch( ua ) {
// If an UA is not provided, default to the current browser UA.
if ( ua === undefined ) {
ua = window.navigator.userAgent;
}
ua = ua.toLowerCase();
var match = /(edge)\/([\w.]+)/.exec( ua ) ||
/(opr)[\/]([\w.]+)/.exec( ua ) ||
/(chrome)[ \/]([\w.]+)/.exec( ua ) ||
/(iemobile)[\/]([\w.]+)/.exec( ua ) ||
/(version)(applewebkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( ua ) ||
/(webkit)[ \/]([\w.]+).*(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( ua ) ||
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
/(msie) ([\w.]+)/.exec( ua ) ||
ua.indexOf("trident") >= 0 && /(rv)(?::| )([\w.]+)/.exec( ua ) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
[];
var platform_match = /(ipad)/.exec( ua ) ||
/(ipod)/.exec( ua ) ||
/(windows phone)/.exec( ua ) ||
/(iphone)/.exec( ua ) ||
/(kindle)/.exec( ua ) ||
/(silk)/.exec( ua ) ||
/(android)/.exec( ua ) ||
/(win)/.exec( ua ) ||
/(mac)/.exec( ua ) ||
/(linux)/.exec( ua ) ||
/(cros)/.exec( ua ) ||
/(playbook)/.exec( ua ) ||
/(bb)/.exec( ua ) ||
/(blackberry)/.exec( ua ) ||
[];
var browser = {},
matched = {
browser: match[ 5 ] || match[ 3 ] || match[ 1 ] || "",
version: match[ 2 ] || match[ 4 ] || "0",
versionNumber: match[ 4 ] || match[ 2 ] || "0",
platform: platform_match[ 0 ] || ""
};
if ( matched.browser ) {
browser[ matched.browser ] = true;
browser.version = matched.version;
browser.versionNumber = parseInt(matched.versionNumber, 10);
}
if ( matched.platform ) {
browser[ matched.platform ] = true;
}
// These are all considered mobile platforms, meaning they run a mobile browser
if ( browser.android || browser.bb || browser.blackberry || browser.ipad || browser.iphone ||
browser.ipod || browser.kindle || browser.playbook || browser.silk || browser[ "windows phone" ]) {
browser.mobile = true;
}
// These are all considered desktop platforms, meaning they run a desktop browser
if ( browser.cros || browser.mac || browser.linux || browser.win ) {
browser.desktop = true;
}
// Chrome, Opera 15+ and Safari are webkit based browsers
if ( browser.chrome || browser.opr || browser.safari ) {
browser.webkit = true;
}
// IE11 has a new token so we will assign it msie to avoid breaking changes
if ( browser.rv || browser.iemobile) {
var ie = "msie";
matched.browser = ie;
browser[ie] = true;
}
// Edge is officially known as Microsoft Edge, so rewrite the key to match
if ( browser.edge ) {
delete browser.edge;
var msedge = "msedge";
matched.browser = msedge;
browser[msedge] = true;
}
// Blackberry browsers are marked as Safari on BlackBerry
if ( browser.safari && browser.blackberry ) {
var blackberry = "blackberry";
matched.browser = blackberry;
browser[blackberry] = true;
}
// Playbook browsers are marked as Safari on Playbook
if ( browser.safari && browser.playbook ) {
var playbook = "playbook";
matched.browser = playbook;
browser[playbook] = true;
}
// BB10 is a newer OS version of BlackBerry
if ( browser.bb ) {
var bb = "blackberry";
matched.browser = bb;
browser[bb] = true;
}
// Opera 15+ are identified as opr
if ( browser.opr ) {
var opera = "opera";
matched.browser = opera;
browser[opera] = true;
}
// Stock Android browsers are marked as Safari on Android.
if ( browser.safari && browser.android ) {
var android = "android";
matched.browser = android;
browser[android] = true;
}
// Kindle browsers are marked as Safari on Kindle
if ( browser.safari && browser.kindle ) {
var kindle = "kindle";
matched.browser = kindle;
browser[kindle] = true;
}
// Kindle Silk browsers are marked as Safari on Kindle
if ( browser.safari && browser.silk ) {
var silk = "silk";
matched.browser = silk;
browser[silk] = true;
}
// Assign the name and platform variable
browser.name = matched.browser;
browser.platform = matched.platform;
return browser;
}
// Run the matching process, also assign the function to the returned object
// for manual, jQuery-free use if desired
window.jQBrowser = uaMatch( window.navigator.userAgent );
window.jQBrowser.uaMatch = uaMatch;
// Only assign to jQuery.browser if jQuery is loaded
if ( jQuery ) {
jQuery.browser = window.jQBrowser;
}
return window.jQBrowser;
}));

View File

@ -0,0 +1,170 @@
/* jFeed : jQuery feed parser plugin
* Copyright (C) 2007 Jean-François Hovinne - http://www.hovinne.com/
* Dual licensed under the MIT (MIT-license.txt)
* and GPL (GPL-license.txt) licenses.
*/
jQuery.getFeed = function(options) {
options = jQuery.extend({
url: null,
data: null,
cache: true,
success: null,
failure: null,
error: null,
global: true
}, options);
if (options.url) {
if (jQuery.isFunction(options.failure) && jQuery.type(options.error)==='null') {
// Handle legacy failure option
options.error = function(xhr, msg, e){
options.failure(msg, e);
}
} else if (jQuery.type(options.failure) === jQuery.type(options.error) === 'null') {
// Default error behavior if failure & error both unspecified
options.error = function(xhr, msg, e){
window.console&&console.log('getFeed failed to load feed', xhr, msg, e);
}
}
return $.ajax({
type: 'GET',
url: options.url,
data: options.data,
cache: options.cache,
dataType: (jQuery.browser.msie) ? "text" : "xml",
success: function(xml) {
var feed = new JFeed(xml);
if (jQuery.isFunction(options.success)) options.success(feed);
},
error: options.error,
global: options.global
});
}
};
function JFeed(xml) {
if (xml) this.parse(xml);
}
;
JFeed.prototype = {
type: '',
version: '',
title: '',
link: '',
description: '',
parse: function(xml) {
if (jQuery.browser.msie) {
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.loadXML(xml);
xml = xmlDoc;
}
if (jQuery('channel', xml).length == 1) {
this.type = 'rss';
var feedClass = new JRss(xml);
} else if (jQuery('feed', xml).length == 1) {
this.type = 'atom';
var feedClass = new JAtom(xml);
}
if (feedClass) jQuery.extend(this, feedClass);
}
};
function JFeedItem() {};
JFeedItem.prototype = {
title: '',
link: '',
description: '',
updated: '',
id: ''
};
function JAtom(xml) {
this._parse(xml);
};
JAtom.prototype = {
_parse: function(xml) {
var channel = jQuery('feed', xml).eq(0);
this.version = '1.0';
this.title = jQuery(channel).find('title:first').text();
this.link = jQuery(channel).find('link:first').attr('href');
this.description = jQuery(channel).find('subtitle:first').text();
this.language = jQuery(channel).attr('xml:lang');
this.updated = jQuery(channel).find('updated:first').text();
this.items = new Array();
var feed = this;
jQuery('entry', xml).each( function() {
var item = new JFeedItem();
item.title = jQuery(this).find('title').eq(0).text();
item.link = jQuery(this).find('link').eq(0).attr('href');
item.description = jQuery(this).find('content').eq(0).text();
item.updated = jQuery(this).find('updated').eq(0).text();
item.id = jQuery(this).find('id').eq(0).text();
feed.items.push(item);
});
}
};
function JRss(xml) {
this._parse(xml);
};
JRss.prototype = {
_parse: function(xml) {
if(jQuery('rss', xml).length == 0) this.version = '1.0';
else this.version = jQuery('rss', xml).eq(0).attr('version');
var channel = jQuery('channel', xml).eq(0);
this.title = jQuery(channel).find('title:first').text();
this.link = jQuery(channel).find('link:first').text();
this.description = jQuery(channel).find('description:first').text();
this.language = jQuery(channel).find('language:first').text();
this.updated = jQuery(channel).find('lastBuildDate:first').text();
this.items = new Array();
var feed = this;
jQuery('item', xml).each( function() {
var item = new JFeedItem();
item.title = jQuery(this).find('title').eq(0).text();
item.link = jQuery(this).find('link').eq(0).text();
item.description = jQuery(this).find('description').eq(0).text();
item.updated = jQuery(this).find('pubDate').eq(0).text();
item.id = jQuery(this).find('guid').eq(0).text();
feed.items.push(item);
});
}
};

View File

@ -151,24 +151,24 @@ function Item(name, button) {
break;
}
_update_button();
updateCreateButton();
}
$(this.button).click(_button_click);
function _update_button(){
switch (that.state) {
case STATE_INACTIVE:
$(button).css('color', 'white');
$(button).addClass('disabled');
$(button).css('color', '#333');
$(button).removeClass(that.name == 'title' ? 'btn-primary' : 'btn-info');
break;
case STATE_SELECTING:
$(button).css('color', '#FFEB0D');
$(button).removeClass('disabled');
$(button).addClass(that.name == 'title' ? 'btn-primary' : 'btn-info');
break;
case STATE_SELECTED:
$(button).css('color', 'white');
break;
}
updateCreateButton();
}
/**

View File

@ -53,17 +53,14 @@
}
}
else {
$('#preview').text($('#preview').text().trim() + ' .');
setTimeout(tryGetFeed, 2000);
$('#preview').text('No items.');
}
},
failure: function () {
$('#preview').text($('#preview').text().trim() + ' .');
setTimeout(tryGetFeed, 2000);
$('#preview').text('Something wrong.');
},
error: function () {
$('#preview').text($('#preview').text().trim() + ' .');
setTimeout(tryGetFeed, 2000);
$('#preview').text('Something wrong.');
}
});
}

View File

@ -5,10 +5,10 @@
<!--h1 style="display: inline">Feed setup:</h1-->
<h2 style="display: inline" id="setup-tool-string">
You are creating feed with
<button id="st-title" class="btn btn-large btn-primary disabled has-tooltip" title="Click on the button and move cursor to the below document and pick item you interested in."
<button id="st-title" class="btn btn-large has-tooltip" title="Click on the button and move cursor to the below document and pick item you interested in."
data-trigger="hover focus manual" data-animation="true">Title</button> and
<button id="st-description" class="btn btn-large btn-info disabled">Description</button>.
<button id="create" class="btn btn-large btn-primary" style="padding-right: 13px; float:right" data-page-url="{{ page_url }}" data-feed-page-url="{{ feed_page_url }}">Create <i class="icon-arrow-right icon-white" style="margin-top: 3px"></i></button>
<button id="st-description" class="btn btn-large">Description</button>.
<button id="create" class="btn btn-large btn-primary disabled" style="padding-right: 13px; float:right" data-page-url="{{ page_url }}" data-feed-page-url="{{ feed_page_url }}">Create <i class="icon-arrow-right icon-white" style="margin-top: 3px"></i></button>
</h2>
</div>

View File

@ -20,11 +20,14 @@ def index(request):
if form.is_valid():
val = URLValidator()
try:
val(request.GET['url'])
url = request.GET['url']
if not url.startswith('http'):
url = 'http://' + url
val(url)
except ValidationError, e:
form.add_error('url', 'Invalid url')
else:
return HttpResponseRedirect('%s?url=%s' % (reverse('setup'), urllib.quote(request.GET['url'].encode('utf8'))))
return HttpResponseRedirect('%s?url=%s' % (reverse('setup'), urllib.quote(url.encode('utf8'))))
else:
form = IndexForm()