paul@13 | 1 | # -*- coding: iso-8859-1 -*- |
paul@13 | 2 | """ |
paul@13 | 3 | MoinMoin - SharedContent macro, based on the FeedReader macro |
paul@13 | 4 | |
paul@58 | 5 | @copyright: 2008, 2012, 2013, 2014 by Paul Boddie <paul@boddie.org.uk> |
paul@13 | 6 | @license: GNU GPL (v2 or later), see COPYING.txt for details. |
paul@13 | 7 | """ |
paul@13 | 8 | |
paul@13 | 9 | from MoinMoin.Page import Page |
paul@46 | 10 | from MoinSupport import parseMacroArguments |
paul@58 | 11 | from MoinShare import getUpdateSources, getUpdates, \ |
paul@58 | 12 | getUpdatesFromPage, getUpdatesFromStore, \ |
paul@61 | 13 | formatUpdate, Update, \ |
paul@61 | 14 | FeedMissingError, FeedContentTypeError |
paul@14 | 15 | |
paul@13 | 16 | Dependencies = ["time"] |
paul@13 | 17 | |
paul@13 | 18 | MAX_ENTRIES = 5 |
paul@22 | 19 | |
paul@22 | 20 | # The macro itself. |
paul@22 | 21 | |
paul@22 | 22 | def execute(macro, args): |
paul@22 | 23 | request = macro.request |
paul@22 | 24 | fmt = macro.formatter |
paul@22 | 25 | _ = request.getText |
paul@22 | 26 | |
paul@31 | 27 | source_pages = [] |
paul@22 | 28 | show_content = None |
paul@22 | 29 | max_entries = None |
paul@22 | 30 | |
paul@22 | 31 | for arg, value in parseMacroArguments(args): |
paul@31 | 32 | if arg == "sources": |
paul@31 | 33 | source_pages.append(value) |
paul@22 | 34 | elif arg == "show": |
paul@28 | 35 | show_content = value.lower() |
paul@22 | 36 | elif arg == "limit": |
paul@22 | 37 | try: |
paul@22 | 38 | max_entries = int(value) |
paul@22 | 39 | except ValueError: |
paul@22 | 40 | return fmt.text(_("SharedContent: limit must be set to the maximum number of entries to be shown")) |
paul@22 | 41 | |
paul@31 | 42 | if not source_pages: |
paul@31 | 43 | return fmt.text(_("SharedContent: at least one sources page must be specified")) |
paul@31 | 44 | |
paul@31 | 45 | sources = {} |
paul@31 | 46 | |
paul@31 | 47 | for source_page in source_pages: |
paul@31 | 48 | sources.update(getUpdateSources(source_page, request)) |
paul@31 | 49 | |
paul@31 | 50 | if not sources: |
paul@31 | 51 | return fmt.text(_("SharedContent: at least one update source must be specified")) |
paul@22 | 52 | |
paul@22 | 53 | show_content = show_content or False |
paul@22 | 54 | max_entries = max_entries or MAX_ENTRIES |
paul@22 | 55 | |
paul@31 | 56 | # Retrieve updates, classifying them as missing or bad and excluding them if |
paul@31 | 57 | # appropriate. |
paul@23 | 58 | |
paul@22 | 59 | updates = [] |
paul@22 | 60 | feeds = [] |
paul@31 | 61 | unspecified = [] |
paul@22 | 62 | missing = [] |
paul@22 | 63 | bad_content = [] |
paul@13 | 64 | |
paul@31 | 65 | for source_name, source_parameters in sources.items(): |
paul@31 | 66 | location = source_parameters.get("location") |
paul@31 | 67 | if not location: |
paul@31 | 68 | unspecified.append(source_name) |
paul@31 | 69 | continue |
paul@31 | 70 | |
paul@22 | 71 | try: |
paul@31 | 72 | max_entries_for_feed = int(source_parameters["limit"]) |
paul@31 | 73 | except (KeyError, ValueError): |
paul@31 | 74 | max_entries_for_feed = None |
paul@22 | 75 | |
paul@31 | 76 | # Retrieve updates from feeds. |
paul@30 | 77 | |
paul@31 | 78 | if source_parameters.get("type") == "url": |
paul@31 | 79 | try: |
paul@35 | 80 | feed_info, feed_updates = getUpdates(request, location, max_entries_for_feed, show_content) |
paul@31 | 81 | updates += feed_updates |
paul@31 | 82 | feeds.append((location, feed_info)) |
paul@31 | 83 | except FeedMissingError: |
paul@31 | 84 | missing.append(location) |
paul@31 | 85 | except FeedContentTypeError: |
paul@31 | 86 | bad_content.append(location) |
paul@30 | 87 | |
paul@31 | 88 | # Retrieve updates from pages. |
paul@30 | 89 | |
paul@31 | 90 | elif source_parameters.get("type") == "page": |
paul@31 | 91 | page = Page(request, location) |
paul@31 | 92 | updates += getUpdatesFromPage(page, request) |
paul@31 | 93 | |
paul@31 | 94 | # Build feed-equivalent information for the update source. |
paul@31 | 95 | |
paul@31 | 96 | feeds.append(( |
paul@31 | 97 | page.url(request, {"action" : "SharedUpdates", "doit" : "1"}), ( |
paul@31 | 98 | "internal", _("Updates from page %s") % location, |
paul@31 | 99 | page.url(request) |
paul@31 | 100 | ) |
paul@31 | 101 | )) |
paul@30 | 102 | |
paul@33 | 103 | # Retrieve updates from message stores. |
paul@33 | 104 | |
paul@33 | 105 | elif source_parameters.get("type") == "store": |
paul@33 | 106 | page = Page(request, location) |
paul@33 | 107 | updates += getUpdatesFromStore(page, request) |
paul@33 | 108 | |
paul@33 | 109 | # Build feed-equivalent information for the update source. |
paul@33 | 110 | |
paul@33 | 111 | feeds.append(( |
paul@33 | 112 | page.url(request, {"action" : "SharedUpdates", "store" : "1", "doit" : "1"}), ( |
paul@33 | 113 | "internal", _("Updates from message store on page %s") % location, |
paul@33 | 114 | page.url(request) |
paul@33 | 115 | ) |
paul@33 | 116 | )) |
paul@33 | 117 | |
paul@30 | 118 | # Prepare the output. |
paul@30 | 119 | |
paul@22 | 120 | output = [] |
paul@22 | 121 | append = output.append |
paul@22 | 122 | |
paul@22 | 123 | # Show the updates. |
paul@22 | 124 | |
paul@22 | 125 | if not show_content: |
paul@22 | 126 | append(fmt.bullet_list(on=1)) |
paul@22 | 127 | |
paul@22 | 128 | # NOTE: Permit configurable sorting. |
paul@22 | 129 | |
paul@22 | 130 | updates.sort() |
paul@22 | 131 | updates.reverse() |
paul@22 | 132 | |
paul@23 | 133 | # Truncate the number of updates to the maximum number. |
paul@23 | 134 | |
paul@23 | 135 | updates = updates[:max_entries] |
paul@23 | 136 | |
paul@22 | 137 | for update in updates: |
paul@22 | 138 | |
paul@22 | 139 | # Emit content where appropriate. |
paul@22 | 140 | |
paul@22 | 141 | if show_content: |
paul@22 | 142 | append(fmt.div(on=1, css_class="moinshare-update")) |
paul@38 | 143 | |
paul@54 | 144 | if update.author: |
paul@54 | 145 | append(fmt.div(on=1, css_class="moinshare-author")) |
paul@54 | 146 | append(fmt.text(update.author)) |
paul@54 | 147 | append(fmt.div(on=0)) |
paul@54 | 148 | |
paul@40 | 149 | append(formatUpdate(update, request, fmt)) |
paul@32 | 150 | |
paul@24 | 151 | append(fmt.div(on=1, css_class="moinshare-date")) |
paul@24 | 152 | append(fmt.text(str(update.updated))) |
paul@24 | 153 | append(fmt.div(on=0)) |
paul@40 | 154 | |
paul@24 | 155 | append(fmt.div(on=0)) |
paul@22 | 156 | |
paul@22 | 157 | # Or emit title and link information for items. |
paul@22 | 158 | |
paul@22 | 159 | elif update.title and update.link: |
paul@22 | 160 | append(fmt.listitem(on=1, css_class="moinshare-update")) |
paul@22 | 161 | append(fmt.url(on=1, href=update.link)) |
paul@22 | 162 | append(fmt.icon('www')) |
paul@22 | 163 | append(fmt.text(" " + update.title)) |
paul@22 | 164 | append(fmt.url(on=0)) |
paul@22 | 165 | append(fmt.listitem(on=0)) |
paul@22 | 166 | |
paul@22 | 167 | if not show_content: |
paul@22 | 168 | append(fmt.bullet_list(on=0)) |
paul@22 | 169 | |
paul@22 | 170 | # Show the feeds. |
paul@22 | 171 | |
paul@26 | 172 | for feed_url, (feed_type, channel_title, channel_link) in feeds: |
paul@13 | 173 | if channel_title and channel_link: |
paul@22 | 174 | append(fmt.paragraph(on=1, css_class="moinshare-feed")) |
paul@22 | 175 | append(fmt.url(on=1, href=channel_link)) |
paul@22 | 176 | append(fmt.text(channel_title)) |
paul@13 | 177 | append(fmt.url(on=0)) |
paul@13 | 178 | append(fmt.text(" ")) |
paul@13 | 179 | append(fmt.url(on=1, href=feed_url)) |
paul@13 | 180 | append(fmt.icon('rss')) |
paul@13 | 181 | append(fmt.url(on=0)) |
paul@13 | 182 | append(fmt.paragraph(on=0)) |
paul@13 | 183 | |
paul@22 | 184 | # Show errors. |
paul@22 | 185 | |
paul@22 | 186 | for feed_url in missing: |
paul@22 | 187 | append(fmt.paragraph(on=1, css_class="moinshare-missing-feed-error")) |
paul@22 | 188 | append(fmt.text(_("SharedContent: updates could not be retrieved for %s") % feed_url)) |
paul@22 | 189 | append(fmt.paragraph(on=0)) |
paul@22 | 190 | |
paul@22 | 191 | for feed_url in bad_content: |
paul@22 | 192 | append(fmt.paragraph(on=1, css_class="moinshare-content-type-feed-error")) |
paul@22 | 193 | return fmt.text(_("SharedContent: updates for %s were not provided in Atom or RSS format") % feed_url) |
paul@22 | 194 | append(fmt.paragraph(on=0)) |
paul@13 | 195 | |
paul@13 | 196 | return ''.join(output) |
paul@13 | 197 | |
paul@13 | 198 | # vim: tabstop=4 expandtab shiftwidth=4 |