mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Contretemps by Kabonix
This commit is contained in:
parent
6dfc2f24cd
commit
74258c0dcb
165
recipes/contretemps.recipe
Normal file
165
recipes/contretemps.recipe
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
'''
|
||||||
|
contretemps.eu
|
||||||
|
'''
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
|
class ContretempsRecipe(BasicNewsRecipe):
|
||||||
|
title = 'Contretemps'
|
||||||
|
__author__ = 'Kabonix'
|
||||||
|
description = 'Revue de critique communiste'
|
||||||
|
publisher = 'Contretemps'
|
||||||
|
category = 'politique, théorie, stratégie'
|
||||||
|
language = 'fr'
|
||||||
|
encoding = 'utf-8'
|
||||||
|
oldest_article = 60
|
||||||
|
max_articles_per_feed = 30
|
||||||
|
publication_type = 'magazine'
|
||||||
|
|
||||||
|
no_stylesheets = True
|
||||||
|
remove_javascript = True
|
||||||
|
auto_cleanup = False
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
('Théorie', 'https://www.contretemps.eu/category/theorie/feed/'),
|
||||||
|
('Stratégie', 'https://www.contretemps.eu/category/strategie/feed/'),
|
||||||
|
('Conjoncture', 'https://www.contretemps.eu/category/conjoncture/feed/')
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_cover_url(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def default_cover(self, cover_file):
|
||||||
|
"""
|
||||||
|
Crée une couverture personnalisée pour Contretemps
|
||||||
|
"""
|
||||||
|
from qt.core import QColor, QFont, QImage, QPainter, QPen, QRect, Qt
|
||||||
|
|
||||||
|
from calibre.gui2 import ensure_app, load_builtin_fonts, pixmap_to_data
|
||||||
|
try:
|
||||||
|
# Préparation de l'environnement Qt
|
||||||
|
ensure_app()
|
||||||
|
load_builtin_fonts()
|
||||||
|
|
||||||
|
# Date en français
|
||||||
|
today = datetime.now(ZoneInfo('Europe/Paris'))
|
||||||
|
wkd = today.weekday()
|
||||||
|
french_weekday = {0:'Lundi',1:'Mardi',2:'Mercredi',3:'Jeudi',4:'Vendredi',5:'Samedi',6:'Dimanche'}
|
||||||
|
french_month = {1:'janvier', 2:'février', 3:'mars', 4:'avril', 5:'mai', 6:'juin',
|
||||||
|
7:'juillet', 8:'août', 9:'septembre', 10:'octobre', 11:'novembre', 12:'décembre'}
|
||||||
|
|
||||||
|
weekday = french_weekday[wkd]
|
||||||
|
month = french_month[today.month]
|
||||||
|
date_str = f"{weekday} {today.day} {month} {today.year}"
|
||||||
|
edition = today.strftime('Édition de %Hh%M')
|
||||||
|
|
||||||
|
# Création de l'image de base (ratio ~1.6 pour format livre)
|
||||||
|
img = QImage(1200, 1920, QImage.Format_RGB888)
|
||||||
|
img.fill(QColor('white'))
|
||||||
|
|
||||||
|
# Téléchargement et ajout du logo
|
||||||
|
br = self.get_browser()
|
||||||
|
logo_data = br.open_novisit('https://www.contretemps.eu/wp-content/uploads/ct14-1-512x241.jpg').read()
|
||||||
|
logo_img = QImage()
|
||||||
|
logo_img.loadFromData(logo_data)
|
||||||
|
|
||||||
|
# Position du logo (centré)
|
||||||
|
x = (img.width() - logo_img.width()) // 2
|
||||||
|
y = (img.height() - logo_img.height()) // 2 - 200 # Un peu plus haut que le centre
|
||||||
|
|
||||||
|
# Dessiner le logo
|
||||||
|
p = QPainter(img)
|
||||||
|
p.drawImage(x, y, logo_img)
|
||||||
|
p.end()
|
||||||
|
|
||||||
|
# Ajout des textes
|
||||||
|
painters = [
|
||||||
|
(36, 'Liberation Serif', False, False, date_str, (0, y + logo_img.height() + 100, 1200, 100)),
|
||||||
|
(32, 'Liberation Serif', True, True, edition, (0, y + logo_img.height() + 200, 1200, 100))
|
||||||
|
]
|
||||||
|
|
||||||
|
for font_size, font_family, is_bold, is_italic, text, rect in painters:
|
||||||
|
p = QPainter(img)
|
||||||
|
pen = QPen(QColor('black'))
|
||||||
|
p.setPen(pen)
|
||||||
|
|
||||||
|
font = QFont()
|
||||||
|
font.setFamily(font_family)
|
||||||
|
font.setPointSize(font_size)
|
||||||
|
font.setBold(is_bold)
|
||||||
|
font.setItalic(is_italic)
|
||||||
|
p.setFont(font)
|
||||||
|
|
||||||
|
r = QRect(*rect)
|
||||||
|
p.drawText(r, Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter, text)
|
||||||
|
p.end()
|
||||||
|
|
||||||
|
# Sauvegarde de l'image
|
||||||
|
img_data = pixmap_to_data(img)
|
||||||
|
cover_file.write(img_data)
|
||||||
|
cover_file.flush()
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.log.error(f'Erreur lors de la création de la couverture: {e}')
|
||||||
|
return False
|
||||||
|
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='article', attrs={'class': 'post'})
|
||||||
|
]
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict(name='div', attrs={'class': ['tags', 'share-buttons', 'related-posts']}),
|
||||||
|
dict(name='div', attrs={'class': ['comments-area', 'nav-links']}),
|
||||||
|
dict(name='div', attrs={'id': ['sidebar', 'comments']}),
|
||||||
|
dict(name='section', attrs={'class': 'comments-area'}),
|
||||||
|
dict(name='footer'),
|
||||||
|
dict(name='div', attrs={'class': 'yarpp-related'}),
|
||||||
|
dict(name='div', attrs={'class': 'related-posts'})
|
||||||
|
]
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
# Nettoyage des styles
|
||||||
|
for tag in soup.findAll(True):
|
||||||
|
if 'style' in tag.attrs:
|
||||||
|
del tag['style']
|
||||||
|
|
||||||
|
# Nettoyage des images
|
||||||
|
for img in soup.findAll('img'):
|
||||||
|
for attr in ['srcset', 'sizes', 'loading', 'class', 'width', 'height', 'decoding', 'data-lazy-srcset', 'data-lazy-sizes']:
|
||||||
|
if attr in img.attrs:
|
||||||
|
del img[attr]
|
||||||
|
|
||||||
|
if 'data-lazy-src' in img.attrs:
|
||||||
|
img['src'] = img['data-lazy-src']
|
||||||
|
del img['data-lazy-src']
|
||||||
|
|
||||||
|
if img.get('src', '').startswith('/'):
|
||||||
|
img['src'] = 'https://www.contretemps.eu' + img['src']
|
||||||
|
|
||||||
|
# Suppression de tout ce qui suit "à voir aussi"
|
||||||
|
for text in soup.findAll(text=lambda text: text and 'à voir aussi' in text.lower()):
|
||||||
|
parent = text.parent
|
||||||
|
for sibling in list(parent.find_next_siblings()):
|
||||||
|
sibling.decompose()
|
||||||
|
parent.decompose()
|
||||||
|
|
||||||
|
return soup
|
||||||
|
|
||||||
|
extra_css = '''
|
||||||
|
h1 { font-size: 1.8em; font-weight: bold; margin: 0 0 1em 0; }
|
||||||
|
h2 { font-size: 1.4em; font-weight: bold; margin: 1em 0; }
|
||||||
|
.author { font-style: italic; margin-bottom: 1.5em; color: #666; }
|
||||||
|
img { max-width: 100%; height: auto; margin: 1em auto; }
|
||||||
|
figcaption { font-size: 0.9em; font-style: italic; color: #666; margin: 0.5em 0 1.5em 0; }
|
||||||
|
p { margin-bottom: 1em; line-height: 1.5; }
|
||||||
|
blockquote { margin: 1em 2em; font-style: italic; }
|
||||||
|
.wp-block-quote { margin: 1em 0; padding: 0 1em; border-left: 3px solid #ccc; }
|
||||||
|
'''
|
Loading…
x
Reference in New Issue
Block a user