# coding: utf-8
"""namu.wiki contrib grabber"""
from datetime import datetime, timedelta
import urllib.parse

from bs4 import BeautifulSoup
import requests

__all__ = 'contrib', 

URL = 'https://namu.wiki/contribution/author/{author}/document'
DATE_FORMAT = r'%Y-%m-%d %H:%M:%S'

class NamuContrib(object):
    """contribution object"""

    def __init__(self, document, revision, changes, when, desc='', revert=None):
        self.document = document
        self.revision = revision
        self.changes = changes
        self.when = when
        self.desc = desc
        self.revert = revert

    @property
    def when(self):
        return self._when

    @when.setter
    def when(self, when):
        if isinstance(when, datetime):
            self._when = when
        else:
            self._when = datetime.strptime(when, DATE_FORMAT) - timedelta(hours=9)

    def __repr__(self):
        return '<NamuContrib doc=%s rev=%s changes=%s when=%s desc=%s>' % (
            self.document, self.revision, self.changes, self.when, self.desc)

def contrib(username):
    """contributions"""
    result = []

    url = URL.format(author=username)
    req = requests.get(url)
    soup = BeautifulSoup(req.text, 'lxml')
    soup.encoding = 'utf-8'

    rows = soup.select('article table tbody tr')
    item = None
    hasdetail = False
    for i, row in enumerate(rows):
        if not item and not hasdetail:
            info = row.select('td')[0]
            document = info.select('a')[0].string
            try:
                qs = {k: ''.join(v) for k, v in
                      urllib.parse.parse_qs(info.select('a')[2].attrs['href'].split('?')[-1]).items()}
            except IndexError:
                revision = 1
            else:
                revision = int(qs['rev'])
            changes = int(info.select('span')[-1].string)
            when = row.select('td')[2].string.strip()
            item = NamuContrib(document=document, revision=revision, changes=changes, when=when)
        elif item and hasdetail:
            desc = row.select('td')[0].string
            item.desc = desc
            hasdetail = False
        if 'no-line' in row.attrs.get('class', []):
            hasdetail = True

        if item and not hasdetail:
            result.append(item)
            item = None

    return result

@@ -872,177 +872,655 @@
 def 
-__repr__(self):%0A        return '%3CNamuContrib doc=%25s rev=%25s changes=%25s when=%25s desc=%25s%3E' %25 (%0A            self.document, self.revision, self.changes, self.when, self.desc)
+as_dict(self):%0A        obj = %7B%0A            'document': self.document,%0A            'revision': self.revision,%0A            'changes': self.changes,%0A            'when': self.when,%0A            'desc': self.desc,%0A            'revert': self.revert,%0A        %7D%0A        return obj%0A%0A    def __repr__(self):%0A        return '%3CNamuContrib doc=%25s rev=%25s changes=%25s when=%25s desc=%25s%3E' %25 (%0A            self.document, self.revision, self.changes, self.when, self.desc)%0A%0Adef extint(input):%0A    %22%22%22Extract numbers from a string%22%22%22%0A    num = None%0A    try:%0A        num = int(''.join(%5Bs for s in input if s.isdigit()%5D))%0A    except ValueError:%0A        pass%0A    return num
 %0A%0Ade
@@ -2465,16 +2465,196 @@
 en=when)
+%0A%0A            # Find reverts%0A            revert = info.select('a + i')%0A            if revert:%0A                revert = extint(revert%5B0%5D.string)%0A                item.revert = revert
 %0A       

Add as_dict method to convert NamuContrib object into a dict, and parse reverts