# -*- coding: utf-8 -*-


from html import unescape

from lxml.etree import QName
from dateutil.parser import parse as get_date
from zope.interface import Interface, implementer

from mydm.util import is_url


class ITagExtractor(Interface):

    def match(self, e):
        """ check if the element  match the tag """

    def extract(self, e):
        """ extract data from element """


@implementer(ITagExtractor)
class TitleTag:
    tag = 'title'

    def __init__(self):
        self.val = None

    def match(self, e):
        name = QName(e.tag).localname.lower()
        return name == 'title'

    def extract(self, e):
        v = e.text
        if v is not None:
            v = v.strip('\r\t\n ')
        if v:
            self.val = unescape(v)


@implementer(ITagExtractor)
class LinkTag:
    tag = 'link'

    def __init__(self):
        self.val = None

    def match(self, e):
        name = QName(e.tag).localname.lower()
        return name in ('link', 'guid')

    def extract(self, e):
        if 'href' in e.attrib:
            v = e.attrib['href']
        else:
            v = e.text
        if v is not None:
            v = v.strip('\r\t\n ')
        if not v:
            return
        if not is_url(v):
            return
        if self.val is None:
            self.val = v
        elif 'isPermaLink' in e.attrib:
            self.val = v


@implementer(ITagExtractor)
class PubDateTag:
    tag = 'pub_date'

    def __init__(self):
        self.val = None

    def match(self, e):
        name = QName(e.tag).localname.lower()
        return name in ('pubdate', 'updated')

    def extract(self, e):
        if e.text is None:
            return
        v = get_date(e.text, ignoretz=True)
        if self.val is None or self.val < v:
            self.val = v


@implementer(ITagExtractor)
class CategoryTag:
    tag = 'tag'
    attrs = ['term', ]

    def __init__(self):
        self.val = None

    def match(self, e):
        name = QName(e.tag).localname.lower()
        return name == 'category'

    def extract(self, e):
        v = None
        if e.text is None and e.attrib:
            for _, d in e.attrib.items():
                if d is not None and len(d) > 0:
                    v = d
                    break
        else:
            v = e.text
        if v is None:
            return
        if self.val is None:
            self.val = []
        self.val.append(v.strip('\t\n\r '))


@implementer(ITagExtractor)
class ContentTag:
    tag = 'content'

    def __init__(self):
        self.val = None

    def match(self, e):
        name = QName(e.tag).localname.lower()
        return name in ('encoded', 'description', 'content', 'summary')

    def extract(self, e):
        if e.text is None:
            return
        if self.val is None or len(self.val) < len(e.text):
            self.val = e.text


class ItemExtractor:

    def __init__(self):
        self.extractors = [
                TitleTag(),
                LinkTag(),
                PubDateTag(),
                CategoryTag(),
                ContentTag()
        ]

    def __call__(self, entry):
        for e in entry:
            for ext in self.extractors:
                try:
                    if ext.match(e):
                        ext.extract(e)
                        break
                except ValueError:
                    continue
        return {
                item.tag: item.val
                for item in self.extractors
                if item.val is not None
        }

@@ -993,32 +993,66 @@
 tract(self, e):%0A
+        for attr in e.attrib:%0A    
         if 'href
@@ -1052,34 +1052,34 @@
 f 'href' in 
-e.
 attr
-ib
 :%0A
+    
             
@@ -1095,16 +1095,36 @@
 rib%5B
-'href'
+attr
 %5D%0A
+                break%0A
     
@@ -1164,36 +1164,32 @@
         if v is 
-not 
 None:%0A          
@@ -1190,38 +1190,22 @@
         
-v = v.strip('%5Cr%5Ct%5Cn ')
+return
 %0A       
@@ -1209,16 +1209,12 @@
     
-if not v
+else
 :%0A  
@@ -1215,38 +1215,54 @@
 se:%0A            
-return
+v = v.strip('%5Cr%5Ct%5Cn ')
 %0A        if not 
@@ -1298,32 +1298,36 @@
 %0A        if 
+not 
 self.val
  is None:%0A  
@@ -1310,32 +1310,24 @@
 not self.val
- is None
 :%0A          

fix bug