arcology-checkin.el 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. ;;; arcology-checkin.el --- Checkin support for arcology
  2. ;; Copyright (C) 2016 Ryan Rix
  3. ;; Author: Ryan Rix <ryan@whatthefuck.computer>
  4. ;; Version: 0.1
  5. ;; Package-Requires: ((json "0.1") (org "8.0"))
  6. ;; Keywords: web
  7. ;; URL: http://notes.whatthefuck.computer/
  8. ;;; Commentary:
  9. ;; This package generates a small blog from org-mode files, leveraging Microformats to provide
  10. ;; semantic information about the posts; you can use this information to automate sharing,
  11. ;; linkbacks, embedding images in 3rd party silso, and more; see http://indiewebcamp.com and
  12. ;; http://microformats.org for more information.
  13. ;; This package can be used by configuring the various variables and then calling [`arcology']
  14. ;; which will publish the blog index, an RSS feed and URLs for each entry. You can then have Brid.gy
  15. ;; automatically syndicate the content to silos by calling [`arcology-syndicate-entry-at-point'].
  16. ;; From Wikipedia:
  17. ;; Arcology, a portmanteau of "architecture" and "ecology", is a vision of architectural design
  18. ;; principles for very densely populated habitats. The concept has been primarily popularized, and
  19. ;; the term itself coined, by architect Paolo Soleri. It also appears in science fiction. These
  20. ;; structures have been largely hypothetical insofar as no 'arcology' envisioned by Soleri himself
  21. ;; has yet been completed, but he posited that a completed arcology would provide space for a
  22. ;; variety of residential, commercial, and agricultural facilities while minimizing individual human
  23. ;; environmental impact. Arcologies are often portrayed in sci-fi as self-contained or economically
  24. ;; self-sufficient.
  25. ;; Arcology aims to be a self-sufficient blogging platform, where you can leverage the work that
  26. ;; IndieWeb actors have done to build a self-sufficient site with the full support of "social media"
  27. ;; type offerings like comments, reposts, checkins, all running under your own domain and backed by
  28. ;; plain text that you can control yourself or generate using simple scripts or Memacs
  29. ;;; Code:
  30. ;;;###autoload
  31. (defgroup arcology-checkin nil
  32. "Checkin support for Arcology."
  33. :group 'arcology)
  34. ;;;###autoload
  35. (defcustom arcology-checkin-foursquare-client-id ""
  36. "Foursquare app client ID.
  37. Register an app at https://foursquare.com/developers/apps."
  38. :group 'arcology-checkin)
  39. ;;;###autoload
  40. (defcustom arcology-checkin-foursquare-client-secret ""
  41. "Foursquare app client secret.
  42. Register an app at https://foursquare.com/developers/apps."
  43. :group 'arcology-checkin)
  44. ;;;###autoload
  45. (defcustom arcology-checkin-cache-location "~/.emacs.d/arcology-venue-data/"
  46. "Directory to put arcology venue cache."
  47. :group 'arcology-checkin)
  48. ;;;###autoload
  49. (defcustom arcology-checkin-template-file "/home/rrix/Projects/notes/templates/default.html"
  50. "Template file to use for notes"
  51. :group 'arcology-checkin)
  52. (defun arcology-add-checkin-content (entry)
  53. "Generate checkin venue information, along with checkin note."
  54. (let ((properties (plist-get entry :properties)))
  55. (when (not (arcology-alist-get "CHECKIN-VENUE-ID" properties))
  56. (with-current-buffer (plist-get entry :buffer)
  57. (display-buffer (current-buffer))
  58. (goto-char (plist-get entry :point))
  59. (call-interactively 'arcology-checkin-get-venue-id)))
  60. (let* ((checkin-venue-id (arcology-alist-get "CHECKIN-VENUE-ID" properties))
  61. (venue (arcology-checkin-venue-cached checkin-venue-id))
  62. (image-str (arcology-add-image-content entry)))
  63. (with-temp-buffer
  64. ;; Render venue information
  65. (insert image-str)
  66. (insert "<div class=\"p-location h-card arcology-venue\">"
  67. "Posted at "
  68. "<a class=\"u-url p-name\" href=\"https://foursquare.com/v/" (arcology-alist-get 'id venue) "\">"
  69. (arcology-alist-get 'name venue)
  70. "</a> on "
  71. "<span class=\"p-street-address\">"
  72. (or (arcology-alist-get 'address (arcology-alist-get 'location venue)) "")
  73. "</span> in "
  74. "<span class=\"p-locality\">"
  75. (or (arcology-alist-get 'city (arcology-alist-get 'location venue)) "")
  76. "</span>, "
  77. "<span class=\"p-region\">"
  78. (or (arcology-alist-get 'state (arcology-alist-get 'location venue)) "")
  79. "</span> "
  80. "<span class=\"p-country-name\">"
  81. (or (arcology-alist-get 'country (arcology-alist-get 'location venue)) "")
  82. "</span>"
  83. "</div>")
  84. (buffer-string)))))
  85. (defun arcology-checkin-venue-cached (id)
  86. (let ((filename (concat arcology-checkin-cache-location
  87. "/" id ".el")))
  88. (if (file-exists-p filename)
  89. (with-current-buffer (find-file-noselect filename)
  90. (goto-char (point-min))
  91. (let ((v (read (current-buffer))))
  92. (kill-buffer)
  93. v))
  94. (arcology-checkin-cache-venue id))))
  95. ;;;###autoload
  96. (defun arcology-checkin-get-venue-id (venue-name location)
  97. "Interactively read checkin information to get venue ID."
  98. (interactive "MWhat is the venue name? \nMWhat city are you in? ")
  99. (let ((req (request "https://api.foursquare.com/v2/venues/search"
  100. :type "GET"
  101. :params `(("client_id" . ,arcology-checkin-foursquare-client-id)
  102. ("client_secret" . ,arcology-checkin-foursquare-client-secret)
  103. ("query" . ,venue-name)
  104. ("near" . ,location)
  105. ("v" . "20140806")
  106. ("m" . "foursquare"))
  107. :parser 'json-read
  108. :sync t)))
  109. (let* ((venue (elt (arcology-alist-get 'venues (cdar (request-response-data req))) 0))
  110. (venue-id (arcology-alist-get 'id venue)))
  111. (arcology-checkin-write-cache-venue venue-id venue)
  112. (org-set-property "CHECKIN-VENUE-ID"
  113. venue-id)
  114. venue-id)))
  115. (defun arcology-checkin-write-cache-venue (id data)
  116. "Cache a checkin search result"
  117. (unless (file-exists-p arcology-checkin-cache-location)
  118. (make-directory arcology-checkin-cache-location))
  119. (with-current-buffer (find-file-noselect
  120. (concat arcology-checkin-cache-location
  121. "/" id ".el"))
  122. (erase-buffer)
  123. (print data (current-buffer))
  124. (save-buffer)
  125. (kill-buffer)))
  126. (defun arcology-checkin-cache-venue (id)
  127. "Hit the foursquare API for an venue's information.
  128. Used if the ID is already known, but the venue is uncached."
  129. (let ((req (request (format "https://api.foursquare.com/v2/venues/%s" id)
  130. :type "GET"
  131. :params `(("client_id" . ,arcology-checkin-foursquare-client-id)
  132. ("client_secret" . ,arcology-checkin-foursquare-client-secret)
  133. ("v" . "20140806")
  134. ("m" . "foursquare"))
  135. :parser 'json-read
  136. :sync t)))
  137. (let* ((response (arcology-alist-get 'response (request-response-data req)))
  138. (venue (arcology-alist-get 'venue response))
  139. (venue-id (arcology-alist-get 'id venue)))
  140. (arcology-checkin-write-cache-venue id venue)
  141. venue)))
  142. (def-arcology-entry-generator checkin
  143. (lambda (entry) (concat
  144. (arcology-get-default-content entry)
  145. (arcology-add-checkin-content entry))))
  146. (provide 'arcology-checkin)
  147. ;; arcology-checkin.el ends here.