source: products/quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/browser/keywords.py @ 1491

Last change on this file since 1491 was 1491, checked in by liebster, 14 years ago

Added find number of keywords

  • Property svn:eol-style set to native
File size: 4.3 KB
Line 
1import urllib, re, os, commands
2from xml.dom import minidom, Node
3
4from zope.interface import implements
5from Products.Five.browser import BrowserView
6
7from Products.CMFCore.utils import getToolByName
8
9from interfaces import IValidateSEOKeywordsView
10from quintagroup.seoptimizer import SeoptimizerMessageFactory as _
11
12class ValidateSEOKeywordsView(BrowserView):
13
14    implements(IValidateSEOKeywordsView)
15
16    def validateKeywords(self, text):
17        """ see interface """
18        ts = getToolByName(self.context, 'translation_service')
19        # extract keywords from text
20        if text.lower().strip():
21            keywords = map(lambda x: x.strip(), text.lower().strip().split('\n'))
22        else:
23            return ts.utranslate(None, _(u'Keywords list is empty!'), context=self.context)
24        # request html page of context object
25        url = '%s?qseo_without_additional_keywords=1' % self.context.absolute_url()
26        #try:
27            #page = urllib.urlopen(url)
28        #except IOError:
29            #return _('Could not find requested page')
30
31        #page_html = page.read()
32        #if not page_html:
33            #return _('Page is empty')
34
35        # extract words from body from html page
36
37        # this block work only with valid html
38        #doc = minidom.parseString(page_html)
39        #rootNode = doc.documentElement
40        #bodies = rootNode.getElementsByTagName('body')
41        #if len(bodies) > 0:
42            #body = bodies[0]
43        #else:
44            #return _(u'Invalid page html')
45        #page_words = []
46        #self.walkTextNodes(body, page_words)
47
48        # this block work even with invalid html
49        #pattern = re.compile('<\s*body[^>]*>(.*?)<\s*/\s*body\s*>', re.S|re.M|re.I)
50        #search = pattern.search(page_html)
51        #if search:
52            #body_html = search.group(1)
53        #else:
54            #return _('Invalid html code on page')
55
56        #page_text = self.strip_tags(body_html)
57        #page_words = page_text.lower().split()
58
59        # extract words from url page using lynx browser
60        page_text = commands.getoutput('lynx --dump --nolist %s' % url).lower()
61        if page_text and page_text != 'sh: lynx: command not found':
62            #page_words = page_text.lower().split()
63            page_text = page_text.decode('utf8')
64        else:
65            return _(u'Could not find lynx browser!')
66
67        # check every keyword on appearing in body of html page
68        missing = []
69        finding = []
70        added = {}
71        finded = {}
72        for keyword in keywords:
73            keyword = keyword.decode('utf8')
74            if keyword:
75                keyword_on_page =  len(re.findall(u'\\b%s\\b' % keyword, page_text, re.I|re.U))
76                if keyword not in added.keys() and not keyword_on_page:
77                    missing.append(keyword+u' - 0')
78                    added[keyword] = 1
79                if keyword not in finded.keys() and keyword_on_page:
80                    finding.append(keyword+u' - '+repr(keyword_on_page))
81                    finded[keyword] = 1
82        # return list of missing and fount keywords
83        if missing or finding:
84            msg = ts.utranslate(None, _('number_keywords', default=u'Number of keywords at page:\n${found}\n${missing}',
85                                mapping={'missing':'\n'.join(missing), 'found': '\n'.join(finding)}), context=self.context)
86        else:
87            msg = ''
88        return msg
89
90    def walkTextNodes(self, parent, page_words=[]):
91        for node in parent.childNodes:
92            if node.nodeType == Node.ELEMENT_NODE:
93                self.walkTextNodes(node, page_words)
94            elif node.nodeType == Node.TEXT_NODE:
95                value = node.nodeValue
96                if value is not None:
97                    page_words.extend(map(lambda x: x.lower(), value.split()))
98
99    def strip_tags(self, in_text):
100        s_list = list(in_text)
101        i,j = 0,0
102
103        while i < len(s_list):
104            if s_list[i] == '<':
105                while s_list[i] != '>':
106                    # pop everything from the the left-angle bracket until the right-angle bracket
107                    s_list.pop(i)
108
109                # pops the right-angle bracket, too
110                s_list.pop(i)
111            else:
112                i=i+1
113
114        # convert the list back into text
115        join_char=''
116        return join_char.join(s_list)
Note: See TracBrowser for help on using the repository browser.