IRC解决方案Gnotty.zip

  • C6_928139
    了解作者
  • 292.5KB
    文件大小
  • 文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-05-27 08:25
    上传日期
Gnotty基于web和IRC。它旨在帮助开源项目开办一个IRC频道来完成项目上的合作、交流。 Gnotty是由几部分组成:主要Gnotty提供了一个现代的Web客户端和IRC频道服务器。服务器使用 gevent和 WebSockets,它提供的IRC频道和web客户端之间的通信层。Gnotty使用Twitter的Bootstrap 界面,提供了一个健全并适用于移动设备使用的布局。还提供了web界面的可自定义模板。 demo: http://gnotty.jupo.org/irc/ 另外,Gnotty提供高度可以定制的IRC机器人,聊天纪录的归档、浏览、搜索。 Gnotty也可以作为私人Django项目的一部分。 标签:Gnotty
gnotty-master.zip
内容介绍
#!/usr/bin/env python from __future__ import with_statement from gevent import monkey, spawn, sleep monkey.patch_all() from Cookie import SimpleCookie from cgi import FieldStorage from logging import getLogger, StreamHandler from mimetypes import guess_type import os import sys from tempfile import gettempdir from traceback import format_exc from daemon import daemonize from socketio import socketio_manage from socketio.server import SocketIOServer from socketio.namespace import BaseNamespace from gnotty.client import WebSocketIRCClient from gnotty.conf import settings HTTP_STATUS_TEXT = { 200: "OK", 301: "MOVED PERMANENTLY", 401: "UNAUTHORIZED", 404: "NOT FOUND", 500: "INTERNAL SERVER ERROR", } class IRCNamespace(BaseNamespace): """ gevent-socketio namespace that's bridged with an IRC client. """ def on_start(self, host, port, channel, nickname, password): """ A WebSocket session has started - create a greenlet to host the IRC client, and start it. """ self.client = WebSocketIRCClient(host, port, channel, nickname, password, self) self.spawn(self.client.start) def on_message(self, message): """ Message received from a WebSocket - send it to the IRC channel. """ if hasattr(self, "client"): self.client.emit_message(message) def disconnect(self, *args, **kwargs): """ WebSocket was disconnected - leave the IRC channel. """ quit_message = "%s %s" % (settings.GNOTTY_VERSION_STRING, settings.GNOTTY_PROJECT_URL) self.client.connection.quit(quit_message) super(IRCNamespace, self).disconnect(*args, **kwargs) class IRCApplication(object): def __init__(self, django=False): """ Loads and starts the IRC bot for the entire application. """ self.django = django self.bot = None if settings.BOT_CLASS: module_name, class_name = settings.BOT_CLASS.rsplit(".", 1) __import__(module_name) bot_class = getattr(sys.modules[module_name], class_name) self.bot = bot_class(settings.IRC_HOST, settings.IRC_PORT, settings.IRC_CHANNEL, settings.BOT_NICKNAME, settings.BOT_PASSWORD) spawn(self.bot.start) spawn(self.bot_watcher) self.logger = getLogger("irc.webhooks") self.logger.setLevel(settings.LOG_LEVEL) self.logger.addHandler(StreamHandler()) def bot_watcher(self): """ Thread (greenlet) that will try and reconnect the bot if it's not connected. """ default_interval = 5 interval = default_interval while True: if not self.bot.connection.connected: if self.bot.reconnect(): interval = default_interval else: interval *= 2 sleep(interval) def respond_webhook(self, environ): """ Passes the request onto a bot with a webhook if the webhook path is requested. """ request = FieldStorage(fp=environ["wsgi.input"], environ=environ) url = environ["PATH_INFO"] params = dict([(k, request[k].value) for k in request]) try: if self.bot is None: raise NotImplementedError response = self.bot.handle_webhook_event(environ, url, params) except NotImplementedError: return 404 except: self.logger.debug(format_exc()) return 500 return response or 200 def respond_static(self, environ): """ Serves a static file when Django isn't being used. """ path = os.path.normpath(environ["PATH_INFO"]) if path == "/": content = self.index() content_type = "text/html" else: path = os.path.join(os.path.dirname(__file__), path.lstrip("/")) try: with open(path, "r") as f: content = f.read() except IOError: return 404 content_type = guess_type(path)[0] return (200, [("Content-Type", content_type)], content) def index(self): """ Loads the chat interface template when Django isn't being used, manually dealing with the Django template bits. """ root_dir = os.path.dirname(__file__) template_dir = os.path.join(root_dir, "templates", "gnotty") with open(os.path.join(template_dir, "base.html"), "r") as f: base = f.read() with open(os.path.join(template_dir, "chat.html"), "r") as f: base = base.replace("{% block content %}", f.read()) replace = { "{% block content %}": "", "{% block extrahead %}": "", "{% endblock %}": "", "{% load gnotty_tags %}": "", "{% extends \"gnotty/base.html\" %}": "", "{% url gnotty_chat %}": "/", "{% gnotty_nav %}": "", "{% templatetag openvariable %}": "{{", "{% templatetag closevariable %}": "}}", } for k, v in replace.items(): base = base.replace(k, v) for k, v in settings.items(): base = base.replace("{{ %s }}" % k, unicode(v or "")) return base def respond_django(self, environ): """ Tries to redirect to a Django app if someone accesses an invalid URL when Django is being used. """ environ["port"] = "" if environ["SERVER_NAME"] in ("127.0.0.1", "localhost"): environ["port"] = ":8000" location = ("%(wsgi.url_scheme)s://" + "%(SERVER_NAME)s%(port)s%(PATH_INFO)s") % environ return (301, [("Location", location)], None) def respond_unauthorized(self, environ): """ Just return unauthorized HTTP status if the ``unauthorized`` method returns ``True`` inside ``__call__``. """ return 401 def authorized(self, environ): """ If we're running Django and ``GNOTTY_LOGIN_REQUIRED`` is set to ``True``, pull the session cookie from the environment and validate that the user is authenticated. """ if self.django and settings.LOGIN_REQUIRED: try: from django.conf import settings as django_settings from django.contrib.auth import SESSION_KEY from django.contrib.auth.models import User from django.contrib.sessions.models import Session from django.core.exceptions import ObjectDoesNotExist cookie = SimpleCookie(environ["HTTP_COOKIE"]) cookie_name = django_settings.SESSION_COOKIE_NAME session_key = cookie[cookie_name].value session = Session.objects.get(session_key=session_key) user_id = session.get_decoded().get(SESSION_KEY) user = User.objects.get(id=user_id) except (ImportError, KeyError, ObjectDoesNotExist): return False return True def __call__(self, environ, start_response): """ WSGI application handler. """ authorized = self.authorized(environ) path = environ["PATH_INFO"] if path.startswith("/socket.io/") and authorized: socketio_manage(environ, {"": IRCNamespace}) return if not authorized: dispatch = self.respond_unauthorized elif path.startswith("/webhook/"): dispatch = self.respond_webhook elif self.django: dispatch = self.respond_django else: dispatch = self.respond_static response = dispatch(environ)
评论
    相关推荐