From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 29469 invoked from network); 13 Jul 2023 15:07:10 -0000 Received: from mx1.math.uh.edu (129.7.128.32) by inbox.vuxu.org with ESMTPUTF8; 13 Jul 2023 15:07:10 -0000 Received: from lists1.math.uh.edu ([129.7.128.208]) by mx1.math.uh.edu with esmtps (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1qJxuN-00DyEo-0F for ml@inbox.vuxu.org; Thu, 13 Jul 2023 10:07:07 -0500 Received: from lists1.math.uh.edu ([127.0.0.1] helo=lists.math.uh.edu) by lists1.math.uh.edu with smtp (Exim 4.96) (envelope-from ) id 1qJxuM-002iJP-0M for ml@inbox.vuxu.org; Thu, 13 Jul 2023 10:07:06 -0500 Received: from mx1.math.uh.edu ([129.7.128.32]) by lists1.math.uh.edu with esmtp (Exim 4.96) (envelope-from ) id 1qJkKy-002hJN-2G for ding@lists.math.uh.edu; Wed, 12 Jul 2023 19:37:40 -0500 Received: from quimby.gnus.org ([95.216.78.240]) by mx1.math.uh.edu with esmtps (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1qJkKl-00DZ1A-36 for ding@lists.math.uh.edu; Wed, 12 Jul 2023 19:37:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Content-Type:MIME-Version:Message-ID:Date:References: In-Reply-To:Subject:To:From:Sender:Reply-To:Cc:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=miI77XIUa5vJAXNftp1mjyj7BkL5dQz0bUswNIN+JUE=; b=Z5hhg0+JttPPlGpu5qC9jlF2AS R3815gyebKSilqDhSyaPW7pCNi9v9f9vpwWtDbj+1GXJ0OlYiXLrEWBR5LBuDpoHyn9cxYfXTR0e1 9LuG2CNsfMVqQlTi6zSLMv4hSlblrBEaKSFrgcXXjWvk/kFC+sh/i6Z8/UNXKCeY/TqQ=; Received: from mail-oo1-xc30.google.com ([2607:f8b0:4864:20::c30]) by quimby.gnus.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1qJkKZ-0003lh-0X for ding@gnus.org; Thu, 13 Jul 2023 02:37:21 +0200 Received: by mail-oo1-xc30.google.com with SMTP id 006d021491bc7-5634db21a58so188877eaf.0 for ; Wed, 12 Jul 2023 17:37:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1689208632; x=1691800632; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:to:from:from:to:cc:subject:date:message-id:reply-to; bh=miI77XIUa5vJAXNftp1mjyj7BkL5dQz0bUswNIN+JUE=; b=gtVF+tqia6KmjVm6TlKY9FwSrR4g5wu/Iak2xWoWiMf7cVVVvjUqhgWEDWTsKzmND6 pnsOdZP+oTFxmV4whRHhe0Vc5lHcln9wRhuS37u29nZoe2UgldB8RePBN/7Oy6G+Goz/ sUozQmJS44ZlnjkMCsPcKW9Q4MgCC8m5VXe99TySD024JAhstvXhEHVlcqLuaWsdiO0c /4sUuKBnfCBuR6ptazI7caBxt/nZ7dsboXE3LZlVmuN2EgHkciFSdW6vxWD655YCev9T 7n9MRzI32oTXmwLYYgoCx1r95MXZS6Foe7enZPvigvxg+sG/Nev6ESqyQGfBhmgK4gDq kWMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689208632; x=1691800632; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=miI77XIUa5vJAXNftp1mjyj7BkL5dQz0bUswNIN+JUE=; b=DynhRcsWAxL7gmZ5x3G+aQk19susDDEx1iiZ8b7Yz1ndq/yE7hq7MDwd5y+03OHZXM uTYiwv2IeuvBRrl94pU3cXdro45kfe7Vi59cm/Yv5RD3UiHevChVB1jHKzcBNhc/MFBt d+W6DfrgfcGabO2iBowE4DYRcPcWaK0PuMNfHlHQGa+PQ1aAnfEUnNhp0tZbK0U8tra7 oUCPKw9ZeKSQrJJ+GmEUivdeWov3kt+CabIePOfbWEBJIAsg5FUXzgxFtbOgybDihEMe Ccl+KhZgHhsF+2tVabatsjIHZ7RCrq6rrtt7mETMqokd20XUjbdb3R9VE1SdbriNn0q6 Yuig== X-Gm-Message-State: ABy/qLY8QIwqZzJQYq0ls8mVuBCO+QUvRd1UOOHUI92TELYA1dpNFf8L 0aQjhePNikKDTGv6wEMMnJsgPPSJ/hM= X-Google-Smtp-Source: APBJJlElQ7NAfvbA1dQN0zQfKyYIfz/Nk+Zvk0H8glonenSAtH4f5vxFQfJFxLaEq9vDnmt+FU5R0w== X-Received: by 2002:a05:6870:40cd:b0:1b3:e225:7077 with SMTP id l13-20020a05687040cd00b001b3e2257077mr501206oal.34.1689208631708; Wed, 12 Jul 2023 17:37:11 -0700 (PDT) Received: from sekai ([2804:14c:da80:82e2::d97d]) by smtp.gmail.com with ESMTPSA id v13-20020a056870e28d00b001b3d5b06b6asm2539514oad.23.2023.07.12.17.37.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jul 2023 17:37:11 -0700 (PDT) From: Fernando de Morais To: ding@gnus.org Subject: Re: download in background? In-Reply-To: <87lek3y4xz.fsf@dataswamp.org> (Emanuel Berg's message of "Sat, 11 Mar 2023 11:10:00 +0100") References: <87lek3y4xz.fsf@dataswamp.org> Date: Wed, 12 Jul 2023 21:36:59 -0300 Message-ID: <87mt00640k.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" List-ID: Precedence: bulk --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello Emanuel, Emanuel Berg writes: > Can we have - not have this?=20 > > Is it difficult to do, to have it in the background with maybe > in the mode bar or something ... > > The Emacs OS anyone? > > How would you do that? Sorry, unfortunately this message will be a bit long... =F0=9F=98=A5 In my time using Rmail, I needed a similar solution. In the configurations of cadadr[1] and Alex Schroeder[2] I've found appropr= iate solutions for what I needed, however I insisted on using the tools I alread= y had on my system, in this case `movemail' from GNU Mailutils, as Rmail needed i= t for some operations. So I wrote my own ``solution'' (attached---straight from my `init.el'). Basically, its only a library for use `movemail' from Emacs and some small extensions to auto-fetch emails periodically and asynchronously. Each acco= unt had their emails stored in a different MBOX file (or a single one, as I pre= fer this days) in a folder. So I could set this directory as a value to the variable `display-time-mail-directory' and, when detecting that the files a= re no longer empty, the indicator of new mail is shown in the `mode-line'. When I migrated back to Gnus, I continued using the same method, out of laziness. I simply set the `mail-sources' variable as below: #+begin_src emacs-lisp (setopt mail-sources '((file :path "~/Mail/spool"))) #+end_src My ``solution'' always seemed pretty bloated to me and I believe we already= have appropriate libraries in Emacs to auto-fetch emails, in this case `mail-source.el'. What we need, I think, is just to find a way to make it = work asynchronously. I've been thinking about this for a while now. It seems to me that we alre= ady have the tools to make Gnus fetch new news asynchronously. Very inspired by some suggestions from an EmacsWiki[3] page, here with my settings, for exam= ple, if I do the following, with Gnus loaded and open in an Emacs instance: 1. Open a new Emacs; 2. On the new instance, run `M-x gnus-child'; 3. Wait for it to be loaded, then `M-x gnus-group-exit'; 4. On the main instance, unplug Gnus (`gnus-agent-toggle-plugged'); 5. And then `M-x gnus-group-restart'. News fetched with `gnus-child' are loaded in the "Parent" instance. I don't know if we could, in the current state of things, replicate this recipe in a `start-process' or by making use of `async.el'... Perhaps a dear Gnus maintainer can give us some direction on this possibility. If you want to make use of my ``solution'' with `movemail' from GNU Mailuti= ls and need some help, just get in touch and I'll help in any way I can. Footnotes: [1] https://cadadr.dreamwidth.org/828.html [2] https://alexschroeder.ch/wiki/2020-12-17_Rmail [3] https://www.emacswiki.org/emacs/GnusSpeed#h5o-26 --=20 Regards, Fernando de Morais. --=-=-= Content-Type: text/x-org Content-Disposition: attachment; filename=movemail.org Content-Description: movemail.org * Movemail #+begin_src emacs-lisp (defgroup movemail nil "GNU Mailutils movemail interface for GNU Emacs." :group 'external :prefix "movemail-" :tag "Movemail") (defcustom movemail-command "movemail" "Command for calling movemail. Do not set options in this variable. To do so, customize `movemail-flags'." :type 'string :group 'movemail) (defcustom movemail-flags '("--emacs" "--ignore-errors") "List of flags to pass to movemail execution. Execute \\[movemail-help] to view a complete list of flags." :type '(repeat string) :group 'movemail) (defcustom movemail-use-tickets nil "Whether to use the tickets file for retrieving credentials. This file will be used to get the password for a remote connection with the desired mailbox(es), but only if the `auth-source' method fails." :type 'boolean :initialize #'custom-initialize-set :set (lambda (symbol value) (set-default symbol value) (when value (add-to-list 'auth-sources "~/.mu-tickets"))) :group 'movemail) (defun movemail--check-installation (&optional fun fun-args) "Verify if movemail is installed. If passed, optional FUN can be applied with optional FUN-ARGS, when movemail is located." (let ((program movemail-command)) (if (executable-find program) (when fun (apply fun fun-args)) (error "Could not find %s in `exec-path'" program)))) (defun movemail--get-password (mailbox host port prompt) "Get password to move mail from remote servers. The password will be searched through `auth-source', associating it with MAILBOX, HOST and PORT. When it fails, the credentials stored in \"~/.mu-tickets\" file will be used by movemail. If `movemail-use-tickets' is nil or the file is absent, the user will be prompted for a password instead, with a custom PROMPT." (let ((remote-password nil)) (setq remote-password (let ((found (nth 0 (auth-source-search :max 1 :user mailbox :host host :port port :require '(:secret))))) (if found (let ((secret (plist-get found :secret))) (if (functionp secret) (funcall secret) secret)) (unless (and movemail-use-tickets (file-exists-p "~/.mu-tickets")) (read-passwd prompt))))))) (defun movemail--get-prompt (proto) "Return a prompt, according to PROTO, for password request." (cond ((string-match-p "\\(?:imaps?\\)" proto) "IMAP password: ") ((string-match-p "\\(?:pops?\\)" proto) "POP password: ") ((string-match-p "smtp" proto) "SMTP password: "))) (defun movemail-help () "Generate a buffer containing movemail help information." (interactive) (let* ((command (list (concat movemail-command " --help"))) (contents (movemail--check-installation #'shell-command-to-string command)) (buffer "*Movemail Help*")) (with-help-window buffer (with-current-buffer buffer (princ contents))))) (defun movemail-version () "Echo movemail version information." (interactive) (let* ((command (list (concat movemail-command " -V"))) (contents (movemail--check-installation #'shell-command-to-string command))) (message (string-trim contents)))) (defun movemail-move-mail (orig dest &optional pop-pass id) "Move mail, asynchronously, from one mailbox to another. ORIG and DEST must be alists whose elements have the form (KEY . VALUE) that are intended to represent the components of a link accepted by movemail. Those are specified in the Info node `(emacs) Movemail'. Here, KEY can be one of the following: protocol: VALUE must be one of the protocols supported by movemail. user: VALUE must be the username for the mailbox. password: VALUE must represent the password used for authentication. auth-mechanism: VALUE must contain the mechanisms used for authentication, when more than one, separated by commas. port: VALUE must be a string containing the port of the remote server. imap-folder: VALUE must be the name of the folder to be accessed over an IMAP connection. extra-params: VALUE must contain extra parameters, separated by semicolons (when more than one). file-name: VALUE must contain the name of a file or directory. For example, the link: imaps://my.email%40example.com@imap.example.com:993/all Can be represented in the following alist: ((protocol . \"imaps\") (user . \"my.email@example.com\") (host . \"imap.example.com\") (port . \"993\") (imap-folder . \"all\")) It is worth noting that certain cons cells are specific to certain protocols, such as \"auth-mechanisms\" and \"extra-params\", commonly used in POP and SMTP connections, as well as the \"file-name\", which should be used to represent links that point to local files or directories. The optional POP-PASS is here for the sake of completeness: it will only be used if ORIG represents a link to a POP connection and if the KEY \"password\" is nil. Finally, the optional ID must be a string that will be concatenated to the name of the process in the form \"movemail--id\"." (let ((creds (list orig dest)) (links '(orig-link dest-link)) (use-pop-pass nil)) (while creds (let-alist (car creds) (if (not .protocol) (setf (symbol-value (car links)) (expand-file-name .file-name) creds (cdr creds) links (cdr links)) (setf (symbol-value (car links)) (concat .protocol "://" (if (not (string-match-p "\\(?:imaps?\\|pops?\\|smtp\\)" .protocol)) (expand-file-name .file-name) (concat (replace-regexp-in-string "@" "%40" .user) (if .password (concat ":" .password) (if (and (length= creds 2) (string-match-p "\\(?:pops?\\)" .protocol) pop-pass) (progn (setq use-pop-pass t) nil) (concat ":" (movemail--get-password .user .host .port (movemail--get-prompt .protocol))))) (when (and .password .auth-mechanisms) (concat ";" .auth-mechanisms)) "@" .host (when .port (concat ":" .port)) (when .imap-folder (concat "/" .imap-folder)) (when .extra-params (concat ";" .extra-params))))) creds (cdr creds) links (cdr links))))) (movemail--check-installation #'start-process (flatten-tree (list (concat "movemail" (when id (concat "--" id))) "*Movemail*" movemail-command movemail-flags orig-link dest-link (if use-pop-pass pop-pass "")))))) #+end_src #+begin_src emacs-lisp ;; Movemail extension: credentials system #+end_src #+begin_src emacs-lisp (defgroup movemail-credentials nil "Provide information to `movemail' from a lisp-data file." :group 'movemail :prefix "movemail-credentials-" :tag "Movemail Credentials") (defcustom movemail-credentials-file (expand-file-name "credentials.el" user-emacs-directory) "File that stores the credentials used by `movemail'. This must to be a lisp-data file, encrypted or not, containing alists whose elements can be structured as follows: ((foo . ((ignore . nil) (mail-address . \"foo@example.com\") (password . \"p4s3w0rd\") (fetch-auth . \"auth=+APOP\") (fetch-protocol . \"pop\") (fetch-server . \"pop.example.com\") (fetch-port . \"110\") (fetch-params . \"notls\") (inbox-filename . \"~/Mail/some-name\")) (bar . ((ignore .t) (mail-address . \"bar@example.com\") (fetch-protocol . \"imaps\") (fetch-server . \"imap.example.com\") (fetch-port . \"993\") (fetch-folder . \"INBOX\") (inbox-filename . (my-func args)))))) The \"inbox-filename\" can be any file or destination link containing any local protocol supported by movemail, as well as a function that returns a string---it will be evaluated when needed. See the Info node `(emacs) Movemail' for more details on supported links. It is not necessary to inform the password in the credentials file, since it will try to retrieve it through the `auth-source'. However, if unsuccessful, movemail will try to get the password from the traditional GNU Mailutils \"~/.mu-tickets\" file. See the Info node `(mailutils) mailutils wicket' for more details about this file. If `movemail-use-tickets' is nil or the tickets file is not in the home directory, the user will be asked for the password instead. Only fields that describes mail address, protocol, server and destination file name are strictly necessary." :type 'file :group 'movemail-credentials) (defun movemail-credentials-read () "Read contents of the `movemail-credentials-file'." (let ((file movemail-credentials-file)) (if (file-exists-p file) (with-temp-buffer (insert-file-contents file) (read (current-buffer))) (error "Credentials file \"%s\" not found" (file-name-nondirectory file))))) (defun movemail-credentials-list () "Return a list of non-ignored mailboxes. Those are listed in the credentials file. See `movemail-credentials-file' for more details." (let ((credentials (movemail-credentials-read)) (mailboxes (list)) (count 0)) (while (< count (length credentials)) (let ((current (nth count credentials))) (unless (alist-get 'ignore current) (push (car current) mailboxes))) (setq count (1+ count))) (nreverse mailboxes))) #+end_src #+begin_src emacs-lisp ;; Movemail extension: fetch mail helper #+end_src #+begin_src emacs-lisp (defgroup movemail-fetch nil "Extension to fetch mail in a convenient way with `movemail'." :group 'movemail :prefix "movemail-fetch-" :tag "Movemail Fetch") (defcustom movemail-fetch-filter nil "Filter function for processes started by `movemail-fetch-mail'. See `set-process-filter' for more info on filter functions." :type '(choice boolean function) :group 'movemail-fetch) (defcustom movemail-fetch-sentinel nil "Sentinel function for processes started by `movemail-fetch-mail'. See `set-process-sentinel' for more info on sentinels." :type 'function :group 'movemail-fetch) (defun movemail-fetch-mail () "Fetch remote mail to a local inbox with `movemail-move-mail'. A filter and a sentinel function can be added to each movemail process execution setting `movemail-fetch-filter' and `movemail-fetch-sentinel', respectively. To use this function it will be necessary to create and set a credentials file. See `movemail-credentials-file' for more information." (interactive) (let ((credentials (movemail-credentials-read)) (mailboxes (movemail-credentials-list))) (while mailboxes (let-alist (alist-get (car mailboxes) credentials) (let ((id (symbol-name (car mailboxes))) (orig (list (cons 'protocol .fetch-protocol) (cons 'user .mail-address) (cons 'password .password) (cons 'auth-mechanisms .fetch-auth) (cons 'host .fetch-server) (cons 'port .fetch-port) (cons 'imap-folder .fetch-folder) (cons 'extra-params .fetch-params))) (dest (list (cons 'file-name (eval .inbox-filename)))) (process nil)) (if (string-match-p "\\(?:\\(?:imaps?\\|pops?\\|smtp\\)://\\)" (alist-get 'file-name dest)) (user-error "%s: \"inbox-filename\" is not a local mailbox" id) (setq process (movemail-move-mail orig dest nil id)) (set-process-filter process movemail-fetch-filter) (when (functionp movemail-fetch-sentinel) (set-process-sentinel process movemail-fetch-sentinel))))) (setq mailboxes (cdr mailboxes))))) #+end_src #+begin_src emacs-lisp ;; Movemail extension: auto-fetch mail #+end_src #+begin_src emacs-lisp (defgroup movemail-auto-fetch nil "Auto-fetch extension for GNU Mailutils movemail on Emacs." :group 'movemail :prefix "movemail-auto-fetch-" :tag "Movemail Auto-Fetch") (defcustom movemail-auto-fetch-step 60 "Time step to calculate the auto fetch frequency." :type 'integer :group 'movemail-auto-fetch) (defcustom movemail-auto-fetch-timer 5 "Timer to auto fetch mails. The time step can be configured in `movemail-auto-fetch-step'." :type 'number :group 'movemail-auto-fetch) (defvar movemail-auto-fetch-object nil "Timer object generated from `movemail-auto-fetch-mode'.") (define-minor-mode movemail-auto-fetch-mode "Minor mode to auto-fetch mail in background with `movemail'." :global t :init-value nil :lighter " AFMail" (let ((time (* movemail-auto-fetch-step movemail-auto-fetch-timer)) (object movemail-auto-fetch-object)) (if (not movemail-auto-fetch-mode) (when (timerp object) (cancel-timer object) (setq movemail-auto-fetch-object nil)) (unless (timerp object) (setq movemail-auto-fetch-object (run-with-timer 0 time #'movemail-fetch-mail)))))) #+end_src #+begin_src emacs-lisp (add-hook 'after-init-hook #'movemail-auto-fetch-mode 100) #+end_src --=-=-=--