Group news sources by language. Fixes #1774 (News grouped by country of origin)

This commit is contained in:
Kovid Goyal
2009-02-04 22:38:32 -08:00
parent e06000a20b
commit e299be70ff
111 changed files with 254 additions and 105 deletions
@@ -1,16 +0,0 @@
__license__ = 'GPL v3'
__copyright__ = '2009, John Schember john@nachtimwald.com'
'''
List View for showing recipies. Allows for keyboad events when selecting new
items.
'''
from PyQt4.Qt import QListView, SIGNAL
class RecipeListView(QListView):
def __init__(self, *args):
QListView.__init__(self, *args)
def selectionChanged(self, selected, deselected):
self.emit(SIGNAL('itemChanged(QModelIndex)'), selected.indexes()[0])
+95 -42
View File
@@ -10,8 +10,8 @@ Scheduler for automated recipe downloads
import sys, copy, time
from datetime import datetime, timedelta, date
from PyQt4.Qt import QDialog, QApplication, QLineEdit, QPalette, SIGNAL, QBrush, \
QColor, QAbstractListModel, Qt, QVariant, QFont, QIcon, \
QFile, QObject, QTimer, QMutex, QMenu, QAction, QTime
QColor, QAbstractItemModel, Qt, QVariant, QFont, QIcon, \
QFile, QObject, QTimer, QMutex, QMenu, QAction, QTime, QModelIndex
from calibre import english_sort
from calibre.gui2.dialogs.scheduler_ui import Ui_Dialog
@@ -30,6 +30,7 @@ class Recipe(object):
self.id = id
self.title = getattr(recipe_class, 'title', None)
self.description = getattr(recipe_class, 'description', None)
self.language = getattr(recipe_class, 'language', _('Unknown'))
self.last_downloaded = datetime.fromordinal(1)
self.downloading = False
self.builtin = builtin
@@ -86,12 +87,12 @@ def load_recipes():
recipes.append(r)
return recipes
class RecipeModel(QAbstractListModel, SearchQueryParser):
class RecipeModel(QAbstractItemModel, SearchQueryParser):
LOCATIONS = ['all']
def __init__(self, db, *args):
QAbstractListModel.__init__(self, *args)
QAbstractItemModel.__init__(self, *args)
SearchQueryParser.__init__(self)
self.default_icon = QIcon(':/images/news.svg')
self.custom_icon = QIcon(':/images/user_profile.svg')
@@ -99,8 +100,11 @@ class RecipeModel(QAbstractListModel, SearchQueryParser):
for x in db.get_recipes():
recipe = compile_recipe(x[1])
self.recipes.append(Recipe(x[0], recipe, False))
self.refresh()
self._map = list(range(len(self.recipes)))
self.refresh()
self.bold_font = QFont()
self.bold_font.setBold(True)
self.bold_font = QVariant(self.bold_font)
def refresh(self):
sr = load_recipes()
@@ -110,7 +114,35 @@ class RecipeModel(QAbstractListModel, SearchQueryParser):
recipe.last_downloaded = sr[sr.index(recipe)].last_downloaded
self.recipes.sort()
self.num_of_recipes = len(self.recipes)
self.category_map = {}
for r in self.recipes:
category = getattr(r, 'language', _('Unknown'))
if not r.builtin:
category = _('Custom')
if r.schedule is not None:
category = _('Scheduled')
if category not in self.category_map.keys():
self.category_map[category] = []
self.category_map[category].append(r)
self.categories = sorted(self.category_map.keys(), cmp=self.sort_categories)
self._map = dict(self.category_map)
def sort_categories(self, x, y):
def decorate(x):
if x == _('Scheduled'):
x = '0' + x
elif x == _('Custom'):
x = '1' + x
else:
x = '2' + x
return x
return cmp(decorate(x), decorate(y))
def universal_set(self):
return set(self.recipes)
@@ -129,48 +161,64 @@ class RecipeModel(QAbstractListModel, SearchQueryParser):
try:
results = self.parse(unicode(query))
except ParseException:
self._map = list(range(len(self.recipes)))
self._map = dict(self.category_map)
else:
self._map = []
for i, recipe in enumerate(self.recipes):
if recipe in results:
self._map.append(i)
self._map = {}
for category in self.categories:
self._map[category] = []
for recipe in self.category_map[category]:
if recipe in results:
self._map[category].append(recipe)
self.reset()
def resort(self):
self.recipes.sort()
self.reset()
def index(self, row, column, parent):
return self.createIndex(row, column, parent.row() if parent.isValid() else -1)
def parent(self, index):
if index.internalId() == -1:
return QModelIndex()
return self.createIndex(index.internalId(), 0, -1)
def columnCount(self, parent):
if not parent.isValid() or not parent.parent().isValid():
return 1
return 0
def rowCount(self, parent):
if not parent.isValid():
return len(self.categories)
if not parent.parent().isValid():
category = self.categories[parent.row()]
return len(self._map[category])
return 0
def columnCount(self, *args):
return 1
def rowCount(self, *args):
return len(self._map)
def data(self, index, role):
recipe = self.recipes[self._map[index.row()]]
if role == Qt.FontRole:
if recipe.schedule is not None:
font = QFont()
font.setBold(True)
return QVariant(font)
if not recipe.builtin:
font = QFont()
font.setItalic(True)
return QVariant(font)
elif role == Qt.DisplayRole:
return QVariant(recipe.title)
elif role == Qt.UserRole:
return recipe
elif role == Qt.DecorationRole:
icon = self.default_icon
icon_path = (':/images/news/%s.png'%recipe.id).replace('recipe_', '')
if not recipe.builtin:
icon = self.custom_icon
elif QFile().exists(icon_path):
icon = QIcon(icon_path)
return QVariant(icon)
if index.parent().isValid():
category = self.categories[index.parent().row()]
recipe = self._map[category][index.row()]
if role == Qt.DisplayRole:
return QVariant(recipe.title)
elif role == Qt.UserRole:
return recipe
elif role == Qt.DecorationRole:
icon = self.default_icon
icon_path = (':/images/news/%s.png'%recipe.id).replace('recipe_', '')
if not recipe.builtin:
icon = self.custom_icon
elif QFile().exists(icon_path):
icon = QIcon(icon_path)
return QVariant(icon)
else:
category = self.categories[index.row()]
if role == Qt.DisplayRole:
num = len(self._map[category])
return QVariant(category + ' [%d]'%num)
elif role == Qt.FontRole:
return self.bold_font
return NONE
def update_recipe_schedule(self, recipe):
@@ -241,7 +289,7 @@ class SchedulerDialog(QDialog, Ui_Dialog):
self._model = RecipeModel(db)
self.current_recipe = None
self.recipes.setModel(self._model)
self.connect(self.recipes, SIGNAL('itemChanged(QModelIndex)'), self.show_recipe)
self.recipes.currentChanged = self.currentChanged
self.connect(self.username, SIGNAL('textEdited(QString)'), self.set_account_info)
self.connect(self.password, SIGNAL('textEdited(QString)'), self.set_account_info)
self.connect(self.schedule, SIGNAL('stateChanged(int)'), self.do_schedule)
@@ -257,10 +305,14 @@ class SchedulerDialog(QDialog, Ui_Dialog):
self.connect(self.download, SIGNAL('clicked()'), self.download_now)
self.search.setFocus(Qt.OtherFocusReason)
self.old_news.setValue(gconf['oldest_news'])
self.rnumber.setText(_('%d recipes')%self._model.rowCount(None))
self.rnumber.setText(_('%d recipes')%self._model.num_of_recipes)
for day in (_('day'), _('Monday'), _('Tuesday'), _('Wednesday'),
_('Thursday'), _('Friday'), _('Saturday'), _('Sunday')):
self.day.addItem(day)
def currentChanged(self, current, previous):
if current.parent().isValid():
self.show_recipe(current)
def download_now(self):
recipe = self._model.data(self.recipes.currentIndex(), Qt.UserRole)
@@ -304,6 +356,7 @@ class SchedulerDialog(QDialog, Ui_Dialog):
hour, minute = t.hour(), t.minute()
recipe.schedule = encode_schedule(day_of_week, hour, minute)
else:
recipe.schedule = None
if recipe in recipes:
recipes.remove(recipe)
save_recipes(recipes)
+14 -9
View File
@@ -24,8 +24,20 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="RecipeListView" name="recipes" >
<property name="alternatingRowColors" >
<widget class="QTreeView" name="recipes" >
<property name="showDropIndicator" stdset="0" >
<bool>false</bool>
</property>
<property name="iconSize" >
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="animated" >
<bool>true</bool>
</property>
<property name="headerHidden" >
<bool>true</bool>
</property>
</widget>
@@ -321,13 +333,6 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RecipeListView</class>
<extends>QListView</extends>
<header>recipelistview.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc" />
</resources>
+3
View File
@@ -47,6 +47,9 @@ class BasicNewsRecipe(object, LoggingInterface):
#: The author of this recipe
__author__ = __appname__
#: The language that the news is in
language = _('Unknown')
#: Maximum number of articles to download from each feed. This is primarily
#: useful for feeds that don't have article dates. For most feeds, you should
#: use :attr:`BasicNewsRecipe.oldest_article`
@@ -18,6 +18,7 @@ class Ambito(BasicNewsRecipe):
no_stylesheets = True
use_embedded_content = False
encoding = 'iso--8859-1'
language = _('Spanish')
cover_url = 'http://www.ambito.com/img/logo_.jpg'
html2lrf_options = [
+24 -23
View File
@@ -9,27 +9,28 @@ spectator.org
from calibre.web.feeds.news import BasicNewsRecipe
class TheAmericanSpectator(BasicNewsRecipe):
title = 'The American Spectator'
__author__ = 'Darko Miletic'
description = 'news from USA'
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
INDEX = 'http://spectator.org'
title = 'The American Spectator'
__author__ = 'Darko Miletic'
language = _('English')
description = 'News from USA'
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
INDEX = 'http://spectator.org'
html2lrf_options = [
html2lrf_options = [
'--comment' , description
, '--category' , 'news, politics, USA'
, '--publisher' , title
]
keep_only_tags = [
keep_only_tags = [
dict(name='div', attrs={'class':'post inner'})
,dict(name='div', attrs={'class':'author-bio'})
]
remove_tags = [
remove_tags = [
dict(name='object')
,dict(name='div', attrs={'class':'col3' })
,dict(name='div', attrs={'class':'post-options' })
@@ -37,17 +38,17 @@ class TheAmericanSpectator(BasicNewsRecipe):
,dict(name='div', attrs={'class':'social' })
]
feeds = [ (u'Articles', u'http://feedproxy.google.com/amspecarticles')]
feeds = [ (u'Articles', u'http://feedproxy.google.com/amspecarticles')]
def get_cover_url(self):
cover_url = None
soup = self.index_to_soup(self.INDEX)
link_item = soup.find('a',attrs={'class':'cover'})
if link_item:
soup2 = self.index_to_soup(link_item['href'])
link_item2 = soup2.find('div',attrs={'class':'post inner issues'})
cover_url = self.INDEX + link_item2.img['src']
return cover_url
def get_cover_url(self):
cover_url = None
soup = self.index_to_soup(self.INDEX)
link_item = soup.find('a',attrs={'class':'cover'})
if link_item:
soup2 = self.index_to_soup(link_item['href'])
link_item2 = soup2.find('div',attrs={'class':'post inner issues'})
cover_url = self.INDEX + link_item2.img['src']
return cover_url
def print_version(self, url):
return url + '/print'
def print_version(self, url):
return url + '/print'
@@ -8,6 +8,7 @@ class AssociatedPress(BasicNewsRecipe):
description = 'Global news'
__author__ = 'Kovid Goyal'
use_embedded_content = False
language = _('English')
max_articles_per_feed = 15
html2lrf_options = ['--force-page-break-before-tag="chapter"']
@@ -13,6 +13,7 @@ class ArsTechnica(BasicNewsRecipe):
title = 'Ars Technica'
description = 'The art of technology'
oldest_article = 7
language = _('English')
no_stylesheets = True
__author__ = 'Michael Warner'
max_articles_per_feed = 100
@@ -14,7 +14,7 @@ class TheAtlantic(BasicNewsRecipe):
__author__ = 'Kovid Goyal'
description = 'Current affairs and politics focussed on the US'
INDEX = 'http://www.theatlantic.com/doc/current'
language = _('English')
remove_tags_before = dict(name='div', id='storytop')
remove_tags = [dict(name='div', id=['seealso', 'storybottom', 'footer', 'ad_banner_top', 'sidebar'])]
no_stylesheets = True
+2 -1
View File
@@ -6,12 +6,13 @@ __copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
b92.net
'''
import string,re
import re
from calibre.web.feeds.news import BasicNewsRecipe
class B92(BasicNewsRecipe):
title = u'B92'
__author__ = 'Darko Miletic'
language = _('Serbian')
description = 'Dnevne vesti iz Srbije i sveta'
oldest_article = 7
max_articles_per_feed = 100
@@ -15,6 +15,7 @@ class Barrons(BasicNewsRecipe):
title = 'Barron\'s'
max_articles_per_feed = 50
needs_subscription = True
language = _('English')
__author__ = 'Kovid Goyal'
description = 'Weekly publication for investors from the publisher of the Wall Street Journal'
timefmt = ' [%a, %b %d, %Y]'
@@ -13,6 +13,7 @@ class BBC(BasicNewsRecipe):
__author__ = 'Kovid Goyal'
description = 'Global news and current affairs from the British Broadcasting Corporation'
no_stylesheets = True
language = _('English')
remove_tags = [dict(name='div', attrs={'class':'footer'})]
extra_css = '.headline {font-size: x-large;} \n .fact { padding-top: 10pt }'
@@ -13,6 +13,7 @@ class BusinessWeek(BasicNewsRecipe):
title = 'Business Week'
description = 'Business News, Stock Market and Financial Advice'
__author__ = 'ChuckEggDotCom'
language = _('English')
oldest_article = 7
max_articles_per_feed = 10
@@ -8,6 +8,7 @@ class ChristianScienceMonitor(BasicNewsRecipe):
description = 'Providing context and clarity on national and international news, peoples and cultures'
max_articles_per_feed = 20
__author__ = 'Kovid Goyal'
language = _('English')
no_stylesheets = True
use_embedded_content = False
@@ -15,6 +15,7 @@ class Clarin(BasicNewsRecipe):
description = 'Noticias de Argentina y mundo'
oldest_article = 2
max_articles_per_feed = 100
language = _('Spanish')
use_embedded_content = False
no_stylesheets = True
cover_url = strftime('http://www.clarin.com/diario/%Y/%m/%d/portada.jpg')
@@ -12,6 +12,7 @@ class CNN(BasicNewsRecipe):
description = 'Global news'
timefmt = ' [%d %b %Y]'
__author__ = 'Kovid Goyal'
language = _('English')
no_stylesheets = True
use_embedded_content = False
oldest_article = 15
@@ -5,6 +5,7 @@ class CommonDreams(BasicNewsRecipe):
title = u'Common Dreams'
description = u'Progressive news and views'
__author__ = u'XanthanGum'
language = _('English')
oldest_article = 7
max_articles_per_feed = 100
@@ -14,6 +14,7 @@ class CriticaDigital(BasicNewsRecipe):
description = 'Noticias de Argentina'
oldest_article = 2
max_articles_per_feed = 100
language = _('Spanish')
no_stylesheets = True
use_embedded_content = False
encoding = 'cp1252'
@@ -6,6 +6,7 @@ class Cyberpresse(BasicNewsRecipe):
title = u'Cyberpresse'
__author__ = 'balok'
description = 'Canadian news in French'
language = _('French')
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
@@ -12,6 +12,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class DailyTelegraph(BasicNewsRecipe):
title = u'Daily Telegraph'
__author__ = u'AprilHare'
language = _('English')
description = u'News from down under'
oldest_article = 2
max_articles_per_feed = 10
@@ -9,6 +9,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class DeStandaard(BasicNewsRecipe):
title = u'De Standaard'
__author__ = u'Darko Miletic'
language = _('French')
description = u'News from Belgium'
oldest_article = 7
max_articles_per_feed = 100
@@ -13,7 +13,8 @@ class DiscoverMagazine(BasicNewsRecipe):
title = u'Discover Magazine'
description = u'Science, Technology and the Future'
__author__ = 'Mike Diaz'
oldest_article = 33
oldest_article = 33
language = _('English')
max_articles_per_feed = 20
feeds = [
(u'Technology', u'http://discovermagazine.com/topics/technology/rss.xml'),
@@ -14,6 +14,7 @@ from urllib2 import quote
class Economist(BasicNewsRecipe):
title = 'The Economist'
language = _('English')
__author__ = "Kovid Goyal"
description = 'Global news and current affairs from a European perspective'
oldest_article = 7.0
@@ -9,6 +9,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class ElMercurio(BasicNewsRecipe):
title = 'El Mercurio online'
language = _('Spanish')
__author__ = 'Darko Miletic'
description = 'El sitio de noticias online de Chile'
oldest_article = 2
@@ -11,6 +11,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class ElPais(BasicNewsRecipe):
title = u'EL PAIS'
language = _('Spanish')
oldest_article = 7
max_articles_per_feed = 100
@@ -12,6 +12,7 @@ class ElArgentino(BasicNewsRecipe):
title = 'ElArgentino.com'
__author__ = 'Darko Miletic'
description = 'Informacion Libre las 24 horas'
language = _('Spanish')
oldest_article = 2
max_articles_per_feed = 100
no_stylesheets = True
@@ -13,6 +13,7 @@ class ElCronista(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'Noticias de Argentina'
oldest_article = 2
language = _('Spanish')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -12,6 +12,7 @@ class ElMundo(BasicNewsRecipe):
title = 'El Mundo'
__author__ = 'Darko Miletic'
description = 'News from Spain'
language = _('Spanish')
oldest_article = 2
max_articles_per_feed = 100
no_stylesheets = True
@@ -12,7 +12,8 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Engadget(BasicNewsRecipe):
title = u'Engadget'
__author__ = 'Darko Miletic'
description = 'Tech news'
description = 'Tech news'
language = _('English')
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
@@ -14,6 +14,7 @@ class ESPN(BasicNewsRecipe):
title = 'ESPN'
description = 'Sports news'
__author__ = 'Kovid Goyal'
language = _('English')
needs_subscription = True
remove_tags = [dict(name='font', attrs={'class':'footer'}), dict(name='hr', noshade='noshade')]
@@ -12,7 +12,8 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Estadao(BasicNewsRecipe):
title = 'O Estado de S. Paulo'
__author__ = 'Darko Miletic'
description = 'News from Brasil'
description = 'News from Brasil'
language = _('Spanish')
oldest_article = 2
max_articles_per_feed = 100
no_stylesheets = True
@@ -12,7 +12,8 @@ class FazNet(BasicNewsRecipe):
title = 'FAZ NET'
__author__ = 'Kovid Goyal'
description = '"Frankfurter Allgemeine Zeitung'
use_embedded_content = False
use_embedded_content = False
language = _('German')
max_articles_per_feed = 30
preprocess_regexps = [
@@ -13,6 +13,7 @@ class FinancialTimes(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'Financial world news'
oldest_article = 2
language = _('English')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -7,6 +7,7 @@ class Forbes(BasicNewsRecipe):
__author__ = 'Darko Miletic'
oldest_article = 30
max_articles_per_feed = 100
language = _('English')
no_stylesheets = True
html2lrf_options = ['--base-font-size', '10']
@@ -10,6 +10,7 @@ class Freakonomics(BasicNewsRecipe):
title = 'Freakonomics Blog'
description = 'The Hidden side of everything'
__author__ = 'Kovid Goyal'
language = _('English')
feeds = [('Blog', 'http://freakonomics.blogs.nytimes.com/feed/atom/')]
@@ -15,6 +15,7 @@ class FTheiseDe(BasicNewsRecipe):
__author__ = 'Oliver Niesner'
use_embedded_content = False
timefmt = ' [%d %b %Y]'
language = _('German')
max_articles_per_feed = 40
no_stylesheets = True
@@ -12,6 +12,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Fudzilla(BasicNewsRecipe):
title = u'Fudzilla'
__author__ = 'Darko Miletic'
language = _('English')
description = 'Tech news'
oldest_article = 7
max_articles_per_feed = 100
@@ -14,6 +14,7 @@ class GlobeAndMail(BasicNewsRecipe):
title = 'Globe and Mail'
__author__ = 'Kovid Goyal'
language = _('English')
description = 'Canada\'s national newspaper'
keep_only_tags = [dict(id='content')]
remove_tags = [dict(attrs={'class':'nav'}), dict(id=['related', 'TPphoto', 'secondaryNav', 'articleBottomToolsHolder'])]
@@ -13,6 +13,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Granma(BasicNewsRecipe):
title = 'Diario Granma'
__author__ = 'Darko Miletic'
language = _('Spanish')
description = 'Organo oficial del Comite Central del Partido Comunista de Cuba'
oldest_article = 2
max_articles_per_feed = 100
@@ -13,6 +13,7 @@ class Guardian(BasicNewsRecipe):
title = u'The Guardian'
__author__ = 'Seabound'
language = _('English')
oldest_article = 7
max_articles_per_feed = 20
@@ -10,6 +10,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Harpers(BasicNewsRecipe):
title = u"Harper's Magazine"
__author__ = u'Darko Miletic'
language = _('English')
description = u"Harper's Magazine: Founded June 1850."
oldest_article = 30
max_articles_per_feed = 100
@@ -15,6 +15,7 @@ class Harpers_full(BasicNewsRecipe):
title = u"Harper's Magazine - articles from printed edition"
__author__ = u'Darko Miletic'
description = u"Harper's Magazine: Founded June 1850."
language = _('English')
oldest_article = 30
max_articles_per_feed = 100
no_stylesheets = True
@@ -13,6 +13,7 @@ class HeiseDe(BasicNewsRecipe):
title = 'heise'
description = 'Computernews from Germany'
__author__ = 'Oliver Niesner'
language = _('German')
use_embedded_content = False
timefmt = ' [%d %b %Y]'
max_articles_per_feed = 40
@@ -11,6 +11,7 @@ from calibre.ptempfile import PersistentTemporaryFile
class InternationalHeraldTribune(BasicNewsRecipe):
title = u'The International Herald Tribune'
__author__ = 'Derry FitzGerald'
language = _('English')
oldest_article = 1
max_articles_per_feed = 10
no_stylesheets = True
@@ -13,6 +13,7 @@ class Infobae(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'Informacion Libre las 24 horas'
oldest_article = 2
language = _('Spanish')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -9,6 +9,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class IrishTimes(BasicNewsRecipe):
title = u'The Irish Times'
__author__ = 'Derry FitzGerald'
language = _('English')
no_stylesheets = True
remove_tags = [dict(name='div', attrs={'class':'footer'})]
@@ -11,7 +11,8 @@ from calibre.web.feeds.news import BasicNewsRecipe
class JapanTimes(BasicNewsRecipe):
title = u'The Japan Times'
__author__ = 'Darko Miletic'
description = 'News from Japan'
description = 'News from Japan'
language = _('English')
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
@@ -13,6 +13,7 @@ class JBOnline(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'News from Brasil'
oldest_article = 2
language = _('Spanish')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -12,6 +12,7 @@ class Joelonsoftware(BasicNewsRecipe):
title = 'Joel on Software'
__author__ = 'Darko Miletic'
description = 'Painless Software Management'
language = _('English')
no_stylesheets = True
use_embedded_content = True
@@ -5,6 +5,7 @@ class JerusalemPost(BasicNewsRecipe):
title = 'Jerusalem Post'
description = 'News from Israel and the Middle East'
use_embedded_content = False
language = _('English')
__author__ = 'Kovid Goyal'
max_articles_per_feed = 10
no_stylesheets = True
@@ -14,6 +14,7 @@ class Juventudrebelde(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'Diario de la Juventud Cubana'
oldest_article = 2
language = _('Spanish')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -12,7 +12,8 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Juventudrebelde_english(BasicNewsRecipe):
title = 'Juventud Rebelde in english'
__author__ = 'Darko Miletic'
description = 'The newspaper of Cuban Youth'
description = 'The newspaper of Cuban Youth'
language = _('English')
oldest_article = 2
max_articles_per_feed = 100
no_stylesheets = True
@@ -13,6 +13,7 @@ class LaCuarta(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'El sitio de noticias online de Chile'
oldest_article = 2
language = _('Spanish')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -11,7 +11,8 @@ from calibre.web.feeds.news import BasicNewsRecipe
class LaSegunda(BasicNewsRecipe):
title = 'La Segunda'
__author__ = 'Darko Miletic'
description = 'El sitio de noticias online de Chile'
description = 'El sitio de noticias online de Chile'
language = _('Spanish')
oldest_article = 2
max_articles_per_feed = 100
no_stylesheets = True
@@ -13,6 +13,7 @@ class LaTercera(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'El sitio de noticias online de Chile'
oldest_article = 2
language = _('Spanish')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -13,6 +13,7 @@ class Lanacion(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'Informacion actualizada las 24 horas, con noticias de Argentina y del mundo - Informate ya!'
oldest_article = 2
language = _('Spanish')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -14,6 +14,7 @@ class LaNacionChile(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'El sitio de noticias online de Chile'
oldest_article = 2
language = _('Spanish')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -14,6 +14,7 @@ class LaPrensa(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'Informacion Libre las 24 horas'
oldest_article = 7
language = _('Spanish')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -14,6 +14,7 @@ class LATimes(BasicNewsRecipe):
description = u'News from Los Angeles'
oldest_article = 7
max_articles_per_feed = 100
language = _('English')
no_stylesheets = True
use_embedded_content = False
@@ -16,6 +16,7 @@ class LeMonde(BasicNewsRecipe):
__author__ = 'Mathieu Godlewski <mathieu at godlewski.fr>'
description = 'Global news in french'
oldest_article = 7
language = _('French')
max_articles_per_feed = 20
no_stylesheets = True
@@ -12,6 +12,7 @@ class Liberation(BasicNewsRecipe):
title = u'Liberation'
__author__ = 'Darko Miletic'
description = 'News from France'
language = _('French')
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
@@ -12,7 +12,8 @@ from calibre.web.feeds.news import BasicNewsRecipe
class LinuxMagazine(BasicNewsRecipe):
title = u'Linux Magazine'
__author__ = 'Darko Miletic'
description = 'Linux news'
description = 'Linux news'
language = _('English')
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
@@ -14,6 +14,7 @@ class LondonReviewOfBooks(BasicNewsRecipe):
description = u'Literary review publishing essay-length book reviews and topical articles on politics, literature, history, philosophy, science and the arts by leading writers and thinkers'
oldest_article = 7
max_articles_per_feed = 100
language = _('English')
no_stylesheets = True
use_embedded_content = False
encoding = 'cp1252'
@@ -11,7 +11,8 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Moscowtimes(BasicNewsRecipe):
title = u'The Moscow Times'
__author__ = 'Darko Miletic'
description = 'News from Russia'
description = 'News from Russia'
language = _('English')
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
@@ -31,6 +31,7 @@ class NASA(BasicNewsRecipe):
title = 'NASA'
timefmt = ' [%Y%b%d %H%M]'
language = _('English')
description = 'News from NASA'
__author__ = 'Scott Wxby & David Chen'
no_stylesheets = True
@@ -19,6 +19,7 @@ class NewScientist(BasicNewsRecipe):
title = u'New Scientist - Online News'
__author__ = 'Darko Miletic'
description = 'News from Science'
language = _('English')
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
@@ -15,6 +15,7 @@ class NewYorkReviewOfBooks(BasicNewsRecipe):
title = u'New York Review of Books'
description = u'Book reviews'
language = _('English')
__author__ = 'Kovid Goyal'
remove_tags_before = {'id':'container'}
@@ -13,6 +13,7 @@ class NewYorker(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'Best of the US journalism'
oldest_article = 7
language = _('English')
max_articles_per_feed = 100
no_stylesheets = False
use_embedded_content = False
@@ -13,6 +13,7 @@ class Newsweek(BasicNewsRecipe):
__author__ = 'Kovid Goyal'
description = 'Weekly news and current affairs in the US'
no_stylesheets = True
language = _('English')
extra_css = '#content { font:serif 12pt; }\n.story {font:12pt}\n.HorizontalHeader {font:18pt}\n.deck {font:16pt}'
keep_only_tags = [dict(name='div', id='content')]
@@ -14,6 +14,7 @@ class Nspm(BasicNewsRecipe):
__author__ = 'Darko Miletic'
description = 'Casopis za politicku teoriju i drustvena istrazivanja'
oldest_article = 7
language = _('Serbian')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -14,6 +14,7 @@ class Nspm_int(BasicNewsRecipe):
description = 'Magazine dedicated to political theory and sociological research'
oldest_article = 20
max_articles_per_feed = 100
language = _('English')
no_stylesheets = True
use_embedded_content = False
INDEX = 'http://www.nspm.rs/?alphabet=l'
@@ -14,6 +14,7 @@ class NYTimesMobile(BasicNewsRecipe):
title = 'The New York Times'
__author__ = 'Kovid Goyal'
language = _('English')
description = 'Daily news from the New York Times (mobile version)'
timefmt = ' [%a, %d %b, %Y]'
multithreaded_fetch = True
@@ -14,6 +14,7 @@ class NYTimes(BasicNewsRecipe):
title = 'The New York Times (subscription)'
__author__ = 'Kovid Goyal'
language = _('English')
description = 'Daily news from the New York Times (subscription version)'
timefmt = ' [%a, %d %b, %Y]'
needs_subscription = True
@@ -14,6 +14,7 @@ class OGlobo(BasicNewsRecipe):
description = 'News from Brasil'
oldest_article = 2
max_articles_per_feed = 100
language = _('Spanish')
no_stylesheets = True
use_embedded_content = False
encoding = 'cp1252'
@@ -14,6 +14,7 @@ class OutlookIndia(BasicNewsRecipe):
title = 'Outlook India'
__author__ = 'Kovid Goyal'
description = 'Weekly news magazine focussed on India.'
language = _('English')
recursions = 1
match_regexp = r'full.asp.*&pn=\d+'
html2lrf_options = ['--ignore-tables']
@@ -12,7 +12,8 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Pagina12(BasicNewsRecipe):
title = u'Pagina/12'
__author__ = 'Darko Miletic'
description = 'Noticias de Argentina y el resto del mundo'
description = 'Noticias de Argentina y el resto del mundo'
language = _('Spanish')
oldest_article = 2
max_articles_per_feed = 100
no_stylesheets = True
@@ -13,6 +13,7 @@ class Portfolio(BasicNewsRecipe):
title = 'Portfolio'
__author__ = 'JTravers'
description = 'Conde Nast Portfolio: For the businessman.'
language = _('English')
use_embedded_content = True
timefmt = ' [%a, %b %d, %Y]'
html2lrf_options = ['--ignore-tables']
@@ -9,6 +9,7 @@ class Reuters(BasicNewsRecipe):
description = 'Global news'
__author__ = 'Kovid Goyal'
use_embedded_content = False
language = _('English')
max_articles_per_feed = 10
@@ -11,7 +11,8 @@ from calibre.web.feeds.news import BasicNewsRecipe
class SanFranciscoChronicle(BasicNewsRecipe):
title = u'San Francisco Chronicle'
__author__ = u'Darko Miletic'
description = u'San Francisco news'
description = u'San Francisco news'
language = _('English')
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
@@ -10,6 +10,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class ScienceAAS(BasicNewsRecipe):
title = u'Science AAAS'
__author__ = u'Darko Miletic'
language = _('English')
description = u'The best in science news, commentary, and research'
oldest_article = 7
max_articles_per_feed = 100
@@ -12,6 +12,7 @@ class Sciencenews(BasicNewsRecipe):
__author__ = u'Darko Miletic'
description = u"Science News is an award-winning weekly newsmagazine covering the most important research in all fields of science. Its 16 pages each week are packed with short, accurate articles that appeal to both general readers and scientists. Published since 1922, the magazine now reaches about 150,000 subscribers and more than 1 million readers. These are the latest News Items from Science News."
oldest_article = 30
language = _('English')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -12,6 +12,7 @@ class ScienceDaily(BasicNewsRecipe):
__author__ = u'Darko Miletic'
description = u"Breaking science news and articles on global warming, extrasolar planets, stem cells, bird flu, autism, nanotechnology, dinosaurs, evolution -- the latest discoveries in astronomy, anthropology, biology, chemistry, climate &amp; environment, computers, engineering, health &amp; medicine, math, physics, psychology, technology, and more -- from the world's leading universities and research organizations."
oldest_article = 7
language = _('English')
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
@@ -14,6 +14,7 @@ class ScientificAmerican(BasicNewsRecipe):
title = u'Scientific American'
description = u'Popular science. Monthly magazine.'
__author__ = 'Kovid Goyal'
language = _('English')
oldest_article = 30
max_articles_per_feed = 100
no_stylesheets = True
@@ -12,6 +12,7 @@ class SecurityWatch(BasicNewsRecipe):
filter_regexps = [r'feedads\.googleadservices\.com']
filter_regexps = [r'ad\.doubleclick']
filter_regexps = [r'advert']
language = _('English')
remove_tags = [dict(id='topBannerContainer'),
dict(id='topBannerSmall'),
@@ -7,6 +7,7 @@ class Shacknews(BasicNewsRecipe):
title = u'Shacknews'
oldest_article = 7
max_articles_per_feed = 100
language = _('English')
no_stylesheets = True
remove_tags = [dict(name='div', attrs={'class': ['nuggets', 'comments']}),
dict(name='p', attrs={'class': 'videoembed'})]
@@ -16,6 +16,7 @@ class SMH(BasicNewsRecipe):
title = 'Sydney Morning Herald'
description = 'Business News, World News and Breaking News in Australia'
__author__ = 'Kovid Goyal'
language = _('English')
def get_browser(self):
br = BasicNewsRecipe.get_browser()
@@ -14,6 +14,7 @@ class Spiegel_int(BasicNewsRecipe):
description = "News and POV from Europe's largest newsmagazine"
oldest_article = 7
max_articles_per_feed = 100
language = _('English')
no_stylesheets = True
use_embedded_content = False
cover_url = 'http://www.spiegel.de/static/sys/v8/headlines/spiegelonline.gif'
@@ -16,6 +16,7 @@ class SpeigelOnline(BasicNewsRecipe):
description = 'Nachrichten des Magazins Der Spiegel'
__author__ = 'Kovid Goyal'
use_embedded_content = False
language = _('German')
timefmt = ' [ %Y-%m-%d %a]'
max_articles_per_feed = 40
no_stylesheets = True
@@ -17,6 +17,7 @@ class PetersburgTimes(BasicNewsRecipe):
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
language = _('Russian')
INDEX = 'http://www.sptimes.ru'
def parse_index(self):
@@ -16,6 +16,7 @@ class Sueddeutsche(BasicNewsRecipe):
use_embedded_content = False
timefmt = ' [%d %b %Y]'
max_articles_per_feed = 40
language = _('German')
no_stylesheets = True
encoding = 'latin1'
remove_tags_after = [dict(name='div', attrs={'class':'artikelBox navigatorBox'})]
@@ -15,6 +15,7 @@ class TelegraphUK(BasicNewsRecipe):
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
language = _('English')
use_embedded_content = False
keep_only_tags = [
@@ -14,6 +14,7 @@ class Telepolis(BasicNewsRecipe):
description = 'News from Germany in German'
oldest_article = 2
max_articles_per_feed = 100
language = _('German')
no_stylesheets = True
use_embedded_content = False
encoding = 'utf-8'
@@ -14,6 +14,7 @@ class Teleread(BasicNewsRecipe):
title = 'Teleread Blog'
description = 'News & views on e-books, libraries, publishing and related topics'
__author__ = 'Kovid Goyal'
language = _('English')
feeds = [('Entries', 'http://www.teleread.org/feed/')]
@@ -16,6 +16,7 @@ class TheAge(BasicNewsRecipe):
title = 'The Age'
description = 'Business News, World News and Breaking News in Melbourne, Australia'
__author__ = 'Matthew Briggs'
language = _('English')
def get_browser(self):
br = BasicNewsRecipe.get_browser()
@@ -14,6 +14,7 @@ class Thenation(BasicNewsRecipe):
oldest_article = 120
max_articles_per_feed = 100
no_stylesheets = True
language = _('English')
use_embedded_content = False
simultaneous_downloads = 1
delay = 1
@@ -13,6 +13,7 @@ class DailyTelegraph(BasicNewsRecipe):
title = u'The Australian'
__author__ = u'Matthew Briggs'
description = u'National broadsheet newspaper from down under - colloquially known as The Oz'
language = _('English')
oldest_article = 2
max_articles_per_feed = 10
remove_javascript = True
@@ -16,6 +16,7 @@ class TheScotsman(BasicNewsRecipe):
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
language = _('English')
simultaneous_downloads = 1
keep_only_tags = [dict(name='div', attrs={'id':'viewarticle'})]
@@ -14,6 +14,7 @@ class Themarketticker(BasicNewsRecipe):
description = 'Commentary On The Capital Markets'
oldest_article = 7
max_articles_per_feed = 100
language = _('English')
no_stylesheets = True
use_embedded_content = True
html2lrf_options = [ '--comment' , description
@@ -15,6 +15,7 @@ class Time(BasicNewsRecipe):
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
language = _('English')
use_embedded_content = False
keep_only_tags = [dict(name='div', attrs={'class':'tout1'})]
@@ -16,6 +16,7 @@ class TimesOnline(BasicNewsRecipe):
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
language = _('English')
simultaneous_downloads = 1
remove_tags_after = dict(name='div', attrs={'class':'bg-666'})

Some files were not shown because too many files have changed in this diff Show More