class BannerBlock(BlockQuerySetItemProvider, Block): name = 'banner' default_place = 'rightsidebar' verbose_name = _('Banner Block') help_text = _('Block that represents a list of banners') config_params = BaseBlock.config_params + BlockQuerySetItemProvider.config_params + [ params.PositiveInteger( name='limit', label=ugettext('limit for banner block'), default=3), params.PositiveInteger(name='width', label=ugettext('thumbnail maximum width'), default=0), params.PositiveInteger(name='height', label=ugettext('thumbnail maximum heigh'), default=0), ] default_caching_params = { 'enabled': False, 'timeout': 3600, 'only_anonymous': True, 'vary_on_user': False, 'vary_on_url': True, 'vary_on_language': True, } @classmethod def get_models_refresh_cache(self): return [Banner, BannerCategory] def get_contents(self, request=None, context=None, section=None): banners_list = get_banners(request, filtering_section=False) return banners_list def render(self, request, place, context, *args, **kwargs): number_banners = self.get_config().get('limit', []).get_value() or None width = self.get_config().get('width', []).get_value() or None height = self.get_config().get('height', []).get_value() or None size = None if width and height: size = str(width) + 'x' + str(height) elif width: size = str(width) + 'x' + str(width) elif height: size = str(height) + 'x' + str(height) banners = self.get_queryset(request, context)[:number_banners] return self.render_block(request, template_name='banner/block_banner.html', block_title=ugettext('banners'), context={ 'banners': banners, 'size': size, })
class PortletBannerBlock(Block): name = 'portlet_banner' default_place = 'rightsidebar' verbose_name = _('Portlet Banner Block') help_text = _('Block that represents a banner') config_params = [ params.PositiveInteger(name='width', label=ugettext('thumbnail maximum width'), default=0), params.PositiveInteger(name='height', label=ugettext('thumbnail maximum heigh'), default=0), BannerParam(name='banner', label=ugettext('Choose a banner'), default=None), ] @classmethod def get_models_refresh_cache(self): return [Banner, BannerCategory] def render(self, request, place, context, *args, **kwargs): width = self.get_config().get('width', []).get_value() or None height = self.get_config().get('height', []).get_value() or None size = None if width and height: size = str(width) + 'x' + str(height) elif width: size = str(width) + 'x' + str(width) elif height: size = str(height) + 'x' + str(height) banner_param = self.get_config().get('banner', None) if banner_param and banner_param.value: banner = banner_param.get_obj() block_title = unicode(banner) else: banner = None block_title = ugettext( 'Click in "configure block" and choose a banner') return self.render_block( request, template_name='banner/block_portlet_banner.html', block_title=block_title, context={ 'banner': banner, 'size': size, })
class HashtagTimelineBlock(TimelineProvider, Block): name = 'hashtagtimeline' default_place = 'rightsidebar' verbose_name = _('Timeline of Tag in Twitter ') help_text = _('Block to show a timeline of Twitter for a hashtag.') template_name = 'twitter/hashtag_timeline_block.html' config_params = BaseBlock.config_params + [params.PositiveInteger(name='limit', label=ugettext('Limit for twitter block'), default=3), params.Single(name='hashtag', label=ugettext('Tweets of a hashtag'), default='#merengueproject'), ] def get_block_title(self): hashtag = self.get_config().get('hashtag', []).get_value() return hashtag def get_link(self): hashtag = self.get_config().get('hashtag', []).get_value() if hashtag.startswith('#'): return ('Search ' + hashtag + ' on Twitter!', 'http://www.twitter.com/#!/search/%23' + hashtag[1:] + '/') else: return ('Search ' + hashtag + ' on Twitter!', 'http://www.twitter.com/#!/search/' + hashtag + '/')
class FooBlock(Block): name = 'fooblock' verbose_name = _('Foo block') help_text = _('Block with last foo items published') default_place = 'leftsidebar' config_params = Block.config_params + [ params.PositiveInteger( name='limit', label=_('number of foo items for the "Foo block" block'), default=3, ), ] default_caching_params = { 'enabled': False, 'timeout': 3600, 'only_anonymous': True, 'vary_on_user': False, 'vary_on_url': False, 'vary_on_language': True, } def render(self, request, place, context, *args, **kwargs): limit = self.get_config().get('limit').get_value() content_list = FooModel.objects.published()[:limit] return self.render_block(request, template_name='foo_block.html', block_title=ugettext('Latest foo items'), context={'content_list': content_list})
class PluginConfig(Plugin): name = 'Registration' description = 'Registration plugin' version = '0.0.1' url_prefixes = (({ 'en': 'registration', 'es': 'registro' }, 'plugins.registration.urls'), ) config_params = [ params.PositiveInteger( name='caducity', label=_('hours before the registration url expires (0 for never)'), default=72), params.Single( name='profile_form_class', label=_('Form class to save extra profile data'), default="plugins.registration.forms.DefaultMerengueProfileForm"), ] def get_actions(self): return [RegisterAction] def models(self): return [(Registration, RegistrationAdmin)]
class UserTimelineBlock(TimelineProvider, Block): name = 'usertimeline' default_place = 'rightsidebar' verbose_name = _('Timeline of Twitter User') help_text = _('Block to show a timeline of Twitter for an user.') template_name = 'twitter/timeline_block.html' config_params = BaseBlock.config_params + [params.PositiveInteger(name='limit', label=ugettext('Limit for twitter block'), default=3), params.Single(name='user', label=ugettext('Tweets of this user'), default='merengueproject'), ] def get_block_title(self): user = self.get_config().get('user', []).get_value() return "@%s" % user def get_link(self): error = self.get_tweets() if "doesn't exists" in error[1]: return ('Twitter Mainpage', 'http://www.twitter.com/') else: user = self.get_config().get('user', []).get_value() return ('Follow ' + user + ' on Twitter!', 'http://www.twitter.com/#!/' + user + '/')
class PluginConfig(ContentTypeFilterProvider, Plugin): name = 'RSS syndication' description = 'Plugin to allow RSS syndication of contents' version = '0.0.1a' url_prefixes = (('rss', 'plugins.rss.urls'), ) config_params = ContentTypeFilterProvider.config_params + [ params.PositiveInteger( name="limit", label=_("number of elements to show at the feed"), default=10, ), params.Single(name="portal", label=_("portal name that will be shown as RSS title"), default="Merengue RSS"), ] def get_actions(self): return [GenerateRSS, GenerateSectionRSS] def get_model_admins(self): return [] def get_blocks(self): return [ RSSGlobalFeed, ]
class TagCloudBlock(BlockQuerySetItemProvider, Block): name = 'tagcloud' verbose_name = _('Tag cloud') help_text = _('Block with a tag cloud') default_place = 'leftsidebar' config_params = BaseBlock.config_params + BlockQuerySetItemProvider.config_params + [ params.PositiveInteger( name='max_tags_in_cloud', label=_('Max number of tags in cloud'), default=20, ), ] default_caching_params = { 'enabled': False, 'timeout': 3600, 'only_anonymous': False, 'vary_on_user': False, 'vary_on_url': True, 'vary_on_language': True, } @classmethod def get_models_refresh_cache(self): return [ITag] def render(self, request, place, context, block_content_relation=None, *args, **kwargs): config = self.get_config() limit = config.get('max_tags_in_cloud', []).get_value() filter_section = config.get('filtering_section', False).get_value() reg_viewlet = RegisteredViewlet.objects.by_item_class( TagCloudViewlet, ).get() tag_cloud = reg_viewlet.get_registry_item().get_tag_cloud( request, context, limit, filter_section) if not tag_cloud: return "" return self.render_block(request, template_name='itags/blocks/tagcloud.html', block_title=ugettext('Tag cloud'), context={ 'taglist': tag_cloud, 'filter_section': filter_section })
class LatestEventsBlock(BlockQuerySetItemProvider, Block): name = 'latestevents' verbose_name = _('Latest events') help_text = _('Block with last events items published') default_place = 'rightsidebar' config_params = BaseBlock.config_params + BlockQuerySetItemProvider.config_params + [ params.PositiveInteger( name='limit', label=_('number of events for the "Latest events" block'), default=3, ), ] default_caching_params = { 'enabled': False, 'timeout': 3600, 'only_anonymous': True, 'vary_on_user': False, 'vary_on_url': True, 'vary_on_language': True, } @classmethod def get_models_refresh_cache(self): return [Event] def get_contents(self, request=None, context=None, section=None): events_list = get_events(request, filtering_section=False) return events_list def render(self, request, place, context, *args, **kwargs): number_events = self.get_config().get('limit').get_value() events_list = self.get_queryset(request, context)[:number_events] if self.get_config().get('filtering_section', False) and not events_list: events_list = get_events(request, filtering_section=False)[:number_events] return self.render_block(request, template_name='event/block_latest.html', block_title=_('Latest events'), context={'events_list': events_list})
class PluginConfig(Plugin): name = 'Content menu' description = 'Plugin to associate some contents between them' version = '0.0.1a' config_params = [ params.PositiveInteger( name="numchars", label=_("number of chars that should have the link as maximum"), default=15, ), ] def get_blocks(self): return [ ContentGroupLinksBlock, ] def get_model_admins(self): return [(ContentGroup, ContentGroupAdmin)]
class LatestNewsViewlet(ViewLetQuerySetItemProvider, Viewlet): name = 'latestnews' help_text = _('Latest news') verbose_name = _('Latest news block') config_params = ViewLetQuerySetItemProvider.config_params + [ params.PositiveInteger(name='limit', label=ugettext('limit for news viewlet'), default=3), ] def queryset(self, request, context, section): limit = self.get_config().get('limit').get_value() return NewsItem.objects.published()[:limit] def render(self, request, context=None): if context is None: context = {} news_list = self.get_queryset(request, context) context.update({'news_list': news_list}) return self.render_viewlet(request, template_name='news/viewlet_latest.html', context=context)
class HighlightMenu(Block): name = 'highlightmenu' verbose_name = _('Highlight menu') help_text = _('Block with the microsite links') default_place = 'rightsidebar' config_params = Block.config_params + BlockQuerySetItemProvider.config_params + [ params.PositiveInteger( name='limit', label=_('number of links for the "Highlight menu" block'), default=5, ), params.Single( name='background', label=_('background color for the "Highlight menu" block'), default='#ffffff', ), params.Single( name='link_color', label=_('color of the links inside the "Highlight menu" block'), default='#0000ff', ), params.Single( name='over_color', label= _('color of the links (when the mouse is over) inside the "Highlight menu" block' ), default='#ff00ff', ), ] default_caching_params = { 'enabled': False, 'timeout': 3600, 'only_anonymous': True, 'vary_on_user': False, 'vary_on_url': True, 'vary_on_language': True, } @classmethod def get_models_refresh_cache(self): return [MicroSiteLink] def render(self, request, place, context, *args, **kwargs): section = get_section(request, context) if isinstance(section, MicroSite): microsite = section limit = self.get_config().get('limit').get_value() links = MicroSiteLink.objects.filter( microsite=microsite).visible_by_user(request.user) links = links[:limit] conf = { 'background': self.get_config().get('background').get_value(), 'link_color': self.get_config().get('link_color').get_value(), 'over_color': self.get_config().get('over_color').get_value(), } else: microsite = None links = [] conf = {} return self.render_block( request, template_name='microsite/blocks/highlight_menu.html', block_title=ugettext('Highlight menu'), context={ 'microsite': microsite, 'links': links, 'conf': conf })
class TagCloudViewlet(ViewLetQuerySetItemProvider, Viewlet): name = 'tagcloud' help_text = _('Tag cloud') verbose_name = _('Tag cloud block') config_params = ViewLetQuerySetItemProvider.config_params + [ params.PositiveInteger( name='max_tags_in_cloud', label=ugettext('Max number of tags in cloud'), default='20', ), ] def get_tag_cloud(self, request, context, limit=20, filter_section=None): section = filter_section and self._get_section(request, context) dbparams = { 'tag_table': Tag._meta.db_table, 'tag_id_field': Tag._meta.pk.name, 'item_table': TaggedItem._meta.db_table, 'item_id_field': 'tag_id', 'content_id_field': 'object_id', } if section: content_ids = [ str(i['id']) for i in section.related_content.values('id') ] if not content_ids: taglist = [] else: dbparams.update( {'content_ids': '(%s)' % ','.join(content_ids)}) taglist = Tag.objects.extra( select={ 'item_count': '''SELECT COUNT(*) FROM %(item_table)s WHERE %(tag_table)s.%(tag_id_field)s=%(item_table)s.%(item_id_field)s AND %(item_table)s.%(content_id_field)s in %(content_ids)s''' % dbparams, }).order_by('-item_count') else: taglist = Tag.objects.select_related('itag').extra( select={ 'item_count': '''SELECT COUNT(*) FROM %(item_table)s WHERE %(tag_table)s.%(tag_id_field)s=%(item_table)s.%(item_id_field)s''' % dbparams, }).order_by('-item_count') tag_cloud = [] for tag in taglist: if (limit and len(tag_cloud) >= limit): break try: if not tag.item_count: continue tag.itag.item_count = tag.item_count tag_cloud.append(tag.itag) except ITag.DoesNotExist: continue if not tag_cloud or tag_cloud[0].item_count == 0: return None max_item_count = tag_cloud[ 0].item_count # the first element is always the biggest for t in tag_cloud: t.count = (float(t.item_count) / max_item_count) + 1 tag_cloud.sort(key=attrgetter('tag_name')) return tag_cloud def render(self, request, context): limit = self.get_config().get('max_tags_in_cloud', []).get_value() filter_section = self.get_config().get('filtering_section', False).get_value() tag_cloud = self.get_tag_cloud(request, context, limit, filter_section) return self.render_viewlet( request, template_name='itags/viewlets/tagcloud.html', context={ 'taglist': tag_cloud, 'filter_section': filter_section })
class LatestFilesBlock(BlockQuerySetItemProvider, Block): name = 'latestfiles' default_place = 'rightsidebar' verbose_name = _('Latest Files Block') help_text = _( 'Block that represents a list of recent files of the filebrowser') config_params = BaseBlock.config_params + BlockQuerySetItemProvider.config_params + [ params.PositiveInteger( name='limit', label=_('number of files for the "Latest Files" block'), default=3, ), params.Single( name='mainrepo', label=_('Name of the repository to show files from it'), default='', ), params.Bool( name='filtering_document', label= _('If the repository name is equal to document slug, filter for the files of this repository' ), default=False, ), ] default_caching_params = { 'enabled': False, 'timeout': 3600, 'only_anonymous': True, 'vary_on_user': False, 'vary_on_url': True, 'vary_on_language': True, } def get_contents(self, request=None, context=None, section=None): repos = Repository.objects.all() return repos def queryset(self, request=None, context=None, section=None): queryset = self.get_contents(request, context, section) content = context.get('content', None) document = isinstance(content, Document) and content if section and self.get_config().get('filtering_section', False).get_value(): queryset = queryset.filter(section=section) if self.get_config().get('filtering_document', False).get_value() and \ document and queryset.filter(name=document.slug): queryset = queryset.filter(name=document.slug) return queryset def render(self, request, place, context, *args, **kwargs): repolist = self.get_queryset(request, context) limit = self.get_config().get('limit').get_value() mainrepo = self.get_config().get('mainrepo').get_value() main = None if mainrepo: try: main = repolist.get(name=mainrepo) except Repository.DoesNotExist: pass if main: files = main.latest_files(limit) else: if not repolist: return '' files = [] for repo in repolist: files += repo.latest_files(limit) if not files: return '' files = sorted(files, key=lambda f: f.modificated, reverse=True)[:limit] return self.render_block( request, template_name='filebrowser/blocks/latestfiles.html', block_title=ugettext('Downloads'), context={ 'files': files, })
class PluginConfig(Plugin): name = 'Saml2' description = 'Adds SAML2 authentication and authorization to Merengue' version = '0.1.0dev' url_prefixes = (('saml2', 'plugins.saml2.urls'), ) required_plugins = {'core': {}} required_apps = { 'djangosaml2': {}, } config_params = [ params.Single(name='entity_name', label=_('Entity Name')), params.Single(name='username_attribute', label=_('Username attribute'), default='uid'), params.Single(name='first_name_attribute', label=_('First name attribute'), default='cn'), params.Single(name='last_name_attribute', label=_('First name attribute'), default='sn'), params.Single(name='email_attribute', label=_('Email attribute'), default='mail'), params.Single( name='required_attributes', label=_('Comma/space separated list of required attributes'), default='uid'), params.Single( name='optional_attributes', label=_('Comma/space separated list of optional attributes'), default=''), params.Single(name='xmlsec_binary', label=_('Path to xmlsec1 program'), default='/usr/bin/xmlsec1'), params.Single(name='key_file_path', label=_('Certificate private part')), params.Single(name='cert_file_path', label=_('Certificate public part')), params.PositiveInteger(name='valid_for', label=_('Expiration time in hours'), default=24) ] def get_model_admins(self): return [ (IdentityProvider, IdentityProviderAdmin), (ContactPerson, ContactPersonAdmin), (Organization, OrganizationAdmin), ] def get_actions(self): return [Saml2LoginAction, Saml2LogoutAction] def post_actions(self): login_smal2_url = '/saml2/login/' plugin = RegisteredPlugin.objects.get_by_item(get_plugin('core')) login_url = plugin.config.get('login_url', None) if login_url != login_smal2_url and (not login_url or login_url == settings.LOGIN_URL): plugin.config['login_url'] = login_smal2_url plugin.save()