Autohotkey pastebin hosting and other things

Talk about anything
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Autohotkey pastebin hosting and other things

03 Oct 2013, 22:50

I'm currently running the irc pastebin (goes by the nick of PasteDude, found at http://ahkbin.no-ip.org/ ) off a spare ubuntu box at my home. I can't keep it hosted here forever. The problem is, it runs as a python script with several dependencies. I don't/can't really pay for a server to host it like I need it, and I don't think a system like it can be set up using standard server-side php. Am I wrong?

If anyone else wants to provide hosting for PasteDude, be my guest. It runs its own HTTP server, and, as I said before, requires ~3-4 dependencies. It runs on python 2.7.X

Should I move PasteDude over to #auto-hotkey? Should I try to implement a dual-channel system?
User avatar
joedf
Posts: 8981
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: Autohotkey pastebin hosting and other things

03 Oct 2013, 23:22

it is weird that it has some many dependencies... Post the source? maybe a fork can be made ;)
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: Autohotkey pastebin hosting and other things

04 Oct 2013, 19:12

Well, I have yet to figure out Git/Github or anything of that kind, so I'm really, really bad at sharing large code projects, as well as versioning. This is the python file, and there are a handful of other html, and css files.

Code: Select all

import os
import mimetypes
import time
import re
import codecs
import json

import cherrypy
import irclib
from mako.template import Template
from pygments import highlight
from pygments.lexers import AutohotkeyLexer
from pygments.formatters import HtmlFormatter

mimetypes.types_map['.ahk']='text/plain'
IRC_IPs={}
IPParse = re.compile('(\d{1,3})[^\w\d](\d{1,3})[^\w\d](\d{1,3})[^\w\d](\d{1,3})')

def handleWho(connection, event):
    args = event.arguments()
    if args[4] == nick:
        return
    r=IPParse.search(args[2])
    if r:
        IRC_IPs["%s.%s.%s.%s"%(r.group(1),r.group(2),r.group(3),r.group(4))]=args[4]

def handleMode(connection, event):
    connection.who(channel)
    connection.privmsg(channel, "The pastebin is now online at %s" % (url))
    irc.remove_global_handler('mode', handleMode)

def handleJoin(connection, event):
    eventHost = event.source().split("@",1)[1]
    eventNick = event.source().split("!")[0]
    print "[%s] %s has joined (%s)" % (time.strftime("%H:%M"), eventNick, event.source())
    if eventNick == nick:
        return
    r=IPParse.search(eventHost) # Extract IP from host
    if r: # If an IP was extracted
        IRC_IPs["%s.%s.%s.%s"%(r.group(1),r.group(2),r.group(3),r.group(4))]=eventNick # Assign the nick to the IP

def handlePart(connection, event):
    eventHost = event.source().split("@",1)[1]
    eventNick = event.source().split("!")[0]
    print "[%s] %s has parted (%s)" % (time.strftime("%H:%M"), eventNick, event.source())

def handleQuit(connection, event):
    eventHost = event.source().split("@",1)[1]
    eventNick = event.source().split("!")[0]
    print "[%s] %s has quit (%s)" % (time.strftime("%H:%M"), eventNick, event.source())

def handleMsg(connection, event):
    message = event.arguments()[0]
    print [time.strftime("%H:%M"), event.source().split("!")[0], message]
    if message[0:len(nick)].lower() == nick.lower() or message[-len(nick):].lower() == nick.lower():
        connection.privmsg(channel, "Please use the unofficial AutoHotkey pastebin at %s to share code."%(url))

