File diff 000000000000 → 000000000000
plugins/tag_cloud/tag_cloud.py
Show inline comments
 
new file 100644
 
'''
 
tag_cloud
 
===================================
 

	
 
This plugin generates a tag cloud from available tags
 
'''
 
from __future__ import unicode_literals
 

	
 
from collections import defaultdict
 
from operator import itemgetter
 

	
 
import logging
 
import math
 
import random
 

	
 
from pelican import signals
 

	
 
logger = logging.getLogger(__name__)
 

	
 

	
 
def set_default_settings(settings):
 
    settings.setdefault('TAG_CLOUD_STEPS', 4)
 
    settings.setdefault('TAG_CLOUD_MAX_ITEMS', 100)
 
    settings.setdefault('TAG_CLOUD_SORTING', 'random')
 
    settings.setdefault('TAG_CLOUD_BADGE', False)
 

	
 

	
 
def init_default_config(pelican):
 
    from pelican.settings import DEFAULT_CONFIG
 
    set_default_settings(DEFAULT_CONFIG)
 
    if(pelican):
 
            set_default_settings(pelican.settings)
 

	
 

	
 
def generate_tag_cloud(generator):
 
    tag_cloud = defaultdict(int)
 
    for article in generator.articles:
 
        for tag in getattr(article, 'tags', []):
 
            tag_cloud[tag] += 1
 

	
 
    tag_cloud = sorted(tag_cloud.items(), key=itemgetter(1), reverse=True)
 
    tag_cloud = tag_cloud[:generator.settings.get('TAG_CLOUD_MAX_ITEMS')]
 

	
 
    tags = list(map(itemgetter(1), tag_cloud))
 
    if tags:
 
        max_count = tags[0]
 
        min_count = tags[-1]
 
    steps = generator.settings.get('TAG_CLOUD_STEPS')
 

	
 
    # calculate word sizes
 
    def generate_tag(tag, count):
 
        tag = (
 
            tag,
 
            int(math.floor(steps - (steps - 1) * math.log(count - min_count + 1)
 
                / (math.log(max_count - min_count + 1) or 1)))
 
        )
 
        if generator.settings.get('TAG_CLOUD_BADGE'):
 
            tag += (count,)
 
        return tag
 

	
 
    tag_cloud = [
 
        generate_tag(tag, count)
 
        for tag, count in tag_cloud
 
    ]
 

	
 
    sorting = generator.settings.get('TAG_CLOUD_SORTING')
 

	
 
    if sorting == 'alphabetically':
 
        tag_cloud.sort(key=lambda elem: elem[0].name)
 
    elif sorting == 'alphabetically-rev':
 
        tag_cloud.sort(key=lambda elem: elem[0].name, reverse=True)
 
    elif sorting == 'size':
 
        tag_cloud.sort(key=lambda elem: elem[1])
 
    elif sorting == 'size-rev':
 
        tag_cloud.sort(key=lambda elem: elem[1], reverse=True)
 
    elif sorting == 'random':
 
        random.shuffle(tag_cloud)
 
    else:
 
        logger.warning("setting for TAG_CLOUD_SORTING not recognized: %s, "
 
                       "falling back to 'random'", sorting)
 
        random.shuffle(tag_cloud)
 

	
 
    # make available in context
 
    generator.tag_cloud = tag_cloud
 
    generator._update_context(['tag_cloud'])
 

	
 

	
 
def register():
 
    signals.initialized.connect(init_default_config)
 
    signals.article_generator_finalized.connect(generate_tag_cloud)