diff options
| author | Ulf Jasper | 2014-10-19 18:50:15 +0200 |
|---|---|---|
| committer | Ulf Jasper | 2014-10-19 18:50:15 +0200 |
| commit | 8259e90ecdd4fd4d85d81fa410f676e8c245f3f4 (patch) | |
| tree | 19ea666d2bfb02720be899b502376339de5093ff | |
| parent | 58af643d69eeb911ac8842c6dc4ddd06f6ea0b00 (diff) | |
| download | emacs-8259e90ecdd4fd4d85d81fa410f676e8c245f3f4.tar.gz emacs-8259e90ecdd4fd4d85d81fa410f676e8c245f3f4.zip | |
Newsticker: Show feedicons in treeview. Small fix in opml export.
* etc/images/newsticker/README: Add rss-feed.png, rss-feed.svg.
* etc/images/newsticker/rss-feed.png: New.
* etc/images/newsticker/rss-feed.svg: New.
* lisp/net/newst-backend.el: Require url-parse.
(newsticker--get-news-by-wget): Store feed name as process property.
(newsticker--sentinel): Read feed name from process property.
(newsticker--sentinel-work): Rename argument name to feed-name.
Rename variable imageurl to image-url. Pick icon url from Atom
1.0 data. Launch download of feed icon.
(newsticker--get-icon-url-atom-1.0): New.
(newsticker--unxml)
(newsticker--unxml-node)
(newsticker--unxml-attribute): Documentation.
(newsticker--icons-dir): New.
(newsticker--image-get): New arguments FILENAME and DIRECTORY.
Use `url-retrieve' if `newsticker-retrieval-method' is 'intern.
(newsticker--image-download-by-wget): New. Use process properties
for storing informations.
(newsticker--image-sentinel): Read informations from process properties.
(newsticker--image-save)
(newsticker--image-remove)
(newsticker--image-download-by-url)
(newsticker--image-download-by-url-callback): New.
(newsticker-opml-export): Handle url list entries containing a
function instead of an url string.
* lisp/net/newst-reader.el (newsticker-html-renderer): Whitespace.
(newsticker--print-extra-elements)
(newsticker--do-print-extra-element): Documentation
(newsticker--image-read): Optionally limit image height. Use
imagemagick if possible.
(newsticker--icon-read): New.
* lisp/net/newst-treeview.el (newsticker--treeview-item-show): Limit height of feed logo.
(newsticker--treeview-tree-expand): Use feed icons in treeview.
(newsticker--tree-widget-icon-create): New. Set the tree widget icon.
(newsticker--tree-widget-leaf-icon): Use feed icon.
| -rw-r--r-- | etc/ChangeLog | 8 | ||||
| -rw-r--r-- | etc/images/newsticker/README | 2 | ||||
| -rw-r--r-- | etc/images/newsticker/rss-feed.png | bin | 0 -> 639 bytes | |||
| -rw-r--r-- | etc/images/newsticker/rss-feed.svg | 121 | ||||
| -rw-r--r-- | lisp/ChangeLog | 37 | ||||
| -rw-r--r-- | lisp/net/newst-backend.el | 212 | ||||
| -rw-r--r-- | lisp/net/newst-reader.el | 44 | ||||
| -rw-r--r-- | lisp/net/newst-treeview.el | 21 |
8 files changed, 378 insertions, 67 deletions
diff --git a/etc/ChangeLog b/etc/ChangeLog index 5b70ee83c8a..4968084b7ec 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2014-10-19 Ulf Jasper <ulf.jasper@web.de> | ||
| 2 | |||
| 3 | * images/newsticker/rss-feed.png: New. | ||
| 4 | |||
| 5 | * images/newsticker/rss-feed.svg: New. | ||
| 6 | |||
| 7 | * images/newsticker/README: Add rss-feed.png, rss-feed.svg. | ||
| 8 | |||
| 1 | 2014-10-18 Michal Nazarewicz <mina86@mina86.com> | 9 | 2014-10-18 Michal Nazarewicz <mina86@mina86.com> |
| 2 | 10 | ||
| 3 | * NEWS: Mention new whitespace-mode option: big-indent. | 11 | * NEWS: Mention new whitespace-mode option: big-indent. |
diff --git a/etc/images/newsticker/README b/etc/images/newsticker/README index 237b7f08e66..31ca46c8aff 100644 --- a/etc/images/newsticker/README +++ b/etc/images/newsticker/README | |||
| @@ -2,7 +2,7 @@ COPYRIGHT AND LICENSE INFORMATION FOR IMAGE FILES | |||
| 2 | 2 | ||
| 3 | Files: browse-url.xpm get-all.xpm mark-immortal.xpm mark-read.xpm | 3 | Files: browse-url.xpm get-all.xpm mark-immortal.xpm mark-read.xpm |
| 4 | narrow.xpm next-feed.xpm next-item.xpm prev-feed.xpm | 4 | narrow.xpm next-feed.xpm next-item.xpm prev-feed.xpm |
| 5 | prev-item.xpm update.xpm | 5 | prev-item.xpm rss-feed.png rss-feed.svg update.xpm |
| 6 | Author: Ulf Jasper | 6 | Author: Ulf Jasper |
| 7 | Copyright (C) 2011-2014 Free Software Foundation, Inc. | 7 | Copyright (C) 2011-2014 Free Software Foundation, Inc. |
| 8 | License: GNU General Public License version 3 or later (see COPYING) | 8 | License: GNU General Public License version 3 or later (see COPYING) |
diff --git a/etc/images/newsticker/rss-feed.png b/etc/images/newsticker/rss-feed.png new file mode 100644 index 00000000000..41a3263390a --- /dev/null +++ b/etc/images/newsticker/rss-feed.png | |||
| Binary files differ | |||
diff --git a/etc/images/newsticker/rss-feed.svg b/etc/images/newsticker/rss-feed.svg new file mode 100644 index 00000000000..a4abd6cc19f --- /dev/null +++ b/etc/images/newsticker/rss-feed.svg | |||
| @@ -0,0 +1,121 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
| 2 | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||
| 3 | |||
| 4 | <svg | ||
| 5 | xmlns:dc="http://purl.org/dc/elements/1.1/" | ||
| 6 | xmlns:cc="http://creativecommons.org/ns#" | ||
| 7 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||
| 8 | xmlns:svg="http://www.w3.org/2000/svg" | ||
| 9 | xmlns="http://www.w3.org/2000/svg" | ||
| 10 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||
| 11 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||
| 12 | width="16px" | ||
| 13 | height="16px" | ||
| 14 | id="svg3028" | ||
| 15 | version="1.1" | ||
| 16 | inkscape:version="0.48.5 r10040" | ||
| 17 | sodipodi:docname="newst-rss.svg"> | ||
| 18 | <defs | ||
| 19 | id="defs3030" /> | ||
| 20 | <sodipodi:namedview | ||
| 21 | id="base" | ||
| 22 | pagecolor="#ffffff" | ||
| 23 | bordercolor="#666666" | ||
| 24 | borderopacity="1.0" | ||
| 25 | inkscape:pageopacity="0.0" | ||
| 26 | inkscape:pageshadow="2" | ||
| 27 | inkscape:zoom="22.197802" | ||
| 28 | inkscape:cx="-0.87475255" | ||
| 29 | inkscape:cy="-1.0099011" | ||
| 30 | inkscape:current-layer="layer1" | ||
| 31 | showgrid="true" | ||
| 32 | inkscape:grid-bbox="true" | ||
| 33 | inkscape:document-units="px" | ||
| 34 | inkscape:snap-global="true" | ||
| 35 | inkscape:snap-object-midpoints="false" | ||
| 36 | inkscape:window-width="1680" | ||
| 37 | inkscape:window-height="1026" | ||
| 38 | inkscape:window-x="0" | ||
| 39 | inkscape:window-y="24" | ||
| 40 | inkscape:window-maximized="0"> | ||
| 41 | <inkscape:grid | ||
| 42 | type="xygrid" | ||
| 43 | id="grid3036" /> | ||
| 44 | </sodipodi:namedview> | ||
| 45 | <metadata | ||
| 46 | id="metadata3033"> | ||
| 47 | <rdf:RDF> | ||
| 48 | <cc:Work | ||
| 49 | rdf:about=""> | ||
| 50 | <dc:format>image/svg+xml</dc:format> | ||
| 51 | <dc:type | ||
| 52 | rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||
| 53 | </cc:Work> | ||
| 54 | </rdf:RDF> | ||
| 55 | </metadata> | ||
| 56 | <g | ||
| 57 | id="layer1" | ||
| 58 | inkscape:label="Layer 1" | ||
| 59 | inkscape:groupmode="layer"> | ||
| 60 | <rect | ||
| 61 | style="fill:#ff8000;fill-opacity:1;stroke:#0000ff;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | ||
| 62 | id="rect3038" | ||
| 63 | width="16" | ||
| 64 | height="16" | ||
| 65 | x="0" | ||
| 66 | y="0" | ||
| 67 | ry="2" | ||
| 68 | rx="2" /> | ||
| 69 | <path | ||
| 70 | sodipodi:type="arc" | ||
| 71 | style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | ||
| 72 | id="path3814" | ||
| 73 | sodipodi:cx="-4.5" | ||
| 74 | sodipodi:cy="7.5" | ||
| 75 | sodipodi:rx="2" | ||
| 76 | sodipodi:ry="2" | ||
| 77 | d="m -2.5,7.5 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z" | ||
| 78 | transform="matrix(0,1,-1,0,11.5,16.5)" /> | ||
| 79 | <path | ||
| 80 | sodipodi:type="arc" | ||
| 81 | style="fill:none;stroke:#ffffff;stroke-width:1.89999996;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | ||
| 82 | id="path3847" | ||
| 83 | sodipodi:cx="8.5" | ||
| 84 | sodipodi:cy="7.5" | ||
| 85 | sodipodi:rx="9.5" | ||
| 86 | sodipodi:ry="9.5" | ||
| 87 | d="m 18,7.5 a 9.5,9.5 0 1 1 -19,0 9.5,9.5 0 1 1 19,0 z" | ||
| 88 | transform="matrix(1.0526316,0,0,1.0526316,-8.9473684,8.1052632)" /> | ||
| 89 | <path | ||
| 90 | sodipodi:type="arc" | ||
| 91 | style="fill:none;stroke:#ffffff;stroke-width:0.96362412;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | ||
| 92 | id="path3849" | ||
| 93 | sodipodi:cx="2" | ||
| 94 | sodipodi:cy="14.5" | ||
| 95 | sodipodi:rx="7" | ||
| 96 | sodipodi:ry="6.5" | ||
| 97 | d="m 9,14.5 a 7,6.5 0 1 1 -14,0 7,6.5 0 1 1 14,0 z" | ||
| 98 | transform="matrix(2,0,0,2.1538461,-3.9999999,-15.230768)" /> | ||
| 99 | <rect | ||
| 100 | style="fill:none;fill-opacity:1;stroke:#ff8000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | ||
| 101 | id="rect3869" | ||
| 102 | width="15" | ||
| 103 | height="15" | ||
| 104 | x="2" | ||
| 105 | y="-1" | ||
| 106 | rx="0" | ||
| 107 | ry="0" /> | ||
| 108 | <path | ||
| 109 | style="fill:#ff8000;fill-opacity:1;stroke:none" | ||
| 110 | d="M 2 0 C 0.892 0 0 0.892 0 2 L 0 14 C 0 15.108 0.892 16 2 16 L 2 0 z " | ||
| 111 | id="rect3891" /> | ||
| 112 | <path | ||
| 113 | style="fill:#ff8000;fill-opacity:1;stroke:none" | ||
| 114 | d="M 0 14 C 0 15.108 0.892 16 2 16 L 14 16 C 15.108 16 16 15.108 16 14 L 0 14 z " | ||
| 115 | id="rect3913" /> | ||
| 116 | </g> | ||
| 117 | <g | ||
| 118 | inkscape:groupmode="layer" | ||
| 119 | id="layer2" | ||
| 120 | inkscape:label="Ebene" /> | ||
| 121 | </svg> | ||
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index af4d5e0e055..3f75bbdc355 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,40 @@ | |||
| 1 | 2014-10-19 Ulf Jasper <ulf.jasper@web.de> | ||
| 2 | |||
| 3 | * net/newst-backend.el: Require url-parse. | ||
| 4 | (newsticker--get-news-by-wget): Store feed name as process property. | ||
| 5 | (newsticker--sentinel): Read feed name from process property. | ||
| 6 | (newsticker--sentinel-work): Rename argument name to feed-name. | ||
| 7 | Rename variable imageurl to image-url. Pick icon url from Atom | ||
| 8 | 1.0 data. Launch download of feed icon. | ||
| 9 | (newsticker--get-icon-url-atom-1.0): New. | ||
| 10 | (newsticker--unxml) | ||
| 11 | (newsticker--unxml-node) | ||
| 12 | (newsticker--unxml-attribute): Documentation. | ||
| 13 | (newsticker--icons-dir): New. | ||
| 14 | (newsticker--image-get): New arguments FILENAME and DIRECTORY. | ||
| 15 | Use `url-retrieve' if `newsticker-retrieval-method' is 'intern. | ||
| 16 | (newsticker--image-download-by-wget): New. Use process properties | ||
| 17 | for storing informations. | ||
| 18 | (newsticker--image-sentinel): Read informations from process properties. | ||
| 19 | (newsticker--image-save) | ||
| 20 | (newsticker--image-remove) | ||
| 21 | (newsticker--image-download-by-url) | ||
| 22 | (newsticker--image-download-by-url-callback): New. | ||
| 23 | (newsticker-opml-export): Handle url list entries containing a | ||
| 24 | function instead of an url string. | ||
| 25 | |||
| 26 | * net/newst-reader.el (newsticker-html-renderer): Whitespace. | ||
| 27 | (newsticker--print-extra-elements) | ||
| 28 | (newsticker--do-print-extra-element): Documentation | ||
| 29 | (newsticker--image-read): Optionally limit image height. Use | ||
| 30 | imagemagick if possible. | ||
| 31 | (newsticker--icon-read): New. | ||
| 32 | |||
| 33 | * net/newst-treeview.el (newsticker--treeview-item-show): Limit height of feed logo. | ||
| 34 | (newsticker--treeview-tree-expand): Use feed icons in treeview. | ||
| 35 | (newsticker--tree-widget-icon-create): New. Set the tree widget icon. | ||
| 36 | (newsticker--tree-widget-leaf-icon): Use feed icon. | ||
| 37 | |||
| 1 | 2014-10-19 Stefan Monnier <monnier@iro.umontreal.ca> | 38 | 2014-10-19 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 39 | ||
| 3 | * emacs-lisp/eieio-opt.el (eieio-lambda-arglist): Remove. | 40 | * emacs-lisp/eieio-opt.el (eieio-lambda-arglist): Remove. |
diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el index b7bd3d0933e..4052116074d 100644 --- a/lisp/net/newst-backend.el +++ b/lisp/net/newst-backend.el | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | (require 'derived) | 37 | (require 'derived) |
| 38 | (require 'xml) | 38 | (require 'xml) |
| 39 | (require 'url-parse) | ||
| 39 | 40 | ||
| 40 | ;; Silence warnings | 41 | ;; Silence warnings |
| 41 | (defvar w3-mode-map) | 42 | (defvar w3-mode-map) |
| @@ -776,6 +777,7 @@ See `newsticker-get-news'." | |||
| 776 | newsticker-wget-name args))) | 777 | newsticker-wget-name args))) |
| 777 | (set-process-coding-system proc 'no-conversion 'no-conversion) | 778 | (set-process-coding-system proc 'no-conversion 'no-conversion) |
| 778 | (set-process-sentinel proc 'newsticker--sentinel) | 779 | (set-process-sentinel proc 'newsticker--sentinel) |
| 780 | (process-put proc 'nt-feed-name feed-name) | ||
| 779 | (setq newsticker--process-ids (cons (process-id proc) | 781 | (setq newsticker--process-ids (cons (process-id proc) |
| 780 | newsticker--process-ids)) | 782 | newsticker--process-ids)) |
| 781 | (force-mode-line-update))))) | 783 | (force-mode-line-update))))) |
| @@ -811,24 +813,24 @@ Argument PROCESS is the process which has just changed its state. | |||
| 811 | Argument EVENT tells what has happened to the process." | 813 | Argument EVENT tells what has happened to the process." |
| 812 | (let ((p-status (process-status process)) | 814 | (let ((p-status (process-status process)) |
| 813 | (exit-status (process-exit-status process)) | 815 | (exit-status (process-exit-status process)) |
| 814 | (name (process-name process)) | 816 | (feed-name (process-get process 'nt-feed-name)) |
| 815 | (command (process-command process)) | 817 | (command (process-command process)) |
| 816 | (buffer (process-buffer process))) | 818 | (buffer (process-buffer process))) |
| 817 | (newsticker--sentinel-work event | 819 | (newsticker--sentinel-work event |
| 818 | (and (eq p-status 'exit) | 820 | (and (eq p-status 'exit) |
| 819 | (= exit-status 0)) | 821 | (= exit-status 0)) |
| 820 | name command buffer))) | 822 | feed-name command buffer))) |
| 821 | 823 | ||
| 822 | (defun newsticker--sentinel-work (event status-ok name command buffer) | 824 | (defun newsticker--sentinel-work (event status-ok feed-name command buffer) |
| 823 | "Actually do the sentinel work. | 825 | "Actually do the sentinel work. |
| 824 | Argument EVENT tells what has happened to the retrieval process. | 826 | Argument EVENT tells what has happened to the retrieval process. |
| 825 | Argument STATUS-OK is the final status of the retrieval process, | 827 | Argument STATUS-OK is the final status of the retrieval process, |
| 826 | non-nil meaning retrieval was successful. | 828 | non-nil meaning retrieval was successful. |
| 827 | Argument NAME is the name of the retrieval process. | 829 | Argument FEED-NAME is the name of the retrieved feed. |
| 828 | Argument COMMAND is the command of the retrieval process. | 830 | Argument COMMAND is the command of the retrieval process. |
| 829 | Argument BUFFER is the buffer of the retrieval process." | 831 | Argument BUFFER is the buffer of the retrieval process." |
| 830 | (let ((time (current-time)) | 832 | (let ((time (current-time)) |
| 831 | (name-symbol (intern name)) | 833 | (name-symbol (intern feed-name)) |
| 832 | (something-was-added nil)) | 834 | (something-was-added nil)) |
| 833 | ;; catch known errors (zombie processes, rubbish-xml etc. | 835 | ;; catch known errors (zombie processes, rubbish-xml etc. |
| 834 | ;; if an error occurs the news feed is not updated! | 836 | ;; if an error occurs the news feed is not updated! |
| @@ -844,14 +846,14 @@ Argument BUFFER is the buffer of the retrieval process." | |||
| 844 | "Return status: `%s'\n" | 846 | "Return status: `%s'\n" |
| 845 | "Command was `%s'") | 847 | "Command was `%s'") |
| 846 | (format-time-string "%A, %H:%M" (current-time)) | 848 | (format-time-string "%A, %H:%M" (current-time)) |
| 847 | name event command) | 849 | feed-name event command) |
| 848 | "" | 850 | "" |
| 849 | (current-time) | 851 | (current-time) |
| 850 | 'new | 852 | 'new |
| 851 | 0 nil)) | 853 | 0 nil)) |
| 852 | (message "%s: Error while retrieving news from %s" | 854 | (message "%s: Error while retrieving news from %s" |
| 853 | (format-time-string "%A, %H:%M" (current-time)) | 855 | (format-time-string "%A, %H:%M" (current-time)) |
| 854 | name) | 856 | feed-name) |
| 855 | (throw 'oops nil)) | 857 | (throw 'oops nil)) |
| 856 | (let* ((coding-system 'utf-8) | 858 | (let* ((coding-system 'utf-8) |
| 857 | (node-list | 859 | (node-list |
| @@ -870,7 +872,7 @@ Argument BUFFER is the buffer of the retrieval process." | |||
| 870 | (coding-system-error | 872 | (coding-system-error |
| 871 | (message | 873 | (message |
| 872 | "newsticker.el: ignoring coding system %s for %s" | 874 | "newsticker.el: ignoring coding system %s for %s" |
| 873 | coding-system name) | 875 | coding-system feed-name) |
| 874 | nil)))) | 876 | nil)))) |
| 875 | ;; Decode if possible | 877 | ;; Decode if possible |
| 876 | (when coding-system | 878 | (when coding-system |
| @@ -886,7 +888,8 @@ Argument BUFFER is the buffer of the retrieval process." | |||
| 886 | (buffer-name) (cadr errordata)) | 888 | (buffer-name) (cadr errordata)) |
| 887 | (throw 'oops nil))))) | 889 | (throw 'oops nil))))) |
| 888 | (topnode (car node-list)) | 890 | (topnode (car node-list)) |
| 889 | (imageurl nil)) | 891 | (image-url nil) |
| 892 | (icon-url nil)) | ||
| 890 | ;; mark all items as obsolete | 893 | ;; mark all items as obsolete |
| 891 | (newsticker--cache-replace-age newsticker--cache | 894 | (newsticker--cache-replace-age newsticker--cache |
| 892 | name-symbol | 895 | name-symbol |
| @@ -904,29 +907,29 @@ Argument BUFFER is the buffer of the retrieval process." | |||
| 904 | ;; RSS 0.91 | 907 | ;; RSS 0.91 |
| 905 | ((and (eq 'rss (xml-node-name topnode)) | 908 | ((and (eq 'rss (xml-node-name topnode)) |
| 906 | (string= "0.91" (xml-get-attribute topnode 'version))) | 909 | (string= "0.91" (xml-get-attribute topnode 'version))) |
| 907 | (setq imageurl (newsticker--get-logo-url-rss-0.91 topnode)) | 910 | (setq image-url (newsticker--get-logo-url-rss-0.91 topnode)) |
| 908 | (newsticker--parse-rss-0.91 name time topnode)) | 911 | (newsticker--parse-rss-0.91 feed-name time topnode)) |
| 909 | ;; RSS 0.92 | 912 | ;; RSS 0.92 |
| 910 | ((and (eq 'rss (xml-node-name topnode)) | 913 | ((and (eq 'rss (xml-node-name topnode)) |
| 911 | (string= "0.92" (xml-get-attribute topnode 'version))) | 914 | (string= "0.92" (xml-get-attribute topnode 'version))) |
| 912 | (setq imageurl (newsticker--get-logo-url-rss-0.92 topnode)) | 915 | (setq image-url (newsticker--get-logo-url-rss-0.92 topnode)) |
| 913 | (newsticker--parse-rss-0.92 name time topnode)) | 916 | (newsticker--parse-rss-0.92 feed-name time topnode)) |
| 914 | ;; RSS 1.0 | 917 | ;; RSS 1.0 |
| 915 | ((or (eq 'RDF (xml-node-name topnode)) | 918 | ((or (eq 'RDF (xml-node-name topnode)) |
| 916 | (eq 'rdf:RDF (xml-node-name topnode))) | 919 | (eq 'rdf:RDF (xml-node-name topnode))) |
| 917 | (setq imageurl (newsticker--get-logo-url-rss-1.0 topnode)) | 920 | (setq image-url (newsticker--get-logo-url-rss-1.0 topnode)) |
| 918 | (newsticker--parse-rss-1.0 name time topnode)) | 921 | (newsticker--parse-rss-1.0 feed-name time topnode)) |
| 919 | ;; RSS 2.0 | 922 | ;; RSS 2.0 |
| 920 | ((and (eq 'rss (xml-node-name topnode)) | 923 | ((and (eq 'rss (xml-node-name topnode)) |
| 921 | (string= "2.0" (xml-get-attribute topnode 'version))) | 924 | (string= "2.0" (xml-get-attribute topnode 'version))) |
| 922 | (setq imageurl (newsticker--get-logo-url-rss-2.0 topnode)) | 925 | (setq image-url (newsticker--get-logo-url-rss-2.0 topnode)) |
| 923 | (newsticker--parse-rss-2.0 name time topnode)) | 926 | (newsticker--parse-rss-2.0 feed-name time topnode)) |
| 924 | ;; Atom 0.3 | 927 | ;; Atom 0.3 |
| 925 | ((and (eq 'feed (xml-node-name topnode)) | 928 | ((and (eq 'feed (xml-node-name topnode)) |
| 926 | (string= "http://purl.org/atom/ns#" | 929 | (string= "http://purl.org/atom/ns#" |
| 927 | (xml-get-attribute topnode 'xmlns))) | 930 | (xml-get-attribute topnode 'xmlns))) |
| 928 | (setq imageurl (newsticker--get-logo-url-atom-0.3 topnode)) | 931 | (setq image-url (newsticker--get-logo-url-atom-0.3 topnode)) |
| 929 | (newsticker--parse-atom-0.3 name time topnode)) | 932 | (newsticker--parse-atom-0.3 feed-name time topnode)) |
| 930 | ;; Atom 1.0 | 933 | ;; Atom 1.0 |
| 931 | (t | 934 | (t |
| 932 | ;; The test for Atom 1.0 does not work when using | 935 | ;; The test for Atom 1.0 does not work when using |
| @@ -938,16 +941,17 @@ Argument BUFFER is the buffer of the retrieval process." | |||
| 938 | ;; (and (eq 'feed (xml-node-name topnode)) | 941 | ;; (and (eq 'feed (xml-node-name topnode)) |
| 939 | ;; (string= "http://www.w3.org/2005/Atom" | 942 | ;; (string= "http://www.w3.org/2005/Atom" |
| 940 | ;; (xml-get-attribute topnode 'xmlns))) | 943 | ;; (xml-get-attribute topnode 'xmlns))) |
| 941 | (setq imageurl (newsticker--get-logo-url-atom-1.0 topnode)) | 944 | (setq image-url (newsticker--get-logo-url-atom-1.0 topnode)) |
| 942 | (newsticker--parse-atom-1.0 name time topnode)) | 945 | (setq icon-url (newsticker--get-icon-url-atom-1.0 topnode)) |
| 946 | (newsticker--parse-atom-1.0 feed-name time topnode)) | ||
| 943 | ;; unknown feed type | 947 | ;; unknown feed type |
| 944 | ;; (t | 948 | ;; (t |
| 945 | ;; (newsticker--debug-msg "Feed type unknown: %s: %s" | 949 | ;; (newsticker--debug-msg "Feed type unknown: %s: %s" |
| 946 | ;; (xml-node-name topnode) name) | 950 | ;; (xml-node-name topnode) feed-name) |
| 947 | ;; nil) | 951 | ;; nil) |
| 948 | ) | 952 | ) |
| 949 | (setq something-was-added t)) | 953 | (setq something-was-added t)) |
| 950 | (error (message "sentinelerror in %s: %s" name error-data))) | 954 | (error (message "sentinelerror in %s: %s" feed-name error-data))) |
| 951 | 955 | ||
| 952 | ;; Remove those old items from cache which have been removed from | 956 | ;; Remove those old items from cache which have been removed from |
| 953 | ;; the feed | 957 | ;; the feed |
| @@ -988,10 +992,29 @@ Argument BUFFER is the buffer of the retrieval process." | |||
| 988 | ;; kill the process buffer if wanted | 992 | ;; kill the process buffer if wanted |
| 989 | (unless newsticker-debug | 993 | (unless newsticker-debug |
| 990 | (kill-buffer buffer)) | 994 | (kill-buffer buffer)) |
| 991 | ;; launch retrieval of image | 995 | ;; launch retrieval of images |
| 992 | (when (and imageurl (boundp 'newsticker-download-logos) | 996 | (when (and (boundp 'newsticker-download-logos) |
| 993 | newsticker-download-logos) | 997 | newsticker-download-logos) |
| 994 | (newsticker--image-get name imageurl))))) | 998 | ;; feed logo |
| 999 | (when image-url | ||
| 1000 | (newsticker--image-get feed-name feed-name (newsticker--images-dir) | ||
| 1001 | image-url)) | ||
| 1002 | ;; icon / favicon | ||
| 1003 | (setq icon-url | ||
| 1004 | (or icon-url | ||
| 1005 | (let* ((feed-url (newsticker--link (cadr (newsticker--cache-get-feed | ||
| 1006 | (intern feed-name))))) | ||
| 1007 | (uri (url-generic-parse-url feed-url))) | ||
| 1008 | (when (and feed-url uri) | ||
| 1009 | (setf (url-filename uri) nil) | ||
| 1010 | (setf (url-target uri) nil) | ||
| 1011 | (concat (url-recreate-url uri) "favicon.ico"))))) | ||
| 1012 | (when icon-url | ||
| 1013 | (newsticker--image-get feed-name | ||
| 1014 | (concat feed-name "." | ||
| 1015 | (file-name-extension icon-url)) | ||
| 1016 | (newsticker--icons-dir) | ||
| 1017 | icon-url)))))) | ||
| 995 | (when newsticker--sentinel-callback | 1018 | (when newsticker--sentinel-callback |
| 996 | (funcall newsticker--sentinel-callback))) | 1019 | (funcall newsticker--sentinel-callback))) |
| 997 | 1020 | ||
| @@ -1055,6 +1078,11 @@ Argument BUFFER is the buffer of the retrieval process." | |||
| 1055 | (car (xml-node-children | 1078 | (car (xml-node-children |
| 1056 | (car (xml-get-children node 'logo))))) | 1079 | (car (xml-get-children node 'logo))))) |
| 1057 | 1080 | ||
| 1081 | (defun newsticker--get-icon-url-atom-1.0 (node) | ||
| 1082 | "Return icon URL from atom 1.0 data in NODE." | ||
| 1083 | (car (xml-node-children | ||
| 1084 | (car (xml-get-children node 'icon))))) | ||
| 1085 | |||
| 1058 | (defun newsticker--get-logo-url-atom-0.3 (node) | 1086 | (defun newsticker--get-logo-url-atom-0.3 (node) |
| 1059 | "Return logo URL from atom 0.3 data in NODE." | 1087 | "Return logo URL from atom 0.3 data in NODE." |
| 1060 | (car (xml-node-children | 1088 | (car (xml-node-children |
| @@ -1133,13 +1161,13 @@ same as in `newsticker--parse-atom-1.0'." | |||
| 1133 | 1161 | ||
| 1134 | (defun newsticker--unxml (node) | 1162 | (defun newsticker--unxml (node) |
| 1135 | "Reverse parsing of an xml string. | 1163 | "Reverse parsing of an xml string. |
| 1136 | Restore an xml-string from a an xml-node that was returned by xml-parse..." | 1164 | Restore an xml-string from a an xml NODE that was returned by xml-parse..." |
| 1137 | (if (or (not node) (stringp node)) | 1165 | (if (or (not node) (stringp node)) |
| 1138 | node | 1166 | node |
| 1139 | (newsticker--unxml-node node))) | 1167 | (newsticker--unxml-node node))) |
| 1140 | 1168 | ||
| 1141 | (defun newsticker--unxml-node (node) | 1169 | (defun newsticker--unxml-node (node) |
| 1142 | "Actually restore xml-string of an xml node." | 1170 | "Actually restore xml-string of an xml NODE." |
| 1143 | (let ((qname (symbol-name (car node))) | 1171 | (let ((qname (symbol-name (car node))) |
| 1144 | (att-list (cadr node)) | 1172 | (att-list (cadr node)) |
| 1145 | (children (cddr node))) | 1173 | (children (cddr node))) |
| @@ -1149,10 +1177,10 @@ Restore an xml-string from a an xml-node that was returned by xml-parse..." | |||
| 1149 | ">" | 1177 | ">" |
| 1150 | (mapconcat 'newsticker--unxml children "") "</" qname ">"))) | 1178 | (mapconcat 'newsticker--unxml children "") "</" qname ">"))) |
| 1151 | 1179 | ||
| 1152 | (defun newsticker--unxml-attribute (att) | 1180 | (defun newsticker--unxml-attribute (attribute) |
| 1153 | "Actually restore xml-string of an attribute of an xml node." | 1181 | "Actually restore xml-string of an ATTRIBUTE of an xml node." |
| 1154 | (let ((name (symbol-name (car att))) | 1182 | (let ((name (symbol-name (car attribute))) |
| 1155 | (value (cdr att))) | 1183 | (value (cdr attribute))) |
| 1156 | (concat name "=\"" value "\""))) | 1184 | (concat name "=\"" value "\""))) |
| 1157 | 1185 | ||
| 1158 | (defun newsticker--parse-atom-1.0 (name time topnode) | 1186 | (defun newsticker--parse-atom-1.0 (name time topnode) |
| @@ -1766,14 +1794,19 @@ Checks list of active processes against list of newsticker processes." | |||
| 1766 | "Return directory where feed images are saved." | 1794 | "Return directory where feed images are saved." |
| 1767 | (concat newsticker-dir "/images/")) | 1795 | (concat newsticker-dir "/images/")) |
| 1768 | 1796 | ||
| 1769 | (defun newsticker--image-get (feed-name url) | 1797 | (defun newsticker--icons-dir () |
| 1770 | "Get image of the news site FEED-NAME from URL. | 1798 | "Return directory where feed icons are saved." |
| 1771 | If the image has been downloaded in the last 24h do nothing." | 1799 | (concat newsticker-dir "/icons/")) |
| 1772 | (let ((image-name (concat (newsticker--images-dir) feed-name))) | 1800 | |
| 1801 | (defun newsticker--image-get (feed-name filename directory url) | ||
| 1802 | "Get image for FEED-NAME by returning FILENAME from DIRECTORY. | ||
| 1803 | If the file does no exist or if it is older than 24 hours | ||
| 1804 | download it from URL first." | ||
| 1805 | (let ((image-name (concat directory feed-name))) | ||
| 1773 | (if (and (file-exists-p image-name) | 1806 | (if (and (file-exists-p image-name) |
| 1774 | (time-less-p (current-time) | 1807 | (time-less-p (current-time) |
| 1775 | (time-add (nth 5 (file-attributes image-name)) | 1808 | (time-add (nth 5 (file-attributes image-name)) |
| 1776 | (seconds-to-time 86400)))) | 1809 | (seconds-to-time 86400)))) |
| 1777 | (newsticker--debug-msg "%s: Getting image for %s skipped" | 1810 | (newsticker--debug-msg "%s: Getting image for %s skipped" |
| 1778 | (format-time-string "%A, %H:%M" (current-time)) | 1811 | (format-time-string "%A, %H:%M" (current-time)) |
| 1779 | feed-name) | 1812 | feed-name) |
| @@ -1781,14 +1814,22 @@ If the image has been downloaded in the last 24h do nothing." | |||
| 1781 | (newsticker--debug-msg "%s: Getting image for %s" | 1814 | (newsticker--debug-msg "%s: Getting image for %s" |
| 1782 | (format-time-string "%A, %H:%M" (current-time)) | 1815 | (format-time-string "%A, %H:%M" (current-time)) |
| 1783 | feed-name) | 1816 | feed-name) |
| 1784 | (let* ((buffername (concat " *newsticker-wget-image-" feed-name "*")) | 1817 | (if (eq newsticker-retrieval-method 'intern) |
| 1785 | (item (or (assoc feed-name newsticker-url-list) | 1818 | (newsticker--image-download-by-url feed-name filename directory url) |
| 1819 | (newsticker--image-download-by-wget feed-name filename directory url))))) | ||
| 1820 | |||
| 1821 | (defun newsticker--image-download-by-wget (feed-name filename directory url) | ||
| 1822 | "Download image for FEED-NAME using external program. | ||
| 1823 | Save image as FILENAME in DIRECTORY, download it from URL." | ||
| 1824 | (let* ((proc-name (concat feed-name "-" filename)) | ||
| 1825 | (buffername (concat " *newsticker-wget-image-" proc-name "*")) | ||
| 1826 | (item (or (assoc feed-name newsticker-url-list) | ||
| 1786 | (assoc feed-name newsticker-url-list-defaults) | 1827 | (assoc feed-name newsticker-url-list-defaults) |
| 1787 | (error | 1828 | (error |
| 1788 | "Cannot get image for %s: Check newsticker-url-list" | 1829 | "Cannot get image for %s: Check newsticker-url-list" |
| 1789 | feed-name))) | 1830 | feed-name))) |
| 1790 | (wget-arguments (or (car (cdr (cdr (cdr (cdr item))))) | 1831 | (wget-arguments (or (car (cdr (cdr (cdr (cdr item))))) |
| 1791 | newsticker-wget-arguments))) | 1832 | newsticker-wget-arguments))) |
| 1792 | (with-current-buffer (get-buffer-create buffername) | 1833 | (with-current-buffer (get-buffer-create buffername) |
| 1793 | (erase-buffer) | 1834 | (erase-buffer) |
| 1794 | ;; throw an error if there is an old wget-process around | 1835 | ;; throw an error if there is an old wget-process around |
| @@ -1797,16 +1838,21 @@ If the image has been downloaded in the last 24h do nothing." | |||
| 1797 | feed-name)) | 1838 | feed-name)) |
| 1798 | ;; start wget | 1839 | ;; start wget |
| 1799 | (let* ((args (append wget-arguments (list url))) | 1840 | (let* ((args (append wget-arguments (list url))) |
| 1800 | (proc (apply 'start-process feed-name buffername | 1841 | (proc (apply 'start-process proc-name buffername |
| 1801 | newsticker-wget-name args))) | 1842 | newsticker-wget-name args))) |
| 1802 | (set-process-coding-system proc 'no-conversion 'no-conversion) | 1843 | (set-process-coding-system proc 'no-conversion 'no-conversion) |
| 1803 | (set-process-sentinel proc 'newsticker--image-sentinel))))))) | 1844 | (set-process-sentinel proc 'newsticker--image-sentinel) |
| 1845 | (process-put proc 'nt-directory directory) | ||
| 1846 | (process-put proc 'nt-feed-name feed-name) | ||
| 1847 | (process-put proc 'nt-filename filename))))) | ||
| 1804 | 1848 | ||
| 1805 | (defun newsticker--image-sentinel (process event) | 1849 | (defun newsticker--image-sentinel (process event) |
| 1806 | "Sentinel for image-retrieving PROCESS caused by EVENT." | 1850 | "Sentinel for image-retrieving PROCESS caused by EVENT." |
| 1807 | (let* ((p-status (process-status process)) | 1851 | (let* ((p-status (process-status process)) |
| 1808 | (exit-status (process-exit-status process)) | 1852 | (exit-status (process-exit-status process)) |
| 1809 | (feed-name (process-name process))) | 1853 | (feed-name (process-get process 'nt-feed-name)) |
| 1854 | (directory (process-get process 'nt-directory)) | ||
| 1855 | (filename (process-get process 'nt-filename))) | ||
| 1810 | ;; catch known errors (zombie processes, rubbish-xml, etc.) | 1856 | ;; catch known errors (zombie processes, rubbish-xml, etc.) |
| 1811 | ;; if an error occurs the news feed is not updated! | 1857 | ;; if an error occurs the news feed is not updated! |
| 1812 | (catch 'oops | 1858 | (catch 'oops |
| @@ -1815,21 +1861,67 @@ If the image has been downloaded in the last 24h do nothing." | |||
| 1815 | (message "%s: Error while retrieving image from %s" | 1861 | (message "%s: Error while retrieving image from %s" |
| 1816 | (format-time-string "%A, %H:%M" (current-time)) | 1862 | (format-time-string "%A, %H:%M" (current-time)) |
| 1817 | feed-name) | 1863 | feed-name) |
| 1864 | (newsticker--image-remove directory feed-name) | ||
| 1818 | (throw 'oops nil)) | 1865 | (throw 'oops nil)) |
| 1819 | (let (image-name) | 1866 | (newsticker--image-save (process-buffer process) directory filename)))) |
| 1820 | (with-current-buffer (process-buffer process) | 1867 | |
| 1821 | (setq image-name (concat (newsticker--images-dir) feed-name)) | 1868 | (defun newsticker--image-save (buffer directory file-name) |
| 1822 | (set-buffer-file-coding-system 'no-conversion) | 1869 | "Save contents of BUFFER in DIRECTORY as FILE-NAME. |
| 1823 | ;; make sure the cache dir exists | 1870 | Finally kill buffer." |
| 1824 | (unless (file-directory-p (newsticker--images-dir)) | 1871 | (with-current-buffer buffer |
| 1825 | (make-directory (newsticker--images-dir))) | 1872 | (let ((image-name (concat directory file-name))) |
| 1826 | ;; write and close buffer | 1873 | (set-buffer-file-coding-system 'no-conversion) |
| 1827 | (let ((require-final-newline nil) | 1874 | ;; make sure the cache dir exists |
| 1828 | (backup-inhibited t) | 1875 | (unless (file-directory-p directory) |
| 1829 | (coding-system-for-write 'no-conversion)) | 1876 | (make-directory directory)) |
| 1830 | (write-region nil nil image-name nil 'quiet)) | 1877 | ;; write and close buffer |
| 1831 | (set-buffer-modified-p nil) | 1878 | (let ((require-final-newline nil) |
| 1832 | (kill-buffer (current-buffer))))))) | 1879 | (backup-inhibited t) |
| 1880 | (coding-system-for-write 'no-conversion)) | ||
| 1881 | (write-region nil nil image-name nil 'quiet)) | ||
| 1882 | (set-buffer-modified-p nil) | ||
| 1883 | (kill-buffer buffer)))) | ||
| 1884 | |||
| 1885 | (defun newsticker--image-remove (directory file-name) | ||
| 1886 | "In DIRECTORY remove FILE-NAME." | ||
| 1887 | (let ((image-name (concat directory file-name))) | ||
| 1888 | (when (file-exists-p file-name) | ||
| 1889 | (delete-file image-name)))) | ||
| 1890 | |||
| 1891 | (defun newsticker--image-download-by-url (feed-name filename directory url) | ||
| 1892 | "Download image for FEED-NAME using `url-retrieve'. | ||
| 1893 | Save image as FILENAME in DIRECTORY, download it from URL." | ||
| 1894 | (let ((coding-system-for-read 'no-conversion)) | ||
| 1895 | (condition-case error-data | ||
| 1896 | (url-retrieve url 'newsticker--image-download-by-url-callback | ||
| 1897 | (list feed-name directory filename)) | ||
| 1898 | (error (message "Error retrieving image from %s: %s" feed-name | ||
| 1899 | error-data)))) | ||
| 1900 | (force-mode-line-update)) | ||
| 1901 | |||
| 1902 | (defun newsticker--image-download-by-url-callback (status feed-name directory filename) | ||
| 1903 | "Callback function for `newsticker--image-download-by-url'. | ||
| 1904 | STATUS is the return status as delivered by `url-retrieve'. | ||
| 1905 | FEED-NAME is the name of the feed that the news were retrieved | ||
| 1906 | from. | ||
| 1907 | The image is saved in DIRECTORY as FILENAME." | ||
| 1908 | (when status | ||
| 1909 | (let ((status-type (car status)) | ||
| 1910 | (status-details (cdr status))) | ||
| 1911 | (cond ((eq status-type :error) | ||
| 1912 | (newsticker--image-remove directory feed-name)) | ||
| 1913 | (t | ||
| 1914 | (let ((buf (get-buffer-create (concat " *newsticker-url-image-" feed-name "-" directory "*"))) | ||
| 1915 | (result (string-to-multibyte (buffer-string)))) | ||
| 1916 | (set-buffer buf) | ||
| 1917 | (erase-buffer) | ||
| 1918 | (insert result) | ||
| 1919 | ;; remove MIME header | ||
| 1920 | (goto-char (point-min)) | ||
| 1921 | (search-forward "\n\n") | ||
| 1922 | (delete-region (point-min) (point)) | ||
| 1923 | ;; save | ||
| 1924 | (newsticker--image-save buf directory filename))))))) | ||
| 1833 | 1925 | ||
| 1834 | (defun newsticker--insert-image (img string) | 1926 | (defun newsticker--insert-image (img string) |
| 1835 | "Insert IMG with STRING at point." | 1927 | "Insert IMG with STRING at point." |
| @@ -2244,6 +2336,7 @@ If AGE is nil, the total number of items is returned." | |||
| 2244 | (defun newsticker-opml-export () | 2336 | (defun newsticker-opml-export () |
| 2245 | "OPML subscription export. | 2337 | "OPML subscription export. |
| 2246 | Export subscriptions to a buffer in OPML Format." | 2338 | Export subscriptions to a buffer in OPML Format." |
| 2339 | ;; FIXME: use newsticker-groups | ||
| 2247 | (interactive) | 2340 | (interactive) |
| 2248 | (with-current-buffer (get-buffer-create "*OPML Export*") | 2341 | (with-current-buffer (get-buffer-create "*OPML Export*") |
| 2249 | (set-buffer-file-coding-system 'utf-8) | 2342 | (set-buffer-file-coding-system 'utf-8) |
| @@ -2263,7 +2356,8 @@ Export subscriptions to a buffer in OPML Format." | |||
| 2263 | (insert " <outline text=\"") | 2356 | (insert " <outline text=\"") |
| 2264 | (insert (newsticker--title sub)) | 2357 | (insert (newsticker--title sub)) |
| 2265 | (insert "\" xmlUrl=\"") | 2358 | (insert "\" xmlUrl=\"") |
| 2266 | (insert (cadr sub)) | 2359 | (insert (xml-escape-string (let ((url (cadr sub))) |
| 2360 | (if (stringp url) url (prin1-to-string url))))) | ||
| 2267 | (insert "\"/>\n")) | 2361 | (insert "\"/>\n")) |
| 2268 | (append newsticker-url-list newsticker-url-list-defaults)) | 2362 | (append newsticker-url-list newsticker-url-list-defaults)) |
| 2269 | (insert " </body>\n</opml>\n")) | 2363 | (insert " </body>\n</opml>\n")) |
diff --git a/lisp/net/newst-reader.el b/lisp/net/newst-reader.el index 8232e4bd9bd..fcf4d19503e 100644 --- a/lisp/net/newst-reader.el +++ b/lisp/net/newst-reader.el | |||
| @@ -110,7 +110,7 @@ window is used when filling. See also `newsticker-justification'." | |||
| 110 | #'shr-render-region) | 110 | #'shr-render-region) |
| 111 | "Function for rendering HTML contents. | 111 | "Function for rendering HTML contents. |
| 112 | If non-nil, newsticker.el will call this function whenever it | 112 | If non-nil, newsticker.el will call this function whenever it |
| 113 | finds HTML-like tags in item descriptions. | 113 | finds HTML-like tags in item descriptions. |
| 114 | Possible functions include `shr-render-region', `w3m-region', `w3-region', and | 114 | Possible functions include `shr-render-region', `w3m-region', `w3-region', and |
| 115 | `newsticker-htmlr-render'. | 115 | `newsticker-htmlr-render'. |
| 116 | Newsticker automatically loads the respective package w3m, w3, or | 116 | Newsticker automatically loads the respective package w3m, w3, or |
| @@ -193,7 +193,8 @@ KEYMAP will be applied." | |||
| 193 | 193 | ||
| 194 | (defun newsticker--print-extra-elements (item keymap &optional htmlish) | 194 | (defun newsticker--print-extra-elements (item keymap &optional htmlish) |
| 195 | "Insert extra-elements of ITEM in a pretty form into the current buffer. | 195 | "Insert extra-elements of ITEM in a pretty form into the current buffer. |
| 196 | KEYMAP is applied." | 196 | KEYMAP is applied. If HTMLISH is non-nil then HTML-markup is used |
| 197 | for formatting." | ||
| 197 | (let ((ignored-elements '(items link title description content | 198 | (let ((ignored-elements '(items link title description content |
| 198 | content:encoded encoded | 199 | content:encoded encoded |
| 199 | dc:subject subject | 200 | dc:subject subject |
| @@ -223,7 +224,8 @@ KEYMAP is applied." | |||
| 223 | 224 | ||
| 224 | (defun newsticker--do-print-extra-element (extra-element width keymap htmlish) | 225 | (defun newsticker--do-print-extra-element (extra-element width keymap htmlish) |
| 225 | "Actually print an EXTRA-ELEMENT using the given WIDTH. | 226 | "Actually print an EXTRA-ELEMENT using the given WIDTH. |
| 226 | KEYMAP is applied." | 227 | KEYMAP is applied. If HTMLISH is non-nil then HTML-markup is used |
| 228 | for formatting." | ||
| 227 | (let ((name (symbol-name (car extra-element)))) | 229 | (let ((name (symbol-name (car extra-element)))) |
| 228 | (if htmlish | 230 | (if htmlish |
| 229 | (insert (format "<li>%s: " name)) | 231 | (insert (format "<li>%s: " name)) |
| @@ -253,10 +255,11 @@ KEYMAP is applied." | |||
| 253 | (insert "</li>") | 255 | (insert "</li>") |
| 254 | (insert "\n")))) | 256 | (insert "\n")))) |
| 255 | 257 | ||
| 256 | (defun newsticker--image-read (feed-name-symbol disabled) | 258 | (defun newsticker--image-read (feed-name-symbol disabled &optional max-height) |
| 257 | "Read the cached image for FEED-NAME-SYMBOL from disk. | 259 | "Read the cached image for FEED-NAME-SYMBOL from disk. |
| 258 | If DISABLED is non-nil the image will be converted to a disabled look | 260 | If DISABLED is non-nil the image will be converted to a disabled look |
| 259 | \(unless `newsticker-enable-logo-manipulations' is not t\). | 261 | \(unless `newsticker-enable-logo-manipulations' is not t\). |
| 262 | Optional argument MAX-HEIGHT specifies the maximal image height. | ||
| 260 | Return the image." | 263 | Return the image." |
| 261 | (let ((image-name (concat (newsticker--images-dir) | 264 | (let ((image-name (concat (newsticker--images-dir) |
| 262 | (symbol-name feed-name-symbol))) | 265 | (symbol-name feed-name-symbol))) |
| @@ -264,18 +267,47 @@ Return the image." | |||
| 264 | (when (file-exists-p image-name) | 267 | (when (file-exists-p image-name) |
| 265 | (condition-case error-data | 268 | (condition-case error-data |
| 266 | (setq img (create-image | 269 | (setq img (create-image |
| 267 | image-name nil nil | 270 | image-name |
| 271 | (and (fboundp 'imagemagick-types) | ||
| 272 | (imagemagick-types) | ||
| 273 | 'imagemagick) | ||
| 274 | nil | ||
| 268 | :conversion (and newsticker-enable-logo-manipulations | 275 | :conversion (and newsticker-enable-logo-manipulations |
| 269 | disabled | 276 | disabled |
| 270 | 'disabled) | 277 | 'disabled) |
| 271 | :mask (and newsticker-enable-logo-manipulations | 278 | :mask (and newsticker-enable-logo-manipulations |
| 272 | 'heuristic) | 279 | 'heuristic) |
| 273 | :ascent 70)) | 280 | :ascent 100 |
| 281 | :max-height max-height)) | ||
| 274 | (error | 282 | (error |
| 275 | (message "Error: cannot create image for %s: %s" | 283 | (message "Error: cannot create image for %s: %s" |
| 276 | feed-name-symbol error-data)))) | 284 | feed-name-symbol error-data)))) |
| 277 | img)) | 285 | img)) |
| 278 | 286 | ||
| 287 | (defun newsticker--icon-read (feed-name-symbol) | ||
| 288 | "Read the cached icon for FEED-NAME-SYMBOL from disk. | ||
| 289 | Return the image." | ||
| 290 | (catch 'icon | ||
| 291 | (when (file-exists-p (newsticker--icons-dir)) | ||
| 292 | (mapc (lambda (file) | ||
| 293 | (condition-case error-data | ||
| 294 | (progn (setq img (create-image | ||
| 295 | file (and (fboundp 'imagemagick-types) | ||
| 296 | (imagemagick-types) | ||
| 297 | 'imagemagick) | ||
| 298 | nil | ||
| 299 | :ascent 'center | ||
| 300 | :max-width 16 | ||
| 301 | :max-height 16)) | ||
| 302 | (throw 'icon img)) | ||
| 303 | (error | ||
| 304 | (message "Error: cannot create icon for %s: %s" | ||
| 305 | feed-name-symbol error-data)))) | ||
| 306 | (directory-files (newsticker--icons-dir) t | ||
| 307 | (concat (symbol-name feed-name-symbol) "\\..*")))) | ||
| 308 | ;; fallback: default icon | ||
| 309 | (find-image '((:type png :file "newsticker/rss-feed.png" :ascent center))))) | ||
| 310 | |||
| 279 | ;; the functions we need for retrieval and display | 311 | ;; the functions we need for retrieval and display |
| 280 | ;;;###autoload | 312 | ;;;###autoload |
| 281 | (defun newsticker-show-news () | 313 | (defun newsticker-show-news () |
diff --git a/lisp/net/newst-treeview.el b/lisp/net/newst-treeview.el index 097a2a58805..6d0720d074e 100644 --- a/lisp/net/newst-treeview.el +++ b/lisp/net/newst-treeview.el | |||
| @@ -735,7 +735,7 @@ for the button." | |||
| 735 | (goto-char (point-min)) | 735 | (goto-char (point-min)) |
| 736 | ;; insert logo at top | 736 | ;; insert logo at top |
| 737 | (let* ((newsticker-enable-logo-manipulations nil) | 737 | (let* ((newsticker-enable-logo-manipulations nil) |
| 738 | (img (newsticker--image-read feed-name-symbol nil))) | 738 | (img (newsticker--image-read feed-name-symbol nil 40))) |
| 739 | (if (and (display-images-p) img) | 739 | (if (and (display-images-p) img) |
| 740 | (newsticker--insert-image img (car item)) | 740 | (newsticker--insert-image img (car item)) |
| 741 | (insert (newsticker--real-feed-name feed-name-symbol)))) | 741 | (insert (newsticker--real-feed-name feed-name-symbol)))) |
| @@ -829,6 +829,7 @@ Callback function for tree widget that adds nodes for feeds and subgroups." | |||
| 829 | :nt-group ,(cdr g) | 829 | :nt-group ,(cdr g) |
| 830 | :nt-feed ,g-name | 830 | :nt-feed ,g-name |
| 831 | :nt-id ,nt-id | 831 | :nt-id ,nt-id |
| 832 | :leaf-icon newsticker--tree-widget-leaf-icon | ||
| 832 | :keep (:nt-feed :num-new :nt-id :open);; :nt-group | 833 | :keep (:nt-feed :num-new :nt-id :open);; :nt-group |
| 833 | :open nil)) | 834 | :open nil)) |
| 834 | (let ((tag (newsticker--treeview-tree-get-tag g nil nt-id))) | 835 | (let ((tag (newsticker--treeview-tree-get-tag g nil nt-id))) |
| @@ -841,6 +842,23 @@ Callback function for tree widget that adds nodes for feeds and subgroups." | |||
| 841 | :open t)))) | 842 | :open t)))) |
| 842 | group))) | 843 | group))) |
| 843 | 844 | ||
| 845 | (defun newsticker--tree-widget-icon-create (icon) | ||
| 846 | "Create the ICON widget." | ||
| 847 | (let* ((g (widget-get (widget-get icon :node) :nt-feed)) | ||
| 848 | (ico (and g (newsticker--icon-read (intern g))))) | ||
| 849 | (if ico | ||
| 850 | (progn | ||
| 851 | (widget-put icon :tag-glyph ico) | ||
| 852 | (widget-default-create icon) | ||
| 853 | ;; Insert space between the icon and the node widget. | ||
| 854 | (insert-char ? 1) | ||
| 855 | (put-text-property | ||
| 856 | (1- (point)) (point) | ||
| 857 | 'display (list 'space :width tree-widget-space-width))) | ||
| 858 | ;; fallback: default icon | ||
| 859 | (widget-put icon :leaf-icon 'tree-widget-leaf-icon) | ||
| 860 | (tree-widget-icon-create icon)))) | ||
| 861 | |||
| 844 | (defun newsticker--treeview-tree-expand-status (tree &optional changed-widget | 862 | (defun newsticker--treeview-tree-expand-status (tree &optional changed-widget |
| 845 | event) | 863 | event) |
| 846 | "Expand the vfeed TREE. | 864 | "Expand the vfeed TREE. |
| @@ -875,6 +893,7 @@ Optional arguments CHANGED-WIDGET and EVENT are ignored." | |||
| 875 | "Icon for a tree-widget leaf node." | 893 | "Icon for a tree-widget leaf node." |
| 876 | :tag "O" | 894 | :tag "O" |
| 877 | :glyph-name "leaf" | 895 | :glyph-name "leaf" |
| 896 | :create 'newsticker--tree-widget-icon-create | ||
| 878 | :button-face 'default) | 897 | :button-face 'default) |
| 879 | 898 | ||
| 880 | (defun newsticker--treeview-tree-update () | 899 | (defun newsticker--treeview-tree-update () |