This commit is contained in:
Robin Fourcade 2025-04-12 11:14:15 +02:00 committed by GitHub
commit 667d95fd46
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 150 additions and 0 deletions

View file

@ -0,0 +1,144 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""SensCritique (movies)
"""
from json import dumps, loads
from typing import Any, Optional
about = {
"website": 'https://www.senscritique.com/',
"wikidata_id": 'Q16676060',
"official_api_documentation": None,
"use_official_api": False,
"require_api_key": False,
"results": 'JSON',
'language': 'fr',
}
categories = ['movies']
paging = True
page_size = 16
graphql_url = 'https://apollo.senscritique.com/'
graphql_query = """query SearchProductExplorer($query: String, $offset: Int, $limit: Int,
$sortBy: SearchProductExplorerSort) {
searchProductExplorer(
query: $query
filters: []
sortBy: $sortBy
offset: $offset
limit: $limit
) {
items {
category
dateRelease
duration
id
originalTitle
rating
title
url
yearOfProduction
medias {
picture
}
countries {
name
}
genresInfos {
label
}
directors {
name
}
stats {
ratingCount
}
}
}
}"""
def request(query: str, params: dict[str, Any]) -> dict[str, Any]:
offset = (params['pageno'] - 1) * page_size
data = {
"operationName": "SearchProductExplorer",
"variables": {"offset": offset, "limit": page_size, "query": query, "sortBy": "RELEVANCE"},
"query": graphql_query,
}
params['url'] = graphql_url
params['method'] = 'POST'
params['headers']['Content-Type'] = 'application/json'
params['data'] = dumps(data)
return params
def response(resp: Any) -> list[dict[str, Any]]:
results = []
response_data = loads(resp.text)
items = response_data.get('data', {}).get('searchProductExplorer', {}).get('items', [])
if not items:
return results
for item in items:
results.append(parse_item(item))
return results
def parse_item(item: dict[str, Any]) -> dict[str, Any]:
"""Parse a single item from the SensCritique API response"""
title = item.get('title', '')
year = item.get('yearOfProduction')
original_title = item.get('originalTitle')
thumbnail = None
if item.get('medias', {}) and item['medias'].get('picture'):
thumbnail = item['medias']['picture']
content_parts = build_content_parts(item, title, original_title)
url = f"https://www.senscritique.com{item['url']}" if item.get('url') else None
return {
'url': url,
'title': title + (f' ({year})' if year else ''),
'content': ' | '.join(content_parts),
'thumbnail': thumbnail,
}
def build_content_parts(item: dict[str, Any], title: str, original_title: Optional[str]) -> list[str]:
"""Build the content parts for an item"""
content_parts = []
if item.get('category'):
content_parts.append(item['category'])
if original_title and original_title != title:
content_parts.append(f"Original title: {original_title}")
if item.get('directors'):
directors = [director['name'] for director in item['directors']]
content_parts.append(f"Director(s): {', '.join(directors)}")
if item.get('countries'):
countries = [country['name'] for country in item['countries']]
content_parts.append(f"Country: {', '.join(countries)}")
if item.get('genresInfos'):
genres = [genre['label'] for genre in item['genresInfos']]
content_parts.append(f"Genre(s): {', '.join(genres)}")
if item.get('duration'):
minutes = item['duration'] // 60
if minutes > 0:
content_parts.append(f"Duration: {minutes} min")
if item.get('rating') and item.get('stats', {}).get('ratingCount'):
content_parts.append(f"Rating: {item['rating']}/10 ({item['stats']['ratingCount']} votes)")
return content_parts

View file

@ -2642,6 +2642,12 @@ engines:
shortcut: pgo
disabled: true
- name: senscritique
engine: senscritique
shortcut: scr
timeout: 4.0
disabled: true
# Doku engine lets you access to any Doku wiki instance:
# A public one or a privete/corporate one.
# - name: ubuntuwiki