Advertisement
Guest User

Untitled

a guest
Feb 8th, 2016
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.57 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. """
  5.    SleekXMPP: The Sleek XMPP Library
  6.    Copyright (C) 2010  Nathanael C. Fritz
  7.    This file is part of SleekXMPP.
  8.    See the file LICENSE for copying permission.
  9. """
  10.  
  11. import sys
  12.  
  13. import logging
  14. import getpass
  15. from optparse import OptionParser
  16. from sleekxmpp.exceptions import IqError, IqTimeout
  17.  
  18. import sqlite3
  19. import time
  20. import datetime
  21.  
  22. import re
  23. import urllib2
  24. import chardet
  25. import feedparser
  26.  
  27. import sleekxmpp
  28.  
  29. # Forcing UTF8
  30. if sys.version_info < (3, 0):
  31.     from sleekxmpp.util.misc_ops import setdefaultencoding
  32.     setdefaultencoding('utf8')
  33. else:
  34.     raw_input = input
  35.  
  36. class MUCBot(sleekxmpp.ClientXMPP):
  37.  
  38.     regex_url = re.compile(r"(https?://\S+)\.(\S+)")
  39.     regex_title = re.compile(r"<title>([^<]+)</title>")
  40.  
  41.     url_ext_blacklist = [
  42.         'png', 'jpg', 'jpeg', 'gif', 'png', 'pdf', 'doc', 'xls',
  43.         'docx', 'djvu', 'ppt', 'pptx', 'avi', 'mp4', 'mp3', 'flac', 'pps',
  44.         'mp3', 'ogg', 'webm'
  45.     ]
  46.  
  47.     def __init__(self, jid, password, room, nick):
  48.         sleekxmpp.ClientXMPP.__init__(self, jid, password)
  49.  
  50.         self.room = room
  51.         self.nick = nick
  52.  
  53.         self.add_event_handler("session_start",     self.start)
  54.         self.add_event_handler("groupchat_message", self.muc_message)
  55.  
  56.         self.schedule('RSS update',      # Unique name for the timer
  57.                         600,             # Seconds to delay before firing
  58.                         self.rss_update, # Callback to execute
  59.                         args=(),         # A tuple of positional argument values
  60.                         kwargs={},       # A dictionary of keyword argument values
  61.                         repeat=True)     # Make the event happen every X seconds
  62.  
  63.     def rss_update(self):
  64.         url_rss = 'http://rulinux.net/rss'
  65.         rss_depth_time = 600
  66.         current_time = datetime.datetime.utcnow()
  67.  
  68.         try:
  69.             rss = feedparser.parse(url_rss)
  70.             for r in rss.entries:
  71.                 time_rss = datetime.datetime.fromtimestamp(time.mktime(r.published_parsed))
  72.                 print current_time
  73.                 t = current_time - time_rss
  74.                 #TODO: normal time pars not like {-(3600*3)} for remove 3 hour
  75.                 time_delta = t.total_seconds()-(3600*3)
  76.                 if (0 < time_delta)  and (time_delta < rss_depth_time):
  77.                     news_title = unicode(r.title)
  78.                     news_link  = unicode(r.link)
  79.                     self.send_message(mto="rulinux@conference.jabber.ru",
  80.                             mbody="RULIN: %s %s" % (news_title, news_link),
  81.                             mtype='groupchat')
  82.                 else:
  83.                     break
  84.         except:
  85.             logging.info("DEBUG: RSS Feed problem, %s" , sys.exc_info()[0])
  86.  
  87.  
  88.     def write_log(self,query):
  89.         #TODO: Сделать раоту базы в тредах иначе приходится на каждый тред открывать и закрывать
  90.         #SQLite objects created in a thread can only be used in that same thread
  91.         connect_db = sqlite3.connect('./rulinux_xmpp_chat_logs.db')
  92.         cursor_db = connect_db.cursor()
  93.         cursor_db.execute("""INSERT INTO chat_log (id, time, jit, name, message)
  94.                            VALUES (NULL,?,?,?,?)""", query)
  95.         connect_db.commit()
  96.         connect_db.close()
  97.  
  98.     def start(self, event):
  99.         self.get_roster()
  100.         self.send_presence()
  101.         self.plugin['xep_0045'].joinMUC(self.room,
  102.                                         self.nick,
  103.                                         # If a room password is needed, use:
  104.                                         # password=the_room_password,
  105.                                         wait=True)
  106.  
  107.     def muc_message(self, msg):
  108.         # Cmopose data and write message to  SQLite DB
  109.         nick_name = unicode(msg['mucnick']) # User nick sowed in chat room
  110.         full_jit  = unicode(msg['from'])    # Like user@jabb.en/UserName
  111.         message   = unicode(msg['body'])    # Message body
  112.  
  113.         query = (time.time(), full_jit, nick_name, message,)
  114.         self.write_log(query)
  115.  
  116.         # Disable self-interaction
  117.         if msg['mucnick'] == self.nick:
  118.             return
  119.  
  120.         # Try to run command
  121.         if msg['body'].startswith(self.nick):
  122.  
  123.             tokens = msg['body'].split()
  124.             if len(tokens) > 1:
  125.                 command = tokens[1]
  126.  
  127.                 if command == 'ping':
  128.                     self.try_ping(msg['from'], msg['mucnick'])
  129.  
  130.         elif "http" in msg['body']:
  131.             self.try_say_url_info(msg['body'], msg['from'])
  132.  
  133.     def try_say_url_info(self, text, mucjid):
  134.         try:
  135.             parse_result = re.search(self.regex_url, text)
  136.             if not parse_result:
  137.                 logging.info("DEBUG: cant find  URL")
  138.                 raise
  139.  
  140.             url_ext = parse_result.group(2).lower()
  141.             if  url_ext in self.url_ext_blacklist:
  142.                 logging.info("DEBUG: url extension blocked")
  143.                 raise
  144.  
  145.             url = parse_result.group(1) + "." + parse_result.group(2)
  146.             req = urllib2.Request(url)
  147.  
  148.             #TODO: добавить ограничение на очередь запросов
  149.             response = urllib2.urlopen(req, timeout = 2)
  150.  
  151.             #6000 MAGIC number  for header in bytes, working on youtube
  152.             data  = response.read(6000)
  153.             enc   = chardet.detect(data)
  154.  
  155.             data  = data.decode(enc['encoding'], errors='ignore')
  156.             title = re.search(self.regex_title, data).group(1)
  157.  
  158.             self.send_message(mto=mucjid.bare,
  159.                             mbody="TITLE: %s" % (title),
  160.                             mtype='groupchat')
  161.  
  162.         except:  #IOError:  IndexError, urllib2.URLError
  163.             logging.info("DEBUG URL Rarsing error: %s", sys.exc_info()[0])
  164.  
  165.     def try_ping(self, pingjid, nick):
  166.         try:
  167.             rtt = self['xep_0199'].ping(pingjid,
  168.                                         timeout=10)
  169.             self.send_message(mto=pingjid.bare,
  170.                             mbody="%s, pong is: %s" % (nick, rtt),
  171.                             mtype='groupchat')
  172.             #logging.info("Success! RTT: %s", rtt)
  173.         except IqError as e:
  174.             logging.info("Error pinging %s: %s",
  175.                     pingjid,
  176.                     e.iq['error']['condition'])
  177.         except IqTimeout:
  178.             logging.info("No response from %s", pingjid)
  179.  
  180. if __name__ == '__main__':
  181.     optp = OptionParser()
  182.  
  183.     # Output verbosity options.
  184.     optp.add_option('-q', '--quiet', help='set logging to ERROR',
  185.                     action='store_const', dest='loglevel',
  186.                     const=logging.ERROR, default=logging.INFO)
  187.     optp.add_option('-d', '--debug', help='set logging to DEBUG',
  188.                     action='store_const', dest='loglevel',
  189.                     const=logging.DEBUG, default=logging.INFO)
  190.     optp.add_option('-v', '--verbose', help='set logging to COMM',
  191.                     action='store_const', dest='loglevel',
  192.                     const=5, default=logging.INFO)
  193.  
  194.     # JID and password options.
  195.     optp.add_option("-j", "--jid", dest="jid",
  196.                     help="JID to use")
  197.     optp.add_option("-p", "--password", dest="password",
  198.                     help="password to use")
  199.     optp.add_option("-r", "--room", dest="room",
  200.                     help="MUC room to join")
  201.     optp.add_option("-n", "--nick", dest="nick",
  202.                     help="MUC nickname")
  203.  
  204.     opts, args = optp.parse_args()
  205.  
  206.     # Setup logging.
  207.     logging.basicConfig(level=opts.loglevel,
  208.                         format='%(levelname)-8s %(message)s')
  209.  
  210.     if opts.jid is None:
  211.         opts.jid = raw_input("Username: ")
  212.     if opts.password is None:
  213.         opts.password = getpass.getpass("Password: ")
  214.     if opts.room is None:
  215.         opts.room = raw_input("MUC room: ")
  216.     if opts.nick is None:
  217.         opts.nick = raw_input("MUC nickname: ")
  218.  
  219.     # Setup the MUCBot and register plugins.
  220.     xmpp = MUCBot(opts.jid, opts.password, opts.room, opts.nick)
  221.  
  222.     xmpp.register_plugin('xep_0030') # Service Discovery
  223.     xmpp.register_plugin('xep_0045') # Multi-User Chat
  224.     xmpp.register_plugin('xep_0199') # XMPP Ping
  225.     xmpp.register_plugin('xep_0004') # Data Forms
  226.     xmpp.register_plugin('xep_0060') # PubSub
  227.  
  228.     # Connect to the XMPP server and start processing XMPP stanzas.
  229.     if xmpp.connect():
  230.         xmpp.process(block=True)
  231.         print("Done")
  232.     else:
  233.         print("Unable to connect.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement