# -*- coding: utf-8 -*-
_tdl_no_reimport = True;

import time
import os.path
from HTMLParser import HTMLParser

import Kittens.utils

import Purr

_verbosity = Kittens.utils.verbosity(name="purrparse");
dprint = _verbosity.dprint;
dprintf = _verbosity.dprintf;

class LogIndexParser (HTMLParser):
  def reset (self):
    HTMLParser.reset(self);
    self.title = None;
    self.timestamp = None;
    self.curclass = None;

  def end (self):
    dprintf(4,"end, title '%s', timestamp %s",self.title,self.timestamp);

  def handle_starttag (self,tag,attrs):
    dprint(4,"start tag",tag,attrs);
    # anchor tag -- data we look for is in here
    if tag == "a":
      attrs = dict(attrs);
      tagclass = attrs.get('class');
      if tagclass:
        # whenever we encounter an A tag with a CLASS attribute, and the class
        # has a _handle_start_class method defined, call the handler.
        # The attributes are passed as keywords to the handler
        start_handler = getattr(self,"_handle_start_%s"%tagclass,None);
        if callable(start_handler):
          start_handler(**attrs);
        # If the class also has a _handle_end_class method defined, accumulate all text
        # inside the tag (in self.curdata) for handling in the end handler
        if hasattr(self,"_handle_end_%s"%tagclass):
          if self.curclass:
            raise ValueError,"nested class %s inside tag of class %s"%(tagclass,self.curclass);
          self.curclass = tagclass;
          self.curdata = "";
    # paragraph tag: add newline to curdata, if accumulating
    elif tag == "p":
      if self.curclass and self.curdata:
        self.curdata += "\n";
    elif tag == "br":
      if self.curclass and self.curdata:
        self.curdata += "<BR>";

  def _handle_start_TITLE (self,timestamp=0,**kw):
    if self.title is None:
      try:
        self.timestamp = int(float(timestamp));
      except:
        self.timestamp = time.time();

  def _handle_end_TITLE (self,data):
    if self.title is None:
      self.title = data;

  def handle_data (self,data):
    dprintf(4,"data: {%s}\n",data);
    # if curclass is None, we're not accumulating data, just skip it
    if self.curclass is None:
      return;
    # is there anything here except whitespace? Append to data, but
    # replace newlines with spaces
    if data.rstrip():
      self.curdata += data.replace("\n"," ");
    # else all space. Append a single space to curdata, if it doesn't
    # already end in a space
    else:
      if self.curdata and self.curdata[-1] not in "\n ":
        self.curdata += " ";

  _entity_dict = dict(lt="<",gt=">");

  def handle_entityref (self,name):
    dprintf(4,"entityref: {%s}\n",name);
    data = self._entity_dict.get(name,None);
    if data:
      self.handle_data(data);

  def handle_endtag (self,tag):
    dprint(4,"end tag",tag);
    # if end of A tag with CLASS attribute, pass accumulated data to data handler
    if tag == "a":
      if self.curclass:
        getattr(self,"_handle_end_%s"%self.curclass)(self.curdata)
        self.curclass = None;
    elif tag == "html":
      self.end();

class LogEntryIndexParser (LogIndexParser):
  def __init__ (self,dirname):
    LogIndexParser.__init__(self);
    self._dirname = dirname;

  def reset (self):
    LogIndexParser.reset(self);
    self.comments = None;
    self.dps = [];
    self._new_dp = None;

  def end (self):
    self._add_data_product();
    LogIndexParser.end(self);

  def _handle_start_DP (self,filename=None,src=None,policy=None,quiet=False,
                        timestamp=0,comment=None,render=None,**kw):
    # dispence with previous DP tag, if any
    self._add_data_product();
    # setup data for this tag
    comment = comment or "";
    try:
      timestamp = float(timestamp);
    except:
      timestamp = time.time();
    if not isinstance(quiet,bool):
      try:
        quiet = bool(int(quiet));
      except:
        quiet = bool(quiet);
    comment = comment.replace("&lt;","<").replace("&gt;",">");
    self._new_dp = Purr.DataProduct(filename=filename,sourcepath=src,
                      timestamp=timestamp,comment=comment,
                      fullpath=os.path.join(self._dirname,filename or ""),
                      policy=policy,render=render,quiet=quiet,archived=True);

  def _handle_end_TITLE (self,data):
    self.title = data.replace("&lt;","<").replace("&gt;",">");

  def _handle_end_COMMENTS (self,data):
    self.comments = data.replace("&lt;","<").replace("&gt;",">");

  def _handle_end_DPCOMMENT (self,data):
    if self._new_dp:
      self._new_dp.comment = data.replace("&lt;","<").replace("&gt;",">");
      self._add_data_product();

  def _add_data_product (self):
    if self._new_dp:
      self.dps.append(self._new_dp);
      self._new_dp = None;

if __name__ == "__main__":
  parser = LogEntryParser();
  for line in file('index.html'):
    parser.feed(line);

