From 24befe49bb192c75e24cb44ea86ca58f615900fe Mon Sep 17 00:00:00 2001 From: Cristi Ghera Date: Fri, 19 Apr 2024 19:46:20 +0200 Subject: [PATCH] Added Parool (NL), Revista 22 (RO), Dilema (RO) and Internazionale (IT); updated Volkskrant to download cover --- recipes/dilema.png | Bin 0 -> 1195 bytes recipes/dilema.recipe | 107 ++++++++++++++++ recipes/internazionale.png | Bin 0 -> 1676 bytes recipes/internazionale.recipe | 117 ++++++++++++++++++ recipes/parool.png | Bin 0 -> 2625 bytes recipes/parool.recipe | 96 ++++++++++++++ recipes/revista22.png | Bin 0 -> 3769 bytes recipes/revista22.recipe | 74 +++++++++++ recipes/volkskrant.png | Bin 0 -> 11901 bytes .../{volksrant.recipe => volkskrant.recipe} | 28 ++++- 10 files changed, 419 insertions(+), 3 deletions(-) create mode 100644 recipes/dilema.png create mode 100644 recipes/dilema.recipe create mode 100644 recipes/internazionale.png create mode 100644 recipes/internazionale.recipe create mode 100644 recipes/parool.png create mode 100644 recipes/parool.recipe create mode 100644 recipes/revista22.png create mode 100644 recipes/revista22.recipe create mode 100644 recipes/volkskrant.png rename recipes/{volksrant.recipe => volkskrant.recipe} (79%) diff --git a/recipes/dilema.png b/recipes/dilema.png new file mode 100644 index 0000000000000000000000000000000000000000..907f122ee1e6acee18bf58262c4d5f78a5fbc7bc GIT binary patch literal 1195 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}0jUw5X}-P; zT0k}j0~4bV12aeo5Hhr9GO&Qz3=C>Ont_3N0V6_o0TWzSVF5FO4N|x-+UG6MkjTuC zh>{3jAFJg2T)o7U{G?R9irfN_0tTB3D*7iAWdWaj57fXq!y$}cUk zRZ;?31P2gzmSmmYbxH&s|F8si)(h|4DY1^ayIU$q&GD~p+#V&Lx1Zt@4ySq32(>c?7*Uz1+IBs<^ zW!_Ht=QhvJ**?FwSSjQ|(>kL zwJVBsJ8FnL^5}l$#Iz@X>B!Tfhx2~CZ(k?T>7w-H^XJLo^09HiLb?8$;)w{rf+c-TWQS`J%+?QjXcoLKgF28!4ny9a4)yP1<>Be!{{c=;h?-NKgLGv;Moc>jIpmZ;TNRjTKE zs2q6yc`mPkmQi>^)`TY;3uNS6_Qv^VeA@Q-hflnmmRPp{51YO^=gSi}nVrrrd5~lF zdxo~;y{1!7jVxvOoZ=<--JaSbW}qV1KiO^Z!Jb%V@jwT5hPc^JIKsRmW<1FBaPHC0 zS#(iDWwPfwgP)$)T~oK*e!Jttq3@;#KRiBdY;tOPMoD?|(IiHnjePBoZ(Yg1t;bPg i{i;v4Yw4qC%Q{BGJu)THDK~{dS>Myu&t;ucLK6Tpj>Iqk literal 0 HcmV?d00001 diff --git a/recipes/dilema.recipe b/recipes/dilema.recipe new file mode 100644 index 0000000000..c12280366e --- /dev/null +++ b/recipes/dilema.recipe @@ -0,0 +1,107 @@ +#!/usr/bin/env python +from calibre.web.feeds.recipes import BasicNewsRecipe +from bs4 import BeautifulSoup + +class Volkskrant(BasicNewsRecipe): + title = 'Dilema' + __author__ = 'Cristi Ghera' + max_articles_per_feed = 100 + description = '"Sint vechi, domnule!" (I.L. Caragiale)' + needs_subscription = False + language = 'ro' + country = 'RO' + category = 'politics, culture, Romania' + resolve_internal_links = True + remove_tags_before = { 'class': 'post' } + remove_tags_after = { 'class': 'post_content' } + remove_tags = [ + dict( + attrs={ + 'class': [ + 'single_meta_category', + 'avatar', + 'jm-post-like', + 'fa', + ] + } + ), + dict( + name=['div'], + attrs={ + 'class': ['mb-2'] + } + ), + dict(id=['like', 'dlik']), + dict(name=['script', 'noscript', 'style']), + ] + remove_attributes = ["class", "id", "name", "style"] + encoding = 'utf-8' + no_stylesheets = True + ignore_duplicate_articles = {'url'} + + def parse_index(self): + homepage_url = 'https://www.dilema.ro/' + soup = self.index_to_soup(homepage_url) + + articles = [] + + # .banner-container + banner_container = soup.find('div', attrs={'class': 'banner-container'}) + container = banner_container.find('h5') + a = container.find('a') + url = homepage_url + a.attrs['href'] + articles.append( + dict( + title=self.tag_to_string(container).strip(), + url=url, + date=self.tag_to_string(banner_container.find(attrs={'class': 'post-date'})).strip(), + description='', + content='' + ) + ) + + # .homepage_builder_3grid_post + containers = soup.findAll('div', attrs={'class': 'homepage_builder_3grid_post'}) + for container in containers: + if self.tag_to_string(container.find('h2')) in ['CELE MAI RECENTE', 'CELE MAI CITITE']: + continue + for article in container.findAll('div', attrs={'class': 'blog_grid_post_style'}): + title_container = article.find('h3') + if not title_container: + continue + url = title_container.find('a')['href'] + url = homepage_url + url + article_title = self.tag_to_string(title_container).strip() + author = self.tag_to_string( + article.find('a', attrs={'rel': 'author'}) + ).strip() + summary = self.tag_to_string(article.find('p')).strip() + pubdate = self.tag_to_string(article.find(attrs={'class': 'post-date'})) + description = author + ' - ' + summary + articles.append( + dict( + title=article_title, + url=url, + date=pubdate, + description=description, + content='' + ) + ) + + sections = [("Numărul curent", articles)] + return sections + + def preprocess_html(self, soup): + main_carousel = soup.find(attrs={'id': 'main-carousel'}) + if main_carousel: + img = main_carousel.find('img') + body = soup.find('body') + body.clear() + body.append(img) + return soup + + def get_cover_url(self): + url = 'https://www.dilema.ro/coperta-saptaminii/' + soup = self.index_to_soup(url) + img = soup.find(attrs={'id': 'main-carousel'}).find('img') + return url + img.attrs['src'] \ No newline at end of file diff --git a/recipes/internazionale.png b/recipes/internazionale.png new file mode 100644 index 0000000000000000000000000000000000000000..b7dce84cfdda523524bf80cf4129dfd13e3e6f02 GIT binary patch literal 1676 zcmaJ?Yfuwc7!9Ngh_O(cB`!VHLFkj@QMR`o8pddYoF`CFKdEnn)qD5fes}qJ$O$BJ{{QOobt6 zPR0!^kVc~ecx(chpokLd2t5aJU^o`Nkz&(mfx#9dqD#X_K#Q%z4H8EGrA7vTqY{Qj zpa2y{8J3EN=bA8et}<4ao2CDG}J`sf$@aJ`1G;xr`4O_qSMFXKP{I_1;cf;^Cb(k7^%s|b$i5lv~8!J~+cf~mZmd0A{_QfZKmr54~@dx|c>mT>-pKtB1 zZbOlQqs)```@K?^sNU+T^Toh97r1E$!|G%8@nxRevDR7u_DNk?#fB57nS}?UV$8L# z#?F_gxc`*dS!R;wUe7u7%5EP{X)w2DZ^}Ehx+#9{oTNaT)0kvS=^;k4-%Pi`h;GoU z;EaNvdZFg|fyTh_7k>yBSVpg{3_3h3&)~Xc`LF4tKRlYPJM&iYH=xsss_Lu30X?wo zBbv+ecs3tS-tcwMLSxw?xad7U^$fiJh@@i8$XBy2LlSufP_(#o2#vB2$LEcO?}h2= z)+^D-#`ciR#Jrv@_S>WFBhPY{SkSZ5CCR|U-O(s?A?(!K2HPXNaQo*hC!y9BM58lf zQaYnPO|zw+J+!P#@cT`D=bwEAaf`y%M>dT_Hl4EG`muJfj9qucXP_)EB%>$sLCqzu zA6W=^%l`KADQB%Ad@gtJTvsv9DxTq2>hAeAKCv9uq<;|ZF)EOL7S}j1L_62(RZF)! z-)SX|D}Cqs&jhxe(0y|3WA4odfBiO?*+O^EFA7^4n9t)s+wL?}?en6v@^PTY&d7tz zlA_xei>vET+Xgz0_VcssJHe{!)%*K*6|Q)sy0M^o4zzz2(|$4QcOlVIAbgSmX qb<{=Kp($cD$2HhyKixcIh<%0T8p57e;t|*7_&-F*m2gc+vh^Q$mWZAJ literal 0 HcmV?d00001 diff --git a/recipes/internazionale.recipe b/recipes/internazionale.recipe new file mode 100644 index 0000000000..52094ed9a4 --- /dev/null +++ b/recipes/internazionale.recipe @@ -0,0 +1,117 @@ +#!/usr/bin/env python +from calibre.web.feeds.recipes import BasicNewsRecipe + +class Volkskrant(BasicNewsRecipe): + title = 'Internazionale' + __author__ = 'Cristi Ghera' + max_articles_per_feed = 100 + description = 'Internazionale - Notizie dall’Italia e dal mondo' + needs_subscription = False + language = 'it' + country = 'IT' + category = 'news, politics, Italy, world' + resolve_internal_links = True + remove_tags_before = { 'name': 'article' } + remove_tags_after = { 'name': 'article' } + remove_tags = [ + dict( + attrs={ + 'class': [ + 'item-banner', + 'hentryfeed__side', + 'magazine-article-share-tools', + 'magazine-article-share-popup', + 'article_next', + 'cta_nl_ext_container', + ] + } + ), + dict(name=['script', 'style']), + ] + remove_attributes = ["class", "id", "name", "style"] + encoding = 'utf-8' + no_stylesheets = True + ignore_duplicate_articles = {'url'} + + current_number_url = "https://www.internazionale.it/sommario" + home_url = "https://www.internazionale.it" + cover_url = None + + def extract_article(self, article): + url = article.find('a')['href'] + if url[0] == '/': + url = self.home_url + url + title_parts = [] + tag = article.find('div', {'class': 'abstract-article__tag'}) + if tag: title_parts.append(self.tag_to_string(tag).upper()) + title_parts.append(self.tag_to_string(article.find('div', {'class': 'abstract-article__title'}))) + article_title = ' \u2022 '.join(title_parts) + pubdate='' + description_parts = [] + author = article.find('div', {'class': 'abstract-article__author'}) + if author: description_parts.append(self.tag_to_string(author)) + summary = article.find('div', {'class': 'abstract-article__content'}) + if summary: description_parts.append(self.tag_to_string(summary)) + description = ' \u2022 '.join(description_parts) + return dict( + title=article_title, + url=url, + date=pubdate, + description=description, + content='' + ) + + def parse_index(self): + soup = self.index_to_soup(self.current_number_url) + self.cover_url = soup.find('span', { 'class': 'img_expand' })['data-src'] + main_container = soup.find('div', { 'class': 'content_data' }) + children = main_container.findAll('div', recursive=False) + sections = [] + current_section = None + for container in children: + if 'abstract-testatina' in container['class'] or 'abstract-testatina-cultura' in container['class']: + if current_section: + sections.append(current_section) + current_section = (self.tag_to_string(container), []) + continue + + if 'masonry-items' in container['class']: + for article in container.findAll('div', {'class': 'abstract-article'}): + current_section[1].append(self.extract_article(article)) + continue + + if 'abstract-article' in container['class']: + current_section[1].append(self.extract_article(container)) + continue + + # print(container['class']) + if current_section: + sections.append(current_section) + return sections + + def preprocess_html(self, soup): + for node in soup.findAll('figure'): + img_src = None + image_attributes = [ + 'data-media1024', + 'data-media1025', + 'data-media641', + 'data-media321', + 'data-media', + ] + for attr in image_attributes: + if node.has_attr(attr): + img_src = node[attr] + break + node.name = 'div' + if img_src: + img = soup.new_tag('img', src=img_src) + node.insert(0, img) + for node in soup.findAll('figcaption'): + node.name = 'div' + # if self.browser.cookiejar: + # self.browser.cookiejar.clear() + return soup + + def get_cover_url(self): + return self.cover_url \ No newline at end of file diff --git a/recipes/parool.png b/recipes/parool.png new file mode 100644 index 0000000000000000000000000000000000000000..ef1fd6252ff6088cf2db9850d6a610b62f890771 GIT binary patch literal 2625 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 literal 0 HcmV?d00001 diff --git a/recipes/parool.recipe b/recipes/parool.recipe new file mode 100644 index 0000000000..3a6bfa408a --- /dev/null +++ b/recipes/parool.recipe @@ -0,0 +1,96 @@ +#!/usr/bin/env python +from calibre.web.feeds.recipes import BasicNewsRecipe +import uuid +from mechanize import Request +from contextlib import closing +import json + +class Parool(BasicNewsRecipe): + title = 'Het Parool' + __author__ = 'Cristi Ghera' + max_articles_per_feed = 100 + description = 'Het Parool - Vrij, Onverveerd' + needs_subscription = False + language = 'nl' + country = 'NL' + category = 'news, politics, Netherlands' + resolve_internal_links = True + remove_tags_before = dict(id='main-content') + remove_tags_after = dict(id='main-content') + remove_tags = [ + dict(attrs={'class':['article-footer__sharing', 'artstyle__editorial-tips', 'artstyle__advertisement','artstyle__container__icon','artstyle__disabled-embed','container__title__icon',]}), + dict(attrs={'data-element-id': ['article-element-authors']}), + dict(name=['script', 'noscript', 'style']), + ] + remove_attributes = ["class", "id", "name", "style"] + encoding = 'utf-8' + no_stylesheets = True + ignore_duplicate_articles = {'url'} + + def parse_index(self): + soup = self.index_to_soup('https://www.parool.nl/privacy-wall/accept?redirectUri=%2Feditie%2Fvandaag%2F&authId=' + str(uuid.uuid4())) + containers = soup.findAll('section', attrs={'class': 'section--horizontal'}) + sections = [] + for container in containers: + section_title = self.tag_to_string(container.find('h2')).strip() + articles = [] + + for art in container.findAll('article'): + a = art.find('a') + url = a['href'] + if url[0] == '/': + url = 'https://www.parool.nl' + url + if '/editie/' not in url: + continue + header = a.find('header') + teaser_label = self.tag_to_string(header.find('h4').find('span', attrs={'class': 'teaser__label'})).strip() + teaser_sublabel = self.tag_to_string(header.find('h4').find('span', attrs={'class': 'teaser__sublabel'})).strip() + teaser_title = self.tag_to_string(header.find('h3').find('span', attrs={'class': 'teaser__title__value--short'})).strip() + ignore = { "dirkjan", "s1ngle", "pukkels", "hein de kort" } + if teaser_label.lower() in ignore: + continue + parts = [] + if teaser_label: + parts.append(teaser_label.upper()) + if teaser_sublabel: + parts.append(teaser_sublabel) + if teaser_title: + parts.append(teaser_title) + article_title = ' \u2022 '.join(parts) + articles.append(dict(title=article_title, + url=url, + content='')) + + sections.append((section_title, articles)) + return sections + + def preprocess_html(self, soup): + for tag in soup(): + if tag.name == 'img': + if tag['src'][0] == '/': + tag['src'] = 'https://www.parool.nl' + tag['src'] + for tag in soup(): + if tag.name == "picture": + tag.replaceWith(tag.find("img")) + comic_articles = { + "Alle strips van Dirkjan", + "S1NGLE", + "Pukkels", + "Bekijk hier alle cartoons van Hein de Kort", + } + if self.tag_to_string(soup.find('h1')).strip() in comic_articles: + for node in soup.find('figure').find_next_siblings(): + node.extract() + return soup + + def get_cover_url(self): + headers = { + 'X-Requested-With': 'XMLHttpRequest', + 'Accept': 'application/json, text/javascript, */*; q=0.01', + 'DNT': '1', + } + url = "https://login-api.e-pages.dk/v1/krant.parool.nl/folders" + with closing(self.browser.open(Request(url, None, headers))) as r: + folders = json.loads(r.read()) + return folders["objects"][0]["teaser_medium"] + return None \ No newline at end of file diff --git a/recipes/revista22.png b/recipes/revista22.png new file mode 100644 index 0000000000000000000000000000000000000000..8a6e568c750b0d4b6b5b24b9e9c4819fe075a947 GIT binary patch literal 3769 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 literal 0 HcmV?d00001 diff --git a/recipes/revista22.recipe b/recipes/revista22.recipe new file mode 100644 index 0000000000..6f91d2bc00 --- /dev/null +++ b/recipes/revista22.recipe @@ -0,0 +1,74 @@ +#!/usr/bin/env python +from calibre.web.feeds.recipes import BasicNewsRecipe + +class Volkskrant(BasicNewsRecipe): + title = 'Revista 22' + __author__ = 'Cristi Ghera' + max_articles_per_feed = 100 + description = 'Revista 22' + needs_subscription = False + language = 'ro' + country = 'RO' + category = 'news, politics, Romania' + resolve_internal_links = True + remove_tags_before = { 'class': 'col-span-8' } + remove_tags_after = { 'class': 'col-span-8' } + remove_tags = [ + dict( + attrs={ + 'class': [ + 'icons', + 'float-left', + 'samesection', + ] + } + ), + dict( + name=['div'], + attrs={ + 'class': ['mb-2'] + } + ), + dict(id=['comments']), + dict(name=['script', 'noscript', 'style']), + ] + remove_attributes = ["class", "id", "name", "style"] + encoding = 'utf-8' + no_stylesheets = True + ignore_duplicate_articles = {'url'} + + def parse_index(self): + soup = self.index_to_soup('https://revista22.ro') + url = soup.find('div', attrs={'class': 'uppercase'}).find('a').attrs['href'] + if url[0] == '/': + url = 'https://revista22.ro' + url + soup = self.index_to_soup(url) + main_container = soup.find('div', attrs={'class': 'col-span-8'}) + containers = main_container.findAll(attrs={'class': 'mb-4'}) + articles = [] + for container in containers: + if 'pb-4' not in container.attrs['class']: + continue + a = container.find('a') + url = a['href'] + if url[0] == '/': + url = 'https://revista22.ro' + url + article_title = self.tag_to_string(a.find('h3')).strip() + author = self.tag_to_string( + container.find('span', attrs={'class': 'text-red'}) + ).strip() + summary = self.tag_to_string(container.find('p')).strip() + pubdate = self.tag_to_string(a.find('span')) + description = author + ' - ' + summary + articles.append( + dict( + title=article_title, + url=url, + date=pubdate, + description=description, + content='' + ) + ) + + sections = [('Numărul curent', articles)] + return sections \ No newline at end of file diff --git a/recipes/volkskrant.png b/recipes/volkskrant.png new file mode 100644 index 0000000000000000000000000000000000000000..50a432ac8541969b4a042945d40365ef3f8822b4 GIT binary patch literal 11901 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