photogal_og.el 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;;;;;;;;;;;;;;;;;;;;; PHOTOGAL ;;;;;;;;;;;;;;;;;;;;;`;
  3. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; v1.0 ;;;;;;
  4. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,;;;;;;;;;*;;;
  5. ;; ` ;;
  6. ;; author: jordyn , - * ;;
  7. ;; authored: spokane valley, summer '22 . ` ;;
  8. ;; * ^ ~ ';
  9. ;; PHOTO * , ' . ` * , ;;
  10. ;; , Grouper ' ` . * - . ;;
  11. ;; . And , ^ ' . ' . ` ` ' ;;
  12. ;; ` Labeler ' , * ' * ;;
  13. ;; , . , ` ' . ` ;;
  14. ;; ' - ' , ;;
  15. ;; ;;
  16. ;; ;;
  17. ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;;
  18. ;;;; -- ---- -- - DATA - -- ---- -- ;;;;
  19. (defvar *photogal/operating-photo-dir* nil)
  20. (defvar *photogal/all-photos* nil)
  21. (defvar *photogal/operating-table* nil)
  22. (defvar *photogal/--resize-photo* nil)
  23. (defvar *photogal/photos-origin-directory* nil)
  24. (defcustom photogal-default-directory "/Users/jwd/bench/photos/"
  25. "This is where photogal will look for photos.")
  26. (photogal-add-tag "Location" "L")
  27. (defun photogal-generate-group-tagger (group-key group-name)
  28. (let ((tags (caddr (assoc group-key photogal/group-tags))))
  29. (map-do (lambda (key name)
  30. (photogal-add-tag (format "%s-%s" group-name name)
  31. (format "%s%s" group-key key)))
  32. tags)))
  33. (photogal-generate-group-tagger "L" "Location")
  34. (defcustom photogal/group-tags
  35. '(("L" . ("Location"
  36. (("b" . "new-york")
  37. ("d" . "seattle")
  38. ("e" . "spokane")))))
  39. "tags in groups")
  40. (defcustom photogal/tags
  41. '(("a" . "art")
  42. ("c" . "cityscape")
  43. ("f" . "family")
  44. ("g" . "good")
  45. ("h" . "screenshot")
  46. ("l" . "politics")
  47. ("m" . "meme")
  48. ("o" . "computer")
  49. ("p" . "portrait")
  50. ("r" . "reaction-photo")
  51. ("t" . "photography")
  52. ("s" . "selfie"))
  53. "Tags and key-command to associate to photos.")
  54. (defvar *photogal/commands*
  55. '(("RET" . "Next")
  56. ("C-p" . "Prev")
  57. ("C-a" . "Add tag")
  58. ("C-d" . "Delete tag")
  59. ("C-f" . "Show filename")
  60. ("C-g" . "Refresh buffer")
  61. ("C-r" . "Resize photo")
  62. ("C-c" . "Commit all")
  63. ("C-n" . "Name the file")
  64. ("C-o" . "Add a dir")))
  65. (defun photogal-get-tags-for-file (photo-filepath)
  66. "what tags does this file have?"
  67. (photogal--get-tags (photogal--lookup-photo photo-filepath)))
  68. (defun photogal-set-tags-for-file (photo-filepath tags)
  69. "make this file have these tags"
  70. (photogal--set-tags (photogal--lookup-photo photo-filepath) tags))
  71. (defun photogal-get-folders-for-file (photo-filepath)
  72. "what folders does this file have?"
  73. (photogal--get-folders (photogal--lookup-photo photo-filepath)))
  74. (defun photogal-set-folders-for-file (photo-filepath folders)
  75. "make this file have these folders"
  76. (photogal--set-folders (photogal--lookup-photo photo-filepath) folders))
  77. (defun photogal-get-name-for-file (photo-filepath)
  78. "does this file have a user-given name?"
  79. (photogal--get-name (photogal--lookup-photo photo-filepath)))
  80. (defun photogal-set-name-for-file (photo-filepath name)
  81. "give this file a Proper name. (embedded in final filename) (optional)"
  82. (photogal--set-name (photogal--lookup-photo photo-filepath) name))
  83. (defun photogal-mark-current-photo-for-copying ()
  84. "toggle on to copy this file. Warning: marks file for committing."
  85. (plist-put (photogal--lookup-photo (photogal-current-file))
  86. 'copy-to-dir t))
  87. (defun photogal-unmark-current-photo-for-copying ()
  88. "toggle on to NOT copy this file. Warning: will not commit file."
  89. (plist-put (photogal--lookup-photo (photogal-current-file))
  90. 'copy-to-dir nil))
  91. (defun photogal-mark-photo-for-copying (photo-filepath)
  92. "toggle on to copy this file. Warning: marks file for committing."
  93. (plist-put (photogal--lookup-photo photo-filepath)
  94. 'copy-to-dir t))
  95. (defun photogal-unmark-photo-for-copying (photo-filepath)
  96. "toggle on to NOT copy this file. Warning: will not commit file."
  97. (plist-put (photogal--lookup-photo photo-filepath)
  98. 'copy-to-dir nil))
  99. (defun photogal-photo-valid-for-committing? (photo-filepath)
  100. (let ((all-fields-for-photo
  101. (mapcar (lambda (field) (plist-get (photogal--lookup-photo photo-filepath)
  102. field))
  103. '(tags name))))
  104. (seq-some (lambda (field) (not (eq nil field)))
  105. all-fields-for-photo)))
  106. (defun photogal-file-marked-for-copying? (photo-filepath)
  107. (plist-get (photogal--lookup-photo photo-filepath)
  108. 'copy-to-dir ))
  109. ;; // internal \\ ;;
  110. (defun photogal--lookup-photo (photo-filepath)
  111. (seq-find (lambda (photo)
  112. (string= (photogal--get-filepath photo) photo-filepath))
  113. *photogal/operating-table*))
  114. (defun photogal--get-filepath (photo)
  115. (plist-get photo 'filepath))
  116. (defun photogal--get-tags (photo)
  117. "What are all the tags for this file?"
  118. (plist-get photo 'tags))
  119. (defun photogal--set-tags (photo tags)
  120. (plist-put photo 'tags
  121. tags))
  122. (defun photogal--get-folders (photo)
  123. "What are all the folders for this file?"
  124. (plist-get photo 'folders))
  125. (defun photogal--set-folders (photo folders)
  126. (plist-put photo 'folders
  127. folders))
  128. (defun photogal--get-name (photo)
  129. (plist-get photo 'name))
  130. (defun photogal--set-name (photo name)
  131. (plist-put photo 'name
  132. name))
  133. ;; \\ internal // ;;
  134. (defun photogal-advance-photo ()
  135. "Move forward by one photo."
  136. (setq *photogal/all-photos*
  137. (append (cdr *photogal/all-photos*) (list (car *photogal/all-photos*)))))
  138. (defun photogal-rewind-photo ()
  139. "Reverse by one photo."
  140. (setq *photogal/all-photos*
  141. (append (last *photogal/all-photos*) (butlast *photogal/all-photos*))))
  142. ;;;; -- ---- -- - THE APP - -- ---- -- ;;;;
  143. (defun photogal (photo-dir)
  144. (interactive
  145. (list (read-directory-name
  146. "where are ur photos? " photogal-default-directory)))
  147. (setq *photogal/photos-origin-directory* (directory-file-name photo-dir))
  148. (setq *photogal/operating-photo-dir* (concat *photogal/photos-origin-directory* "-photogal"))
  149. (setq *photogal/all-photos* (photogal-all-photos *photogal/photos-origin-directory*))
  150. (photogal-init (photogal-current-file))
  151. (photogal-init-operating-table)
  152. (photogal-generate-tag-commands (photogal-general-tag-list)))
  153. (defun photogal-restart ()
  154. (interactive)
  155. (setq *photogal/all-photos* (photogal-all-photos *photogal/photos-origin-directory*))
  156. (photogal-init-operating-table)
  157. (photogal-init (photogal-current-file)))
  158. ;;;; -- ---- -- - INITIALIZATION - -- ---- -- ;;;;
  159. (defun photogal-make-photo (filepath)
  160. `(filepath ,filepath
  161. tags ,nil
  162. name ,nil
  163. folders ,(list *photogal/operating-photo-dir*)
  164. copy-to-dir ,nil))
  165. (defun photogal-init-operating-table ()
  166. (setq *photogal/operating-table*
  167. (mapcar (lambda (photo)
  168. (photogal-make-photo photo))
  169. *photogal/all-photos*)))
  170. (defun photogal-generate-tag-commands ()
  171. "Generate and activate M-x (photogal-toggle-tag-TAG) to tag curent photo,
  172. for all tags defined -- one function per tag."
  173. (mapcar (lambda (tag)
  174. (let ((tag-key (car tag))
  175. (tag-name (cdr tag)))
  176. (eval `(photogal-generate-tagger ,(intern tag-name)))
  177. (define-key photogal-mode-map (kbd tag-key)
  178. (intern (format "photogal-toggle-tag-%s" tag-name)))))
  179. photogal/tags))
  180. ;;;; -- ---- -- - TAG - -- ---- -- ;;;;
  181. (defun photogal-add-tag (new-tag new-tag-code)
  182. "Add a user-generated tag to the tag library."
  183. (interactive "sNew tag: \nsTag code (length 1): ")
  184. (let ((tag-code-too-long (> (length new-tag-code) 1))
  185. (tag-code-in-use (photogal-tag-code-in-use new-tag-code)))
  186. (if (or tag-code-too-long tag-code-in-use)
  187. (progn (message "tag code must be a single character and can't be already in use")
  188. (call-interactively 'photogal-add-tag))
  189. (photogal--add-tag new-tag new-tag-code)
  190. (photogal-refresh-buffer))))
  191. (defun photogal-delete-tag (tag-code)
  192. "Remove a tag from the library."
  193. (interactive "sDelete tag: ")
  194. (customize-save-variable
  195. 'photogal/tags
  196. (seq-remove (lambda (tag) (string= (car tag) tag-code)) photogal/tags))
  197. (photogal-refresh-buffer))
  198. (defun photogal--add-tag (new-tag new-tag-code)
  199. "Modify the defcustom var to the new collection of tags."
  200. (let ((escaped-str-tag (string-replace " " "-" new-tag)))
  201. ;; (customize-save-variable
  202. ;; 'photogal/tags
  203. ;; (cons (cons new-tag-code escaped-str-tag) photogal/tags)))
  204. (photogal-generate-tag-commands (photogal-tags-including-families))))
  205. (defun photogal-tag-code-in-use (tag-code)
  206. (seq-contains-p
  207. photogal/tags tag-code
  208. (lambda (tag test) (string= (car tag) test))))
  209. (defun photogal-tag-name-in-use (tag)
  210. (seq-contains-p
  211. photogal/tags tag
  212. (lambda (tag test) (string= (cdr tag) test))))
  213. (defun photogal-tags-including-families ()
  214. ;; ugly lol
  215. (append photogal/tags (mapcar (lambda (x) (cons (car x) (cadr x))) photogal/group-tags)))
  216. (defun photogal-general-tag-list ()
  217. "alist of tags without depth (families are flattened)"
  218. (mapcar (lambda (tag) (let* ((key-command (car tag))
  219. (tag-name (if (listp (cdr tag))
  220. (car (cdr tag))
  221. (cdr tag))))
  222. `(,key-command . ,tag-name)))
  223. photogal/tags))
  224. ;;;; -- ---- -- - TAGGING FILES - -- ---- -- ;;;;
  225. (defun photogal-for-file-toggle-tag (tag)
  226. "If a file has the tag, remove it. If it doesn't have it, add it."
  227. (let ((file (current-file)))
  228. (if (photogal-file-has-tag? file tag)
  229. (photogal-rm-tag-from-file file tag)
  230. (photogal-add-tag-to-file file tag))))
  231. (defun photogal-add-tag-to-file (file tag)
  232. "Append new tag for a file."
  233. (let ((tags (photogal-get-tags-for-file file)))
  234. (photogal-set-tags-for-file file
  235. (seq-sort #'string< (seq-uniq (cons tag tags))))))
  236. (defun photogal-rm-tag-from-file (file tag)
  237. "Dissociate tag from file."
  238. (defun tags-without-tag (tags tag)
  239. (seq-sort
  240. #'string<
  241. (seq-uniq
  242. (seq-remove
  243. (lambda (tg) (string= tg tag)) tags))))
  244. (let ((tags (photogal-get-tags-for-file file)))
  245. (photogal-set-tags-for-file file
  246. (tags-without-tag tags tag))))
  247. (defun photogal-file-has-tag? (file tag)
  248. "Does this file have this tag?"
  249. (let ((tags (photogal-get-tags-for-file file)))
  250. (seq-contains-p tags tag)))
  251. ;;;; -- ---- -- - DEST DIRS - -- ---- -- ;;;;
  252. (defun photogal-add-folder-for-file (file folder)
  253. "Append new folder for a file."
  254. (let ((folders (photogal-get-folders-for-file file)))
  255. (photogal-set-folders-for-file file
  256. (seq-sort #'string< (seq-uniq (cons folder folders))))))
  257. (defun photogal-give-a-folder (name)
  258. (interactive ;"sWhat folder do u wannan put this in ")
  259. (list (read-directory-name
  260. "What folder do u wannan put this in " photogal-default-directory)))
  261. (let ((folder-name (directory-file-name name)))
  262. (photogal-add-folder-for-file (photogal-current-file) folder-name)
  263. (photogal-mark-photo-for-copying (photogal-current-file))
  264. (photogal-refresh-buffer)))
  265. ;;;; -- ---- -- - FILE NAME - -- ---- -- ;;;;
  266. (defun photogal-name-the-file (name)
  267. (interactive "sWhat do u want to name this file? ")
  268. (photogal-set-name-for-file
  269. (photogal-current-file)
  270. (string-replace " " "-" name))
  271. (photogal-mark-photo-for-copying (photogal-current-file))
  272. (photogal-refresh-buffer))
  273. ;;;; -- ---- -- - FILE OPS - -- ---- -- ;;;;
  274. (defun photogal-all-photos (directory)
  275. "Give me a list of all the photos in my operating directory."
  276. (directory-files directory
  277. t directory-files-no-dot-files-regexp))
  278. (defun photogal-current-file ()
  279. "What is the file currently being operated on?"
  280. (car *photogal/all-photos*))
  281. ;;;; -- ---- -- - U I - -- ---- -- ;;;;
  282. (defun photogal-init (photo-file-path &optional show-filepath)
  283. "Set everything up in the buffer."
  284. (let ((buf (get-buffer-create "photogal")))
  285. (with-current-buffer buf
  286. (photogal-mode)
  287. (photogal-draw-ui photo-file-path (photogal-tags-including-families))
  288. (switch-to-buffer buf))))
  289. (defun photogal-draw-ui (photo-file-path tags)
  290. (erase-buffer)
  291. (photogal-index-tracker)
  292. (if (photogal-file-marked-for-copying? photo-file-path)
  293. (progn
  294. (insert "\t\t\t\t will commit?: ")
  295. (photogal--insert-print-color "✓" "SeaGreen3"))
  296. (progn
  297. (insert "\t\t\t\t will commit?: ")
  298. (photogal--insert-print-color "✗" "red")))
  299. (insert "\n")
  300. (insert " ")
  301. (insert-image
  302. (if *photogal/--resize-photo*
  303. (create-image photo-file-path 'imagemagick nil
  304. :width (- (window-pixel-width) 75))
  305. (create-image photo-file-path 'imagemagick nil
  306. :height (/ (window-pixel-height) 2))))
  307. (insert "\n\nCurrent tags: ")
  308. (insert (format "%s" (photogal-get-tags-for-file photo-file-path)))
  309. (let ((padding "\n"))
  310. (if (photogal-get-name-for-file photo-file-path)
  311. (insert (format "\nName: %s" (photogal-get-name-for-file photo-file-path)))
  312. (setq padding (concat padding "\n")))
  313. (if (photogal-get-folders-for-file photo-file-path)
  314. (photogal--insert-print-color
  315. (format "\ndest dir: %s"
  316. (photogal-get-folders-for-file photo-file-path))
  317. "light gray")
  318. (setq padding (concat padding "\n")))
  319. (insert padding))
  320. (insert "\n")
  321. (photogal--insert-print-color "Tag:\n" "red")
  322. (photogal-insert-tags-to-buffer tags)
  323. (photogal--insert-print-color "\n\nCommands:\n" "red")
  324. (photogal-insert-commands-to-buffer
  325. *photogal/commands*)
  326. (when show-filepath
  327. (insert "\n\n")
  328. (insert (photogal-current-file))))
  329. (defun photogal-next-file ()
  330. (interactive)
  331. (photogal-advance-photo)
  332. (photogal-refresh-buffer))
  333. (defun photogal-prev-file ()
  334. (interactive)
  335. (photogal-rewind-photo)
  336. (photogal-refresh-buffer))
  337. (defun photogal-refresh-buffer (&optional show-filepath)
  338. "Refresh buffer."
  339. (interactive)
  340. ;; (message "refreshing buffer") ;; useful to know when screen re-draws
  341. (progn ; useful stuff to run every page draw
  342. (if (not (photogal-photo-valid-for-committing? (photogal-current-file)))
  343. (photogal-unmark-photo-for-copying (photogal-current-file))))
  344. (photogal-init (photogal-current-file) show-filepath)
  345. (photogal-generate-tag-commands (photogal-general-tag-list))
  346. (beginning-of-buffer))
  347. (defun photogal-resize-photo ()
  348. (interactive)
  349. (setq *photogal/--resize-photo* (not *photogal/--resize-photo*))
  350. (photogal-refresh-buffer))
  351. (defun photogal-show-filepath ()
  352. (interactive)
  353. (photogal-refresh-buffer t))
  354. (defun photogal-index-tracker ()
  355. ;; this is a little expensive, running photogal-all-photos
  356. ;; on every paint, but i'd like to have the file count
  357. ;; be very accurate.
  358. (let ((current-index
  359. (+ 1 (seq-position
  360. (photogal-all-photos *photogal/photos-origin-directory*)
  361. (photogal-current-file))))
  362. (total-photos
  363. (length (photogal-all-photos *photogal/photos-origin-directory*))))
  364. (insert " ur lookin at photo ")
  365. (photogal--insert-print-color current-index "red")
  366. (insert " of ")
  367. (photogal--insert-print-color total-photos "red")))
  368. ;;;; -- ---- -- - LO-LEVEL DISPLAY - -- ---- -- ;;;;
  369. ;; this stuff paints the words on the screen, changing ;;
  370. ;; color, etc, pprinting stuff at a pretty granular and ;;
  371. ;; tediously technical level. ;;
  372. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  373. (defun photogal-insert-tags-to-buffer (tags)
  374. "Pretty print the tags with their toggle key."
  375. (mapcar (lambda (tag)
  376. (let* ((key-command (car tag))
  377. (tag-name (cdr tag))
  378. (activated (photogal-file-has-tag? (photogal-current-file) tag-name)))
  379. (photogal--pprint-key-command key-command tag-name 16 activated)))
  380. (seq-sort (lambda (t1 t2) (string< (car t1) (car t2))) tags)))
  381. (defun photogal-insert-commands-to-buffer (commands)
  382. "Pretty print the commands with their invoke key."
  383. (mapcar (lambda (command)
  384. (let ((key-command (car command))
  385. (command-name (cdr command)))
  386. (photogal--pprint-key-command key-command command-name 24)))
  387. commands))
  388. (defun photogal--pprint-key-command (key-to-type name-of-command padding &optional activated)
  389. "Make the low-level insertions to the buffer to render a key-command."
  390. (let ((length-of-unit (+ (length key-to-type) (length name-of-command) 3)))
  391. (when (> (+ (+ (current-column) length-of-unit)
  392. 10)
  393. (window-width))
  394. (insert "\n"))
  395. (insert "[")
  396. (if activated
  397. (photogal--insert-print-color key-to-type "SeaGreen3")
  398. (photogal--insert-print-color key-to-type "dark gray"))
  399. (insert "] ")
  400. (photogal--insert-print-color name-of-command "blue" (- padding (length key-to-type)))
  401. (insert " ")))
  402. (defun photogal--insert-print-color (string-to-insert-to-buffer color &optional padding)
  403. "Insert some text in this color."
  404. (let ((beg (point))
  405. (padding
  406. (if padding
  407. (format "%s" padding)
  408. "0")))
  409. (insert (format (concat "%-" padding "s") string-to-insert-to-buffer))
  410. (put-text-property beg (point) 'font-lock-face `(:foreground ,color))))
  411. ;;;; -- ---- -- - META SHIT - -- ---- -- ;;;;
  412. (defmacro photogal-generate-tagger (name)
  413. "Generate function to toggle a tag which is itself on the current file.
  414. One of these is needed per tag. For instance if you want to create the tag
  415. 'cool', you can run and evaluate (photogal-generate-tagger cool) to create a new
  416. function `photogal-toggle-tag-cool` that will toggle the tag 'cool' for
  417. the current file."
  418. (let ((my-funcname (intern (format "photogal-toggle-tag-%s" name))))
  419. `(defun ,my-funcname ()
  420. (interactive)
  421. (photogal-for-file-toggle-tag (photogal-current-file) ,(format "%s" name))
  422. (photogal-mark-photo-for-copying (photogal-current-file))
  423. (photogal-refresh-buffer))))
  424. ;;;; -- ---- -- -MOVING FILES AROUND- -- ---- -- ;;;;
  425. (defun photogal-files--get-extension (filepath)
  426. (file-name-extension filepath))
  427. (defun photogal-files--generate-unique-identifier (filepath)
  428. "Not GUARANTEED unique, but probably unique enough for my purposes."
  429. (seq-take (md5 (concat (current-time-string) filepath))
  430. 6))
  431. (defun photogal-files--new-file-name-for-photo (filepath tags name)
  432. (cons
  433. filepath
  434. (let (( new-name (concat
  435. (photogal-files--generate-unique-identifier filepath)
  436. "-"
  437. (format-time-string "%M%H,%d%m%y")
  438. "-"
  439. name
  440. "-_"
  441. (string-join tags "_")
  442. "_")))
  443. (if (file-name-extension filepath)
  444. (file-name-with-extension new-name (file-name-extension filepath))
  445. new-name))))
  446. (defun photogal-files--new-filenames-for-photos ()
  447. (mapcar
  448. (lambda (photo)
  449. (let ((filepath (photogal--get-filepath photo))
  450. (tags (photogal--get-tags photo))
  451. (name (photogal--get-name photo)))
  452. (photogal-files--new-file-name-for-photo filepath tags name)))
  453. *photogal/operating-table*))
  454. (defun photogal-compile-and-commit ()
  455. (interactive)
  456. (if (y-or-n-p (format "Are u sure? "))
  457. (photogal-heavy-move-files-to-directory)
  458. (message "whoops")))
  459. (defun photogal-heavy-move-files-to-directory ()
  460. ;; THIS DOES A LOTTA SHIT!!!
  461. (defun rename-file-to-folders (file-rename)
  462. (let ((origin (car file-rename))
  463. (new-name (cdr file-rename)))
  464. (when (photogal-photo-valid-for-committing? origin)
  465. (let ((dest-dirs (photogal-get-folders-for-file origin)))
  466. (mapcar (lambda (directory)
  467. (make-directory directory 'parents)
  468. (let ((new-file-name (expand-file-name new-name directory)))
  469. (message (format "renaming %s to %s" origin new-file-name))
  470. (copy-file origin new-file-name)))
  471. dest-dirs)
  472. (delete-file origin)))))
  473. (let* ((new-names (photogal-files--new-filenames-for-photos)))
  474. (mapcar
  475. #'rename-file-to-folders
  476. new-names)
  477. (photogal-restart)))
  478. ;;;; -- ---- -- - KEY BINDINGS - -- ---- -- ;;;;
  479. (defvar photogal-mode-map nil "Keymap for `photogal-mode`")
  480. (defvar key-commands
  481. '(("G" . photogal-refresh-buffer)
  482. ("RET" . photogal-next-file)
  483. ("<right>" . photogal-next-file)
  484. ("SPC" . photogal-next-file)
  485. ("C-p" . photogal-prev-file)
  486. ("<left>" . photogal-prev-file)
  487. ("C-a" . photogal-add-tag)
  488. ("C-d" . photogal-delete-tag)
  489. ("C-f" . photogal-show-filepath)
  490. ("C-r" . photogal-resize-photo)
  491. ("C-c" . photogal-compile-and-commit)
  492. ("C-n" . photogal-name-the-file)
  493. ("C-o" . photogal-give-a-folder)))
  494. (progn
  495. (setq photogal-mode-map (make-sparse-keymap))
  496. (map-do (lambda (key command)
  497. (eval `(define-key photogal-mode-map (kbd ,key) ',command)))
  498. key-commands))
  499. (define-derived-mode photogal-mode text-mode "photogal"
  500. "Major mode for grouping and labeling images.")
  501. ;;;
  502. ;;new stuff:
  503. (defun make-tag (name key family)
  504. (list name key family))
  505. (defun tag-name (tag) (intern (car tag)))
  506. (defun tag-key (tag) (cadr tag))
  507. (defun tag-family (tag) (caddr tag))