iorg-controller.el 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. ;;; iorg-controller -- elnode handlers and such for handling web POST/GET requests
  2. (require 'org)
  3. (require 'elnode)
  4. (require 'org-export)
  5. (require 'org-e-html)
  6. (require 'org-agenda)
  7. (require 'iorg-util)
  8. (eval-when-compile
  9. (require 'cl))
  10. ;;; Customs, Constants and Variables
  11. ;; Customisation Groups and Variables
  12. (defgroup iorg nil
  13. "A webframework based on Org-mode, Elnode and dVCS."
  14. :tag "iOrg"
  15. :group 'org
  16. :group 'elnode)
  17. (defgroup iorg-controller nil
  18. "Elnode handlers for handling web request."
  19. :tag "iorg-controller"
  20. :group 'iorg)
  21. (defcustom iorg-controller-load-hook nil
  22. "Hook that is run after iorg-controller.el has been loaded."
  23. :group 'iorg-controller
  24. :type 'hook)
  25. ;; Constants
  26. (defconst iorg-controller-dir
  27. (file-name-directory (or load-file-name (buffer-file-name)))
  28. "The directory of iorg-controller.el in canonical form")
  29. (defconst iorg-controller-urls
  30. '(("^$" . iorg-initialize-simple-handler)
  31. ("^edit/$" . iorg-change-state-handler)
  32. ("^send/$" . iorg-change-state-handler)
  33. ("^reset/$" . iorg-edit-headline-handler)))
  34. ;; Variables
  35. ;;; Functions
  36. ;; Declare functions
  37. (declare-function org-entry-is-todo-p "org" nil)
  38. (declare-function org-get-todo-state "org" nil)
  39. (declare-function org-check-for-org-mode "org-agenda" nil)
  40. (defun iorg-controller-dispatcher-handler (httpcon)
  41. "Dispatch requests to the 'iorg-controller' app"
  42. (elnode-log-access "iorg-controller" httpcon)
  43. (elnode-dispatcher httpcon iorg-controller-urls))
  44. (defun iorg-controller-postprocess (transc-str back-end comm-chan)
  45. "Add buttons to HTML export to make headlines editable."
  46. ;; TODO: (2) adding buttons to html export
  47. (with-temp-buffer
  48. (insert transc-str)
  49. (goto-char (point-min))
  50. (while (and
  51. (re-search-forward iorg-controller-todo-regexp nil t)
  52. (re-search-forward iorg-controller-outline-text-regexp nil t))
  53. (goto-char (match-beginning 0))
  54. (insert
  55. (concat
  56. "<form action=\"http://localhost:8031/todo/\">"
  57. " <input type=\"submit\" value=\" Finish \" name=\"outline-1\">"
  58. "</form>")))
  59. (buffer-substring-no-properties (point-min) (point-max))))
  60. (defun iorg-controller-launch
  61. (project &optional host port docroot &rest config)
  62. "Launch the elnode server which will serve PROJECT.
  63. PROJECT must be a predefined project in customisation variable
  64. 'iorg-projects-config', from which configuration is read.
  65. If optional arguments HOST, PORT and DOCROOT are given, they
  66. override the values from 'iorg-projects-config'.
  67. CONFIG is an alist of additional project configuration variables
  68. in the ((:key1 . value1) (:key2 value2)...) format that override
  69. their counterparts in 'iorg-projects-config'"
  70. (interactive "DProject: ")
  71. (let* ((proj (file-name-nondirectory
  72. (file-name-as-directory
  73. project)))
  74. (proj-config (assoc proj iorg-projects-config)))
  75. (if (not (assoc proj iorg-projects-config))
  76. (error (concat "Project not registered in customizable "
  77. "variable 'iorg-projects-config'"))
  78. (elnode-start
  79. 'iorg-controller-dispatcher-handler
  80. :host (or host (cdr (assoc :host proj-config)))
  81. :port (or port (cdr (assoc :port proj-config)))
  82. ;;:docroot (or docroot (cdr (assoc :port proj-config)))
  83. ))))
  84. (defun iorg-change-state-handler (httpcon)
  85. "Called by the elnode form handler to update task state."
  86. ;; TODO: (3) handle form post data and update an Org-mode file
  87. (message "entering `iorg-change-state-handler'")
  88. (let ((params (elnode-http-params httpcon)))
  89. (message "These are the http-params: \n %s" params)
  90. (with-current-buffer
  91. (find-file (expand-file-name "simple.org" iorg-controller-dir))
  92. (save-excursion
  93. (iorg--params-find-entry params)
  94. (org-todo 'done))
  95. (save-buffer)
  96. ;(kill-buffer (current-buffer))
  97. )
  98. (iorg-initialize-iorg-controller-handler httpcon)))
  99. ;; (defun iorg-edit-headline-handler (httpcon)
  100. ;; "Called by the elnode form handler to update headline."
  101. ;; ;; TODO: (3) handle form post data and update an Org-mode file
  102. ;; (message "entering `iorg-edit-headline-handler'")
  103. ;; (let ((params (elnode-http-params httpcon)))
  104. ;; (message "These are the http-params: \n %s" params)
  105. ;; (with-current-buffer
  106. ;; (find-file (expand-file-name "simple.org" iorg-controller-dir))
  107. ;; (save-excursion
  108. ;; ;; (iorg--params-find-entry params)
  109. ;; ;; (org-todo 'done))
  110. ;; (save-buffer)
  111. ;; ;(kill-buffer (current-buffer))
  112. ;; )
  113. ;; (iorg-initialize-iorg-controller-handler httpcon))))
  114. (defun iorg--get-outline-level (param-list)
  115. "Return level of outline-tree encoded in http-params"
  116. (and
  117. (listp param-list)
  118. (assoc-re iorg-alist-outline-regexp param-list 2)))
  119. (defun iorg--normalize-outline-level (outline-level)
  120. "Normalize OUTLINE-LEVEL in the format \"[-[:digit:]]+\" to a
  121. list of numbers (as strings). The lenght of the returned list is
  122. equal to the number of sublevels we need to walk down in the
  123. outline tree, the value of each number identifies the nth-entry
  124. in the Org file on that level."
  125. (if (not
  126. (and
  127. (iorg--stringp outline-level)
  128. (string-match "[-[:digit:]]+" outline-level)))
  129. (error "Wrong type or format of OUTLINE-LEVEL argument")
  130. (delete "" (split-string outline-level "-"))))
  131. (defun iorg--params-find-entry (param-list &optional file)
  132. "Go to the entry in the current Org buffer that is specified in the PARAM-LIST"
  133. (condition-case err
  134. (let* ((outline-level
  135. (iorg--get-outline-level param-list))
  136. (normalized-outline-level
  137. (iorg--normalize-outline-level outline-level))
  138. (sublevel-p nil))
  139. (with-current-buffer
  140. (if (and file (file-exists-p file))
  141. (find-file file)
  142. (find-file (expand-file-name "simple.org" iorg-controller-dir)))
  143. (org-check-for-org-mode)
  144. (save-restriction
  145. (widen)
  146. (iorg--goto-first-entry)
  147. (mapc
  148. (lambda (n)
  149. (if sublevel-p
  150. (outline-next-heading))
  151. (org-forward-same-level
  152. (1- (string-to-number n)) "INVISIBLE-OK")
  153. (unless sublevel-p
  154. (setq sublevel-p 1)))
  155. normalized-outline-level))))
  156. (error "Error while going to outline entry specified in PARAM-LIST: %s " err)))
  157. (defun iorg--org-to-html (org-file)
  158. "Export ORG-FILE to html and return the expanded filename"
  159. (if (not (file-exists-p (expand-file-name org-file iorg-controller-dir)))
  160. (error "File doesn't exist")
  161. (save-window-excursion
  162. (with-current-buffer
  163. (find-file (expand-file-name org-file iorg-controller-dir))
  164. (and
  165. (org-check-for-org-mode)
  166. (org-export-to-file
  167. 'e-html
  168. (expand-file-name
  169. (concat
  170. (file-name-sans-extension
  171. (file-name-nondirectory org-file))
  172. ".html") iorg-controller-dir )))))))
  173. (defun iorg-404-handler (httpcon)
  174. ;; TODO: This should probably actually serve a 404 page rather than
  175. ;; throwing an error
  176. (progn
  177. (elnode-log-access "simple" httpcon)
  178. (error "iorg: 404 handler invoked")))
  179. (provide 'iorg-controller)
  180. ; -----------------------------------
  181. (defun iorg-controller-static-export-handler (httpcon file)
  182. "Exports an Org file to static html"
  183. (elnode-send-file httpcon (iorg--org-to-html file 'STATIC)))
  184. (defun iorg--org-to-html (org-file &optional STATIC)
  185. "Export ORG-FILE to html and return the expanded filename. If STATIC is non nil, export to static html, otherwise use the iOrg exporter"
  186. (if (not (file-exists-p (expand-file-name org-file iorg-controller-dir)))
  187. (error "File doesn't exist")
  188. (save-window-excursion
  189. (with-current-buffer
  190. (find-file (expand-file-name org-file iorg-controller-dir))
  191. (and
  192. (org-check-for-org-mode)
  193. (org-export-to-file
  194. (if STATIC 'e-html 'iorg)
  195. (expand-file-name
  196. (concat
  197. (file-name-sans-extension
  198. (file-name-nondirectory org-file))
  199. ".html") iorg-controller-dir )))))))
  200. (provide 'iorg-controller)