class Root:
    @cherrypy.expose
    def __init__(self):
        self.template = Template(filename=os.path.join(StaticDir, 'templates', 'paste.htm'))
        self.indexPage = Template(filename=os.path.join(StaticDir, 'templates', 'index.htm'))
        self.last = time.time()
        self.pasteLenLimit = 500003
    
    @cherrypy.expose
    def index(self, code="", edit=False):
        try:
            nick = IRC_IPs[cherrypy.request.remote.ip]
        except:
            nick = ""
        if edit and edit.isdigit():
            with open(os.path.join(RootDirp, edit+'.json'),'r') as f:
                code = json.loads(f.read())['code']
        return self.indexPage.render(code=code, nick=nick, maxlength=self.pasteLenLimit)
    
    @cherrypy.expose
    def submit(self, code, name="", desc="", IRC=None):
        if name == "":
            name = "Anonymous"
        IRC_IPs[cherrypy.request.remote.ip] = name
        
        if time.time() - self.last < 5:
            return "Flood prevention enabled: no more than 1 paste every 5 seconds.\nTry again in a few seconds."
        if code == "":
            raise cherrypy.HTTPRedirect('/')
        
        if len(code) > self.pasteLenLimit:
            return "Paste length %s over limit of %s characters."%(len(code),self.pasteLenLimit)
        
        self.last = time.time()
        ts = time.strftime("%d%H%M%S")
        
        name = name[0:16]
        desc = desc[0:150]
        
        EnsureDir(RootDirp)
        with open(os.path.join(RootDirp, '%s.json'%(ts)), 'w') as f:
            f.write(json.dumps({'name':name,'desc':desc,'code':code}))
        
        if IRC and IRC != 'off':
            self.IRC(name, url, ts, desc)
        
        raise cherrypy.HTTPRedirect('p?%s'%(ts))
    
    @cherrypy.expose
    def IRC_IPs(self):
        try: # Try to find your ip/nick in the list
            nick = IRC_IPs[cherrypy.request.remote.ip]
        except: # If it can't, try to refresh the list
            try:
                connection.who(channel) # Call a who
                time.sleep(1) # and wait a second for it to finish
                nick = IRC_IPs[cherrypy.request.remote.ip]
            except: # If we still can't find your nick, just set it to ""
                nick = ""
        
        return nick + str(IRC_IPs)
    
    @cherrypy.expose
    def setLen(self, len):
        self.pasteLenLimit = int(len)
    
    def IRC(self, name, url, ts, desc):
        if desc:
            server.privmsg(channel, "%s just pasted %sp?%s - %s"%(name, url, ts, desc))
        else:
            server.privmsg(channel, "%s just pasted %sp?%s"%(name, url, ts))
    
    @cherrypy.expose
    def p(self, **kwargs):
        # the page is the name of the first parameter
        page = kwargs.keys()[0]
        if not page.isdigit():
            raise cherrypy.HTTPRedirect('/')
        
        # check for, then read the json file
        file = os.path.join(RootDirp, page) + ".json"
        if not os.path.exists(file):
            raise cherrypy.HTTPRedirect('/')
        with open(file, 'r') as f:
            paste = json.loads(f.read())
        
        # assign all the variables
        ahk = page
        code = paste['code']
        desc = paste['name']
        if paste['desc']:
            desc += ' - ' + paste['desc']
        
        return self.template.render(code = highlight(code, AutohotkeyLexer(), HtmlFormatter(linenos=True))
                , ahk = ahk, desc = desc)
    
    @cherrypy.expose
    def t(self, **kwargs):
        page = kwargs.keys()[0]
        if not page.isdigit():
            raise cherrypy.HTTPRedirect('/')
        
        file = os.path.join(RootDirp, page) + ".json"
        if not os.path.exists(file):
            raise cherrypy.HTTPRedirect('/')
        with open(file, 'r') as f:
            text = json.loads(f.read())['code']
        cherrypy.response.headers['Content-Type'] = 'text/plain'
        return text
    #


def EnsureDir(f):
    d = os.path.dirname(f)
    if not os.path.exists(d):
        os.makedirs(d)

StaticDir = os.path.join(os.getcwd(), 'static')
RootDir = os.path.join(StaticDir, 'root')
RootDirp = os.path.join(RootDir, 'p')
IPFile = os.path.join(os.getcwd(), 'IPs.json')

serverConfig = {
    '/': {
        'tools.staticdir.on': True,
        'tools.staticdir.dir': RootDir,
        'tools.staticdir.index': "index.htm"
    }
}

globalConfig = {
    'server.socket_host': "0.0.0.0",
    'server.socket_port': 8080,
    'server.thread_pool': 10
}

url = 'http://ahkbin.no-ip.org/'

root = Root()

cherrypy.config.update(globalConfig)
cherrypy.tree.mount(root, "/", config=serverConfig)
cherrypy.engine.start()

channel = '#ahk'
nick = 'PasteDude'
irc = irclib.IRC()

irc.add_global_handler('join', handleJoin)
irc.add_global_handler('part', handlePart)
irc.add_global_handler('quit', handleQuit)

irc.add_global_handler('mode', handleMode) # You've been voiced
irc.add_global_handler('whoreply', handleWho) # List of hosts
irc.add_global_handler('pubmsg', handleMsg) # Chat messages

server = irc.server()
server.connect('irc.freenode.net', 6667, nick)
server.join(channel)
irc.process_forever()
And don't tell me my python is horrible. I know.
User avatar
joedf
Posts: 8981
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: Autohotkey pastebin hosting and other things

04 Oct 2013, 20:02

no it's fine... But that seems more compilcated then need be.
Why not just a simple php script with a key? dont worry, i dont think anybody is going to attack the server... ( i hope not :P )
Also, for the whole project, you could use Dropbox. :)

cheers
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: Autohotkey pastebin hosting and other things

05 Oct 2013, 15:07

I wasn't aware that web-based PHP could run an IRC bot and keep it connected to the IRC server (respond to PONG & PRIVMSG requests). Also, already someone has tried to hack into the "php admin" and "mysql admin" pages, which my server doesn't have.

Edit: It's already in my dropbox. I should probably give it a dedicated folder, though. It's just floating in my generic "python" folder

Return to “Off-topic Discussion”

Who is online

Users browsing this forum: No registered users and 42 guests