salut la communauté ,
vais vous proposer un petit travail assisté par une ia , vous pouvez s'en servir ou ça nous sert pour discuter et à le développer aussi
vais vous proposer un petit travail assisté par une ia , vous pouvez s'en servir ou ça nous sert pour discuter et à le développer aussi
tcl
# -----------------------------------------------------------------------------
# Script YouTube pour Eggdrop Bot IRC
# Version : 1.1.16
# Description : Ce script permet d'intégrer des fonctionnalités YouTube dans un bot IRC.
# Il permet de rechercher des vidéos YouTube, de détecter automatiquement
# les liens YouTube partagés dans le chat, et d'afficher des informations
# détaillées sur les vidéos.
#
# Prérequis :
# - Tcl 8.6 ou supérieur
# - Packages Tcl : http, json, tls
# - Clé API YouTube valide (à configurer par l'utilisateur)
#
# Commandes :
# - !yt <terme> : Recherche une vidéo YouTube basée sur le terme de recherche fourni.
#
# Fonctionnalités :
# - Détection automatique des liens YouTube et affichage des détails des vidéos.
# - Mise en cache des résultats de recherche pour optimiser les appels API.
# - Formatage des messages pour une présentation claire des informations.
# -----------------------------------------------------------------------------
# ---------------------------------------------------------------------
# Configuration Utilisateur
# ---------------------------------------------------------------------
# Veuillez entrer votre clé API YouTube ci-dessous
namespace eval ::youtube {
# Clé API YouTube (à configurer par l'utilisateur)
variable api_key "VOTRE_CLE_ICI"
}
# ---------------------------------------------------------------------
# Script Principal (Ne modifiez rien ci-dessous)
# ---------------------------------------------------------------------
namespace eval ::youtube {
# Version du script
variable script_version "1.1.16"
# Préfixe pour les messages YouTube
variable yt_prefix "\002\00301,00You\00300,04Tube\017"
# Cache pour stocker les résultats de recherche
variable cache
# Cache pour stocker les résultats automatiques
variable auto_cache
# S'assurer que la version de Tcl est 8.6 ou supérieure pour le support Unicode
if {[catch {package require Tcl 8.6}]} {
putlog "Attention : Tcl < 8.6 détecté - Unicode limité"
}
# Procédure d'initialisation
proc init {} {
# Packages requis
foreach pkg {http json tls} {
if {[catch {package require $pkg} err]} {
error "Package requis manquant : $pkg"
}
}
# Initialiser les caches
array set ::youtube::cache {}
array set ::youtube::auto_cache {}
# Définir le flag YouTube s'il n'est pas déjà défini
if {![info exists ::youtube_flag_defined]} {
setudef flag youtube
set ::youtube_flag_defined 1
}
# Lier les commandes à leurs procédures respectives
bind pub - "!yt" ::youtube::pub:youtube
bind pubm - "*youtube*" ::youtube::pubm:youtube_auto
bind pubm - "*youtu.be*" ::youtube::pubm:youtube_auto
# Message de confirmation du chargement du script
putlog "Script YouTube version $::youtube::script_version chargé. Pour l'activer, utilisez la commande : .chanset #channel +youtube"
}
# Procédure pour envoyer un message YouTube
proc send_youtube_message {target message {type "PRIVMSG"}} {
variable yt_prefix
if {$type eq "PRIVMSG"} {
puthelp "PRIVMSG $target :${yt_prefix}\003 $message"
} elseif {$type eq "NOTICE"} {
puthelp "NOTICE $target :$message\003"
}
}
# Procédure pour vérifier si YouTube est activé pour un canal
proc check_youtube_enabled {chan {silent 0}} {
set enabled [channel get $chan youtube]
if {!$enabled && !$silent} {
send_youtube_message $chan "Erreur : YouTube non activé (activer via DCC chat)"
}
return $enabled
}
# Gestionnaire pour la commande !yt
proc pub:youtube {nick host hand chan arg} {
variable cache
if {![check_youtube_enabled $chan]} { return }
set query [string trim $arg]
if {$query eq ""} {
send_youtube_message $chan "Utilisation : !yt <terme>"
return
}
if {[info exists cache($query)]} {
send_youtube_message $chan $cache($query)
return
}
upvar #0 ::youtube::title title
upvar #0 ::youtube::video_id video_id
if {[catch {search_youtube $nick $chan $query} err]} {
send_youtube_message $chan "Erreur : $err"
return
}
upvar #0 ::youtube::channel_title channel_title
upvar #0 ::youtube::duration duration
upvar #0 ::youtube::views views
upvar #0 ::youtube::published_at published_at
upvar #0 ::youtube::video_link video_link
if {[catch {process_youtube_url $nick $chan $video_id $query} err]} {
send_youtube_message $chan "Erreur lors de la récupération des détails : $err"
return
}
set message [format_yt_message [list $title $channel_title $duration $views $published_at $video_link]]
set cache($query) $message
utimer 300 [list unset ::youtube::cache($query)]
send_youtube_message $chan $message
}
# Gestionnaire pour la détection automatique des liens YouTube dans les messages
proc pubm:youtube_auto {nick host hand chan text} {
variable auto_cache
if {![check_youtube_enabled $chan 1]} { return }
if {[string match "!yt*" $text]} { return }
set youtube_pattern {(?:https?://)?(?:www\.|m\.)?(?:youtube\.com/(?:watch\?v=|shorts/|embed/|live/)|youtu\.be/)([^&\s\?]+)}
set music_pattern {(?:https?://)?(?:www\.|m\.)?music\.youtube\.com/watch\?v=([^&\s\?]+)}
if {![regexp $youtube_pattern $text] && ![regexp $music_pattern $text]} { return }
set ids [regexp -all -inline $youtube_pattern $text]
set music_ids [regexp -all -inline $music_pattern $text]
foreach {match id} $ids {
if {[info exists auto_cache($id)]} {
send_youtube_message $chan $auto_cache($id)
continue
}
if {[catch {process_youtube_url $nick $chan $id $text "" 0} err]} {
continue
}
upvar #0 ::youtube::title title
upvar #0 ::youtube::channel_title channel_title
upvar #0 ::youtube::duration duration
upvar #0 ::youtube::views views
upvar #0 ::youtube::published_at published_at
if {$title eq ""} {
continue
}
set message [format_yt_message [list $title $channel_title $duration $views $published_at]]
set auto_cache($id) $message
utimer 300 [list unset ::youtube::auto_cache($id)]
send_youtube_message $chan $message
}
foreach {match music_id} $music_ids {
if {[info exists auto_cache($music_id)]} {
send_youtube_message $chan $auto_cache($music_id)
continue
}
if {[catch {process_youtube_url $nick $chan $music_id $text "music" 0} err]} {
continue
}
upvar #0 ::youtube::title title
upvar #0 ::youtube::channel_title channel_title
upvar #0 ::youtube::duration duration
upvar #0 ::youtube::views views
upvar #0 ::youtube::published_at published_at
if {$title eq ""} {
continue
}
set message [format_yt_message [list $title $channel_title $duration $views $published_at]]
set auto_cache($music_id) $message
utimer 300 [list unset ::youtube::auto_cache($music_id)]
send_youtube_message $chan $message
}
}
# Procédure pour encoder une requête URL
proc url_encode {query} {
set encoded ""
foreach char [split $query ""] {
if {[regexp {^[a-zA-Z0-9]$} $char]} {
append encoded $char
} else {
scan $char %c code
append encoded [format "%%%02X" $code]
}
}
return $encoded
}
# Procédure pour nettoyer et formater les titres des vidéos
proc clean_title {title {keep_emojis 0}} {
set cleaned $title
if {!$keep_emojis} {
set cleaned [string map {
"í ¼í·©í ¼í·¿" "" "í ¼í·²í ¼í·¦" "" "í ¼í·¨" "" "í ¼í·§" ""
"í ¼í·ª" "" "í ¼í·«" "" "í ¼í·¬" "" "í ¼í·" ""
"í ¼í·®" "" "í ¼í·¯" "" "í ¼í·°" "" "í ¼í·±" ""
"í ¼í¸" "" "í ¼í¹" "" "í ¼íº" "" "í ¼í»" ""
"í" "" "¼" "" "ÿ" "" "\n" " "
} $cleaned]
regsub -all {[^[:alnum:][:space:][:punct:]\u4e00-\u9FFF]} $cleaned "" cleaned
}
return [string trim $cleaned]
}
# Procédure pour récupérer les données YouTube avec des tentatives répétées
proc fetch_youtube_data {url chan} {
catch {package require tls}
::http::register https 443 [list ::tls::socket -tls1 1]
set token ""
for {set i 1} {$i <= 5} {incr i} {
if {[catch {set token [::http::geturl $url -timeout 5000]} err]} {
if {$i == 5} {
::http::unregister https
send_youtube_message $chan "Erreur HTTP après 5 tentatives : $err"
return ""
}
after 1000
continue
}
if {[::http::status $token] eq "ok"} { break }
set err_msg [::http::error $token]
switch -exact [::http::ncode $token] {
429 {
send_youtube_message $chan "Erreur : Limite de requêtes atteinte, réessayez plus tard."
::http::cleanup $token
::http::unregister https
return ""
}
403 {
set raw_response [::http::data $token]
putlog "Erreur YouTube API (HTTP 403): $raw_response"
::http::cleanup $token
::http::unregister https
send_youtube_message $chan "Erreur : Vidéo privée ou restrictions activées."
return ""
}
404 {
set raw_response [::http::data $token]
putlog "Erreur YouTube API (HTTP 404): $raw_response"
::http::cleanup $token
::http::unregister https
send_youtube_message $chan "Erreur : Vidéo supprimée ou introuvable."
return ""
}
}
::http::cleanup $token
if {$i == 5} {
::http::unregister https
send_youtube_message $chan "Erreur HTTP après 5 tentatives : $err_msg"
return ""
}
after 1000
}
set data [::http::data $token]
::http::cleanup $token
::http::unregister https
if {[string trim $data] eq ""} {
send_youtube_message $chan "Erreur : Réponse vide de l’API"
return ""
}
if {[catch {set json_data [::json::json2dict $data]} err]} {
send_youtube_message $chan "Erreur JSON : $err"
return ""
}
return $json_data
}
# Procédure pour récupérer les données de chaîne depuis l'API YouTube
proc fetch_channel_data {url chan type} {
set json_data [fetch_youtube_data $url $chan]
if {$json_data eq ""} {
return ""
}
if {![dict exists $json_data items] || [llength [dict get $json_data items]] == 0} {
return ""
}
return [lindex [dict get $json_data items] 0]
}
# Procédure pour formater un message YouTube
proc format_yt_message {parts {separator "|"}} {
set message ""
set first 1
foreach part $parts {
if {$first} {
append message "\002$part\002 "
set first 0
} else {
append message "\00304${separator}\003 $part"
}
}
append message " \00304${separator}\003"
return [string trim $message]
}
# Procédure pour rechercher des vidéos YouTube
proc search_youtube {nick chan query} {
variable api_key
upvar #0 ::youtube::title title
upvar #0 ::youtube::video_id video_id
set formatted_query [url_encode $query]
set url "https://www.googleapis.com/youtube/v3/search?part=snippet&q=$formatted_query&type=video&key=$api_key"
set json_data [fetch_youtube_data $url $chan]
if {$json_data eq ""} {
error "Échec de la recherche"
}
set video [lindex [dict get $json_data items] 0]
if {![dict exists $video id] || ![dict exists $video snippet]} {
error "Aucune vidéo trouvée pour cette recherche"
}
set id_dict [dict get $video id]
set snippet_dict [dict get $video snippet]
if {![dict exists $id_dict videoId] || ![dict exists $snippet_dict title]} {
error "ID ou titre manquant"
}
set title [clean_title [dict get $snippet_dict title]]
set video_id [dict get $id_dict videoId]
}
# Procédure pour formater la durée d'une vidéo
proc format_duration {duration} {
if {$duration eq "P0D" || $duration eq "PT0S" || $duration eq ""} {
return "Live"
}
if {![regexp {PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?} $duration _ hours minutes seconds]} {
return "En cours de traitement"
}
set hours [expr {$hours ne "" ? $hours : 0}]
set minutes [expr {$minutes ne "" ? $minutes : 0}]
set seconds [expr {$seconds ne "" ? $seconds : 0}]
if {$hours > 0} { return "${hours}h ${minutes}mn ${seconds}s" }
if {$minutes > 0} { return "${minutes}mn ${seconds}s" }
return "${seconds}s"
}
# Procédure pour formater le nombre de vues d'une vidéo
proc format_views {views} {
if {![string is integer -strict $views]} { return "N/A" }
if {$views >= 1000000} { return [format "%.1fM" [expr {$views / 1000000.0}]] }
if {$views >= 1000} { return [format "%.1fK" [expr {$views / 1000.0}]] }
return $views
}
# Procédure pour formater la date de publication
proc format_published_date {published_at} {
regsub {\.\d+Z$} $published_at "Z" clean_date
if {[catch {set timestamp [clock scan $clean_date -format "%Y-%m-%dT%H:%M:%SZ"]} err]} {
return "Date inconnue"
}
return [clock format $timestamp -format "%d-%m-%Y"]
}
# Procédure pour traiter l'URL d'une vidéo YouTube
proc process_youtube_url {nick chan id text {source ""} {include_link 1}} {
variable api_key
upvar #0 ::youtube::title title
upvar #0 ::youtube::channel_title channel_title
upvar #0 ::youtube::duration duration
upvar #0 ::youtube::views views
upvar #0 ::youtube::published_at published_at
upvar #0 ::youtube::video_link video_link
set title ""
set channel_title ""
set duration ""
set views ""
set published_at ""
set video_link ""
set url "https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id=$id&key=$api_key"
set video [fetch_channel_data $url $chan "Vidéo"]
if {$video eq ""} {
send_youtube_message $chan "Erreur : Vidéo invalide ou introuvable"
return
}
set title [clean_title [dict get $video snippet title]]
set channel_title [clean_title [dict get $video snippet channelTitle]]
set raw_duration [dict get $video contentDetails duration]
set duration [expr {$raw_duration eq "P0D" ? "Live" : [format_duration $raw_duration]}]
set views [format_views [dict get $video statistics viewCount]]
set published_at [format_published_date [dict get $video snippet publishedAt]]
set video_link "https://youtu.be/$id"
}
# Initialisation
init
}