email-eww

Emacs library to send region or eww buffer by email
git clone https://logand.com/git/email-eww.git/
Log | Files | Refs

email-eww.el (13139B)


      1 ;;; -*- lexical-binding: t -*-
      2 ;;;
      3 ;;; email-eww.el
      4 ;;;
      5 ;;; Emacs library to send region or eww buffer by email.
      6 ;;;
      7 ;;; Author: Tomas Hlavaty <tom at logand dot com>
      8 ;;;
      9 ;;; License: GPL v3 or later
     10 ;;;
     11 ;;; Inspired by
     12 ;;; http://kitchingroup.cheme.cmu.edu/blog/2014/06/08/Better-integration-of-org-mode-and-email/
     13 
     14 (defcustom email-eww-from
     15   ""
     16   "Sender email address."
     17   :group 'email-eww
     18   :type 'string)
     19 
     20 (defcustom email-eww-to
     21   ""
     22   "Recipient email address."
     23   :group 'email-eww
     24   :type 'string)
     25 
     26 (defun email-string (string &optional url title in-reply-to)
     27   (compose-mail email-eww-to
     28                 (or title
     29                     (with-temp-buffer
     30                       (insert string)
     31                       (goto-char (point-min))
     32                       (end-of-line)
     33                       (buffer-substring (point-min) (point))))
     34                 `(("From" . ,email-eww-from)
     35                   ("In-Reply-To" . ,in-reply-to)))
     36   (message-goto-body)
     37   (when url
     38     (insert url)
     39     (insert "\n\n"))
     40   (insert string)
     41   (message-goto-to))
     42 
     43 (defun email-region (start end)
     44   "Send region as the body of an email."
     45   (interactive "r")
     46   (let ((string (buffer-substring start end)))
     47     (email-string string
     48                   (or (plist-get eww-data :url)
     49                       (buffer-name (current-buffer)))
     50                   (plist-get eww-data :title))))
     51 
     52 (defun clean-up-ycombinator ()
     53   (forward-line)
     54   (kill-line 2)
     55   (cond
     56    ((search-forward "Ask HN" nil t)
     57     )
     58    ((search-forward "comment" nil t)
     59     (beginning-of-line))
     60    )
     61   (let ((start (point)))
     62     (cond
     63      ((search-forward "add comment" nil t)
     64       (beginning-of-line)
     65       (forward-line)
     66       (delete-region start (point)))
     67      ))
     68   (goto-char (point-max))
     69   (search-backward "reply")
     70   (forward-line)
     71   (delete-region (point) (point-max))
     72   (message-goto-body)
     73   (unless (bolp)
     74     (forward-line 1))
     75   (delete-whitespace-rectangle (point) (point-max) nil)
     76   (message-goto-body)
     77   (flush-lines "^reply$" (point) (point-max)))
     78 
     79 (defun clean-up-reddit ()
     80   (forward-line 2)
     81   (let ((start (point)))
     82     (cond
     83      ((search-forward "Posted by" nil t)
     84       (beginning-of-line)
     85       (forward-line)
     86       (delete-region start (point)))
     87      ((search-forward-regexp "^submitted" nil t)
     88       (beginning-of-line)
     89       (forward-line -1)
     90       (backward-paragraph)
     91       (delete-region start (point)))
     92      ))
     93   (goto-char (point-max))
     94   (or (search-backward "Community Details" nil t)
     95       (search-backward "* reply"))
     96   (beginning-of-line)
     97   (delete-region (point) (point-max))
     98   (message-goto-body)
     99   (flush-lines "^share$" (point) (point-max))
    100   (flush-lines "^save$" (point) (point-max))
    101   (flush-lines "^hide$" (point) (point-max))
    102   (flush-lines "^report$" (point) (point-max))
    103   (flush-lines "^search$" (point) (point-max))
    104   (flush-lines "^Reply$" (point) (point-max))
    105   (flush-lines "^reportSave$" (point) (point-max))
    106   (flush-lines "^Sort by$" (point) (point-max))
    107   (flush-lines "^best$" (point) (point-max))
    108   (flush-lines "^besttopnewcontroversialoldq&a$" (point) (point-max))
    109   (flush-lines "^* permalink$" (point) (point-max))
    110   (flush-lines "^* embed$" (point) (point-max))
    111   (flush-lines "^* save$" (point) (point-max))
    112   (flush-lines "^* parent$" (point) (point-max))
    113   (flush-lines "^* report$" (point) (point-max))
    114   (flush-lines "^* give gold$" (point) (point-max))
    115   (flush-lines "^* share$" (point) (point-max))
    116   (flush-lines "^Post a comment!$" (point) (point-max))
    117   (flush-lines "^Create an account$" (point) (point-max))
    118   (flush-lines "^* reply$" (point) (point-max))
    119   (flush-lines "^*$" (point) (point-max))
    120   ;;(delete-blank-lines)
    121   (while (search-forward-regexp "\\(^\\s-*$\\)\n" nil t)
    122     (replace-match "\n")
    123     (unless (= (point) (point-max))
    124       (forward-char 1))))
    125 
    126 (defun clean-up-faz () ;; TODO Artikel auf einer Seite lesen
    127   (forward-line 2)
    128   (let ((start (point)))
    129     (goto-char (point-max))
    130     (or (search-backward "Mehr zum Thema" nil t)
    131         (search-backward "* Submit Submit"))
    132     (forward-line -1)
    133     (delete-region (point) (point-max))
    134     (goto-char (point-max))
    135     (search-backward "Abo")
    136     (beginning-of-line)
    137     (forward-line 2)
    138     (delete-region start (point)))
    139   (message-goto-body))
    140 
    141 (defun clean-up-mmnews ()
    142   (forward-line 2)
    143   (let ((start (point)))
    144     (forward-line)
    145     (search-forward-regexp "^[*]$" nil t)
    146     (forward-line 4)
    147     (delete-region start (point))
    148     ;;
    149     (goto-char (point-max))
    150     (or (search-backward "Wissen macht reich:" nil t)
    151         (search-backward "Neue Videos:" nil t))
    152     (beginning-of-line)
    153     (forward-line -1)
    154     (delete-region (point) (point-max)))
    155   (message-goto-body))
    156 
    157 (defun clean-up-voanews ()
    158   (forward-line 2)
    159   (let ((start (point)))
    160     (search-forward "Print this page")
    161     (beginning-of-line)
    162     (forward-line 3)
    163     (delete-region start (point))
    164     (search-forward "Related Stories")
    165     (forward-line -3)
    166     (delete-region (point) (point-max)))
    167   (message-goto-body))
    168 
    169 (defun clean-up-guardian ()
    170   (forward-line 2)
    171   (let ((start (point)))
    172     (goto-char (point-max))
    173     (search-backward-regexp "^Topics")
    174     (delete-region (point) (point-max))
    175     (goto-char start)
    176     (or (search-forward "Last modified" nil t)
    177         (search-forward "First published" nil t)
    178         (search-forward-regexp "^Published")
    179         )
    180     (or (search-backward "Submit" nil t)
    181         (search-backward-regexp "^* ")
    182         )
    183     (beginning-of-line)
    184     (forward-line 1)
    185     (delete-region start (point)))
    186   (message-goto-body))
    187 
    188 (defun clean-up-wikipedia ()
    189   (or (search-forward "Retrieved from" nil t)
    190       (search-forward "Abgerufen von" nil t))
    191   (beginning-of-line)
    192   (delete-region (point) (point-max))
    193   (message-goto-body))
    194 
    195 (defun clean-up-stackoverflow ()
    196   (forward-line 2)
    197   (let ((start (point)))
    198     (search-forward "Ask Question" nil t)
    199     (beginning-of-line)
    200     (search-backward "Learn more" nil t)
    201     (beginning-of-line)
    202     (forward-line 3)
    203     (delete-region (point) start))
    204   (goto-char (point-max))
    205   (search-backward "Add a comment" nil t)
    206   (beginning-of-line)
    207   (delete-region (point) (point-max))
    208   (message-goto-body))
    209 
    210 (defun clean-up-schneier ()
    211   (forward-line 2)
    212   (let ((start (point)))
    213     (search-forward "HomeBlog" nil t)
    214     (beginning-of-line)
    215     (forward-line 2)
    216     (delete-region (point) start))
    217   (goto-char (point-max))
    218   (search-backward "Atom Feed" nil t)
    219   (beginning-of-line)
    220   (delete-region (point) (point-max))
    221   (message-goto-body))
    222 
    223 (defun clean-up-counterpunch ()
    224   (forward-line 2)
    225   (let ((start (point)))
    226     (search-forward "Submit" nil t)
    227     (beginning-of-line)
    228     (forward-line 1)
    229     (delete-region (point) start))
    230   (goto-char (point-max))
    231   (search-backward "New from" nil t)
    232   (beginning-of-line)
    233   (delete-region (point) (point-max))
    234   (message-goto-body))
    235 
    236 (defun clean-up-wallstreetonparade ()
    237   (forward-line 1)
    238   (let ((start (point)))
    239     (search-forward "Search for:" nil t)
    240     (beginning-of-line)
    241     (forward-line 1)
    242     (forward-paragraph 1)
    243     (delete-region (point) start))
    244   (goto-char (point-max))
    245   (search-backward "Bookmark the permalink." nil t)
    246   (beginning-of-line)
    247   (delete-region (point) (point-max))
    248   (message-goto-body))
    249 
    250 (defun clean-up-cnn ()
    251   (forward-line 1)
    252   (let ((start (point)))
    253     (search-forward "Follow CNN" nil t)
    254     (beginning-of-line)
    255     (forward-paragraph 2)
    256     (delete-region (point) start))
    257   (goto-char (point-max))
    258   (search-backward "Submit" nil t)
    259   (beginning-of-line)
    260   (delete-region (point) (point-max))
    261   (message-goto-body))
    262 
    263 (defun clean-up-commondreams ()
    264   (forward-line 1)
    265   (let ((start (point)))
    266     (or (search-forward "(Photo" nil t)
    267         (search-forward "A project of Common Dreams" nil t))
    268     (beginning-of-line)
    269     (forward-paragraph 2)
    270     (delete-region (point) start))
    271   (goto-char (point-max))
    272   (or (search-backward "From Your Site Articles" nil t)
    273       (search-backward "SUBSCRIBE TO OUR FREE NEWSLETTER" nil t))
    274   (beginning-of-line)
    275   (delete-region (point) (point-max))
    276   (message-goto-body))
    277 
    278 (defun clean-up-wsws ()
    279   (forward-line 1)
    280   (let ((start (point)))
    281     (search-forward "* Donate" nil t)
    282     (beginning-of-line)
    283     (forward-paragraph)
    284     (delete-region (point) start))
    285   (goto-char (point-max))
    286   (or
    287    (search-backward "The World Socialist Web Site is the voice" nil t)
    288    (search-backward "Sign up for " nil t)
    289    (search-backward "Read more" nil t)
    290    (search-backward "Join the fight for socialism" nil t)
    291    (search-backward "Only by building an independent movement" nil t)
    292    )
    293   (beginning-of-line)
    294   (delete-region (point) (point-max))
    295   (message-goto-body))
    296 
    297 (defun clean-up-zsposepneho ()
    298   (forward-line 1)
    299   (let ((start (point)))
    300     (search-forward "Publikováno" nil t)
    301     (beginning-of-line)
    302     (backward-paragraph 2)
    303     (delete-region (point) start))
    304   (goto-char (point-max))
    305   (search-backward "Rychle k cíli" nil t)
    306   (beginning-of-line)
    307   (forward-line -1)
    308   (delete-region (point) (point-max))
    309   (message-goto-body))
    310 
    311 (defun clean-up-euractiv ()
    312   (forward-line 1)
    313   (let ((start (point)))
    314     (cond
    315      ((search-forward "Est. " nil t)
    316       (beginning-of-line)
    317       (backward-paragraph 3)
    318       (delete-region (point) start))
    319      ((search-forward "Content-Type:")
    320       (backward-paragraph 3)
    321       (delete-region (point) start)))
    322     ;; tail
    323     (goto-char (point-max))
    324     (or
    325      (search-backward "Euractiv is part of the Trust Project" nil t)
    326      (search-backward "Topics" nil t)
    327      (search-backward "Read more with Euractiv" nil t)
    328      )
    329     (when (< start (point))
    330       (beginning-of-line)
    331       (forward-line -1)
    332       (backward-paragraph 1)
    333       (delete-region (point) (point-max)))
    334     ;; whitespace
    335     (goto-char start)
    336     (while (re-search-forward "^[ \t]+" nil t)
    337       (replace-match "")))
    338   (message-goto-body))
    339 
    340 (defun clean-up-infomigrants ()
    341   (forward-line 1)
    342   (let ((start (point)))
    343     (search-forward "Published on : " nil t)
    344     (beginning-of-line)
    345     (backward-paragraph 2)
    346     (delete-region (point) start)
    347     ;; tail
    348     (goto-char (point-max))
    349     (search-backward "More articles" nil t)
    350     (beginning-of-line)
    351     (forward-line -1)
    352     (delete-region (point) (point-max))
    353     ;; other
    354     (goto-char start)
    355     (while (re-search-forward "^*\n" nil t)
    356       (replace-match ""))
    357     (goto-char start)
    358     (while (re-search-forward "^Also read: " nil t)
    359       (beginning-of-line)
    360       (forward-line -1)
    361       (kill-paragraph 1))
    362     )
    363   (message-goto-body))
    364 
    365 (defun email-eww ()
    366   (interactive)
    367   (let ((content (buffer-string))
    368         (title (or (plist-get eww-data :title)
    369                    (buffer-name (current-buffer))))
    370         (url (plist-get eww-data :url)))
    371     (compose-mail email-eww-to title `(("From" . ,email-eww-from)))
    372     (message-goto-body)
    373     (when url
    374       (insert url)
    375       (insert "\n\n"))
    376     (insert content)
    377     (message-goto-body)
    378     (delete-trailing-whitespace)
    379     (message-goto-body)
    380     (cond
    381      ((string-match "news.ycombinator.com" url)
    382       (clean-up-ycombinator))
    383      ((string-match "reddit.com" url)
    384       (clean-up-reddit))
    385      ((string-match "faz.net" url)
    386       (clean-up-faz))
    387      ((string-match "mmnews.de" url)
    388       (clean-up-mmnews))
    389      ((string-match "voanews.com" url)
    390       (clean-up-voanews))
    391      ((string-match "guardian.com" url)
    392       (clean-up-guardian))
    393      ((string-match "wikipedia.org" url)
    394       (clean-up-wikipedia))
    395      ((or (string-match "stackoverflow.com" url)
    396           (string-match "stackexchange.com" url))
    397       (clean-up-stackoverflow))
    398      ((string-match "schneier.com" url)
    399       (clean-up-schneier))
    400      ((string-match "counterpunch.org" url)
    401       (clean-up-counterpunch))
    402      ((string-match "wallstreetonparade.com" url)
    403       (clean-up-wallstreetonparade))
    404      ((string-match "cnn.com" url)
    405       (clean-up-cnn))
    406      ((string-match "commondreams.org" url)
    407       (clean-up-commondreams))
    408      ((string-match "wsws.org" url)
    409       (clean-up-wsws))
    410      ((string-match "zsposepneho.cz" url)
    411       (clean-up-zsposepneho))
    412      ((string-match "euractiv.com" url)
    413       (clean-up-euractiv))
    414      ((string-match "infomigrants.net" url)
    415       (clean-up-infomigrants))
    416      )
    417     (goto-char (point-max))
    418     (delete-blank-lines)
    419     (message-goto-to)
    420     (current-buffer)))
    421 
    422 (defun email-w3m (url)
    423   (when url
    424     (let ((b (get-buffer-create url)))
    425       (shell-command (concat "w3m -dump " (shell-quote-argument url)) b b)
    426       (with-current-buffer b
    427         (email-region (point-min) (point-max))
    428         (message-goto-body)
    429         (insert url)
    430         (insert "\n\n")
    431         (cond
    432          ((or
    433            (string-match "serverfault.com" url)
    434            (string-match "stackexchange.com" url)
    435            (string-match "stackoverflow.com" url)
    436            (string-match "superuser.com" url)
    437            )
    438           (search-forward "Ask Question" nil t)
    439           (beginning-of-line)
    440           (backward-paragraph 1)
    441           (beginning-of-line)
    442           (forward-line 3)
    443           (delete-region (point) start)
    444           (clean-up-stackoverflow)))
    445         (message-goto-to)))))
    446 (provide 'email-eww)