123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- # SPDX-License-Identifier: AGPL-3.0-or-later
- """SensCritique (movies)
- """
- from __future__ import annotations
- from json import dumps, loads
- from typing import Any, Optional
- from searx.result_types import EngineResults, MainResult
- 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) -> EngineResults:
- res = EngineResults()
- response_data = loads(resp.text)
- items = response_data.get('data', {}).get('searchProductExplorer', {}).get('items', [])
- if not items:
- return res
- for item in items:
- result = parse_item(item)
- if not result:
- continue
- res.add(result=result)
- return res
- def parse_item(item: dict[str, Any]) -> MainResult | None:
- """Parse a single item from the SensCritique API response"""
- title = item.get('title', '')
- if not title:
- return None
- year = item.get('yearOfProduction')
- original_title = item.get('originalTitle')
- thumbnail: str = ""
- 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']}"
- return MainResult(
- 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
|