From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1 ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id CMoZN/xURWAuKwAA0tVLHw (envelope-from ) for ; Sun, 07 Mar 2021 22:34:36 +0000 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1 with LMTPS id mEDHMvxURWCQaQAAbx9fmQ (envelope-from ) for ; Sun, 07 Mar 2021 22:34:36 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id DBB3519C25 for ; Sun, 7 Mar 2021 23:34:35 +0100 (CET) Received: from localhost ([::1]:44166 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lJ1yt-0004rs-1S for larch@yhetil.org; Sun, 07 Mar 2021 17:34:35 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46898) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lJ1yO-0004qk-Ky for emacs-orgmode@gnu.org; Sun, 07 Mar 2021 17:34:05 -0500 Received: from stw1.rcdrun.com ([217.170.207.13]:42093) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lJ1yJ-0000Oi-Av for emacs-orgmode@gnu.org; Sun, 07 Mar 2021 17:34:04 -0500 Received: from localhost ([::ffff:41.210.141.24]) (AUTH: PLAIN securesender, TLS: TLS1.2,256bits,ECDHE_RSA_AES_256_GCM_SHA384) by stw1.rcdrun.com with ESMTPSA id 000000000001E079.00000000604554D4.000034B2; Sun, 07 Mar 2021 15:33:55 -0700 Date: Mon, 8 Mar 2021 01:31:18 +0300 From: Jean Louis To: Ian Garmaise Subject: Re: content management in emacs Message-ID: Mail-Followup-To: Ian Garmaise , emacs-orgmode References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=_stw1.rcdrun.com-13490-1615156437-0001-2" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/2.0 (3d08634) (2020-11-07) Received-SPF: pass client-ip=217.170.207.13; envelope-from=bugs@gnu.support; helo=stw1.rcdrun.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: emacs-orgmode Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: "Emacs-orgmode" X-Migadu-Flow: FLOW_IN ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1615156476; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post; bh=nNp9jwPvJDbgnanCLxIdyqns6zmVhvCd4P+6pRMxr5o=; b=owj0G0h8qNal6rQQAoT6UtGoxjajxnX6ecYv3ZX9XbgmlDs+w+gRViTts/PM/BwC8AyHjh 3SpZuUMdpBVljsFcimKyKp+bK2TSwtUMnWRXewfUw0EgIRpH5sPd/DHWblqUTUJgxWDHzd CavTI8FNPzQwPFBQnEhXq/U7GMRyj8xef+Kdy9CD7uI94FV5eK5JXM9haWmxARuzHArE2V MfHs/WM1AHekmtO0iATbX3BL9iZizclePs/JO1jdJmwykWw6/O+ddoeYW6qdOj8++xr/B4 b52nlXtdxqySPwV6FG4ZfPjTEQXjqoDTUUgwff2hxJ2ajRTLk7MnQ0bUGFrEMg== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1615156476; a=rsa-sha256; cv=none; b=ffI+qlnvmeoG0TqP2+bw4o7TDUbVMO7JnX0xHZBVPUMhi242MHQYXb56Up3m1aNYEPhRQV 7DdFOcJfp/G9TFtp9ycVP1RVdWR54g6TzOhK0SRTp6N8Va8HdNnotW4SA/Yu04m9gzB8U3 Z5rILbcJNKKOAP/eRxS7oDk7dKAZMth+xWU0XoU4ZKat82EdvuZ4mzHuOBaRBUfwxaSIKo IgBl/zcDTttZk9ANEPp2POMHUiDw4c7wwE0HbCDLhDe0kX+Lf1v3Qwb2WwBVoykaQGbdi3 OjrzbXVefPF40GgS3zp5j4uLB1MNf1dzg2qrDNGY48EDRvKHkLsrMh2IAZyUfw== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of emacs-orgmode-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=emacs-orgmode-bounces@gnu.org X-Migadu-Spam-Score: -0.88 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of emacs-orgmode-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=emacs-orgmode-bounces@gnu.org X-Migadu-Queue-Id: DBB3519C25 X-Spam-Score: -0.88 X-Migadu-Scanner: scn0.migadu.com X-TUID: ygGUZxNkEso7 This is a MIME-formatted message. If you see this text it means that your E-mail software does not support MIME-formatted messages. --=_stw1.rcdrun.com-13490-1615156437-0001-2 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline * Ian Garmaise [2021-02-27 21:59]: > Hi Bob, > > How do you send mail to mailing lists with BBDB? Do you use a templating > tool? Also, how do you start a phone call? Phone call may be started by using Android/Replicant/LineageOS devices and Termux tools' https://termux.com command: `termux-telephony-call` I am adding some of functions I am using, but cannot help in polishing the package for you. If you need some more functions from here, I will send you. You can then send termux command `termux-telephony-call` and initiate the call on Android/Replicant/LineageOS devices. For sending SMS I am heavily using KDEConnect, but you may use termux to send SMS by loading older library (ask me), or by using ShellMS application. Jean --=_stw1.rcdrun.com-13490-1615156437-0001-2 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="termux.el" ;;; termux.el --- Termux functions. -*- lexical-binding: t; -*- ;; Copyright (C) 2016-2021 by Jean Louis ;; Author: Jean Louis ;; Version: 0.1 ;; Package-Requires: (rcd-utilities rcd-cf rcd-db-init rcd-db time-date) ;; Keywords: ;; URL: https://gnu.support/gnu-emacs/packages/termux-el.html ;; This file is not part of GNU Emacs. ;; This program is free software: you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as ;; published by the Free Software Foundation, either version 3 of the ;; License, or (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, but ;; WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; These are the Termux utilities for GNU Emacs Lisp ;; ;; RCD is acronym for Reach, Connect, Deliver, my personal ;; principle and formula for Wealth. ;;; Change Log: ;;; Code: (require 'rcd-db-init) (require 'rcd-db) (require 'rcd-utilities) (require 'subr-x) (require 'time-date) (defcustom termux-ip "192.168.43.1" "IP Address of Replicant system" :type 'string :group 'Termux) (setq termux-ip "192.168.42.129") ;;(setq termux-ip "192.168.43.1") (defvar termux-ssh-command "ssh") (defvar termux-ssh-port "8022") (defvar termux-bin-directory "/data/data/com.termux/files/usr/bin/") ;;;; END OF SETUP (defun termux/send-command (command) "Sends command to connected Replicant device and returns the output string" (let* ((command (concat termux-ssh-command " -p " termux-ssh-port " " termux-ip " \"" command "\"")) (output (shell-command-to-string command)) (output (string-trim output))) output)) (defun termux/error (error) "Messages error" (message error)) (defun termux/escape-double-quotes (s) "Escapes double quotes" (replace-regexp-in-string "\"" "\\\\\"" s)) (defun termux/escape-single-quotes (s) "Escapes single quotes" (replace-regexp-in-string "'" "\'" s)) (defun termux/escape-quotes (s) "Escapes double and single quotes" (let* ((s (termux/escape-double-quotes s))) ;;(s (termux/escape-single-quotes s))) s)) (defun termux/commands () "Returns the list of all available termux commands and run the command if available." (interactive) (let* ((command (concat "cd " termux-bin-directory " && ls termux*")) (commands (termux/send-command command)) (commands (split-string commands "\n")) (commands (append commands '("insert-location"))) (command (completing-read "Termux commands: " commands)) (command (intern (concat "termux/" command)))) (if (functionp command) (funcall command) (message (concat "Command " (symbol-name command) " does not exist"))))) (defun termux/termux-location () (let* ((command "termux-location") (result (termux/send-command command)) (parsed (json-parse-string result))) (if (gethash "longitude" parsed) (let* ((latitude (number-to-string (gethash "latitude" parsed))) (longitude (number-to-string (gethash "longitude" parsed))) (location (concat latitude "," longitude))) location) (termux/error "Could not get location")))) (defun termux/termux-location-insert () "Inserts current location in the buffer" (interactive) (let ((location (termux/termux-location))) (insert location))) (defun termux/termux-clipboard-get () "Returns the Replicant clipboard value" (let* ((command "termux-clipboard-get") (result (termux/send-command command))) result)) (defun termux/termux-clipboard-get-insert () "Inserts the Replicant clipboard value" (interactive) (let ((clipboard (termux/termux-clipboard-get))) (insert clipboard))) (defun termux/termux-clipboard-set (value) "Sets the Replicant clipboard value" (interactive "MSet clipboard to: ") (let* ((value (termux/escape-double-quotes value)) (command (concat "termux-clipboard-set \"" value "\""))) (termux/send-command command))) (defun termux/termux-wifi-enable (boolean) ;; TODO "Enable or disable Wi-Fi on Replicant" (interactive "MEnable Wi-Fi (T for true, F or else for false): ") (let* ((boolean (if (string-match "t" (downcase boolean)) "true" "false")) (command (concat "termux-wifi-enable \"" boolean "\""))) (termux/send-command command))) (defun termux/termux-tts-speak (text) "Speaks by using termux" (interactive "MText to speak: ") (let* ((text (termux/escape-quotes text)) (command (concat "termux-tts-speak \"" text "\""))) (termux/send-command command))) (defun termux/termux-vibrate () "Vibrate Replicant device" (interactive) (let* ((command "termux-vibrate")) (termux/send-command command))) ;; (defun termux-sms-send (number text) ;; "Sends SMS message by using termux" ;; (interactive "MNumber: \nMText: ") ;; (let* ((text (termux/escape-double-quotes text)) ;; (command (concat "termux-sms-send -n \"" number "\" \"" text "\""))) ;; (termux/send-command command))) (defun termux-sms-send (number text) "Send SMS message by using ShellMS application" (let* ((text (termux/escape-quotes text)) (command (format "am startservice --user 0 -n com.android.shellms/.sendSMS -e contact %s -e msg \\\"%s\\\"" number text))) (termux/send-command command))) ;; (termux-sms-send "+123" sms) ;; (termux-sms-send "+123" "Hello") ;; (termux-sms-send "+123" "Hello thank you, but I do not have this number registered, what is your name?") (defun termux-import-sms-list () (interactive) (let* ((command "termux-sms-list -t inbox -l 500") (list (termux/send-command command)) (list (json-parse-string list)) (remainder-file (concat (getenv "TMPDIR") "SMS-import-" (rcd-timestamp) ".el")) (_ (data-to-file list remainder-file)) (how-many (length list))) (dotimes (n how-many) (let ((sms (elt list n))) (cf-sms-insert sms))))) ;; (termux-import-sms-list) (defun cf-sms-handle (sms) "Returns list after reading the `sms' hash" (let* ((type (gethash "type" sms)) (status (cf-sms-status type)) (number (gethash "number" sms)) (date-received (gethash "received" sms)) (body (gethash "body" sms))) (list status number date-received body))) (defun cf-sms-status (status) (cond ((string= status "inbox") 2) (t (error (concat "Cannot find SMS type: " status))))) (defun cf-sms-insert (sms) "Inserts the SMS hash into the database" (let ((exists (cf-sms-imported-exists sms))) (if exists (message-any sms) (let* ((sms (cf-sms-handle sms)) (status (elt sms 0)) (number (elt sms 1)) (date-received (elt sms 2)) (date-received (cf-sms-repair-date date-received)) (body (elt sms 3)) (body (sql-escape-string body)) (id (cf-contact-by-phone-1 number)) (sql (format "INSERT INTO sms (sms_datecreated, sms_contacts, sms_smsstatus, sms_body, sms_phone) VALUES ('%s', %s, %s, %s, '%s') RETURNING sms_id" date-received id status body number))) (if id (rcd-sql-first sql *cf*) (message (format "SMS not entered: %s" (prin1-to-string sms)))))))) (defun cf-sms-imported-exists (sms) (let* ((sms (cf-sms-handle sms)) (status (elt sms 0)) (number (elt sms 1)) (date-received (elt sms 2)) (date-received (cf-sms-repair-date date-received)) (body (elt sms 3)) (body (sql-escape-string body)) (id (cf-contact-by-phone-1 number)) (sql (format "SELECT * FROM sms WHERE sms_datecreated = '%s' AND sms_contacts = %s AND sms_smsstatus = %s AND sms_body = %s AND sms_phone = '%s'" date-received id status body number))) (if id (let ((ids (rcd-sql-list sql *cf*))) (if ids ids nil)) (message (format "SMS did not find ID: %s" (prin1-to-string sms)))))) (defun cf-sms-repair-date (date) "Repairs the date give by `termux-sms-list' function" (let* ((time (decoded-time-add (parse-time-string date) '(nil nil nil nil nil nil nil nil nil))) (year (decoded-time-year time)) (month (decoded-time-month time)) (day (decoded-time-day time)) (hour (decoded-time-hour time)) (minute (decoded-time-minute time)) (second (decoded-time-second time)) (date-time (format "%04.f-%02.f-%02.f %02.f:%02.f:%02.f" year month day hour minute second))) date-time)) ;; (defun termux-sms-list () ;; (interactive) ;; (let* ((command "termux-sms-list -t inbox -l 500") ;; (list (termux/send-command command)) ;; (list (json-parse-string list)) ;; (how-many (length list))) ;; (dotimes (n how-many) ;; (let ((sms (elt list n))) ;; (cf-sms-insert sms))))) (defun rcd-kdeconnect-send-sms (number message) (let* ((status (shell-command (mapconcat 'identity (list "kdeconnect-cli" "-d" ;; "73fc592ea61a3a70" ;; Airtel "c47e5d958b455603" ;; MTN "--destination" number "--send-sms" (shell-quote-argument message)) " ")))) status)) (defvar rcd-prefixes-uganda-airtel-mobile '(700 701 702 703 704 705 706 710 711 712 713 714 715 716 717 718 719 750 751 752 753 754 755 756 757 758 759)) (defvar rcd-prefixes-uganda-mtn-mobile '(770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789)) (defun rcd-sql-phone-national-prefix-or (country-prefix prefixes) (let* ((country-prefix (if (numberp country-prefix) (number-to-string country-prefix) country-prefix)) (prefixes (mapcar (lambda (n) (single-quote (concat country-prefix (number-to-string n)))) prefixes)) (prefixes (string-join prefixes ", "))) prefixes)) (defun rcd-sql-phone-recent-people-by-mobile-prefix (prefixes &optional how-many) (let* ((how-many (or how-many 200)) (sql (format "SELECT people_id, get_full_contacts_name(people_id) FROM people WHERE (substring(people_officephone, 2, 6) IN (%s) OR substring(people_mobilephone, 2, 6) IN (%s) OR substring(people_homephone, 2, 6) IN (%s) OR substring(people_otherphone, 2, 6) IN (%s) OR substring(people_fax, 2, 6) IN (%s)) ORDER BY people_id DESC LIMIT %s" prefixes prefixes prefixes prefixes prefixes how-many))) sql)) (defun cf-tabulated-people-recent-by-airtel-mobile () (interactive) (let* ((prefixes (rcd-sql-phone-national-prefix-or 256 rcd-prefixes-uganda-airtel-mobile)) (sql (rcd-sql-phone-recent-people-by-mobile-prefix prefixes))) (rcd-db-sql-report-two "Recent people with UG Airtel numbers" sql [("ID" 8) ("Person" 80)] "people" nil))) (provide 'termux) ;;; termux.el ends here --=_stw1.rcdrun.com-13490-1615156437-0001-2--