From 0d1203dab1358f48093fae50525f05e82fd87f15 Mon Sep 17 00:00:00 2001 From: Valentin Samir Date: Sat, 26 Oct 2013 19:20:04 +0200 Subject: [PATCH] =?UTF-8?q?[wiki]=20=20th=C3=A8me=20solenoid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wiki/action/allactions.py | 75 +++++ wiki/theme/solenoid.py | 617 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 692 insertions(+) create mode 100644 wiki/action/allactions.py create mode 100644 wiki/theme/solenoid.py diff --git a/wiki/action/allactions.py b/wiki/action/allactions.py new file mode 100644 index 00000000..98d85cf0 --- /dev/null +++ b/wiki/action/allactions.py @@ -0,0 +1,75 @@ +# -*- coding: iso-8859-1 -*- +""" + All Actions action + + Lists the actions available for the current page. + Based on Mandarin's PageAction. + + @copyright: Radomir Dopieralski, and possibly others + 2009, 2010 Renato Silva + + @license: See the README file. +""" + +from MoinMoin import wikiutil +from MoinMoin.Page import Page + +def execute(pagename, request): + _ = request.getText + from MoinMoin.formatter.text_html import Formatter + fmt = request.formatter = Formatter(request) + + emit_http_headers = getattr(request, 'emit_http_headers', None) or getattr(request, 'http_headers', None) + if emit_http_headers is not None: + emit_http_headers() + + request.setContentLanguage(request.lang) + request.theme.send_title(_('Actions for %s') % pagename, page_name=pagename) + request.write(fmt.startContent("content")) # content div provides direction support + request.write(availableactions(request)) + request.write(fmt.endContent()) + request.theme.send_footer(pagename) + +def actionlink(request, action, title, comment=''): + page = request.page + params = '%s?action=%s' % (page.page_name, action) + if action == 'RenamePage': + params += '&subpages_checked=1' + link = wikiutil.link_tag(request, params, title) + return u''.join([u'
  • ', link, comment, u'
  • ']) + + +def availableactions(request): + page = request.page + _ = request.getText + links = [] + try: + available = request.getAvailableActions(page) # Moin 1.8 + except AttributeError: + from MoinMoin.action import get_available_actions + available = get_available_actions(request.cfg, page, request.user) # Moin 1.9 + + def split_and_translate(title): + title = Page(request, title).split_title(request) + return _(title, formatted=False) + + available = [(split_and_translate(action), action) for action in available] + + if page.isWritable() and request.user.may.write(page.page_name): + available.append((_('Edit Text'), 'edit')) + + if request.user.valid and request.user.email: + subscribed = request.user.isSubscribedTo([page.page_name]) + title = (_('Subscribe'), _('Unsubscribe'))[subscribed] + action = ('subscribe', 'unsubscribe')[subscribed] + available.append((title, action)) + + available.append((_('Print View'), 'print')) + available.append((_('View Raw Text'), 'raw')) + available.append((_('Delete Cache'), 'refresh')) + + available.sort() + for title, action in available: + links.append(actionlink(request, action, title)) + + return u'' % u''.join(links) diff --git a/wiki/theme/solenoid.py b/wiki/theme/solenoid.py new file mode 100644 index 00000000..5e69681c --- /dev/null +++ b/wiki/theme/solenoid.py @@ -0,0 +1,617 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin Solenoid theme + + @copyright: 2007 Radomir Dopieralski , Oliver Siemoneit + 2009, 2010 Renato Silva + + @license: See the README file. +""" + +from MoinMoin import wikiutil +from MoinMoin.theme import ThemeBase, modernized +from MoinMoin.Page import Page +from MoinMoin.i18n import Translation, translations, po_filename +import re, os, glob, StringIO + +class Theme(ThemeBase): + + name = "solenoid" + Name = name.capitalize() + home = "http://moinmo.in/ThemeMarket/Solenoid" + + _ = lambda x: x + + icons = { + + # Key Alt Icon filename W H + # ---------------------------------------------------------------------------------- + # Navibar + 'help': ("%(page_help_contents)s", "moin-help.png", 16, 16), + 'find': ("%(page_find_page)s", "moin-search.png", 16, 16), + 'diff': (_("Diffs"), "moin-diff.png", 20, 16), + 'info': (_("Info"), "moin-info.png", 16, 16), + 'edit': (_("Edit"), "moin-edit.png", 16, 16), + 'unsubscribe': (_("Unsubscribe"), "moin-unsubscribe.png", 16, 16), + 'subscribe': (_("Subscribe"), "moin-subscribe.png", 16, 16), + 'addquicklink': (_("Add quicklink"), "moin-addquicklink.png", 16, 16), + 'delquicklink': (_("Delete quicklink"), "moin-delquicklink.png", 16, 16), + + 'raw': (_("Raw"), "moin-raw.png", 16, 16), + 'xml': (_("XML"), "moin-xml.png", 20, 13), + 'print': (_("Print"), "moin-print.png", 16, 16), + 'view': (_("View"), "moin-show.png", 16, 16), + 'home': (_("Home"), "moin-home.png", 16, 16), + 'up': (_("Up"), "moin-parent.png", 16, 16), + + # FileAttach + 'attach': ("%(attach_count)s", "moin-attach.png", 16, 16), + 'attachimg': ("[ATTACH]", "attach.png", 32, 32), + + # RecentChanges + 'rss': (_("[RSS]"), "moin-rss.png", 39, 14), + 'deleted': (_("[DELETED]"), "moin-deleted.png", 16, 16), + 'updated': (_("[UPDATED]"), "moin-edit.png", 16, 16), + 'renamed': (_("[RENAMED]"), "moin-renamed.png", 16, 16), + 'conflict': (_("[CONFLICT]"), "moin-conflict.png", 23, 16), + 'new': (_("[NEW]"), "moin-new.png", 16, 16), + 'diffrc': (_("[DIFF]"), "moin-diff.png", 16, 16), + + # General + 'bottom': (_("[BOTTOM]"), "moin-bottom.png", 12, 12), + 'top': (_("[TOP]"), "moin-top.png", 12, 12), + 'www': ("[WWW]", "moin-www.png", 12, 12), + 'mailto': ("[MAILTO]", "moin-email.png", 12, 12), + 'news': ("[NEWS]", "moin-news.png", 12, 12), + 'irc': ("[IRC]", "moin-irc.png", 15, 15), + 'telnet': ("[TELNET]", "moin-telnet.png", 12, 12), + 'ftp': ("[FTP]", "moin-ftp.png", 12, 12), + 'file': ("[FILE]", "moin-ftp.png", 12, 12), + + # Search forms + 'searchbutton': ("[?]", "moin-search.png", 16, 16), + 'interwiki': ("[%(wikitag)s]", "moin-inter.png", 12, 12), + 'badinterwiki': ("[%(wikitag)s]", "moin-badinter.png", 12, 12), + + # Smileys + 'X-(': ("X-(", 'angry.png', 18, 18), + ':D': (":D", 'biggrin.png', 18, 18), + '<:(': ("<:(", 'frown.png', 18, 18), + ':o': (":o", 'redface.png', 18, 18), + ':(': (":(", 'sad.png', 18, 18), + ':)': (":)", 'smile.png', 18, 18), + 'B)': ("B)", 'smile2.png', 18, 18), + ':))': (":))", 'smile3.png', 18, 18), + ';)': (";)", 'smile4.png', 18, 18), + '/!\\': ("/!\\", 'alert.png', 16, 16), + '': ("", 'attention.png', 16, 16), + '(!)': ("(!)", 'idea.png', 16, 16), + ':-?': (":-?", 'tongue.png', 18, 18), + ':\\': (":\\", 'ohwell.png', 18, 18), + '>:>': (">:>", 'devil.png', 18, 18), + '|)': ("|)", 'tired.png', 18, 18), + ':-(': (":-(", 'sad.png', 18, 18), + ':-)': (":-)", 'smile.png', 18, 18), + 'B-)': ("B-)", 'smile2.png', 18, 18), + ':-))': (":-))", 'smile3.png', 18, 18), + ';-)': (";-)", 'smile4.png', 18, 18), + '|-)': ("|-)", 'tired.png', 18, 18), + '(./)': ("(./)", 'checkmark.png', 16, 16), + '{OK}': ("{OK}", 'thumbs-up.png', 16, 16), + '{X}': ("{X}", 'icon-error.png', 16, 16), + '{i}': ("{i}", 'icon-info.png', 16, 16), + '{1}': ("{1}", 'prio1.png', 16, 16), + '{2}': ("{2}", 'prio2.png', 16, 16), + '{3}': ("{3}", 'prio3.png', 16, 16), + '{*}': ("{*}", 'star_on.png', 16, 16), + '{o}': ("{o}", 'star_off.png', 16, 16), + + # New big icons for classic theme + 'diff-big': (_("Diffs"), "moin-diff-big.png", 31, 25), + 'info-big': (_("Info"), "moin-info-big.png", 25, 25), + 'edit-big': (_("Edit"), "moin-edit-big.png", 25, 25), + 'unsubscribe-big': (_("Unsubscribe"), "moin-unsubscribe-big.png", 25, 25), + 'subscribe-big': (_("Subscribe"), "moin-subscribe-big.png", 25, 25), + 'raw-big': (_("Raw"), "moin-raw-big.png", 25, 25), + 'print-big': (_("Print"), "moin-print-big.png", 25, 25), + 'view-big': (_("View"), "moin-show-big.png", 25, 25), + 'delquicklink-big': (_("Delete quicklink"), "moin-delquicklink-big.png", 25, 25), + 'addquicklink-big': (_("Add quicklink"), "moin-addquicklink-big.png", 25, 25), + 'attach-big': (_("Add/Manage files"), "moin-iconattach-big.png", 25, 25), + } + + del _ + + def _(self, text): + lang = self.request.lang + _translations = self._translations + if lang in _translations: + if text in _translations[lang]: + return _translations[lang][text] + return self.request.getText(text, formatted=False) + + def _get_config(self, source, config_name, default=None): + return getattr(source, '%s_%s' % (self.name, config_name), default) + + def get_bool_user_config(self, config_name): + user = self.request.user + if not user.valid: + return None + user_config = self._get_config(user, config_name) + return {'0': False, '1': True}.get(user_config, None) + + def get_config(self, config_name, default=None, by_user=True): + if by_user and self.userprefs_allowed: + user_config = self.get_bool_user_config(config_name) + if user_config is not None: + return user_config + return self._get_config(self.cfg, config_name, default) + + def _remove_old_userprefs(self): + user = self.request.user + old_attribute = 'solenoid_enable_prefs' + if hasattr(user, old_attribute): + delattr(user, old_attribute) + user.save() + + def __init__(self, request): + ThemeBase.__init__(self, request) + append_translation = self.get_config('append_translation', default=True, by_user=False) + self._translations = self.theme_translations(append_translation) + self.cms_mode = self.get_config('cms_mode', default=False, by_user=False) + + self._remove_old_userprefs() + self.userprefs_allowed = self.get_config('userprefs', default=False, by_user=False) + if self.userprefs_allowed: + self.userprefs_definition = [ + (bool, 'clear', self._('Clear look')), + (bool, 'shadow', self._('Shadows for box mode')), + (bool, 'full_screen', self._('Full screen mode')) ] + + try: + self.static_prefix = self.cfg.url_prefix_static + except AttributeError: + self.static_prefix = self.cfg.url_prefix + + def theme_translations(self, append=False): + """Load personal translations to be used by this theme. + + @param append: if True makes theme translation global by appending it to the default Moin translation system. + @return: a dict (indexed by language) of translation dicts, or an empty dict if append=True. + """ + _translations = {} + request = self.request + po_dir = os.path.join('i18n', self.name) + + for lang_file in glob.glob(po_filename(request, i18n_dir=po_dir, language='*', domain='Theme')): + dummy_language, domain, ext = os.path.basename(lang_file).split('.') + language = dummy_language.split('_')[0] + t = Translation(dummy_language, domain) + t.loadLanguage(request, trans_dir=po_dir) + + if append: + if not language in translations: + translations[language] = Translation(language) + translations[language].loadLanguage(request) + translations[language].raw.update(t.raw) + else: + _translations[language] = {} + for key, text in t.raw.items(): + _translations[language][key] = text + + return _translations + + def title_for_print(self, d): + _ = self._ + cfg = self.request.cfg + page_path = wikiutil.escape(d['title_text'].replace('/', ' / ')) + lines = d['page'].get_raw_body().split('\n') + + for line in lines: + line = line.strip() + if not line.startswith('#') and not line.startswith('<<') and not line == '': + + inline_display = u'' + print_action = self.request.action == 'print' + for media, display in (('all', ('none', 'block')[print_action]), ('print', 'block')): + inline_display += '' % (media, display) + + if re.sub('^\s*=+\s+[^=]+\s+=+\s*$', '', line) == '': + # If page starts with a title, then make page path a header before it + return u'%s%s: %s' % (inline_display, _('Page name'), page_path) + else: + # Page does not start with a title, so we use page path as title + interwiki_name = '%s: ' % (cfg.interwikiname or 'Wiki') + prefix = ['', interwiki_name][cfg.show_interwiki] + return u'%s

    %s%s

    ' % (inline_display, prefix, page_path) + break + return u'' + + def header(self, d): + _ = self._ + wrapper_class = u'wrapper' + sidebar = self.sidebar(d) + if sidebar == u'': + wrapper_class += u' no-sidebar' + page_title = self.title(d) + site_logo = self.logo() + if (site_logo == ''): + site_logo = page_title.replace('

    ', '

    ', '') + site_logo = site_logo.replace('id="', 'id="logo_') + site_logo = site_logo.replace("id='", "id='logo_") + page_title = '

     

    ' + page_title = (page_title, '')[self.cms_mode and not self.request.user.valid] + parts = [ + self.emit_custom_html(self.cfg.page_header1), + u'
    ', + site_logo, + self.searchform(d), + self.username(d), + self.gotobar(d), + self.msg(d), + self.editbar(d), + page_title, + self.logged_trail(d), + u'
    ', + self.emit_custom_html(self.cfg.page_header2), + self.title_for_print(d), + u'
    ' % wrapper_class, + sidebar, + u'
    \n' % self.content_lang_attr(), + "" + % (_("Attention"), _("You are using an outdated version of Internet Explorer " + "which is not supported by this site. Please update your browser.")) + ] + return u''.join(parts) + + editorheader = header + + def title(self, d): + if self.request.action == 'print': + return self.title_for_print(d) + modernized_theme = modernized.Theme(self.request) + try: + screen_title = self.title_with_separators # Moin 1.9 + except AttributeError: + screen_title = modernized_theme.title # Moin 1.8 + return u'

    %s%s

    ' % (modernized_theme.interwiki(d), screen_title(d)) + + def logged_trail(self, d): + user = self.request.user + html = u"" + if user.valid and user.show_page_trail: + if len(user.getTrail())>1: + html = self.trail(d) + return html + + def footer(self, d, **keywords): + page = d['page'] + custom_footer = self.cfg.page_credits + if isinstance(custom_footer, list): + if self.get_config('theme_credit', True, by_user=False): + theme_link = u'%s Theme Powered' % (self.home, self.Name) + custom_footer = [theme_link] + custom_footer + custom_footer = '  |  '.join(custom_footer) + custom_footer = '%s' % custom_footer + parts = [ + u'
    ', + u'
    ', # wrapper and content divs + self.emit_custom_html(self.cfg.page_footer1), + u'', + self.emit_custom_html(self.cfg.page_footer2), + ] + return u''.join(parts) + + def sidebar(self, d, **keywords): + """ Display page called SideBar as an additional element on every page + + @param d: parameter dictionary + @rtype: string + @return: sidebar html + """ + request = self.request + _ = self._ + sidebar = request.getPragma('sidebar', u'SideBar') + page = Page(request, sidebar) + if not page.exists() or not request.user.may.read(page.page_name): + return u'' + buff = StringIO.StringIO() + request.redirect(buff) + try: + try: + page.send_page(content_only=1, content_id="sidebar") + except TypeError: + page.send_page(request, content_only=1, content_id="sidebar") + finally: + request.redirect() + return u'' % buff.getvalue() + + def editbar(self, d, **keywords): + if self.cms_mode and not self.request.user.valid: + return u'' + page = d['page'] + if not self.shouldShowEditbar(page): + return u'' + result = [] + enabled_items = self.request.cfg.edit_bar + suplementation_enabled = self.request.cfg.supplementation_page + + if 'Edit' in enabled_items: + result.append(self.edit_link(page)) + result.append(self.revert_link(page)) + + if 'Comments' in enabled_items: + result.append(self.toggle_comments_link(page)) + + if ('Discussion' in enabled_items and + self.request.getPragma('supplementation-page', suplementation_enabled) in + (True, 1, 'on', '1')): + result.append(self.supplementation_page_nameLink(page)) + + if 'Info' in enabled_items: + result.append(self.info_link(page)) + if 'Subscribe' in enabled_items: + result.append(self.subscribeLink(page)) + if 'Quicklink' in enabled_items: + result.append(self.quicklinkLink(page)) + if 'Attachments' in enabled_items: + result.append(self.attach_link(page)) + + if 'ActionsMenu' in enabled_items: + result.append(self.actionsMenu(page).replace('', '')) + else: + result.append(self.admin_link(page)) + return u'
    %s
    ' % (u' '.join(result)) + + def edit_link(self, page): + if not (page.isWritable() and self.request.user.may.write(page.page_name)): + return self.disabledEdit() + params = '%s?action=edit' % wikiutil.quoteWikinameURL(page.page_name) + return wikiutil.link_tag(self.request, params, self._('Edit'), css_class="edit", name="texteditlink") + + def info_link(self, page): + params = '%s?action=info' % wikiutil.quoteWikinameURL(page.page_name) + return wikiutil.link_tag(self.request, params, self._('History'), css_class="history") + + def revert_link(self, page): + try: + rev = self.request.rev + except AttributeError: + return u'' + if not (rev and page.isWritable() and self.request.user.may.revert(page.page_name)): + return u'' + params = '%s?action=revert&rev=%d' % (wikiutil.quoteWikinameURL(page.page_name), rev) + return wikiutil.link_tag(self.request, params, self._('Revert'), css_class="revert") + + def attach_link(self, page): + params = '%s?action=AttachFile' % wikiutil.quoteWikinameURL(page.page_name) + return wikiutil.link_tag(self.request, params, self._('Attachments'), css_class="attachments") + + def toggle_comments_link(self, page): + return '''''' % self._('Comments') + + def admin_link(self, page): + params = '%s?action=allactions' % wikiutil.quoteWikinameURL(page.page_name) + return wikiutil.link_tag(self.request, params, self._('All Actions'), css_class="admin") + + def gotobar(self, d, **k): + request = self.request + found = {} + items = [] + item_template = u'
  • %s
  • ' + current = d['page_name'] + if request.cfg.navi_bar: + for text in request.cfg.navi_bar: + pagename, link = self.splitNavilink(text, localize=1) + if self.request.user.may.read(pagename): + cls = ['wikilink', 'wikilink current'][pagename == current] + items.append(item_template %(cls, link)) + found[pagename] = 1 + userlinks = request.user.getQuickLinks() + for text in userlinks: + pagename, link = self.splitNavilink(text, localize=0) + if not pagename in found: + cls = ['userlink', 'userlink current'][pagename == current] + items.append(item_template % (cls, link)) + found[pagename] = 1 + return u'' % u' '.join(items) + + def browser_is_konqueror(self): + try: + browser = self.request.user_agent.browser # Moin 1.9 + except AttributeError: + browser = self.request.http_user_agent # Moin 1.8 + return 'konqueror' in browser.lower() + + def html_stylesheets(self, d): + + def ie_version_spec(ie_style): return re.compile('msie/.*_ie').sub('IE ', ie_style) + def ie_style(style, ie_version): return 'msie/%s_ie%d' % (style, ie_version) + def is_konqueror_style(style): return style.startswith('konqueror') + def is_ie_style(style): return style.startswith('msie') + + def ie_content(content, version_spec='IE'): + version_spec = version_spec.replace('<= ', 'lte ') + return '' % (version_spec, content) + + def is_expected(style, namespace, custom_dir_exists): + if namespace == '/custom': + return custom_dir_exists + else: + return not (is_ie_style(style) or is_konqueror_style(style)) or (style in expected_styles) + + def get_media_param(): + try: + return self.request.values.get('media') + except AttributeError: + return self.request.form.get('media', [None])[0] + + def add_style(style, media='all'): + styles.append((style, media)) + if self.browser_is_konqueror(): + styles.append(('konqueror/%s' % style, media)) + for version in [7, 8]: + style_for_ie = ie_style(style, version) + styles.append((style_for_ie, media)) + + expected_styles = [ie_style(style, version) for style, version in ( + ('style', 7), + ('style', 8), + ('shadow', 8), + ('shadow_clear', 8) + )] + expected_styles.append('konqueror/style') + expected_styles.append('konqueror/shadow') + expected_styles.append('konqueror/shadow_clear') + + clear = self.get_config('clear', default=False) + shadow = self.get_config('shadow', default=False) + full_screen = self.get_config('full_screen', default=False) + print_action = self.request.action == 'print' + + tags = [] + styles = [] + add_style('style') + if clear: + add_style('clear') + + if print_action: + add_style('print') + if get_media_param() == 'projection': + add_style('projection') + else: + add_style('projection', media='projection') + else: + if full_screen: + add_style('full', media='screen') + elif shadow: + add_style('shadow', media='screen') + if clear: + add_style('shadow_clear', media='screen') + + add_style('print', media='print') + add_style('print', media='projection') + add_style('projection', media='projection') + + static_dir = self.get_config('htdocs_dir', by_user=False) + if static_dir is None: + try: + # Moin 1.9 + from MoinMoin.web.static import STATIC_FILES_PATH + static_dir = STATIC_FILES_PATH + except ImportError: + # Moin 1.8 + moin_base = re.sub('MoinMoin$', '', self.cfg.moinmoin_dir) + static_dir = os.path.join(moin_base, 'wiki', 'htdocs') + if not os.path.exists(static_dir): + static_dir = '/usr/share/moin/htdocs' + + link_template = '' + url_prefix = "%s/%s/css" % (self.static_prefix, self.name) + css_dir = os.path.join(static_dir, self.name, 'css') + custom_dir = os.path.join(css_dir, 'custom') + found_css_dir = os.path.exists(css_dir) + found_custom_dir = found_css_dir and os.path.exists(custom_dir) + + for style, media in styles: + for namespace in ['', '/custom']: + css_url = '%s%s/%s.css' % (url_prefix, namespace, style) + css_file = '%s%s/%s.css' % (css_dir, namespace, style) + if not found_css_dir or (is_expected(style, namespace, found_custom_dir) and os.path.exists(css_file)): + css_link = link_template % (media, css_url) + if is_ie_style(style): + css_link = ie_content(css_link, ie_version_spec(style)) + tags.append(css_link) + + return '\n'.join(tags) + + def searchform(self, d): + _ = self._ + form = self.request.form + updates = { + 'search_label' : _('Search:'), + 'search_value': wikiutil.escape(form.get('value', [''])[0], 1), + 'search_full_label' : _('Text'), + 'search_title_label' : _('Titles'), + } + d.update(updates) + + return u''' +''' % d + + def pageinfo(self, page): + if self.cms_mode and not self.request.user.valid: + return u'' + if self.request.action == 'print': + return u'' + _ = self._ + html = '' + if self.shouldShowPageinfo(page): + info = page.lastEditInfo() + if info: + if info['editor']: + info = _("last edited %(time)s by %(editor)s") % info + else: + info = _("last modified %(time)s") % info + html = '%(info)s\n' % { + 'lang': self.ui_lang_attr(), + 'info': info + } + return html + + def logo(self): + logo = u'' + if self.cfg.logo_string: + pagename = wikiutil.getFrontPage(self.request).page_name + pagename = wikiutil.quoteWikinameURL(pagename) + logo = wikiutil.link_tag(self.request, pagename, self.cfg.logo_string, css_class="logo") + return logo + + def headscript(self, d): + """Override the stupid default script with its hardcoded HTML structure""" + return u''' +''' + +def execute(request): + return Theme(request)