Register Guidelines E-Books Search Today's Posts Mark Forums Read

Go Back   MobileRead Forums > E-Book Software > Calibre > Recipes

Notices

Reply
 
Thread Tools Search this Thread
Old 01-18-2025, 11:00 AM   #1
alphonk
Member
alphonk began at the beginning.
 
Posts: 10
Karma: 10
Join Date: Dec 2024
Device: kindle scribe
Arrêt sur images (French) - 2025 recipe

Arrêt sur images (French) - 2025 recipe


Quote:
Code:
#!/usr/bin/env python
# vim:fileencoding=utf-8

from calibre.web.feeds.news import BasicNewsRecipe
from datetime import datetime
from zoneinfo import ZoneInfo
import urllib.request
import json
import mechanize

class ArretSurImages(BasicNewsRecipe):
    title = 'Arrêt sur Images'
    description = 'Site français d\'analyse des médias'
    language = 'fr'
    encoding = 'utf-8'
    needs_subscription = True
    oldest_article = 7
    max_articles_per_feed = 100
    no_stylesheets = True
    remove_javascript = True
    
    feeds = [
        ('Arrêt sur images', 'https://api.arretsurimages.net/api/public/rss/all-content')
    ]

    def default_cover(self, cover_file):
        """
        Crée une couverture personnalisée avec le logo ASI
        """
        from qt.core import QFont, QImage, QPainter, QPen, QRect, Qt, QColor
        from calibre.gui2 import ensure_app, load_builtin_fonts, pixmap_to_data
        try:
            ensure_app()
            load_builtin_fonts()
            
            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')

            img = QImage(1400, 1920, QImage.Format_RGB888)
            img.fill(QColor('white'))
            
            # Dessiner la bordure rouge
            border_painter = QPainter(img)
            border_pen = QPen(QColor('red'))
            border_pen.setWidth(120)  # Épaisseur de la bordure
            border_painter.setPen(border_pen)
            border_painter.drawRect(10, 10, img.width()-20, img.height()-20)  # Marge de 10 pixels
            border_painter.end()

            logo_url = 'https://www.arretsurimages.net/assets/img/front/logo-asi-grand.png'
            logo_data = urllib.request.urlopen(logo_url).read()
            logo = QImage()
            logo.loadFromData(logo_data)

            logo_width = 800
            scaled_logo = logo.scaledToWidth(logo_width, Qt.SmoothTransformation)

            x = (img.width() - scaled_logo.width()) // 2
            y = (img.height() - scaled_logo.height()) // 2 - 100

            p = QPainter(img)
            p.drawImage(x, y, scaled_logo)
            p.end()

            p = QPainter(img)
            p.setPen(QPen(QColor('black')))
            
            font = QFont('Liberation Sans', 36)
            p.setFont(font)
            
            r = QRect(0, y + scaled_logo.height() + 50, img.width(), 100)
            p.drawText(r, Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter, date_str)

            font.setItalic(True)
            font.setPointSize(32)
            p.setFont(font)
            
            r = QRect(0, y + scaled_logo.height() + 150, img.width(), 100)
            p.drawText(r, Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter, edition)
            
            p.end()

            img_data = pixmap_to_data(img)
            cover_file.write(img_data)
            cover_file.flush()
            return True

        except Exception as e:
            print(f'Erreur lors de la création de la couverture: {e}')
            return False

    def get_browser(self):
        br = BasicNewsRecipe.get_browser(self)
        if self.username and self.password:
            auth_data = {
                'client_id': '1_1e3dazertyukilygfos7ldzertyuof7pfd',
                'client_secret': '2r8yd4a8un0fn45d93acfr3efrgthzdheifhrehihidg4dk5kds7ds23',
                'username': self.username,
                'password': self.password,
                'grant_type': 'password'
            }
            request = mechanize.Request(
                'https://api.arretsurimages.net/oauth/v2/token',
                data=json.dumps(auth_data).encode('utf-8'),
                headers={'Content-Type': 'application/json', 'Accept': 'application/json'}
            )
            try:
                response = br.open(request)
                auth_response = json.loads(response.read().decode('utf-8'))
                if 'access_token' in auth_response:
                    br.addheaders += [('Authorization', f'Bearer {auth_response["access_token"]}')]
                    print('Authentification réussie')
                else:
                    print('Échec de l\'authentification - Vérifiez vos identifiants')
            except Exception as e:
                print(f'Erreur lors de l\'authentification: {str(e)}')
        return br

    def get_article_url(self, article):
        url = article.get('link', article.get('guid'))
        if url:
            return url.replace('www.arretsurimages.net/', 'api.arretsurimages.net/api/public/contents/')
        return None

    def preprocess_raw_html(self, raw_html, url):
        try:
            article_data = json.loads(raw_html)
            authors = ', '.join([a.get('name', '') for a in article_data.get('authors', [])])
            cover_html = ''
            if article_data.get('cover') and article_data['cover'].get('formats', {}).get('article_header'):
                cover_slug = article_data['cover']['slug']
                cover_url = f'https://api.arretsurimages.net/api/public/media/{cover_slug}/action/show?format=article_header'
                cover_html = f'<img src="{cover_url}" alt="{article_data.get("title", "")}">'
            return f'''
                <html>
                <head><title>{article_data.get('title', 'Article sans titre')}</title></head>
                <body>
                    <article>
                        <h1>{article_data.get('title', 'Article sans titre')}</h1>
                        <div class="article-meta">
                            <p>Par {authors or "Auteur inconnu"}</p>
                        </div>
                        {cover_html}
                        <div class="article-content">
                            <p><strong>{article_data.get('lead', '')}</strong></p>
                            {article_data.get('content', '')}
                        </div>
                    </article>
                </body>
                </html>
            '''
        except Exception as e:
            print(f'Erreur preprocessing HTML: {str(e)}')
            return raw_html

    def preprocess_html(self, soup):
        try:
            for tag in soup.find_all(['asi-html', 'asi-image', 'asi-video']):
                if tag.name == 'asi-html' and tag.get('data-html'):
                    tag.replace_with(soup.new_tag('div', attrs={'class': 'asi-content'}).append(tag['data-html']))
                elif tag.name == 'asi-image':
                    img_data = tag.get('data-image', {})
                    if img_data:
                        try:
                            img_data = json.loads(img_data)
                            if img_data.get('slug'):
                                img_url = f'https://api.arretsurimages.net/api/public/media/{img_data["slug"]}/action/show?format=article_body'
                                img_tag = soup.new_tag('img', src=img_url)
                                if img_data.get('caption'):
                                    caption_div = soup.new_tag('div', attrs={'class': 'image-caption'})
                                    caption_div.string = img_data['caption']
                                    tag.replace_with(img_tag)
                                    img_tag.insert_after(caption_div)
                                else:
                                    tag.replace_with(img_tag)
                        except Exception as e:
                            print(f'Erreur processing image: {str(e)}')
                            tag.decompose()
                else:
                    tag.decompose()
            return soup
        except Exception as e:
            print(f'Erreur preprocessing HTML: {str(e)}')
            return soup

Last edited by PeterT; 01-18-2025 at 05:57 PM.
alphonk is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Le Canard Enchainé (French) - 2025 receipt alphonk Recipes 0 01-18-2025 10:52 AM
Request to Update Economist World Ahead Recipe for 2025 xkcklzn Recipes 2 11-28-2024 01:03 AM
Other Fiction Tinseau, Léon de: Sur le Seuil [French] V.1 23.07.2020 Leonatus ePub Books 0 07-23-2020 02:35 AM
Other Fiction Tinseau, Léon de: Sur les deux rives [French] V.1 12.06.2020 Leonatus ePub Books 0 06-12-2020 05:05 AM
Arrêt sur images Calibre Recipe franek Recipes 1 03-30-2013 09:54 PM


All times are GMT -4. The time now is 07:25 PM.


MobileRead.com is a privately owned, operated and funded community.