-
Notifications
You must be signed in to change notification settings - Fork 842
/
Copy pathsubcategory.py
135 lines (120 loc) · 5.56 KB
/
subcategory.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# -*- coding: utf-8 -*-
"""
@Author: Alistair Magee
Adds support for subcategories on pelican articles
"""
import os
from operator import attrgetter
from functools import partial
from pelican import signals
from pelican.urlwrappers import URLWrapper, Category
from pelican.utils import slugify
from six import text_type
class SubCategory(URLWrapper):
def __init__(self, name, parent, settings):
super(SubCategory, self).__init__(name, settings)
self.parent = parent
self.shortname = name.split('/')
self.shortname = self.shortname.pop()
self.slug = slugify(self.shortname, settings.get('SLUG_SUBSTITUIONS', ()))
if isinstance(self.parent, SubCategory):
self.savepath = os.path.join(self.parent.savepath, self.slug)
self.fullurl = '{}/{}'.format(self.parent.fullurl, self.slug)
else: #parent is a category
self.savepath = os.path.join(self.parent.slug, self.slug)
self.fullurl = '{}/{}'.format(self.parent.slug, self.slug)
def as_dict(self):
d = self.__dict__
d['shortname'] = self.shortname
d['savepath'] = self.savepath
d['fullurl'] = self.fullurl
d['parent'] = self.parent
return d
def __hash__(self):
return hash(self.fullurl)
def _key(self):
return self.fullurl
def get_subcategories(generator, metadata):
if 'SUBCATEGORY_SAVE_AS' not in generator.settings:
generator.settings['SUBCATEGORY_SAVE_AS'] = os.path.join(
'subcategory', '{savepath}.html')
if 'SUBCATEGORY_URL' not in generator.settings:
generator.settings['SUBCATEGORY_URL'] = 'subcategory/{fullurl}.html'
if ('PAGINATED_TEMPLATES' in generator.settings and
'subcategory' not in generator.settings['PAGINATED_TEMPLATES']):
generator.settings['PAGINATED_TEMPLATES']['subcategory'] = None
if 'subcategory_path' in metadata:
category_list = text_type(metadata.get('subcategory_path')).split('/')
else:
category_list = text_type(metadata.get('category')).split('/')
category = (category_list.pop(0)).strip()
category = Category(category, generator.settings)
metadata['category'] = category
#generate a list of subcategories with their parents
sub_list = []
parent = category.name
for subcategory in category_list:
subcategory = parent + '/' + subcategory.strip()
sub_list.append(subcategory)
parent = subcategory
metadata['subcategories'] = sub_list
def create_subcategories(generator):
generator.subcategories = []
for article in generator.articles:
parent = article.category
actual_subcategories = []
for subcategory in article.subcategories:
#following line returns a list of items, tuples in this case
sub_cat = [item for item in generator.subcategories
if item[0].name == subcategory]
if sub_cat:
sub_cat[0][1].append(article)
parent = sub_cat[0][0]
actual_subcategories.append(parent)
else:
new_sub = SubCategory(subcategory, parent, generator.settings)
generator.subcategories.append((new_sub, [article,]))
parent = new_sub
actual_subcategories.append(parent)
article.subcategories = actual_subcategories
"""Add subpath and suburl to the article metadata. This allows the
the last subcategory's fullurl and savepath to be used when definining
Article URL's. If an article has no subcategories, the Category slug
is used instead
"""
try:
last_subcat = article.subcategories[-1]
article.metadata['subpath'] = last_subcat.savepath
article.metadata['suburl'] = last_subcat.fullurl
except IndexError: #No Subcategory
article.metadata['subpath'] = article.category.slug
article.metadata['suburl'] = article.category.slug
def generate_subcategories(generator, writer):
write = partial(writer.write_file,
relative_urls=generator.settings['RELATIVE_URLS'])
subcategory_template = generator.get_template('subcategory')
for subcat, articles in generator.subcategories:
articles.sort(key=attrgetter('date'), reverse=True)
dates = [article for article in generator.dates if article in articles]
write(subcat.save_as, subcategory_template, generator.context,
subcategory=subcat, articles=articles, dates=dates,
template_name='subcategory', page_name=subcat.page_name,
all_articles=generator.articles)
def generate_subcategory_feeds(generator, writer):
for subcat, articles in generator.subcategories:
articles.sort(key=attrgetter('date'), reverse=True)
if generator.settings.get('SUBCATEGORY_FEED_ATOM'):
writer.write_feed(articles, generator.context,
generator.settings['SUBCATEGORY_FEED_ATOM']
% subcat.fullurl)
if generator.settings.get('SUBCATEGORY_FEED_RSS'):
writer.write_feed(articles, generator.context,
generator.settings['SUBCATEGORY_FEED_RSS']
% subcat.fullurl, feed_type='rss')
def generate(generator, writer):
generate_subcategory_feeds(generator, writer)
generate_subcategories(generator, writer)
def register():
signals.article_generator_context.connect(get_subcategories)
signals.article_generator_finalized.connect(create_subcategories)
signals.article_writer_finalized.connect(generate)