Mise en forme de code: pensez à utiliser les balises [ tcl ] et [ /tcl ] (sans les espaces bien sûr) autour de vos codes tcl afin d'avoir un meilleur rendu et une coloration syntaxique. x


Check de proxy avec ip-api
#1
Suite à la demande faite sur ce post, voici un bout de script qui permet de signaler si une IP est un proxy ou non.


tcl
bind pub n|n "!proxy" ipcheck
proc ipcheck {nick uhost handle chan text} {
  set data [getipdatas $text]
  if {[dict get $data status] eq "success"} {
      if {[dict get $data proxy] eq "true"} {
        putserv "PRIVMSG $chan :$text est un proxy"
      }
  }
}
proc json2dict {JSONtext} {
  string range [string trim [string trimleft [string map {\t {} \n {} \r {} , { } : { } \[ \{ \] \}} $JSONtext] {\uFEFF}]] 1 end-1
}
proc getipdatas { ip } {
  ::http::config -useragent "lynx"
  set ipq [http::geturl http://ip-api.com/json/$ip?fields=status,proxy,query&lang=fr]
  set data [json2dict [http::data $ipq]]
  ::http::cleanup $ipq
  return $data
}

zeolia: tchat gratuit, sans inscription ni publicité
Merci de ne pas demander d'aide en MP
Away
  Reply
#2
Top mille merci
  Reply
#3
Super base , pour optimiser et récupérer le plus d'informations possible sur une IP, ça me servira prochainement pour récupérer aussi la géolocalisation par exemple, ça permet aussi de voir sur un code léger et accessible comment fonctionne le package json et http.

Merci pour ce partage, ça me donne quelques idées
  Reply
#4
Reçu en MP (je mets donc ici pour qu'on suive la conversation)
uDc Wrote:Bonjour,

J'ai essaye ton script que tu ma poste mais j'ai 1 erreur j'arrive pas comprendre l'erreur:

Hey Bluetooth! My name is Rambo and I am running eggdrop v1.9.0, on Linux 3.10.0-1160.25.1.el7.x86_64.

Local time is now 11:48

You are an owner of this bot. Only +n users can see this! For more info,
see .help set motd. Please edit the motd file in your bot's 'text'
directory.
Use .help for basic help.
Use .help for help on a specific command.
Use .help all to get a full command list.
Use .help somestring to list any help texts containing "somestring".

Have fun.

Commands start with '.' (like '.quit' or '.help')
Everything else goes out to the party line.

* Bluetooth joined the party line.
[11:48:14] #Bluetooth# rehash
Rehashing.
[11:48:14] Rehashing ...
[11:48:14] INFO: The config setting for "net-type" has transitioned from a number
to a text string. Please update your choice to one of the allowed values
listed in the current configuration file from the source directory

[11:48:14] Listening for telnet connections on 54.36.12.7 port 2888 (all).
[11:48:14] nodbot3.1-8+ctcrfix(Wcc) by nodnuke23 with customizations and fixes made by MaSteR loaded
[11:48:14] Tcl error [circumvent_queues]: too many nested evaluations (infinite loop?)
[11:48:14] m00nie::youtube 1.8 loaded
[11:48:14] JoinPartChan by duarteper - Loaded!
[11:48:14] Tcl error in file 'eggdrop.conf':
[11:48:14] extra characters after close-quote
while executing
"bind pub -|- .ipdel "exemps:cmd
bind pub -|- .addport "exemps:cmd
bind pub -|- .delport "exemps:cmd
bind pub -|- .adddns "exemps:cmd
bind pub -|- .del..."
(file "alb/pro.tcl" line 35)
invoked from within
"source alb/pro.tcl"
(file "eggdrop.conf" line 319)
[11:48:14] * CONFIG FILE NOT LOADED (NOT FOUND, OR ERROR)

Les erreurs sont dans le script alb/pro.tcl, aucun des binds mis en évidence n'est présent dans le script posté au tout début de cette conversation.
zeolia: tchat gratuit, sans inscription ni publicité
Merci de ne pas demander d'aide en MP
Away
  Reply
#5
Tout d'abord, il manque une accolade fermante dans la proc ipcheck :



Code:
bind pub n|n "!proxy" ipcheck
proc ipcheck {nick uhost handle chan text} {
  set data [getipdatas $text]
  if {[dict get $data status] eq "success"} {
      if {dict get $data proxy] eq "true"} {
        putserv "PRIVMSG $chan :$text est un proxy"
      }
   }
}

proc json2dict {JSONtext} {
  string range [string trim [string trimleft [string map {\t {} \n {} \r {} , { } : { } \[ \{ \] \}} $JSONtext] {\uFEFF}]] 1 end-1
}

proc getipdatas { ip } {
  ::http::config -useragent "lynx"
  set ipq [http::geturl http://ip-api.com/json/$ip?fields=status,proxy,query&lang=fr]
  set data [json2dict [http::data $ipq]]
  ::http::cleanup $ipq
  return $data
}
ensuite , le code retourne une erreur en partyline :

[17:34:51] Tcl error [ipcheck]: invalid bareword "dict"
in expression "dict get $data proxy] eq "...";
should be "$dict" or "{dict}" or "dict(...)" or ...
  Reply
#6
Les deux fautes sont corrigées dans le source.

Pour la seconde, il manquait un [ dans la ligne en question.
zeolia: tchat gratuit, sans inscription ni publicité
Merci de ne pas demander d'aide en MP
Away
  Reply
#7
(21/12/2021, 18:26)Amand Wrote: Tout d'abord, il manque une accolade fermante dans la proc ipcheck :



Code:
bind pub n|n "!proxy" ipcheck
proc ipcheck {nick uhost handle chan text} {
  set data [getipdatas $text]
  if {[dict get $data status] eq "success"} {
      if {dict get $data proxy] eq "true"} {
        putserv "PRIVMSG $chan :$text est un proxy"
      }
   }
}

proc json2dict {JSONtext} {
  string range [string trim [string trimleft [string map {\t {} \n {} \r {} , { } : { } \[ \{ \] \}} $JSONtext] {\uFEFF}]] 1 end-1
}

proc getipdatas { ip } {
  ::http::config -useragent "lynx"
  set ipq [http::geturl http://ip-api.com/json/$ip?fields=status,proxy,query&lang=fr]
  set data [json2dict [http::data $ipq]]
  ::http::cleanup $ipq
  return $data
}
ensuite , le code retourne une erreur en partyline :

[17:34:51] Tcl error [ipcheck]: invalid bareword "dict"
in expression "dict get $data proxy] eq "...";
should be "$dict" or "{dict}" or "dict(...)" or ...

Bonjour, 

le code que vous avez postule c'est Corrige ?
  Reply
#8
Oui, c'est corrigé dans le premier post de CrazyCat.

J'ai plus d'erreur mais l'eggdrop ne me retourne rien.

Edit:

Pour les conditions de la proc ipcheck, ça reviendrait pas au même de faire :


Code:
  if {[dict get $data status] eq "success" && [dict get $data proxy] eq "true"} {
        putserv "PRIVMSG $chan :$text est un proxy"
  }
Edit 2:

Ça fonctionne , je vérifiais des ips qui n'étaient pas des proxys.

Pour avoir un retour quand l'ip n'est pas un proxy, il faut ajouter un else :


Code:
      if {[dict get $data proxy] eq "true"} {
        putserv "PRIVMSG $chan :$text est un proxy"
      } else {
        putserv "PRIVMSG $chan :$text n'est pas un proxy"
      }
Il a fallu que je fasse un putlog de $data pour le voir :

data => "status" "success" "proxy" false "query" "*.*.*.*"

 Je confirme que le script fonctionne nickel.
  Reply
#9
(21/12/2021, 20:35)Amand Wrote: Pour les conditions de la proc ipcheck, ça reviendrait pas au même de faire :


Code:
  if {[dict get $data status] eq "success" && [dict get $data proxy] eq "true"} {
        putserv "PRIVMSG $chan :$text est un proxy"
  }

En effet, mais ce bout de code est à considérer comme un tuto, je préfère donc bien scinder les conditions quand c'est possible et utile. Et c'est utile si tu veux avoir une info lorsque tu as un retour et que l'ip n'est pas définie comme proxy.
Si tu regardes la doc (https://ip-api.com/docs/api:json) tu vois qu'il y a énormément de choses exploitables, il est donc logique de vérifier qu'on a un status "success" et d'ensuite traiter les données présentes.
zeolia: tchat gratuit, sans inscription ni publicité
Merci de ne pas demander d'aide en MP
Away
  Reply
#10
J'ai modifié la proc ipcheck et getipdatas pour récupérer un tas d'information sur une IP :


tcl
bind pub - "!proxy" ipcheck
proc ipcheck {nick uhost handle chan text} {
  set data [getipdatas $text]
 
  # Encoding pour corriger un problème de charset. Ex: Île-de-France
  set continent [encoding convertfrom utf-8 [lindex $data 3]]
  set country [encoding convertfrom utf-8 [lindex $data 5]]
  set region [encoding convertfrom utf-8 [lindex $data 7]]
  set city [encoding convertfrom utf-8 [lindex $data 9]]
 
  set codepostal [lindex $data 11]
  set isp [lindex $data 13]
  set mobile [lindex $data 15]
  set proxy [lindex $data 17]
  set hosting [lindex $data 19]
 
  # Si une valeure est vide par exemple codepostal
  if {$codepostal eq ""} { set codepostal "vide" }
 
  putlog "continent => $continent / country => $country / region => $region / city => $city / codepostal => $codepostal / isp => $isp / mobile => $mobile / proxy => $proxy / hosting => $hosting"
  putlog "data => $data"
 
  if {[dict get $data status] eq "success"} {
      putserv "PRIVMSG $chan :$text : Continent: $continent - Country: $country - Region: $region - City: $city - Code postal: $codepostal - ISP: $isp - Mobile: $mobiletrad - Proxy: $proxytrad - Hosting: $hostingtrad"
  }
}
 
proc json2dict {JSONtext} {
  string range [string trim [string trimleft [string map {\t {} \n {} \r {} , { } : { } \[ \{ \] \}} $JSONtext] {\uFEFF}]] 1 end-1
}
 
proc getipdatas { ip } {
  ::http::config -useragent "lynx"
  set ipq [http::geturl http://ip-api.com/json/$ip?fields=continent,mobile,country,regionName,city,zip,isp,hosting,status,proxy,query&lang=fr]
  set data [json2dict [http::data $ipq]]
  ::http::cleanup $ipq
  return $data
}

  Reply
#11
Sauf que tu ne vérifies le status uniquement pour l'affichage.
Si la requête échoue (status en error, voir absent), tu auras des erreurs fatales dans les lignes précédentes.
zeolia: tchat gratuit, sans inscription ni publicité
Merci de ne pas demander d'aide en MP
Away
  Reply
#12
(22/12/2021, 09:22)CrazyCat Wrote: Sauf que tu ne vérifies le status uniquement pour l'affichage.
Si la requête échoue (status en error, voir absent), tu auras des erreurs fatales dans les lignes précédentes.

Hello,

j'ai mis la déclaration des variables dans la condition :


tcl
bind pub - "!proxy" ipcheck
proc ipcheck {nick uhost handle chan text} {
  set data [getipdatas $text]
 
  # Si une valeure est vide par exemple codepostal
  if {$codepostal eq ""} { set codepostal "vide" }
 
  putlog "continent => $continent / country => $country / region => $region / city => $city / codepostal => $codepostal / isp => $isp / mobile => $mobiletrad / proxy => $proxytrad / hosting => $hostingtrad"
  putlog "data => $data"
 
  if {[dict get $data status] eq "success"} {
 
  # Encoding pour corriger un problème de charset. Ex: Île-de-France
  set continent [encoding convertfrom utf-8 [lindex $data 3]]
  set country [encoding convertfrom utf-8 [lindex $data 5]]
  set region [encoding convertfrom utf-8 [lindex $data 7]]
  set city [encoding convertfrom utf-8 [lindex $data 9]]
 
  set codepostal [lindex $data 11]
  set isp [lindex $data 13]
  set mobile [lindex $data 15]
  set proxy [lindex $data 17]
  set hosting [lindex $data 19]
 
  putserv "PRIVMSG $chan :$text : Continent: $continent - Country: $country - Region: $region - City: $city - Code postal: $codepostal - ISP: $isp - Mobile: $mobile - Proxy: $proxy - Hosting: $hosting"
  }
}
 
proc json2dict {JSONtext} {
  string range [string trim [string trimleft [string map {\t {} \n {} \r {} , { } : { } \[ \{ \] \}} $JSONtext] {\uFEFF}]] 1 end-1
}
 
proc getipdatas { ip } {
  ::http::config -useragent "lynx"
  set ipq [http::geturl http://ip-api.com/json/$ip?fields=continent,mobile,country,regionName,city,zip,isp,hosting,status,proxy,query&lang=fr]
  set data [json2dict [http::data $ipq]]
  ::http::cleanup $ipq
  return $data
}


Si vous voyez des choses à améliorer ou à refaire, n'hésitez surtout pas.

Il y a sûrement une autre façon de faire pour récupérer les valeurs json , j'ai fait celle qui me paraissait le plus simple.
  Reply
#13
Ta variable $codepostal ne sera jamais instanciée à ce niveau là, elle est dans $data et doit être récupérée par un dict get. De plus c'est une très mauvaise idée de traiter $data comme une liste alors que c'est un dict.
Je verrais plutôt :

tcl
proc ipcheck {nick uhost handle chan text} {
  set data [getipdatas $text]
  if {[llength $data] == 0 || ([dict exists $data status] && [dict get $data status] ne "success")} {
    putlog "No data found"
    return 0
  }
 
  # Encoding pour corriger un problème de charset. Ex: Île-de-France
  set continent [encoding convertfrom utf-8 [dict get $data continent]]
  set country [encoding convertfrom utf-8 [dict get $data country]]
  set region [encoding convertfrom utf-8 [dict get $data region]]
  set city [encoding convertfrom utf-8 [dict get $data city]]
 
  set codepostal [lindex $data zip]
  set isp [dict get $data isp]
  set mobile [dict get $data mobile]
  set proxy [dict get $data proxy]
  set hosting [dict get $data hosting]
  set proxytrad [string map -nocase {"true" "\0033oui\003" "false" "\0034non\003"} $proxy]
  set mobiletrad [string map -nocase {"true" "\0033oui\003" "false" "\0034non\003"} $mobile]
  set hostingtrad [string map -nocase {"true" "\0033oui\003" "false" "\0034non\003"} $hosting]
 
  putserv "PRIVMSG $chan :$text : Continent: $continent - Country: $country - Region: $region - City: $city - Code postal: $codepostal - ISP: $isp - Mobile: $mobiletrad - Proxy: $proxytrad - Hosting: $hostingtrad"
}


Note que j'utilise llength sur la première condition parce que c'est le plus simple pour vérifier que la procédure getipdatas a bien retourné quelque chose qui puisse ressembler à un dictionnaire
zeolia: tchat gratuit, sans inscription ni publicité
Merci de ne pas demander d'aide en MP
Away
  Reply
#14
(22/12/2021, 18:50)CrazyCat Wrote: Ta variable $codepostal ne sera jamais instanciée à ce niveau là, elle est dans $data et doit être récupérée par un dict get. De plus c'est une très mauvaise idée de traiter $data comme une liste alors que c'est un dict.
Je verrais plutôt :

tcl
proc ipcheck {nick uhost handle chan text} {
  set data [getipdatas $text]
  if {![llength data] == 0 || ([dict exist $data status] && [dict get $data status] ne "success")} {
    putlog "No data found"
    return 0
  }
 
  # Encoding pour corriger un problème de charset. Ex: Île-de-France
  set continent [encoding convertfrom utf-8 [dict get $data continent]]
  set country [encoding convertfrom utf-8 [dict get $data country]]
  set region [encoding convertfrom utf-8 [dict get $data region]]
  set city [encoding convertfrom utf-8 [dict get $data city]]
 
  set codepostal [lindex $data zip]
  set isp [dict get $data isp]
  set mobile [dict get $data mobile]
  set proxy [dict get $data proxy]
  set hosting [dict get $data hosting]
  set proxytrad [string map -nocase {"true" "\0033oui\003" "false" "\0034non\003"} $proxy]
  set mobiletrad [string map -nocase {"true" "\0033oui\003" "false" "\0034non\003"} $mobile]
  set hostingtrad [string map -nocase {"true" "\0033oui\003" "false" "\0034non\003"} $hosting]
 
  putserv "PRIVMSG $chan :$text : Continent: $continent - Country: $country - Region: $region - City: $city - Code postal: $codepostal - ISP: $isp - Mobile: $mobiletrad - Proxy: $proxytrad - Hosting: $hostingtrad"
  }
}


Note que j'utilise llength sur la première condition parce que c'est le plus simple pour vérifier que la procédure getipdatas a bien retourné quelque chose qui puisse ressembler à un dictionnaire

il manque un $ sur le $data du llength et il y a une accolade en trop à la fin .

Ça me retourne toujours " No data found " , je fais des tests.
  Reply
#15
(22/12/2021, 19:21)Amand Wrote:
(22/12/2021, 18:50)CrazyCat Wrote: Ta variable $codepostal ne sera jamais instanciée à ce niveau là, elle est dans $data et doit être récupérée par un dict get. De plus c'est une très mauvaise idée de traiter $data comme une liste alors que c'est un dict.
Je verrais plutôt :

tcl
proc ipcheck {nick uhost handle chan text} {
  set data [getipdatas $text]
  if {![llength data] == 0 || ([dict exist $data status] && [dict get $data status] ne "success")} {
    putlog "No data found"
    return 0
  }
 
  # Encoding pour corriger un problème de charset. Ex: Île-de-France
  set continent [encoding convertfrom utf-8 [dict get $data continent]]
  set country [encoding convertfrom utf-8 [dict get $data country]]
  set region [encoding convertfrom utf-8 [dict get $data region]]
  set city [encoding convertfrom utf-8 [dict get $data city]]
 
  set codepostal [lindex $data zip]
  set isp [dict get $data isp]
  set mobile [dict get $data mobile]
  set proxy [dict get $data proxy]
  set hosting [dict get $data hosting]
  set proxytrad [string map -nocase {"true" "\0033oui\003" "false" "\0034non\003"} $proxy]
  set mobiletrad [string map -nocase {"true" "\0033oui\003" "false" "\0034non\003"} $mobile]
  set hostingtrad [string map -nocase {"true" "\0033oui\003" "false" "\0034non\003"} $hosting]
 
  putserv "PRIVMSG $chan :$text : Continent: $continent - Country: $country - Region: $region - City: $city - Code postal: $codepostal - ISP: $isp - Mobile: $mobiletrad - Proxy: $proxytrad - Hosting: $hostingtrad"
  }
}


Note que j'utilise llength sur la première condition parce que c'est le plus simple pour vérifier que la procédure getipdatas a bien retourné quelque chose qui puisse ressembler à un dictionnaire

il manque un $ sur le $data du  llength et il y a une accolade en trop à la fin .

Ça me retourne toujours " No data found " , je fais des tests.


Est-ce que il est possible de la faire uniquement sur #opers car il est adopte a tout les salon.
Merci d'avance
  Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)