# Description: short blogging via JSON and RSS exports
# Author: Wijnand Modderman
# Website: http://tehmaze.com
# Licsense: BSD
#
# A javascript implementation can be found on http://tehmaze.com/media/js/shortblog.js

from gozerbot.addon import addon
from gozerbot.aliases import aliases
from gozerbot.commands import cmnds
from gozerbot.datadir import datadir
from gozerbot.examples import examples
from gozerbot.generic import rlog
from gozerbot.pdod import Pdod
from gozerbot.persistconfig import PersistConfig
from gozerbot.plughelp import plughelp
from gozerbot.users import users
import cgi, os, random, time
from zlib import crc32

simplejson = addon.load('simplejson', 
    'http://cheeseshop.python.org/packages/source/s/simplejson/simplejson-1.7.1.tar.gz',
    md5sig='b723d488ea43583122511263e9c2c93a')

cfg = PersistConfig()
cfg.define('seed', str(random.randint(1000, 9999)))
cfg.define('export', '')
cfg.define('baseurl', '')
cfg.define('entries', 10)

plughelp.add('shortblog', 'provides a blogging service via downloadable JSON and RSS export')

class ShortBlogException(Exception):
    pass

class ShortBlog(Pdod):
    def __init__(self):
        Pdod.__init__(self, os.path.join(datadir, 'shortblog'))

    def export(self, user):
        if not self.data.has_key(user):
            return
        if not cfg.get('baseurl'):
            raise ShortBlogException('No baseurl configured, use !shortblog-cfg baseurl <url>')
        data = self.data[user]
        if not data:
            return
        data.sort(self.sorter)
        data.reverse()
        if len(data) > cfg.get('entries'):
            data = data[cfg.get('entries'):]
        json = simplejson.dumps({'entries': data}) # export object
        rss  = ['<?xml version="1.0" encoding="utf-8"?>', '<rss version="2.0"><channel>']
        rss.append('<title>shortblog of %s</title>' % user)
        rss.append('<link>%s/%s</link>' % (cfg.get('baseurl'), os.path.basename(self.filename(user))))
        rss.append('<lastBuildDate>%s</lastBuildDate>' % time.strftime('%a, %d %b %Y %H:%M:%S', time.localtime(data[0]['timestamp'])))
        for item in data:
            rss.append('<item>')
            rss.append('<title>%s</title>' % (cgi.escape(item['text'])))
            rss.append('<pubDate>%s</pubDate>' % time.strftime('%a, %d %b %Y %H:%M:%S', time.localtime(item['timestamp'])))
            rss.append('</item>')
        rss.append('</channel></rss>')
        rss = '\n'.join(rss) 
        rlog(10, 'shortblog', 'writing %d bytes for %s to %s' % (len(json), user, self.filename(user)))
        fh = open(self.filename(user), 'w')
        fh.write(json)
        fh.close()
        rlog(10, 'shortblog', 'writing %d bytes for %s to %s' % (len(rss), user, self.filename(user, 'rss')))
        fh = open(self.filename(user, 'rss'), 'w')
        fh.write(rss)
        fh.close()
        del json
        del rss

    @staticmethod
    def sorter(a, b):
        return cmp(a['timestamp'], b['timestamp'])

    def filename(self, user, ext='js'):
        if not cfg.get('export'):
            raise ShortBlogException('No export directory configured, use !shortblog-cfg export <directory>')
        if not os.path.isdir(cfg.get('export')):
            raise ShortBlogException('Export directory does not exist')
        userencs = '%08x.%s' % (abs(crc32(user+cfg.get('seed'))), ext)
        filename = os.path.join(cfg.get('export'), userencs)
        return filename

    def handle_shortblog(self, bot, ievent):
        if not ievent.rest:
            ievent.missing('<text>')
            return
        user = users.getname(ievent.userhost)
        if not self.data.has_key(user):
            self.data[user] = []
        self.data[user].append({
            'timestamp': time.time(),
            'network':   bot.name,
            'channel':   ievent.channel,
            'text':      ievent.rest
            })
        self.save()
        self.export(user)
        ievent.reply('ok')

    def handle_shortblogurl(self, bot, ievent):
        user = users.getname(ievent.userhost)
        if not self.data.has_key(user):
            ievent.reply('you have to blog something first')
        else:
            if not cfg.get('baseurl'):
                raise ShortBlogException('No baseurl configured, use !shortblog-cfg baseurl <url>')
            js  = '%s/%s' % (cfg.get('baseurl'), os.path.basename(self.filename(user, 'js')))
            rss = '%s/%s' % (cfg.get('baseurl'), os.path.basename(self.filename(user, 'rss')))
            ievent.reply('%s %s' % (js, rss))
    
    def handle_shortblogexport(self, bot, ievent):
        user = users.getname(ievent.userhost)
        if not self.data.has_key(user):
            ievent.reply('you have to blog something first')
        else:
            ievent.reply('ok')
            self.export(user)

shortblog = ShortBlog()
cmnds.add('shortblog', shortblog.handle_shortblog, 'USER')
examples.add('shortblog', 'blogs a line of text to your shortblog', '!shortblog The weather today is crap')
aliases.data['sb'] = 'shortblog'
cmnds.add('shortblog-export', shortblog.handle_shortblogexport, 'USER')
cmnds.add('shortblog-url', shortblog.handle_shortblogurl, 'USER')
examples.add('shortblog-url', 'Show the URL of your shortblog export', '!shortblog-url')
aliases.data['sb-url'] = 'shortblog-url'

def size():
    global shortblog
    return len(shortblog.data.keys())

