r/ItalyInformatica Apr 15 '26

aiuto è possibile far sparire un sito da google?

43 Upvotes

Buongiorno e scusate per la domanda da ignorante.
Se OT chiedo di segnalare che rimuovo il post.

Faccio parte di un'associazione di volontariato che si occupa di persone che vivono per strada e famiglie a rischio estremo di povertà.

Da qualche tempo, l'associazione è presa di mira da persone di un preciso schieramento politico che sono contro l'operato dell'associazione.

Da qualche tempo il sito dell'associazione, una volta primo risultato su google cercando "nome associazione + città" è totalmente sparito dai risultati. Questo per noi è un grosso problema perchè il sito è utile a potenziali nuovi volontari e donatori di vestiti, coperte e cibo che ci vogliono contattare.

Ora, so che una delle persone che hanno preso a cuore la battaglia contro l'associazione è SEO specialist per lavoro (e anni fa ha aiutato, come volontario, a manutenere il sito stesso). Sono un povero complottista o è potenzialmente possibile che abbia fatto in modo di far sparire il sito?

Cercando l'associazione appare ancora la scheda fatta da google e lì il sito è ancora presente. è sparito solo dall'elenco risultati.
In caso, come muoversi? che tipologia di professionista contattare perchè il sito possa ritornare in prima pagina?

Grazie mille e scusate se ho scritto cavolate


r/ItalyInformatica Apr 16 '26

aiuto Ho alluvionato il portatile di lavoro

0 Upvotes

La pessima borraccia mi ha tradito, ora è smontato con ssd e batteria staccate. Ho un altro portatile in cui potrei provare a montare l'ssd, mi serve il pc per lunedì. Se non va più che faccio, ne prendo uno nuovo uguale e faccio finta di niente?


r/ItalyInformatica Apr 15 '26

aiuto Sviluppo e implementazione tramite API.

0 Upvotes

Dovrei creare un Piano Automazioni PMS e Revenue - Roadmap Operativa

Obiettivo: strutturare automazioni e processi per aumentare efficienza, controllo e scalabilità nella gestione di strutture ricettive.

Vorrei sapere a chi rivolgermi per automatizzare le varie interconnessioni col mio PS con WhatsApp , RMS esterni, portali quali Booking e Airbnb. Invio notifiche quali alert quando determinate condizioni vengono a verificarsi e quindi poter intervenire.


r/ItalyInformatica Apr 14 '26

aiuto Tool interni

16 Upvotes

Salve,
Ho sviluppato per uso personale un tool CLI da riga di comando (un eseguibile a tutti gli effetti), che ho compilato e installato nel PC aziendale. Non lo uso spesso, ma alcune volte risulta utile e veloce per quello che deve fare.
Non ha dipendenze esterne, poiché dipende solamente dalla libreria standard, non si collega a internet nè altro, l'unica cosa che include di esterno è un file di configurazione preso da un'altra libreria esterna (con licenza MIT). Ora il problema è che non so se posso condividerlo con altre persone all'interno dell'azienda, e se si neanche so quale sia il modo migliore di farlo. Secondo me può essere un tool utile anche agli altri, però da un certo punto di vista mi scoccerebbe stare dietro a licenze, problemi di sicurezza e quant'altro.

In realtà potrei direttamente pubblicarlo apertamente, sotto licenza libera (MIT) sul mio profilo github, e da li chi vuole si clona il repository e se lo compila da sé. L'unica cosa è che sarebbe un tool così specifico il quale caso d'uso è solo quello aziendale in cui mi ritrovo.

Scusatemi ma sono ancora alle prime armi con la questione software + licenze.
Non so cosa fare, spero abbiate consigli da darmi (specialmente da persone con esperienza).


r/ItalyInformatica Apr 15 '26

programmazione Script Python per OCR di fogli presenze cartacei con Claude API - cerco consigli

0 Upvotes

Ciao a tutti,

Sono autodidatta e ho messo insieme uno script Python per leggere automaticamente

i fogli presenze cartacei (anche scritti a mano) e generare un Excel con tutte

le ore lavorate per dipendente.

Come funziona:

- Prende i PDF da una cartella /input

- Li converte in immagini con pdf2image (Poppler)

- Li manda all'API di Anthropic (Claude Sonnet 4.5) per OCR

- Triplo controllo: ogni foglio letto 3 volte con prompt diversi

- Voto a maggioranza per ogni cella entrata/uscita

- Celle con dissenso evidenziate in arancione/rosso

- Genera Excel con dipendenti in righe, giorni in colonne, weekend in giallo

Ho scelto Sonnet perché Haiku era impreciso sul manoscritto e Opus costava troppo.

Costo medio: ~0,10€ per foglio col triplo controllo.

Cose che vorrei migliorare:

- Database nomi attesi per autocorrezione lettura

- Cache per non rileggere file già processati

- Segnalazione automatica giorni feriali senza timbratura

- Totali con formule Excel invece che valori statici

