tipue_search.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tipue Search
  4. ============
  5. A Pelican plugin to serialize generated HTML to JSON
  6. that can be used by jQuery plugin - Tipue Search.
  7. Copyright (c) Talha Mansoor
  8. """
  9. from __future__ import unicode_literals
  10. import os.path
  11. import json
  12. from bs4 import BeautifulSoup
  13. from codecs import open
  14. try:
  15. from urlparse import urljoin
  16. except ImportError:
  17. from urllib.parse import urljoin
  18. from pelican import signals
  19. class Tipue_Search_JSON_Generator(object):
  20. def __init__(self, context, settings, path, theme, output_path, *null):
  21. self.output_path = output_path
  22. self.context = context
  23. self.siteurl = settings.get('SITEURL')
  24. self.relative_urls = settings.get('RELATIVE_URLS')
  25. self.tpages = settings.get('TEMPLATE_PAGES')
  26. self.output_path = output_path
  27. self.json_nodes = []
  28. def create_json_node(self, page):
  29. if getattr(page, 'status', 'published') != 'published':
  30. return
  31. soup_title = BeautifulSoup(page.title.replace(' ', ' '), 'html.parser')
  32. page_title = soup_title.get_text(' ', strip=True).replace('“', '"').replace('”', '"').replace('’', "'").replace('^', '^')
  33. soup_text = BeautifulSoup(page.content, 'html.parser')
  34. page_text = soup_text.get_text(' ', strip=True).replace('“', '"').replace('”', '"').replace('’', "'").replace('¶', ' ').replace('^', '^')
  35. page_text = ' '.join(page_text.split())
  36. page_category = page.category.name if getattr(page, 'category', 'None') != 'None' else ''
  37. page_url = '.'
  38. if page.url:
  39. page_url = page.url if self.relative_urls else (self.siteurl + '/' + page.url)
  40. node = {'title': page_title,
  41. 'text': page_text,
  42. 'tags': page_category,
  43. 'url': page_url}
  44. self.json_nodes.append(node)
  45. def create_tpage_node(self, srclink):
  46. srcfile = open(os.path.join(self.output_path, self.tpages[srclink]), encoding='utf-8')
  47. soup = BeautifulSoup(srcfile, 'html.parser')
  48. page_title = soup.title.string if soup.title is not None else ''
  49. page_text = soup.get_text()
  50. # Should set default category?
  51. page_category = ''
  52. page_url = urljoin(self.siteurl, self.tpages[srclink])
  53. node = {'title': page_title,
  54. 'text': page_text,
  55. 'tags': page_category,
  56. 'url': page_url}
  57. self.json_nodes.append(node)
  58. def generate_output(self, writer):
  59. path = os.path.join(self.output_path, 'tipuesearch_content.json')
  60. pages = self.context['pages'] + self.context['articles']
  61. for article in self.context['articles']:
  62. pages += article.translations
  63. for srclink in self.tpages:
  64. self.create_tpage_node(srclink)
  65. for page in pages:
  66. self.create_json_node(page)
  67. root_node = {'pages': self.json_nodes}
  68. with open(path, 'w', encoding='utf-8') as fd:
  69. json.dump(root_node, fd, separators=(',', ':'), ensure_ascii=False)
  70. def get_generators(generators):
  71. return Tipue_Search_JSON_Generator
  72. def register():
  73. signals.get_generators.connect(get_generators)