Soddisfatto Giacomo

This commit is contained in:
Nunzi99
2025-10-20 15:10:17 +02:00
parent e2125d5815
commit 6b71a5a553
5 changed files with 23 additions and 68 deletions

View File

@@ -2,6 +2,8 @@
# Infatti scegliamo l'immagine ufficiale di uv che ha già tutto configurato # Infatti scegliamo l'immagine ufficiale di uv che ha già tutto configurato
FROM ghcr.io/astral-sh/uv:python3.12-alpine FROM ghcr.io/astral-sh/uv:python3.12-alpine
RUN apk add --update npm
RUN npm install -g rettiwt-api
# Dopo aver definito la workdir mi trovo già in essa # Dopo aver definito la workdir mi trovo già in essa
WORKDIR /app WORKDIR /app

View File

@@ -38,7 +38,6 @@ dependencies = [
# API di social media # API di social media
"praw", # Reddit "praw", # Reddit
"docker", # Necessario per usare Rettiwt per X
] ]
[tool.pytest.ini_options] [tool.pytest.ini_options]

View File

@@ -43,97 +43,60 @@ class ChanWrapper(SocialWrapper):
if 'sticky' in thread: if 'sticky' in thread:
continue continue
else: else:
# print(thread)
# Otteniamo la data
time: str = thread['now'] time: str = thread['now']
# Otteniamo dalla data il mese (primi 2 caratteri)
month: str = time[:2] month: str = time[:2]
# Otteniamo dalla data il giorno (caratteri 4 e 5)
day: str = time[4:6] day: str = time[4:6]
# Otteniamo dalla data l'anno (caratteri 7 e 8)
year: str = time[7:9] year: str = time[7:9]
# Ricreiamo la data completa come dd/mm/yy
time: str = day + '/' + month + '/' + year time: str = day + '/' + month + '/' + year
# Otteniamo il nome dell'utente
name: str = thread['name'] name: str = thread['name']
# Proviamo a recuperare il titolo
try: try:
# Otteniamo il titolo del thread contenuto nella key "sub"
title: str = thread['sub'] title: str = thread['sub']
# Ripuliamo la stringa
# Decodifichiamo caratteri ed entità HTML
html_entities = html.unescape(title) html_entities = html.unescape(title)
# Rimuoviamo caratteri HTML
soup = BeautifulSoup(html_entities, 'html.parser') soup = BeautifulSoup(html_entities, 'html.parser')
title = soup.get_text(separator=" ") title = soup.get_text(separator=" ")
# Rimuoviamo backlash e doppi slash
title = re.sub(r"[\\/]+", "/", title) title = re.sub(r"[\\/]+", "/", title)
# Rimuoviamo spazi in piú
title = re.sub(r"\s+", " ", title).strip() title = re.sub(r"\s+", " ", title).strip()
# Aggiungiamo il nome dell'utente al titolo
title = name + " posted: " + title title = name + " posted: " + title
except: except:
title: str = name + " posted" title: str = name + " posted"
try: try:
# Otteniamo il commento del thread contenuto nella key "com"
thread_description: str = thread['com'] thread_description: str = thread['com']
# Ripuliamo la stringa
# Decodifichiamo caratteri ed entità HTML
html_entities = html.unescape(thread_description) html_entities = html.unescape(thread_description)
# Rimuoviamo caratteri HTML
soup = BeautifulSoup(html_entities, 'html.parser') soup = BeautifulSoup(html_entities, 'html.parser')
thread_description = soup.get_text(separator=" ") thread_description = soup.get_text(separator=" ")
# Rimuoviamo backlash e doppi slash
thread_description = re.sub(r"[\\/]+", "/", thread_description) thread_description = re.sub(r"[\\/]+", "/", thread_description)
# Rimuoviamo spazi in piú
thread_description = re.sub(r"\s+", " ", thread_description).strip() thread_description = re.sub(r"\s+", " ", thread_description).strip()
except: except:
thread_description = None thread_description = None
# Creiamo la lista delle risposte al thread
try: try:
response_list: list[dict] = thread['last_replies'] response_list: list[dict] = thread['last_replies']
except: except:
response_list: list[dict] = [] response_list: list[dict] = []
# Creiamo la lista che conterrà i commenti
comments_list: list[SocialComment] = [] comments_list: list[SocialComment] = []
# Otteniamo i primi 5 commenti # Otteniamo i primi 5 commenti
i = 0 i = 0
for response in response_list: for response in response_list:
# Otteniamo la data
time: str = response['now'] time: str = response['now']
# print(time)
# Otteniamo dalla data il mese (primi 2 caratteri)
month: str = time[:2] month: str = time[:2]
# Otteniamo dalla data il giorno (caratteri 4 e 5)
day: str = time[3:5] day: str = time[3:5]
# Otteniamo dalla data l'anno (caratteri 7 e 8)
year: str = time[6:8] year: str = time[6:8]
# Ricreiamo la data completa come dd/mm/yy
time: str = day + '/' + month + '/' + year time: str = day + '/' + month + '/' + year
try: try:
# Otteniamo il commento della risposta contenuto nella key "com"
comment_description: str = response['com'] comment_description: str = response['com']
# Ripuliamo la stringa
# Decodifichiamo caratteri ed entità HTML
html_entities = html.unescape(comment_description) html_entities = html.unescape(comment_description)
# Rimuoviamo caratteri HTML
soup = BeautifulSoup(html_entities, 'html.parser') soup = BeautifulSoup(html_entities, 'html.parser')
comment_description = soup.get_text(separator=" ") comment_description = soup.get_text(separator=" ")
# Rimuoviamo backlash e doppi slash
comment_description = re.sub(r"[\\/]+", "/", comment_description) comment_description = re.sub(r"[\\/]+", "/", comment_description)
# Rimuoviamo spazi in piú
comment_description = re.sub(r"\s+", " ", comment_description).strip() comment_description = re.sub(r"\s+", " ", comment_description).strip()
except: except:
comment_description = None comment_description = None
# Se la descrizione del commento non esiste, passiamo al commento successivo
if comment_description is None: if comment_description is None:
continue continue
else: else:
# Creiamo il SocialComment
social_comment: SocialComment = SocialComment( social_comment: SocialComment = SocialComment(
time=time, time=time,
description=comment_description description=comment_description
@@ -145,7 +108,6 @@ class ChanWrapper(SocialWrapper):
if thread_description is None: if thread_description is None:
continue continue
else: else:
# Creiamo il SocialPost
social_post: SocialPost = SocialPost( social_post: SocialPost = SocialPost(
time=time, time=time,
title=title, title=title,

View File

@@ -6,9 +6,10 @@ https://www.npmjs.com/package/rettiwt-api
''' '''
import os import os
import docker
import json import json
from .base import SocialWrapper, SocialPost, SocialComment from .base import SocialWrapper, SocialPost
from shutil import which
import subprocess
class XWrapper(SocialWrapper): class XWrapper(SocialWrapper):
def __init__(self): def __init__(self):
''' '''
@@ -26,10 +27,13 @@ class XWrapper(SocialWrapper):
] ]
self.api_key = os.getenv("X_API_KEY") self.api_key = os.getenv("X_API_KEY")
assert self.api_key, "X_API_KEY environment variable not set" assert self.api_key, "X_API_KEY environment variable not set"
'''
# Connection to the docker deamon # Connection to the docker deamon
self.client = docker.from_env() self.client = docker.from_env()
# Connect with the relative container # Connect with the relative container
self.container = self.client.containers.get("node_rettiwt") self.container = self.client.containers.get("node_rettiwt")
'''
assert which('rettiwt') is not None, "Command `rettiwt` not installed"
self.social_posts: list[SocialPost] = [] self.social_posts: list[SocialPost] = []
def get_top_crypto_posts(self, limit = 5) -> list[SocialPost]: #-> list[SocialPost]: def get_top_crypto_posts(self, limit = 5) -> list[SocialPost]: #-> list[SocialPost]:
''' '''
@@ -38,7 +42,8 @@ class XWrapper(SocialWrapper):
social_posts: list[SocialPost] = [] social_posts: list[SocialPost] = []
for user in self.users: for user in self.users:
# This currently doesn't work as intended since it returns the posts in random order # This currently doesn't work as intended since it returns the posts in random order
tweets = self.container.exec_run("rettiwt -k" + self.api_key + " tweet search -f " + str(user), tty=True) # tweets = self.container.exec_run("rettiwt -k" + self.api_key + " tweet search -f " + str(user), tty=True)
tweets = subprocess.run("rettiwt -k" + self.api_key + " tweet search -f " + str(user))
tweets = tweets.output.decode() tweets = tweets.output.decode()
tweets = json.loads(tweets) tweets = json.loads(tweets)
tweets: list[dict] = tweets['list'] tweets: list[dict] = tweets['list']

39
uv.lock generated
View File

@@ -377,6 +377,17 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/40/cd/ef820662e0d87f46b829bba7e2324c7978e0153692bbd2f08f7746049708/ddgs-9.6.0-py3-none-any.whl", hash = "sha256:24120f1b672fd3a28309db029e7038eb3054381730aea7a08d51bb909dd55520", size = 41558, upload-time = "2025-09-17T13:27:08.99Z" }, { url = "https://files.pythonhosted.org/packages/40/cd/ef820662e0d87f46b829bba7e2324c7978e0153692bbd2f08f7746049708/ddgs-9.6.0-py3-none-any.whl", hash = "sha256:24120f1b672fd3a28309db029e7038eb3054381730aea7a08d51bb909dd55520", size = 41558, upload-time = "2025-09-17T13:27:08.99Z" },
] ]
[[package]]
name = "deepseek"
version = "1.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "requests" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/04/7b/bede06edf1a25a6ab06553b15f6abf8e912848dfa5f68514720d3e388550/deepseek-1.0.0-py3-none-any.whl", hash = "sha256:ee4175bfcb7ac1154369dbd86a4d8bc1809f6fa20e3e7baa362544567197cb3f", size = 4542, upload-time = "2025-01-03T08:06:23.887Z" },
]
[[package]] [[package]]
name = "distro" name = "distro"
version = "1.9.0" version = "1.9.0"
@@ -395,20 +406,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" },
] ]
[[package]]
name = "docker"
version = "7.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pywin32", marker = "sys_platform == 'win32'" },
{ name = "requests" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/91/9b/4a2ea29aeba62471211598dac5d96825bb49348fa07e906ea930394a83ce/docker-7.1.0.tar.gz", hash = "sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c", size = 117834, upload-time = "2024-05-23T11:13:57.216Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl", hash = "sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0", size = 147774, upload-time = "2024-05-23T11:13:55.01Z" },
]
[[package]] [[package]]
name = "docstring-parser" name = "docstring-parser"
version = "0.17.0" version = "0.17.0"
@@ -1360,16 +1357,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" },
] ]
[[package]]
name = "pywin32"
version = "311"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload-time = "2025-07-14T20:13:20.765Z" },
{ url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload-time = "2025-07-14T20:13:22.543Z" },
{ url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload-time = "2025-07-14T20:13:24.682Z" },
]
[[package]] [[package]]
name = "pyyaml" name = "pyyaml"
version = "6.0.3" version = "6.0.3"
@@ -1677,7 +1664,7 @@ dependencies = [
{ name = "agno" }, { name = "agno" },
{ name = "coinbase-advanced-py" }, { name = "coinbase-advanced-py" },
{ name = "ddgs" }, { name = "ddgs" },
{ name = "docker" }, { name = "deepseek" },
{ name = "dotenv" }, { name = "dotenv" },
{ name = "gnews" }, { name = "gnews" },
{ name = "google-genai" }, { name = "google-genai" },
@@ -1696,7 +1683,7 @@ requires-dist = [
{ name = "agno" }, { name = "agno" },
{ name = "coinbase-advanced-py" }, { name = "coinbase-advanced-py" },
{ name = "ddgs" }, { name = "ddgs" },
{ name = "docker" }, { name = "deepseek" },
{ name = "dotenv" }, { name = "dotenv" },
{ name = "gnews" }, { name = "gnews" },
{ name = "google-genai" }, { name = "google-genai" },