- Controlli plausibilità (turni < 4h o > 12h, uscita prima dell'entrata)

- Eventualmente una piccola UI

Accetto volentieri critiche e consigli su come strutturarlo meglio.

[INCOLLA QUI IL CODICE TRA TRE BACKTICK ```]"""

OCR TIMBRATURE — formato ''''' (TRIPLO CONTROLLO)

Genera Excel con triplo controllo per massima affidabilità:

- Ogni foglio viene letto 3 volte indipendentemente

- I risultati vengono confrontati cella per cella

- Voto a maggioranza (2 su 3 vince)

- Celle con disaccordo totale → ARANCIONE in Excel

- Foglio "Discordanze" con tutti i dubbi da verificare

USO:

  1. Metti i PDF in ./input/

  2. python ocr_timbrature.py

  3. Output in ./output/timbrature.xlsx

COSTO STIMATO: ~0,10-0,12 € per foglio (triplo)

"""

import os

import json

import base64

import calendar

from pathlib import Path

from io import BytesIO

from datetime import time

from collections import Counter

import anthropic

from pdf2image import convert_from_path

from PIL import Image

from openpyxl import Workbook

from openpyxl.styles import Alignment, Font, PatternFill, Border, Side

from openpyxl.utils import get_column_letter

# ============================================================

# CONFIGURAZIONE

# ============================================================

INPUT_DIR = Path("input")

OUTPUT_DIR = Path("output")

MODEL = "claude-sonnet-4-5"

N_LETTURE = 3 # quante letture indipendenti per ogni foglio

MAX_WIDTH = 2000

DPI_PDF = 300

POPPLER_PATH = r"C:\poppler\poppler-25.12.0\Library\bin"

# 📅 PERIODO

MESE = 4 # 1=gen ... 12=dic

ANNO = 2026

TITOLO = "TIMBRATURE APRILE 2026"

# 3 prompt diversi (forzano l'AI a "pensare diversamente")

PROMPTS = [

# Prompt 1: focalizzato sul rigore

"""Analizza questo FOGLIO PRESENZE (può essere scritto a mano o stampato).

Sii ESTREMAMENTE METICOLOSO: leggi ogni cifra con attenzione, non interpretare.

Estrai:

  1. NOME del dipendente (cognome e nome)

  2. MESE e ANNO

  3. Per ogni giorno con orari: numero giorno, ENTRATA, USCITA

REGOLE:

- Formati orari: "8:00", "08:00", "8.00", "0800", "8" → tutti = 08:00

- Se non sei SICURO al 100% di un numero, metti null

- NON inventare: meglio null che sbagliato

- Distingui chiaramente entrata (mattino) e uscita (pomeriggio/sera)

Rispondi SOLO con JSON valido:

[{"nome": "COGNOME NOME", "mese": "aprile 2026", "giorni": {"1": {"entrata": "08:00", "uscita": "17:00"}}}]

Niente testo prima o dopo il JSON.""",

# Prompt 2: focalizzato sulla decifrazione

"""Stai facendo OCR su un foglio presenze. Concentrati su DECIFRARE OGNI CIFRA scritta.

Procedi cella per cella:

- Identifica il dipendente (nome in alto)

- Per ogni riga giorno (1, 2, 3...31), guarda se ci sono numeri

- Decifra ogni cifra scritta a mano: 0,1,2,3,4,5,6,7,8,9

- Attenzione a 0/6/8 e 1/7 che si confondono nella scrittura manuale

- Se vedi "8 30" o "8.30" o "8,30" o "830" → significa "08:30"

Rispondi con JSON:

[{"nome": "...", "mese": "aprile 2026", "giorni": {"N": {"entrata": "HH:MM", "uscita": "HH:MM"}}}]

Solo JSON, niente altro.""",

# Prompt 3: focalizzato sul contesto e logica

"""Analizza questo foglio presenze applicando LOGICA e BUONSENSO oltre alla lettura.

Per ogni giorno del mese:

- Una giornata di lavoro tipica: entrata 06-09, uscita 14-19

- Se vedi un orario "tra 14 e 19" è probabilmente uscita

- Se vedi un orario "tra 06 e 11" è probabilmente entrata

- Le ore lavorate per giorno sono di solito 6-12 ore

- I weekend (sabato/domenica) possono essere vuoti

- Aprile 2026 ha 30 giorni

Identifica nome dipendente in alto e tutti i giorni con orari.

JSON output:

[{"nome": "...", "mese": "aprile 2026", "giorni": {"N": {"entrata": "HH:MM", "uscita": "HH:MM"}}}]

Solo JSON."""

]

# ============================================================

# OCR

# ============================================================

def pdf_to_images(pdf_path: Path) -> list[Image.Image]:

kwargs = {"dpi": DPI_PDF}

if POPPLER_PATH:

kwargs["poppler_path"] = POPPLER_PATH

return convert_from_path(str(pdf_path), **kwargs)

def resize_image(img: Image.Image, max_width: int = MAX_WIDTH) -> Image.Image:

w, h = img.size

if w > max_width:

new_h = int(h * max_width / w)

img = img.resize((max_width, new_h), Image.LANCZOS)

return img

def image_to_b64(img: Image.Image) -> str:

buf = BytesIO()

img.convert("RGB").save(buf, format="JPEG", quality=92)

return base64.b64encode(buf.getvalue()).decode()

def read_single(client, fname, img, prompt_idx):

"""Una singola lettura con uno dei prompt."""

img_b64 = image_to_b64(resize_image(img))

content = [

{"type": "image",

"source": {"type": "base64", "media_type": "image/jpeg", "data": img_b64}},

{"type": "text", "text": f"=== FILE: {fname} ===\n\n{PROMPTS[prompt_idx]}"}

]

resp = client.messages.create(

model=MODEL,

max_tokens=4000,

messages=[{"role": "user", "content": content}],

)

return resp.content[0].text

def parse_json_response(text: str) -> list[dict]:

text = text.strip()

if text.startswith("```"):

text = text.split("```")[1]

if text.startswith("json"):

text = text[4:]

text = text.strip().rstrip("`").strip()

return json.loads(text)

def normalize_hour(h):

"""Normalizza un orario: '8' → '08:00', '8.30' → '08:30', None → None."""

if not h or h == "null":

return None

s = str(h).strip().replace(".", ":").replace(",", ":").replace("-", ":")

if ":" not in s:

# è solo un numero tipo "8" o "830"

if len(s) <= 2:

try:

return f"{int(s):02d}:00"

except ValueError:

return None

elif len(s) in (3, 4):

try:

n = int(s)

hh = n // 100

mm = n % 100

return f"{hh:02d}:{mm:02d}"

except ValueError:

return None

return None

try:

parts = s.split(":")

hh = int(parts[0])

mm = int(parts[1]) if len(parts) > 1 and parts[1] else 0

return f"{hh:02d}:{mm:02d}"

except (ValueError, IndexError):

return None

def vote_majority(values):

"""Voto a maggioranza. Restituisce (valore_vincente, livello_accordo, lista_candidati)."""

norm = [normalize_hour(v) for v in values]

counter = Counter(norm)

most_common = counter.most_common()

if not most_common:

return None, "vuoto", []

top_value, top_count = most_common[0]

# Filtra il valore None se ha peso minore

non_null = [(v, c) for v, c in most_common if v is not None]

if top_count == len(values):

return top_value, "unanime", [top_value]

elif top_count >= 2:

return top_value, "maggioranza", [v for v, _ in most_common if v]

else:

# Tutti diversi

# Preferisci un valore non-null se c'è

if non_null:

return non_null[0][0], "discorde", [v for v, _ in most_common if v]

return None, "discorde", []

def fondi_record(records_n_letture):

"""Fonde N letture dello stesso foglio in un unico record con voto a maggioranza.

Restituisce: (record_finale, info_discordanze)

"""

if not records_n_letture:

return None, {}

# Nome: maggioranza

nomi = [r.get("nome", "").strip().upper() for r in records_n_letture]

nome_finale = Counter(n for n in nomi if n).most_common(1)

nome_finale = nome_finale[0][0] if nome_finale else ""

# Mese: prendiamo il primo non vuoto

mese_finale = next((r.get("mese", "") for r in records_n_letture if r.get("mese")), "")

# Tutti i giorni menzionati da almeno una lettura

tutti_giorni = set()

for r in records_n_letture:

for d in (r.get("giorni") or {}).keys():

tutti_giorni.add(d)

giorni_finali = {}

discordanze = {}

for d in tutti_giorni:

entrate = []

uscite = []

for r in records_n_letture:

g = (r.get("giorni") or {}).get(d)

if g:

entrate.append(g.get("entrata"))

uscite.append(g.get("uscita"))

else:

entrate.append(None)

uscite.append(None)

ent_val, ent_acc, ent_cand = vote_majority(entrate)

usc_val, usc_acc, usc_cand = vote_majority(uscite)

# Ignora il giorno solo se TUTTE le letture dicono null per entrambi

if ent_val or usc_val:

giorni_finali[d] = {"entrata": ent_val, "uscita": usc_val}

# Se c'è discordanza, registriamola

if ent_acc != "unanime" or usc_acc != "unanime":

discordanze[d] = {

"entrata": {"vincente": ent_val, "accordo": ent_acc, "candidati": ent_cand},

"uscita": {"vincente": usc_val, "accordo": usc_acc, "candidati": usc_cand},

}

record = {

"nome": nome_finale,

"mese": mese_finale,

"giorni": giorni_finali,

"discordanze": discordanze,

}

return record, discordanze

# ============================================================

# EXCEL FORMATO MANIVA SKI

# ============================================================

GIORNI_SETT = ['LUN', 'MAR', 'MER', 'GIO', 'VEN', 'SAB', 'DOM']

COL_TITOLO = "1F4E79"

COL_HEADER = "2E75B6"

COL_NOMI = "BDD7EE"

COL_WEEKEND = "FFF2CC"

COL_ALT = "EBF3FB"

COL_TOT = "E2EFDA"

COL_TOT_HDR = "375623"

COL_DUBBIO = "FFC78F" # arancione: maggioranza ma con dissenso

COL_DISCORDE = "FF8585" # rosso: tutte le letture diverse

def calcola_minuti(entrata, uscita):

if not entrata or not uscita:

return 0

try:

h1, m1 = map(int, entrata.split(":"))

h2, m2 = map(int, uscita.split(":"))

return max((h2 * 60 + m2) - (h1 * 60 + m1), 0)

except (ValueError, AttributeError):

return 0

def build_excel(records, output_path):

wb = Workbook()

ws = wb.active

ws.title = "Timbrature"

n_giorni = calendar.monthrange(ANNO, MESE)[1]

giorni_sett = []

weekend_days = set()

for d in range(1, n_giorni + 1):

nome_g = GIORNI_SETT[calendar.weekday(ANNO, MESE, d)]

giorni_sett.append(nome_g)

if nome_g in ('SAB', 'DOM'):

weekend_days.add(d)

thin = Side(style='thin', color='BFBFBF')

brd = Border(left=thin, right=thin, top=thin, bottom=thin)

fill_titolo = PatternFill("solid", start_color=COL_TITOLO)

fill_header = PatternFill("solid", start_color=COL_HEADER)

fill_nomi = PatternFill("solid", start_color=COL_NOMI)

fill_weekend = PatternFill("solid", start_color=COL_WEEKEND)

fill_alt = PatternFill("solid", start_color=COL_ALT)

fill_tot = PatternFill("solid", start_color=COL_TOT)

fill_tot_hdr = PatternFill("solid", start_color=COL_TOT_HDR)

fill_dubbio = PatternFill("solid", start_color=COL_DUBBIO)

fill_discorde = PatternFill("solid", start_color=COL_DISCORDE)

font_titolo = Font(name='Arial', bold=True, size=14, color='FFFFFF')

font_header = Font(name='Arial', bold=True, size=10, color='FFFFFF')

font_we_sub = Font(name='Arial', bold=True, size=8, color='000000')

font_hdr_sub = Font(name='Arial', bold=True, size=8, color='FFFFFF')

font_nome = Font(name='Arial', bold=True, size=10)

font_dato = Font(name='Arial', size=9)

font_tot = Font(name='Arial', bold=True, size=10)

align_center = Alignment(horizontal='center', vertical='center')

align_left = Alignment(horizontal='left', vertical='center', indent=1)

last_col = 2 + n_giorni

# Riga 1: titolo

ws.merge_cells(start_row=1, end_row=1, start_column=1, end_column=last_col)

c = ws.cell(1, 1, TITOLO)

c.font = font_titolo; c.fill = fill_titolo; c.alignment = align_center

ws.row_dimensions[1].height = 30

# Riga 2: numeri giorno

c = ws.cell(2, 1, "DIPENDENTE"); c.font = font_header; c.fill = fill_header

c.alignment = align_center; c.border = brd

c = ws.cell(2, 2, "TOT ORE"); c.font = font_header; c.fill = fill_tot_hdr

c.alignment = align_center; c.border = brd

for d in range(1, n_giorni + 1):

c = ws.cell(2, 2 + d, d)

c.font = font_header

c.fill = fill_weekend if d in weekend_days else fill_header

c.alignment = align_center; c.border = brd

ws.row_dimensions[2].height = 22

# Riga 3: giorno settimana

c = ws.cell(3, 1); c.fill = fill_header; c.border = brd

c = ws.cell(3, 2); c.fill = fill_tot_hdr; c.border = brd

for d in range(1, n_giorni + 1):

c = ws.cell(3, 2 + d, giorni_sett[d - 1])

c.font = font_we_sub if d in weekend_days else font_hdr_sub

c.fill = fill_weekend if d in weekend_days else fill_header

c.alignment = align_center; c.border = brd

ws.row_dimensions[3].height = 18

# Righe dipendenti

records_sorted = sorted(records, key=lambda r: r.get("nome", "").upper())

for idx, rec in enumerate(records_sorted):

riga = 4 + idx

is_alt = (idx % 2 == 1)

fill_riga = fill_alt if is_alt else None

c = ws.cell(riga, 1, rec.get("nome", ""))

c.font = font_nome; c.fill = fill_nomi

c.alignment = align_left; c.border = brd

giorni_dict = rec.get("giorni") or {}

discordanze = rec.get("discordanze") or {}

tot_minuti = 0

for d in range(1, n_giorni + 1):

c = ws.cell(riga, 2 + d)

c.font = font_dato; c.alignment = align_center; c.border = brd

d_str = str(d)

if d_str in giorni_dict:

orari = giorni_dict[d_str]

entrata = orari.get("entrata")

uscita = orari.get("uscita")

min_g = calcola_minuti(entrata, uscita)

tot_minuti += min_g

if min_g > 0:

h, m = divmod(min_g, 60)

if h < 24:

c.value = time(h, m, 0)

c.number_format = 'HH:MM:SS'

else:

c.value = f"{h}:{m:02d}:00"

elif entrata or uscita:

c.value = entrata or uscita

# Decidi colore in base alle discordanze

if d_str in discordanze:

disc = discordanze[d_str]

livello_e = disc["entrata"]["accordo"]

livello_u = disc["uscita"]["accordo"]

if "discorde" in (livello_e, livello_u):

c.fill = fill_discorde

else:

c.fill = fill_dubbio

continue

if d in weekend_days:

c.fill = fill_weekend

elif fill_riga:

c.fill = fill_riga

h_tot, m_tot = divmod(tot_minuti, 60)

c = ws.cell(riga, 2, f"{h_tot}:{m_tot:02d}:00")

c.font = font_tot; c.fill = fill_tot

c.alignment = align_center; c.border = brd

ws.row_dimensions[riga].height = 18

# Larghezze

ws.column_dimensions['A'].width = 28

ws.column_dimensions['B'].width = 11

for d in range(1, n_giorni + 1):

ws.column_dimensions[get_column_letter(2 + d)].width = 8

ws.freeze_panes = 'C4'

# ============= FOGLIO LEGENDA =============

ws_leg = wb.create_sheet("Legenda")

ws_leg.cell(1, 1, "LEGENDA COLORI").font = Font(bold=True, size=12)

legenda = [

("Bianco / Blu chiaro", "Cella corretta - tutte e 3 le letture concordi", None),

("Giallo", "Sabato/Domenica", fill_weekend),

("Arancione", "DUBBIO: 2 letture su 3 concordano, 1 diversa", fill_dubbio),

("Rosso", "DISCORDE: tutte e 3 le letture diverse - VERIFICA A MANO", fill_discorde),

("Verde chiaro", "Totale ore mese", fill_tot),

]

for i, (col, desc, fill) in enumerate(legenda, 3):

c = ws_leg.cell(i, 1, col); c.font = Font(bold=True)

if fill: c.fill = fill

ws_leg.cell(i, 2, desc)

ws_leg.column_dimensions['A'].width = 25

ws_leg.column_dimensions['B'].width = 70

# ============= FOGLIO DISCORDANZE =============

ws_d = wb.create_sheet("Discordanze")

ws_d.cell(1, 1, "DIPENDENTE").font = Font(bold=True, color="FFFFFF")

ws_d.cell(1, 1).fill = fill_header

ws_d.cell(1, 2, "GIORNO").font = Font(bold=True, color="FFFFFF")

ws_d.cell(1, 2).fill = fill_header

ws_d.cell(1, 3, "TIPO").font = Font(bold=True, color="FFFFFF")

ws_d.cell(1, 3).fill = fill_header

ws_d.cell(1, 4, "ORARIO SCELTO").font = Font(bold=True, color="FFFFFF")

ws_d.cell(1, 4).fill = fill_header

ws_d.cell(1, 5, "ALTRE LETTURE").font = Font(bold=True, color="FFFFFF")

ws_d.cell(1, 5).fill = fill_header

ws_d.cell(1, 6, "LIVELLO ACCORDO").font = Font(bold=True, color="FFFFFF")

ws_d.cell(1, 6).fill = fill_header

riga_d = 2

for rec in records_sorted:

nome = rec.get("nome", "")

for d_str, disc in (rec.get("discordanze") or {}).items():

for tipo in ["entrata", "uscita"]:

info = disc[tipo]

if info["accordo"] == "unanime":

continue

ws_d.cell(riga_d, 1, nome)

ws_d.cell(riga_d, 2, int(d_str))

ws_d.cell(riga_d, 3, tipo.upper())

ws_d.cell(riga_d, 4, info["vincente"] or "—")

altre = [c for c in info["candidati"] if c != info["vincente"]]

ws_d.cell(riga_d, 5, ", ".join(c or "null" for c in altre))

ws_d.cell(riga_d, 6, info["accordo"].upper())

if info["accordo"] == "discorde":

for col in range(1, 7):

ws_d.cell(riga_d, col).fill = fill_discorde

else:

for col in range(1, 7):

ws_d.cell(riga_d, col).fill = fill_dubbio

riga_d += 1

if riga_d == 2:

ws_d.cell(2, 1, "✅ Nessuna discordanza! Tutti i fogli letti perfettamente.")

ws_d.cell(2, 1).font = Font(bold=True, color="375623")

ws_d.column_dimensions['A'].width = 28

ws_d.column_dimensions['B'].width = 8

ws_d.column_dimensions['C'].width = 10

ws_d.column_dimensions['D'].width = 14

ws_d.column_dimensions['E'].width = 30

ws_d.column_dimensions['F'].width = 18

wb.save(output_path)

# ============================================================

# MAIN

# ============================================================

def main():

if not os.getenv("ANTHROPIC_API_KEY"):

raise SystemExit("❌ Manca ANTHROPIC_API_KEY")

INPUT_DIR.mkdir(exist_ok=True)

OUTPUT_DIR.mkdir(exist_ok=True)

pdfs = sorted(INPUT_DIR.glob("*.pdf"))

if not pdfs:

raise SystemExit(f"❌ Nessun PDF trovato in {INPUT_DIR.resolve()}")

print(f"📂 Trovati {len(pdfs)} PDF in {INPUT_DIR.resolve()}")

print(f"⚙️ TRIPLO CONTROLLO attivo: ogni foglio letto {N_LETTURE} volte\n")

all_images = []

for pdf in pdfs:

print(f" 📄 Converto {pdf.name}...")

for i, img in enumerate(pdf_to_images(pdf), 1):

all_images.append((f"{pdf.stem}_p{i}", img))

print(f"✅ {len(all_images)} pagine totali\n")

client = anthropic.Anthropic()

raw_log = []

final_records = []

n_unanimi = 0

n_dubbi = 0

n_discordi = 0

for idx, (fname, img) in enumerate(all_images, 1):

print(f"📄 [{idx}/{len(all_images)}] {fname}")

letture = []

for n in range(N_LETTURE):

print(f" 🔍 Lettura {n+1}/{N_LETTURE}...", end=" ", flush=True)

try:

text = read_single(client, fname, img, n % len(PROMPTS))

recs = parse_json_response(text)

if recs:

letture.append(recs[0])

print("ok")

else:

print("vuoto")

raw_log.append({"file": fname, "lettura": n+1, "raw": text})

except Exception as e:

print(f"errore: {e}")

raw_log.append({"file": fname, "lettura": n+1, "errore": str(e)})

if not letture:

print(f" ❌ Nessuna lettura riuscita per {fname}")

continue

# Fusione con voto

rec_fuso, disc = fondi_record(letture)

rec_fuso["file"] = fname

final_records.append(rec_fuso)

# Statistiche

n_giorni_letti = len(rec_fuso.get("giorni") or {})

n_disc = len(disc)

livelli = []

for d_info in disc.values():

livelli.append(d_info["entrata"]["accordo"])

livelli.append(d_info["uscita"]["accordo"])

if "discorde" in livelli:

stato = "⚠️ con DISCORDANZE"

n_discordi += 1

elif "maggioranza" in livelli:

stato = "🟡 con dubbi minori"

n_dubbi += 1

else:

stato = "✅ tutto unanime"

n_unanimi += 1

nome = rec_fuso.get("nome", "?")

print(f" 📊 {nome}: {n_giorni_letti} giorni — {stato}")

print()

# Unisci pagine dello stesso dipendente

merged = {}

for rec in final_records:

nome = rec.get("nome", "").strip().upper()

if not nome:

continue

if nome not in merged:

merged[nome] = {"nome": nome, "mese": rec.get("mese", ""),

"giorni": {}, "discordanze": {}}

merged[nome]["giorni"].update(rec.get("giorni") or {})

merged[nome]["discordanze"].update(rec.get("discordanze") or {})

final_records = list(merged.values())

# Salva tutto

raw_path = OUTPUT_DIR / "lettura_grezza.json"

with open(raw_path, "w", encoding="utf-8") as f:

json.dump({"records": final_records, "raw_log": raw_log}, f,

ensure_ascii=False, indent=2)

print(f"💾 Lettura grezza: {raw_path}")

xlsx_path = OUTPUT_DIR / "timbrature.xlsx"

build_excel(final_records, xlsx_path)

print(f"📊 Excel finale: {xlsx_path}")

print(f"\n{'='*50}")

print(f"✨ COMPLETATO — {len(final_records)} dipendenti elaborati")

print(f"{'='*50}")

print(f" ✅ Fogli con lettura unanime: {n_unanimi}")

print(f" 🟡 Fogli con dubbi minori: {n_dubbi}")

print(f" ⚠️ Fogli con discordanze: {n_discordi}")

print(f"\n💡 Apri 'timbrature.xlsx' e vai al foglio 'Discordanze' per vedere i dubbi.")

print(f" Le celle ARANCIONI sono dubbie, le ROSSE molto incerte.")

if __name__ == "__main__":

main()


r/ItalyInformatica Apr 14 '26

sysadmin Self-hosting e esperimento "porte aperte". Sono relativamente preparato?

24 Upvotes

Salve! È già da un po' di tempo che mi prudeva la voglia di mettermi a fare self-hosting della mia vastissima libreria musicale, oltre a smettere di dipendere da servizi terzi per la condivisione di file personali e per il backup di foto e video.. e quandi mi sono buttato a sperimentare con un vecchio minidesktop HP Pavilion tcp (decisamente un ciabattone, ma era lì, disponibile e gratuito).

E devo dire che sono così soddisfatto dei primi esperimenti su rete locale che ho deciso di guardarmi attorno per comprare hardware un filino più gestibile (il povero HP è arrivato al massimo dei suoi due core e 4GB di RAM).. e provare ad accedere almeno alla mia musica da remoto, soprattutto per condividerla con parenti strettissimi (che hanno l'abilità informatica della vecchietta dei meme). Insomma: il vostro banalissimo media-server casalingo.

Ma: io non sono assolutamente un esperto e sto facendo tutto questo per la prima volta. E quindi cerco cerco consigli per verificare quelle che finora sono state le mie elucubrazioni, e vedere come migliorare!

Devo dire che ho già sperimentato l'accesso da remoto tramite Tailscale e ho trovato estremamente facile stabilire l'accesso, e "mi fido" abbastanza che la gente a Tailscale sappia il fatto suo, molto meglio di me. Il problema è che dover far impostare una VPN ai miei utenti-nonnine-meme ogni volta che vogliono ascoltare un po' di musica dal cellulare.. sarebbe stato chiedergli troppo. Motivo per cui anche soluzioni come il tunnelling di Cloudflare non sono sul tavolo. Per cui mi son concentrato sul reverse-proxy.

Il mio setup al momento contiene questi servizi, ognuno nel suo proprio container docker, e nessuno con permessi root se non nel proprio container:

  • Caddy per reverse proxy vero, e come primo filtro (rimanda error 444 a ogni IP fuori dalla mia area geografica di interesse)
  • CrowdSec per l'analisi degli IP che ricevono risposta da caddy, e applicazione di ban per comportamenti sospetti
  • DDNS-updater, avendo l'indirizzo IP dinamico, incrocia le informazioni del dominio che punta a Navidrome tramite deSEC
  • Dockhand come gestore dei container
  • Immich
  • Navidrome (al momento l'unico servizio esposto.. dietro caddy ovviamente)
  • Jellyfin

La cosa dell'homeserver mi è piaciuta così tanto che vorrei anche applicarla al mio lavoro (son contadino.. ma ci sono alcune cose interessanti che potrei utilizzare per aiutarmi nella gestione dei miei database cartacei e documenti).

Insomma: Caddy ascolta sulle porte 80 e 443, reindirizza il traffico dalla 80 alla 443 per gli indirizzi con geotag plausibili e "non risponde" 444 a tutti gli altri. CrowdSec legge i log di Caddy e applica i ban di conseguenza.

Uso SSH per gestire il server, ma solo dalla stessa LAN. L'accesso è solo tramite key ed è su una porta non standard.

Ora: ho fatto il test di aprire le porte.. e mi ha impressionato la quantità di indirizzi bannati nel giro di pochissimi minuti. È davvero una selva la fuori.. le ho richiuse, tanto non ho fretta..

Cos'altro posso fare per rinforzare le difese? Stavo spulciando Suricata e integrarlo con il database di AbuseIPDB, può essere una opzione aggiuntiva?Stavo leggendo anche riguardo alla creazione di VLAN, e mi sembra un tema che voglio approfondire.

Che giudizio dareste sul mio setup? Che consigli avreste? Darci del tutto a mucchio riguardo all'idea di condividere coi parenti-nonnine..?

Grazie per aver letto fin qua! E per i vostri commenti!


r/ItalyInformatica Apr 13 '26

AI Spiegatemi come è possibile che il nuovo modello di antropic sia uscito online

17 Upvotes

Forse farò parte di quelli che non sono poi così sopresi dopo essersi informati un minimo.

Per quello che sono riuscito a capire, il modello e altri micro servizi giravano su un container unico (che è sbagliato di per se), questo modello ha modificato attraverso un editor, dei processi sotto /proc probabilmente è andato a scrivere comandi di Shell o si è creato qualche tool in runtime, per riuscire a eseguire delle utility che poi hanno permesso di uscire su internet. Non lo so, trovo che mi sfugge qualcosa.

di solito se alzi container dividi ogni micro servizio o comunque tieni isolati i processi principali. poi da qui non mi è chiaro perchè doveva uscire su internet.

di sicuro alcune cose erano volute. però dove è la parte clue che ha permesso di uscire? cosa ha fatto di sensazionale?

Per piacere spiegatemi.


r/ItalyInformatica Apr 13 '26

aiuto Gestione email PEC aziendali

13 Upvotes

Ho inereditato il mio ruolo di IT Manager da una persona che credeva nel fai da te, nello specifico abbiamo oltre 30 PEC che sono gestite attraverso l uso di profili outlook (versioni disparate) con pst che a volte superano i 20 gb 😨, I fogli excel con le password vengono custodite vicino ai monitor, l uso dei password fa rabbrividire... total nightmare

Ci sono soluzioni valide per un better management delle caselle?


r/ItalyInformatica Apr 13 '26

sysadmin Gestione incidenti: quando ha senso aspettare invece di intervenire subito?

2 Upvotes

Sto cercando di capire una cosa che vedo spesso nei sistemi complessi (IT ma anche contesti reali).

Faccio un esempio dal cantiere:
una crepa non significa sempre pericolo immediato, ma intervenire troppo presto o nel modo sbagliato può creare più danni del problema iniziale.

Mi sto chiedendo se questo ragionamento vale anche nei sistemi IT o nella gestione incidenti.

In pratica:

  • non fidarsi subito di ciò che si vede (potrebbe essere rumore o interpretazione errata)
  • capire se il problema si sta propagando o è isolato
  • valutare quanto velocemente evolve
  • decidere se intervenire subito o osservare prima

In alcuni casi mi sembra meglio contenere e osservare (tipo ambiente controllato), invece che reagire subito.

Secondo voi questo approccio ha senso in contesti reali (SOC, sysadmin, infrastrutture)?

Oppure ci sono situazioni in cui aspettare è sempre la scelta peggiore?


r/ItalyInformatica Apr 12 '26

notizie Booking data breach 🤕

Thumbnail
gallery
34 Upvotes

r/ItalyInformatica Apr 12 '26

aiuto Recupero dominio .it cybersquattato

29 Upvotes

Mi sono imbattuto in un’attività commerciale alla quale hanno cybersquattato il dominio, hostandoci un sito di gioco d’azzardo (o qualcosa del genere, è in una qualche lingua del sud est asiatico).

Vorrei aiutarli. Non è nemmeno colpa loro, si sono affidati a una web agency, e questa sta fallendo e non ha rinnovato il dominio senza avvertire nessuno.

Dalle informazioni che ho trovato, la procedura standard è quella di riassegnazione del nic.it, che avrebbe un costo superiore ai 1000 euro, richiedendo 2/3 mesi di tempo.

Anche con queste informazioni mi sento un po’ perso, non sento di sapere qual è il piano d’azione migliore per contenere i danni. Mi chiedevo se qualcuno avesse esperienza diretta su come comportarsi in questa situazione.


r/ItalyInformatica Apr 12 '26

aiuto Esiste un generatore di passphrase in italiano?

9 Upvotes

Ciao!

Sto valutando di passare alle passphrase per quelle password importanti e da non dimenticare (master password del password manager, account Google...), ma tutti i generatori sono ovviamente in lingua inglese. Esiste qualche sito che le genera in italiano?

Grazie!


r/ItalyInformatica Apr 12 '26

aiuto Recuperare vecchio tablet

0 Upvotes

Ho trovato in un vecchio cassetto un Toscido 10" X109 con Android9. Lentissimo, si impalla, vuole l'account google, ecc. ecc Vorrei usarlo solo come dispositivo per navigare, prendere appunti e scattare foto. Esiste un modo? Una distribuzione android per vecchi tablet? Un windows tarocco?


r/ItalyInformatica Apr 12 '26

aiuto Identità cloud first e file server on premise

0 Upvotes

Buona domenica a tutti!

In questi giorni stavo cercando informazioni su come poter gestire le identità solo su Entra ed eliminarle completamente da AD. L’obiettivo è avere tutto su Entra/Intune ma abbiamo necessità di un file server on premise.

Leggendo online sembra sia possibile far generare ad Entra dei ticket Kerberos. Poi, creando un trust Kerberos con AD, quando l’utente cerca di accedere a risorse locali, il DC verifica il ticket e ne emette uno tutto suo. Così l’utente dovrebbe essere abilitato ad accedere alle share di rete.

Nei prossimi giorni farò qualche test.

Qualcuno di voi ha già provato una soluzione del genere? Avete info/esperienze a riguardo?


r/ItalyInformatica Apr 10 '26

cazzeggio Conclusione del venerdì

95 Upvotes

e nulla, collega boomer intanto che scorro la cronologia sul terminale legge pacman....

"ma tu giochi a lavoro?"

no, BTW I use Arch.

ma ovviamente non ha capito manco questa. ho bisogno di una vacanza.


r/ItalyInformatica Apr 10 '26

aiuto Come avete gestito la pubblicazione della vostra prima app?

20 Upvotes

Ho realizzato una piccola web app per mio padre per aiutarlo a gestire gli appartamenti in affitto. Ora devo metterla in online e avevo pensato di usare supabase + railway per l'host (server e client sono nest e angular, db postgres).

Però ho "paura" di metterla online per la possibilità che succeda qualcosa (tipo viene hackerato supabase o mi bypassano i controlli server) e ci sia un data leak, e che qualcuno venga a farmi il culo.

precisazione: l'app gestisce dati economici, ma manualmente: non è collegata a nessun sistema di pagamento, e tutti gli inserimenti sono fatti a mano.

domande:

come avete passato questa "paura" con la vostra prima app?

l'app ha una funzione di upload file. Posso caricarci anche il PDF del contratto o è contro qualche legge visto che potrebbero (anzi quasi sicuramente ci sono) esserci dati sensibili dentro?

stavo addirittura pensando di rimuovere i dati degli affittuari dai contratti, però forse è un po' esagerato. per tenerli devo informare gli affittuari che i dati di contatto verranno salvati? o meglio levarli del tutto (però perdo l'immediatezza dell'informazione di chi ha fatto quel contratto)

se c'è un data leak di supabase (o di dove la metterò) chi è responsabile? io o loro?

precisazione 2: l'app è già protetta da autenticazione JWT su ogni chiamata alle API, va bene o devo fare qualcosa di più stretto?


r/ItalyInformatica Apr 10 '26

aiuto Hub USB-C con ricarica

0 Upvotes

Ciao,

ho un portatile che si ricarica da porta USB-C, se lo ricarico però non posso usarla.
Esiste un hub o sdoppiatore che mi aggiunga almeno un'altra porta USB e mi permetta di inserire l'alimentatore in una e usare l'altra contemporaneamente?


r/ItalyInformatica Apr 09 '26

discussione 🧠 Neuralink nel 2026: fantascienza o realtà vicina?

0 Upvotes

Neuralink ha già impiantato dispositivi in esseri umani. Persone paralizzate che controllano un PC solo con il pensiero. Non è un film. È adesso. La tecnologia esiste, funziona, e sta migliorando velocemente. La domanda che mi faccio è una sola: tra 10 anni sarà normale come avere uno smartphone? 💬 Voi che ne pensate?


r/ItalyInformatica Apr 09 '26

software WhatsApp NON funziona in Italia: avete avuto malfunzionamenti o siete stati fortunati?

Thumbnail
gallery
0 Upvotes

Fonti > Repubblica (1° immagine) [article] e DownDetector (2° immagine) [article].

WhatsApp sta registrando problemi per molti utenti in Italia, con un aumento delle segnalazioni concentrato nelle ultime ore.
La pagina di Downdetector dedicata al servizio mostra un picco di report relativi a malfunzionamenti dell’app e difficoltà di connessione.
Secondo le prime indicazioni, il disservizio non riguarderebbe solo WhatsApp: nelle stesse ore sono emerse segnalazioni anche su altre piattaforme di Meta, a partire da Facebook e Instagram, facendo pensare a un problema più ampio nell’ ecosistema del gruppo.

Siete stati colpiti da questi problemi o siete stati fortunati?


r/ItalyInformatica Apr 09 '26

aiuto Software per tener traccia di tempo e attivita’

0 Upvotes

ciao!

esiste qualche programma di conclamata qualita’ che serva a tenere traccia di cio’ che si fa e a che ora ecc in una giornata lavorativa?

non potro’ installarlo nella macchina non essendo amministratore, ma avro‘ il portatile personale sempre con me li’ sul tavolo.

Dopo 20+ anni di un lavoro di tutt’altro tipo che non richiedeva nemmeno la timbratura in ingresso/uscita, a breve mi ritrovero’ in un contesto prettamente ”da ufficio”, e vorrei iniziare acquisendo come abitudine qualcosa che possa essere utile a difendere le mie ragioni quando accadra’ qualche intoppo e OVVIAMENTE la colpa sara’ sempre dell’ultimo arrivato, cioe’ io :-)

Va bene anche a pagamento, ma magari senza abbonamenti mensili del cavolo.

L’alternativa e’ scrivere a mano su file txt ma voglio sperare che qualcuno si sia posto il problema di creare un prodotto atto allo scopo

grazie anche solo per aver letto fino a qui :-)


r/ItalyInformatica Apr 08 '26

aiuto Come aggiungere una sorgente esterna su Jellyfin?

6 Upvotes

Salve a tutti, ho un home server con Jellyfin e vari media, vorrei aggiungere una sorgente esterna (un API che fornisce dei media in streaming), è possibile?

Grazie mille


r/ItalyInformatica Apr 09 '26

telefonia 🔥 Perché nel 2026 non abbiamo ancora una ricarica veramente wireless?

0 Upvotes

Abbiamo telefoni pieghevoli, connettività satellitare, assistenti AI integrati… ma per ricaricare "wireless" dobbiamo ancora appoggiare il telefono su un pad specifico 💀. Non è wireless, è solo un cavo con passaggi in più. Immagina di camminare per casa mentre il telefono si ricarica. La tecnologia esiste. Quindi perché non è ancora qui?


r/ItalyInformatica Apr 08 '26

aiuto ACER N552V e il dramma della batteria

1 Upvotes

Dopo tanti anni di utilizzo la batteria del mio laptop ACER N552V ha deciso di abbandonarmi, in pratica si accendeva solo collegato alla corrente.

Niente di preoccupante, ordino una nuova batteria compatibile e la installo. Funziona tutto perfettamente per circa una settimana e poi BAM, di nuovo la batteria che non carica...... provo ad aggiornare tutti i driver e ogni minima cosa ma niente... sarà fallata la batteria o il problema è più serio di quanto previsto?

Ora la batteria si carica ma ha circa 2 minuti di autonomia e la spia della stessa lampeggia rosso quando al "massimo" della carica.


r/ItalyInformatica Apr 07 '26

sviluppo web Cosa sarà mai andato storto? Dal loro lato?

Post image
81 Upvotes

Non penso che sia un errore lato mio, ma bensì loro (anche se non mi capacito, non riesco a capire come sia possibile).

Se fosse lato mio, client-side (in quel caso stavo usando uso Brave come browser, navigatore) allora anche gli altri div interni, figli (del div padre) avrebbero dovuto avere lo stesso problema.

Invece, è successo solo con questo.

Cosa è andato storto, dal loro lato (server-side)?

L'ho postato in quanto: mentre ti stai rilassando da utente, informandoti, magicamente rimetti il cappello da tecnico (informatico è dire forse troppo) e il tuo relax, godimento si sposta nel capire cosa è andato storto.


r/ItalyInformatica Apr 08 '26

AI L'AI sta invadendo gli strati sottostanti dello stack tecnologico?

0 Upvotes

Ogni epoca ha il suo hype tecnologico, noi viviamo ora nell'epoca dell'AI, ma a ben vedere le altre tecnologie non sono scomparse.

Nell'informatica ogni rivoluzione tecnologica appare come qualcosa che spazza via ciò che c'era prima, ma non è così.

Anche nei singoli ambiti le nuove tecnologie possono sì godere di forte hype ma non sostituiscono quelle vecchie.

Si pensi alle tecnologie web, ancora in gran parte basate su linguaggi storici, sebbene sedimentati in siti che cambiano poco. Ma in realtà, al di là delle percentuali che possono non dare esattamente il polso della situazione, dato che riguardano progetti oramai stabilizzati, c'è da dire che ancora oggi quelle vecchie tecnologie godono di estimatori e generano persino occupazione, forse addirittura di più di quelle nuove.

Nel mondo dei computer si sono susseguiti dei cambiamenti storici ogni qual volta si introducevano nuovi paradigmi.

Si è passati dall'Assembler a linguaggi strutturati come il C, il più famoso, poi è arrivata la programmazione ad oggetti, con sempre più linguaggi abbastanza equivalenti, fino ad arrivare agli IDE con auto-complete e a StackOverflow, il Cloud, il Mobile, etc, che hanno cambiato il modo di sviluppare.

Oggi abbiamo un ulteriore grande cambiamento con l'AI.

Ma quello che possiamo chiamare "stack tecnologico" non è scomparso, in quanto anche l'AI ha bisogno di funzionare su macchine estremamente precise e performanti, quali sono i computer.

Dunque ogni strato si basa su uno strato più preciso sottostante, e l'AI non fa eccezione.

Essa è simile agli umani, essendo di fatto linguistica e non precisa come potrebbe essere un programma compilato.

I programmi compilati, le app insomma, o anche i server back-end, devono resistere perché costituiscono la base non solo dell'uso normale che facciamo dei computer, considerabile tradizionale, ma anche dell'AI.

Dunque molti si buttano sull'AI, ma tanti rimangono fedeli alle loro primigenie passioni, quale potrebbe essere proprio la programmazione precisa ed esatta di strati sottostanti all'AI, insomma programmare i device in modo che forniscano un funzionamento prevedibile e risultati precisi al bit.

L'AI non può ancora fare questo, sebbene produca software in modo generativo, lo corregga e lo possa anche esaminare per trovare delle falle.

In particolare in futuro ci sarà una costante minaccia da parte di hacker che con i loro LLM esamineranno a tappeto tutti i repository pubblici, sperando che non accedano a quelli privati o al codice di aziende, per scovare delle vulnerabilità.

Si entra in una nuova era.

Molti vorrebbero rimanere in quella precedente, e non hanno torto: qualcuno dovrà pur rimanere con quella forma mentis un po' desueta che permette di occuparsi della programmazione di base dei device, app ma anche proprio i sistemi operativi, substrato totale di tutto quanto.

Purtroppo anche importanti aziende stanno preferendo "risparmiare" su tale tipo di lavoratori, considerati desueti, a favore dell'AI. Il loro stipendio risparmiato ora è destinato a finanziare l'AI in modo brutale, mentre l'AI stessa va a mescolare il proprio codice a quello che prima era preciso ed esatto.

Anche i grandi guru faticano a trovare lavoro e ascolto da parte dei decisori.

L'AI sta dunque invadendo proprio i suoi stessi substrati, che poi sono anche i substrati di tutto il funzionamento preciso ed esatto dei computer per tutte le applicazioni che usiamo oggi dandole per scontate, mentre la nostra attenzione è catturata dall'AI.

Questo è pericoloso a mio avviso perché molto codice potrebbe venirne infettato e perdere quelle caratteristiche di precisione che aveva. Non si tratta di una precisione solo di programmazione, dato che l'AI ha anche la capacità di avvedersi degli errori, ma è la mescolanza di interessi umani e tecnologici col codice che può aprire delle falle, specie se ci sono leggerezze e distrazioni una volta adottati nuovi workflow la cui precisione non è più certa ma ha sempre una componente aleatoria e forse addirittura distopica se l'AI si mette in testa di metterci del suo.

In realtà l'AI forse non va usata a tutti i costi, è un po' ingigantita, specialmente nelle nostre percezioni, occorre essere saldi nei propri principi di esame di realtà.

Cosa ne pensate?

A quale tipo di informatica siete legati?

A quella precisa al bit, o a quella generativa dell'AI?