2015-05-26 05:26:13 +00:00
# coding=utf-8
2017-08-26 14:56:05 +00:00
import json
2015-05-26 05:26:13 +00:00
import re
from nemubot import context
2015-10-30 20:57:45 +00:00
from nemubot . exception import IMException
2015-05-26 05:26:13 +00:00
from nemubot . hooks import hook
from nemubot . tools . xmlparser . node import ModuleState
nemubotversion = 3.4
2017-08-27 16:22:53 +00:00
from nemubot . module . more import Response
from nemubot . module . networking . page import headers
2015-05-26 05:26:13 +00:00
PASSWD_FILE = None
2018-12-30 09:59:10 +00:00
# You can get one with: curl -b "sessionid=YOURSESSIONID" 'https://accounts.cri.epita.net/api/users/?limit=10000' > users.json
2017-08-26 14:56:05 +00:00
APIEXTRACT_FILE = None
2015-05-26 05:26:13 +00:00
def load ( context ) :
global PASSWD_FILE
2015-10-27 17:03:28 +00:00
if not context . config or " passwd " not in context . config :
2015-05-26 05:26:13 +00:00
print ( " No passwd file given " )
2017-08-26 14:56:05 +00:00
else :
PASSWD_FILE = context . config [ " passwd " ]
print ( " passwd file loaded: " , PASSWD_FILE )
global APIEXTRACT_FILE
if not context . config or " apiextract " not in context . config :
print ( " No passwd file given " )
else :
APIEXTRACT_FILE = context . config [ " apiextract " ]
print ( " JSON users file loaded: " , APIEXTRACT_FILE )
if PASSWD_FILE is None and APIEXTRACT_FILE is None :
2015-05-26 05:26:13 +00:00
return None
if not context . data . hasNode ( " aliases " ) :
context . data . addChild ( ModuleState ( " aliases " ) )
context . data . getNode ( " aliases " ) . setIndex ( " from " , " alias " )
if not context . data . hasNode ( " pics " ) :
context . data . addChild ( ModuleState ( " pics " ) )
context . data . getNode ( " pics " ) . setIndex ( " login " , " pict " )
import nemubot . hooks
2017-07-05 20:54:07 +00:00
context . add_hook ( nemubot . hooks . Command ( cmd_whois , " whois " , keywords = { " lookup " : " Perform a lookup of the begining of the login instead of an exact search. " } ) ,
2015-11-16 06:19:09 +00:00
" in " , " Command " )
2015-05-26 05:26:13 +00:00
class Login :
2018-12-30 09:59:10 +00:00
def __init__ ( self , line = None , login = None , uidNumber = None , firstname = None , lastname = None , promo = None , * * kwargs ) :
2017-08-26 14:56:05 +00:00
if line is not None :
s = line . split ( " : " )
self . login = s [ 0 ]
self . uid = s [ 2 ]
self . gid = s [ 3 ]
self . cn = s [ 4 ]
self . home = s [ 5 ]
else :
self . login = login
self . uid = uidNumber
self . promo = promo
2018-12-30 09:59:10 +00:00
self . cn = firstname + " " + lastname
try :
self . gid = " epita " + str ( int ( promo ) )
except :
self . gid = promo
2015-05-26 05:26:13 +00:00
def get_promo ( self ) :
2017-08-26 14:56:05 +00:00
if hasattr ( self , " promo " ) :
return self . promo
if hasattr ( self , " home " ) :
2018-12-30 09:59:10 +00:00
try :
return self . home . split ( " / " ) [ 2 ] . replace ( " _ " , " " )
except :
return self . gid
2015-05-26 05:26:13 +00:00
def get_photo ( self ) :
if self . login in context . data . getNode ( " pics " ) . index :
return context . data . getNode ( " pics " ) . index [ self . login ] [ " url " ]
2018-12-30 09:59:10 +00:00
for url in [ " https://photos.cri.epita.fr/ %s " , " https://intra-bocal.epitech.eu/trombi/ %s .jpg " ] :
2015-05-28 05:18:07 +00:00
url = url % self . login
2015-09-24 04:09:59 +00:00
try :
_ , status , _ , _ = headers ( url )
if status == 200 :
return url
except :
logger . exception ( " On URL %s " , url )
2015-05-28 05:18:07 +00:00
return None
2015-05-26 05:26:13 +00:00
2017-08-26 14:56:05 +00:00
def login_lookup ( login , search = False ) :
2015-05-26 05:26:13 +00:00
if login in context . data . getNode ( " aliases " ) . index :
login = context . data . getNode ( " aliases " ) . index [ login ] [ " to " ]
2017-08-26 14:56:05 +00:00
if APIEXTRACT_FILE :
with open ( APIEXTRACT_FILE , encoding = " utf-8 " ) as f :
api = json . load ( f )
2018-12-30 09:59:10 +00:00
for l in api [ " results " ] :
2017-08-26 14:56:05 +00:00
if ( not search and l [ " login " ] == login ) or ( search and ( ( " login " in l and l [ " login " ] . find ( login ) != - 1 ) or ( " cn " in l and l [ " cn " ] . find ( login ) != - 1 ) or ( " uid " in l and str ( l [ " uid " ] ) == login ) ) ) :
yield Login ( * * l )
2017-07-05 20:54:07 +00:00
login_ = login + ( " : " if not search else " " )
2015-05-26 05:26:13 +00:00
lsize = len ( login_ )
2017-08-26 14:56:05 +00:00
if PASSWD_FILE :
with open ( PASSWD_FILE , encoding = " iso-8859-15 " ) as f :
for l in f . readlines ( ) :
if l [ : lsize ] == login_ :
yield Login ( l . strip ( ) )
2015-05-26 05:26:13 +00:00
def cmd_whois ( msg ) :
if len ( msg . args ) < 1 :
2015-10-30 20:57:45 +00:00
raise IMException ( " Provide a name " )
2015-05-26 05:26:13 +00:00
2017-07-05 20:54:07 +00:00
def format_response ( t ) :
srch , l = t
if type ( l ) is Login :
2015-05-26 05:26:13 +00:00
pic = l . get_photo ( )
2017-07-05 20:54:07 +00:00
return " %s is %s ( %s %s ): %s %s " % ( srch , l . cn . capitalize ( ) , l . login , l . uid , l . get_promo ( ) , " and looks like %s " % pic if pic is not None else " " )
2015-05-26 05:26:13 +00:00
else :
2017-07-05 20:54:07 +00:00
return l % srch
res = Response ( channel = msg . channel , count = " ( %d more logins) " , line_treat = format_response )
for srch in msg . args :
found = False
2017-08-26 14:56:05 +00:00
for l in login_lookup ( srch , " lookup " in msg . kwargs ) :
2017-07-05 20:54:07 +00:00
found = True
res . append_message ( ( srch , l ) )
if not found :
res . append_message ( ( srch , " Unknown %s :( " ) )
2015-05-26 05:26:13 +00:00
return res
2015-11-02 19:19:12 +00:00
@hook.command ( " nicks " )
2015-05-29 17:28:07 +00:00
def cmd_nicks ( msg ) :
if len ( msg . args ) < 1 :
2015-10-30 20:57:45 +00:00
raise IMException ( " Provide a login " )
2017-08-26 14:56:05 +00:00
nick = login_lookup ( msg . args [ 0 ] )
2015-05-29 17:28:07 +00:00
if nick is None :
nick = msg . args [ 0 ]
else :
nick = nick . login
nicks = [ ]
for alias in context . data . getNode ( " aliases " ) . getChilds ( ) :
if alias [ " to " ] == nick :
nicks . append ( alias [ " from " ] )
if len ( nicks ) > = 1 :
return Response ( " %s is also known as %s . " % ( nick , " , " . join ( nicks ) ) , channel = msg . channel )
else :
return Response ( " %s has no known alias. " % nick , channel = msg . channel )
2015-11-02 19:19:12 +00:00
@hook.ask ( )
2015-05-26 05:26:13 +00:00
def parseask ( msg ) :
2017-07-18 04:48:15 +00:00
res = re . match ( r " ^( \ S+) \ s*( ' s|suis|est|is|was|were) \ s+([a-zA-Z0-9_-] { 3,8})$ " , msg . message , re . I )
2015-05-26 05:26:13 +00:00
if res is not None :
nick = res . group ( 1 )
login = res . group ( 3 )
if nick == " my " or nick == " I " or nick == " i " or nick == " je " or nick == " mon " or nick == " ma " :
2017-07-18 04:32:48 +00:00
nick = msg . frm
2015-05-26 05:26:13 +00:00
if nick in context . data . getNode ( " aliases " ) . index :
context . data . getNode ( " aliases " ) . index [ nick ] [ " to " ] = login
else :
ms = ModuleState ( " alias " )
ms . setAttribute ( " from " , nick )
ms . setAttribute ( " to " , login )
context . data . getNode ( " aliases " ) . addChild ( ms )
context . save ( )
return Response ( " ok, c ' est noté, %s est %s "
% ( nick , login ) ,
channel = msg . channel ,
2017-07-18 04:32:48 +00:00
nick = msg . frm )