sebbu

hexchat plugin python gateway_support

Sep 22nd, 2020 (edited)
511
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.69 KB | None | 0 0
  1. # Replace messages comming from a Gateway (with discord, irc, jabber/xmpp, matrix, telegram or other) with native messages
  2. # Author: sebbu
  3. # License: CC0 https://creativecommons.org/publicdomain/zero/1.0/
  4.  
  5. import hexchat
  6. import os
  7. import types
  8. from types import SimpleNamespace
  9. import simplejson as json
  10.  
  11. __module_name__ = "gateway_support"
  12. __module_version__ = "1.0.7"
  13. __module_description__ = "Translate gateway'd message into native messages"
  14.  
  15. print ("Loading gateway_support")
  16.  
  17. chmsg = "Channel Message"
  18. chmsg2= "Channel Msg Hilight"
  19. chact = "Channel Action"
  20. chact2= "Channel Action Hilight"
  21. chnot = "Channel Notice"
  22. chon = "Join"
  23. choff = "Part"
  24. choff2 = "Part with Reason"
  25. off = "Quit"
  26. nic = "Change Nick"
  27. pract = "Private Action to Dialog"
  28. prmsg = "Private Message to Dialog"
  29. # join : nick, channel, [host, account]
  30. # part : nick, host, channel, reason [ with reason]
  31. # quit : nick, reason, host
  32. # message : nick, text, modechar
  33. # notice : who, channel, message
  34. # nick : old, new
  35.  
  36. styles = {
  37.     "\x02", # bold (STX)
  38.     "\x03", # color (ETX)
  39.     "\x04", # ?hex color? (EOT)
  40.     "\x0F", # normal or end-of-style (SI)
  41.     "\x11", # ?monospace? (DC1)
  42.     "\x16", # reverse (SYN)
  43.     "\x1D", # italic (GS)
  44.     "\x1E", # ?strike-through? (RS)
  45.     "\x1F", # underline (US)
  46. }
  47.  
  48. dir=hexchat.get_info("xchatdir")+"\\gateway_support"
  49. if not os.path.exists(dir):
  50.     os.mkdir(dir)
  51.  
  52. chans = set()
  53. chans2 = set()
  54.  
  55. def un_gateway_ize(words, word_eol, userdata):
  56.     global chans, chans2
  57.     # tripplet server, channel, gateway username
  58.     serv = hexchat.get_info("network").lower()
  59.     chan = hexchat.get_info("channel").lower()
  60.     who = hexchat.strip(words[0])
  61.     # basic conditions, real channel (notice), text
  62.     #print(":".join("{:02x}".format(ord(c)) for c in who)) # debug invisible & unicode characters
  63.     if len(words)<2:
  64.         return hexchat.EAT_NONE
  65.     if userdata["msgtype"]==chmsg or userdata["msgtype"]==chmsg2:
  66.         if len(words)>=2:
  67.             txt = words[1]
  68.         else:
  69.             txt = ""
  70.     elif userdata["msgtype"]==chact or userdata["msgtype"]==chact2:
  71.         txt= words[1]
  72.     elif userdata["msgtype"]==chnot:
  73.         txt = words[2]
  74.         chan = words[1]
  75.     who=who.replace('\u200b','').replace('\u200c','').replace('\u200d','')
  76.     # user info
  77.     user = [i for i in hexchat.get_list("users") if i.nick==who]
  78.     if not user:
  79.         user = SimpleNamespace(nick= who, account= 'gw', host= 'gw@gateway', realname= 'gateway')
  80.     else:
  81.         user = user[0]
  82.     who = who.lower()
  83.     if len(who)==0 or len(chan)==0 or len(txt)==0:
  84.         return hexchat.EAT_NONE
  85.     # single gateway
  86.     if (serv, chan, who) in chans:
  87.         who_ = txt.split(' ')
  88.         who2a = who_[0]
  89.         if len(who2a)==0:
  90.             return hexchat.EAT_NONE
  91.         who2 = hexchat.strip(who2a)
  92.         # patterns
  93.         if ((who2a[0] in styles and who2a[-1] in styles and who2a[1]!='<' and who2a[-2]=='>') or
  94.           (who2a[0] in styles and who2a[-4] in styles and who2a[-3]=='@')):
  95.             if userdata["msgtype"]==chmsg or userdata["msgtype"]==chmsg2:
  96.                 who2 = who2[0:-4]
  97.                 txt2 = ' '.join( who_[1:] )
  98.             elif userdata["msgtype"]==chact or userdata["msgtype"]==chact2:
  99.                 who2 = who2[0:-4]
  100.                 txt2 = ' '.join( who_[1:] )
  101.             elif userdata["msgtype"]==chnot:
  102.                 who2 = who2[0:-3]
  103.                 txt2 = ' '.join( who_[1:] )
  104.             else:
  105.                 return hexchat.EAT_NONE
  106.         elif who_[0]=='[' and who_[2]==']' and who_[3]==':':
  107.             if len(who_)<4:
  108.                 return hexchat.EAT_NONE
  109.             who2 = hexchat.strip(who_[1])
  110.             txt2 = ' '.join( who_[4:] )
  111.         elif (
  112.             (who2[0]=='<' and who2[-1]=='>') or
  113.             (who2[0]=='[' and who2[-1]==']') or
  114.             (who2[0]=='`' and who2[-1]=='`') or
  115.             (who2[0]=='x' and who2[-1]=='»') or
  116.             (who2[0]=='@' and who2[-1]==':')
  117.           ) :
  118.             who2 = who2[1:-1]
  119.             txt2 = ' '.join( who_[1:] )
  120.         # control patterns
  121.         elif (who.startswith('system/') or who=='system') and (who_[1].strip() in ['joins', 'leaves', 'parts']):
  122.             txt2 = ''
  123.         else:
  124.             return hexchat.EAT_NONE
  125.         user2 = [i for i in hexchat.get_list("users") if i.nick==who2]
  126.         if not user2:
  127.             hexchat.command('RECV :' + who2 + '!' + user.host + ' JOIN ' + chan)
  128.         if (userdata["msgtype"]==chmsg) or (userdata["msgtype"]==chmsg2):
  129.             if who.startswith('system/') or who=='system':
  130.                 if who_[1].strip()=='joins':
  131.                     #hexchat.emit_print( chon, who2, chan, user.host)
  132.                     hexchat.command('RECV :' + who2 + '!' + user.host + ' JOIN ' + chan)
  133.                     return hexchat.EAT_ALL
  134.                 elif who_[1].strip() in ['leaves', 'parts']:
  135.                     #hexchat.emit_print( choff, who2, user.host, chan)
  136.                     hexchat.command('RECV :' + who2 + '!' + user.host + ' PART ' + chan)
  137.                     return hexchat.EAT_ALL
  138.                 else:
  139.                     return hexchat.EAT_NONE
  140.             else:
  141.                 #hexchat.emit_print( userdata["msgtype"], who2, txt2)
  142.                 hexchat.command('RECV :' + who2 + '!' + user.host + ' PRIVMSG ' + chan + ' :' + txt2);
  143.             return hexchat.EAT_ALL
  144.         elif (userdata["msgtype"]==chact) or (userdata["msgtype"]==chact2):
  145.             #hexchat.emit_print( userdata["msgtype"], who2, txt2)
  146.             hexchat.command('RECV :' + who2 + '!' + user.host + ' PRIVMSG ' + chan + " :\1ACTION" + txt2 + "\1");
  147.             return hexchat.EAT_ALL
  148.         elif userdata["msgtype"]==chnot:
  149.             # notice is usually control messages (join, let, quit, nick change)
  150.             if txt2=="joined the channel":
  151.                 #hexchat.emit_print( chon, who2, chan, user.host)
  152.                 hexchat.command('RECV :' + who2 + '!' + user.host + ' JOIN ' + chan)
  153.                 return hexchat.EAT_ALL
  154.             elif txt2=="left the channel":
  155.                 #hexchat.emit_print( choff, who2, user.host, chan)
  156.                 hexchat.command('RECV :' + who2 + '!' + user.host + ' PART ' + chan)
  157.                 return hexchat.EAT_ALL
  158.             elif txt2=="quit the server":
  159.                 #hexchat.emit_print( off, who2, "", user.host)
  160.                 hexchat.command('RECV :' + who2 + '!' + user.host + ' QUIT')
  161.                 return hexchat.EAT_ALL
  162.             elif ' '.join(txt2.split(' ')[:-1])=="is the new nick of":
  163.                 who3 = txt2.split(' ')[-1]
  164.                 #hexchat.emit_print( nic, who3, who2)
  165.                 hexchat.command('RECV :' + who2 + '!' + user.host + ' NICK ' + who3)
  166.                 return hexchat.EAT_ALL
  167.             # debug, shouldn't happen
  168.             print(who2)
  169.             print(txt2)
  170.         else:
  171.             # debug, shouldn't happen
  172.             print(userdata["msgtype"])
  173.         return hexchat.EAT_NONE
  174.     # multiple gateway
  175.     if (serv, chan, who) in chans2:
  176.         who_ = txt.split(' ')
  177.         if len(who_)<2:
  178.             return hexchat.EAT_NONE
  179.         who2a = who_[0]
  180.         if len(who2a)==0:
  181.             return hexchat.EAT_NONE
  182.         who2 = hexchat.strip(who2a)
  183.         arg0 = hexchat.strip(who_[0])
  184.         # allowed prefixes
  185.         if(arg0!='[TG]' and arg0!='[telegram]' and arg0!='[FGD]' and arg0!='[xmpp]' and arg0!='[matrix]' and arg0!='[discord]'):
  186.             return hexchat.EAT_NONE
  187.         arg1 = hexchat.strip(who_[1])
  188.         if len(who_)>=3:
  189.             arg2 = hexchat.strip(who_[2])
  190.         else:
  191.             arg2 = ''
  192.         act=False
  193.         if(arg1[0]=='<' and arg1[-1]=='>'):
  194.             who2 = arg1[1:-1]
  195.             txt2 = ' '.join( who_[2:] )
  196.         elif(arg1[0]=='x' and arg1[-1]=='»'):
  197.             who2 = arg1[1:-1]
  198.             txt2 = ' '.join( who_[2:] )
  199.         elif(arg1[0]=='@' and arg1[-1]==':'):
  200.             who2 = arg2
  201.             txt2 = arg1 + ' ' + ' '.join( who_[3:] )
  202.             act = True
  203.         elif(who2[0] in styles and who2[-1] in styles and who2[-2]=='>'):
  204.             who2 = arg1[1:-2]
  205.             txt2 = ' '.join( who_[2:])
  206.         elif(
  207.             (arg1[0]>='a' and arg1[0]<='z') or
  208.             (arg1[0]>='A' and arg1[0]<='Z')
  209.         ):
  210.             who2=arg1
  211.             txt2 = ' '.join( who_[2:] )
  212.             act = True
  213.         else:
  214.             return hexchat.EAT_NONE
  215.         if act:
  216.             if(userdata["msgtype"]==chmsg):
  217.                 what = chact
  218.             elif(userdata["msgtype"]==chmsg2):
  219.                 what = chact2
  220.             else:
  221.                 return hexchat.EAT_NONE
  222.             #hexchat.emit_print( what, who2, txt2)
  223.             hexchat.command('RECV :' + who2 + '!' + user.host + ' PRIVMSG ' + chan + ' :' + txt2);
  224.             return hexchat.EAT_ALL
  225.         else:
  226.             hexchat.emit_print( userdata["msgtype"], who2, txt2)
  227.             return hexchat.EAT_ALL
  228.     return hexchat.EAT_NONE
  229.  
  230. def gateway_on(word, word_eol, userdata):
  231.     global chans
  232.     serv = hexchat.get_info("network").lower()
  233.     chan = hexchat.get_info("channel").lower()
  234.     who = hexchat.strip(word[1]).lower()
  235.     if (serv, chan, who) not in chans:
  236.         chans.add( (serv, chan, word[1].lower()) )
  237.         # chans.append( (serv, chan, word[1].lower()) )
  238.         print("added")
  239.     else:
  240.         print("already existed, so not added")
  241.     # print("INFO '%s' '%s' '%s'" % (serv, chan, who) )
  242.     return hexchat.EAT_ALL
  243.  
  244. def gateway_off(word, word_eol, userdata):
  245.     global chans
  246.     serv = hexchat.get_info("network").lower()
  247.     chan = hexchat.get_info("channel").lower()
  248.     who = hexchat.strip(word[1]).lower()
  249.     if (serv, chan, who) in chans:
  250.         chans.remove( (serv, chan, word[1].lower()) )
  251.         print("removed")
  252.     else:
  253.         print("didn't existed, so not removed")
  254.     # print("INFO '%s' '%s' '%s'" % (serv, chan, who) )
  255.     return hexchat.EAT_ALL
  256.  
  257. def gateway_on2(word, word_eol, userdata):
  258.     global chans2
  259.     serv = hexchat.get_info("network").lower()
  260.     chan = hexchat.get_info("channel").lower()
  261.     who = hexchat.strip(word[1]).lower()
  262.     if (serv, chan, who) not in chans2:
  263.         chans2.add( (serv, chan, word[1].lower()) )
  264.         # chans2.append( (serv, chan, word[1].lower()) )
  265.         print("added")
  266.     else:
  267.         print("already existed, so not added")
  268.     # print("INFO '%s' '%s' '%s'" % (serv, chan, who) )
  269.     return hexchat.EAT_ALL
  270.  
  271. def gateway_off2(word, word_eol, userdata):
  272.     global chans2
  273.     serv = hexchat.get_info("network").lower()
  274.     chan = hexchat.get_info("channel").lower()
  275.     who = hexchat.strip(word[1]).lower()
  276.     if (serv, chan, who) in chans2:
  277.         chans2.remove( (serv, chan, word[1].lower()) )
  278.         print("removed")
  279.     else:
  280.         print("didn't existed, so not removed")
  281.     # print("INFO '%s' '%s' '%s'" % (serv, chan, who) )
  282.     return hexchat.EAT_ALL
  283.  
  284. def gateway_clear(word, word_eol, userdata):
  285.     global chans, chans2
  286.     chans = set()
  287.     chans2 = set()
  288.     return hexchat.EAT_ALL
  289.  
  290. def file_load(replace = False):
  291.     global dir, chans, chans2
  292.     if replace:
  293.         chans = set()
  294.         chans2 = set()
  295.     with open(dir+"\\gateway1.tsv", "a+") as f:
  296.         f.seek(0)
  297.         f.readline()
  298.         for line in f:
  299.             line = line.strip("\r\n")
  300.             line2=line.split("\t")
  301.             elem = ( line2[0], line2[1], line2[2])
  302.             if elem not in chans:
  303.                 chans.add( elem )
  304.     with open(dir+"\\gateway2.tsv", "a+") as f:
  305.         f.seek(0)
  306.         f.readline()
  307.         for line in f:
  308.             line = line.strip("\r\n")
  309.             line2=line.split("\t")
  310.             elem = ( line2[0], line2[1], line2[2])
  311.             if elem not in chans2:
  312.                 chans2.add( elem )
  313.     return True
  314.  
  315. def file_save():
  316.     global dir, chans, chans2
  317.     with open(dir+"\\gateway1.tsv", "w+") as f:
  318.         f.write("server\tchannel\tbridge\n")
  319.         for elem in chans:
  320.             f.write(elem[0]+"\t"+elem[1]+"\t"+elem[2]+"\n")
  321.     with open(dir+"\\gateway2.tsv", "w+") as f:
  322.         f.write("server\tchannel\tbridge\n")
  323.         for elem in chans2:
  324.             f.write(elem[0]+"\t"+elem[1]+"\t"+elem[2]+"\n")
  325.     return True
  326.  
  327. def gateway_load(word, word_eol, userdata):
  328.     global chans, chans2
  329.     file_load()
  330.     print("loading gateway_support data")
  331.     return hexchat.EAT_ALL
  332.  
  333. def gateway_reload(word, word_eol, userdata):
  334.     global chans, chans2
  335.     file_load(True)
  336.     print("reloading gateway_support data")
  337.     return hexchat.EAT_ALL
  338.  
  339. def gateway_save(word, word_eol, userdata):
  340.     global chans, chans2
  341.     file_save()
  342.     print("Saving gateway_support data")
  343.     return hexchat.EAT_ALL
  344.  
  345. def gateway_list(word, word_eol, userdata):
  346.     global chans
  347.     ms=len("Server")
  348.     mc=len("Channel")
  349.     mn=len("Nick")
  350.     count=0
  351.     for elem in chans:
  352.         if len(elem[0]) > ms:
  353.             ms = len(elem[0])
  354.         if len(elem[1]) > mc:
  355.             mc = len(elem[1])
  356.         if len(elem[2]) > mn:
  357.             mn = len(elem[2])
  358.         count+=1
  359.     for elem in chans2:
  360.         if len(elem[0]) > ms:
  361.             ms = len(elem[0])
  362.         if len(elem[1]) > mc:
  363.             mc = len(elem[1])
  364.         if len(elem[2]) > mn:
  365.             mn = len(elem[2])
  366.         count+=1
  367.     print("{0:<{1}} {2:<{3}} {4:<{5}}\n{6:{7}<{1}} {6:{7}<{3}} {6:{7}<{5}}".format("Server", ms, "Channel", mc, "Nick", mn, "#", "#"))
  368.     for elem in chans:
  369.         print("{0:<{1}} {2:<{3}} {4:<{5}}".format(elem[0], ms, elem[1], mc, elem[2], mn))
  370.     for elem in chans2:
  371.         print("{0:<{1}} {2:<{3}} {4:<{5}}".format(elem[0], ms, elem[1], mc, elem[2], mn))
  372.     if count==0:
  373.         print("List is empty.")
  374.     return hexchat.EAT_ALL
  375.  
  376. def unload_cb(userdata):
  377.     global chans, chans2
  378.     print("Unloading gateway_support")
  379.     hexchat.command('MENU DEL "$NICK/Use Gateway"')
  380.     #gateway_save([], [], [])
  381.     return hexchat.EAT_ALL
  382.  
  383. hexchat.hook_unload(unload_cb)
  384.  
  385. gateway_load([], [], [])
  386.  
  387. hexchat.hook_command('gateway_on', gateway_on, help="/gateway_on <nick> Add the user as the gateway for the channel")
  388. hexchat.hook_command('gateway_off', gateway_off, help="/gateway_off <nick> Remove the user as the gateway for the channel")
  389. hexchat.hook_command('gateway_on2', gateway_on2, help="/gateway_on2 <nick> Add the user as the gateway [prefixed] for the channel")
  390. hexchat.hook_command('gateway_off2', gateway_off2, help="/gateway_off2 <nick> Remove the user as the gateway [prefixed] for the channel")
  391.  
  392. hexchat.hook_command('gateway_save', gateway_save, help="/gateway_save Save the gateway list for all servers / channel")
  393. hexchat.hook_command('gateway_load', gateway_load, help="/gateway_load Read the gateway list for all servers / channel (WARNING: overwrite content)")
  394.  
  395. hexchat.hook_command('gateway_reload', gateway_reload, help="/gateway_reload Read the gateway list for all servers / channel (WARNING: append content)")
  396. hexchat.hook_command('gateway_clear', gateway_clear, help="/gateway_clear Clears the gateway list for all servers / channel (WARNING: delete content)")
  397.  
  398. hexchat.hook_command('gateway_list', gateway_list, help="/gateway_list List the gateway list for all servers / channel")
  399.  
  400. #hexchat.command('MENU -t0 ADD "$NICK/Use as gateway" "gateway_on %s" "gateway_off %s"')
  401.  
  402. hexchat.hook_print(chmsg , un_gateway_ize, {"msgtype": chmsg })
  403. hexchat.hook_print(chmsg2, un_gateway_ize, {"msgtype": chmsg2})
  404. hexchat.hook_print(chnot, un_gateway_ize, {"msgtype": chnot})
  405. hexchat.hook_print(chact , un_gateway_ize, {"msgtype": chact })
  406. hexchat.hook_print(chact2, un_gateway_ize, {"msgtype": chact2})
  407. # hexchat.hook_print(pract, un_gateway_ize, {"msgtype": pract})
  408. # hexchat.hook_print(prmsg, un_gateway_ize, {"msgtype": prmsg})
  409.  
Add Comment
Please, Sign In to add comment