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