emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Jean Louis <bugs@gnu.support>
To: Ian Garmaise <ian.g@phorixsol.com>
Cc: emacs-orgmode <emacs-orgmode@gnu.org>
Subject: Re: content management in emacs
Date: Mon, 8 Mar 2021 01:31:18 +0300	[thread overview]
Message-ID: <YEVUNjFkkfgjQZEv@protected.rcdrun.com> (raw)
In-Reply-To: <CALWEx6Upb9+Uru54M4YYDtz7Fm9P8tZz+0wgNDXkn2wYG2nSOQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 765 bytes --]

* Ian Garmaise <ian.g@phorixsol.com> [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


[-- Attachment #2: termux.el --]
[-- Type: text/plain, Size: 10601 bytes --]

;;; termux.el --- Termux functions. -*- lexical-binding: t; -*-

;; Copyright (C) 2016-2021 by Jean Louis

;; Author: Jean Louis <bugs@gnu.support>
;; 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 <http://www.gnu.org/licenses/>.

;;; 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

  parent reply	other threads:[~2021-03-07 22:34 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <mailman.47.1614445226.20994.emacs-orgmode@gnu.org>
2021-02-27 18:57 ` Ian Garmaise
2021-02-27 19:16   ` Martin Steffen
2021-02-27 20:11     ` Juan Manuel Macías
2021-03-01  5:17     ` Bob Newell
2021-02-28 10:39   ` Eric S Fraga
2021-03-07 22:31   ` Jean Louis [this message]
2021-03-07 22:38   ` Jean Louis
2021-02-27 20:52 ` contact " dalanicolai
2021-03-07 22:51   ` Jean Louis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YEVUNjFkkfgjQZEv@protected.rcdrun.com \
    --to=bugs@gnu.support \
    --cc=emacs-orgmode@gnu.org \
    --cc=ian.g@phorixsol.com \
    --subject='Re: content management in emacs' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Code repositories for project(s) associated with this inbox:

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).