├── .gitignore
├── img
├── 1.png
├── 2.png
├── 3.png
└── 4.png
├── 3_Restore_Directly_to_v0.md
├── README.md
├── 1_Save_Snapshot.md
└── 2_Compare_or_Restore_Snapshot.md
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .DS_Store
3 |
4 | *.plist
5 |
--------------------------------------------------------------------------------
/img/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bcdavasconcelos/DEVONthink-3-Snapshot-Mechanism/master/img/1.png
--------------------------------------------------------------------------------
/img/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bcdavasconcelos/DEVONthink-3-Snapshot-Mechanism/master/img/2.png
--------------------------------------------------------------------------------
/img/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bcdavasconcelos/DEVONthink-3-Snapshot-Mechanism/master/img/3.png
--------------------------------------------------------------------------------
/img/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bcdavasconcelos/DEVONthink-3-Snapshot-Mechanism/master/img/4.png
--------------------------------------------------------------------------------
/3_Restore_Directly_to_v0.md:
--------------------------------------------------------------------------------
1 | # A third little script - Restore Directly to v0
2 |
3 | ```applescript
4 |
5 | -- Restore Directly to v0
6 |
7 | -- bcdavasconcelos 2020-06-09-12-12-27
8 | -- https://github.com/bcdavasconcelos/DEVONthink-3-Snapshot-Mechanism
9 |
10 | -- **Do not use this as a backup mechanism.**
11 | -- These snapshots should be considered *a convenience* for editing plain text.
12 | -- It was not intended to protect from loss of data.
13 |
14 | tell application id "DNtp"
15 |
16 | set theRecord to (content record of think window 1)
17 | set thePath to the path of theRecord -- Get the file path
18 |
19 | set theText to the plain text of theRecord
20 |
21 | set theText to get custom meta data for "v0" from theRecord default value ""
22 |
23 | set the plain text of theRecord to theText
24 |
25 | log message "Version restored" info "Restored to template version " & ((current date) as string) --
26 |
27 | end tell
28 |
29 |
30 | ```
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # A Snapshots Mechanism for DEVONthink 3
5 |
6 | ## Warning
7 | 1. **Do not use this as a backup mechanism.** These snapshots should be considered *a convenience*. It was not intended to protect from loss of data. There is no safety net here.
8 | 2. These are **potentially destructive** scripts. **You cannot ⌘Z your way out of changes made by scripts.**
9 | 3. Finally, this is intended for markdown and/or plain text **only**.
10 |
11 | ***
12 |
13 | # The first script: Save Snapshot
14 |
15 | The idea is very simple. I created custom metadata fields to store snapshots of the text (**v1**-**v9**) and the modification time (**d1**-**d9**). The [first script](1_Save_Snapshot.md) is for *storing the text*. It will store the current text in v1 and throw what was in v1 to v2, what was in v2 to v3 and so on. What was in v9 says goodbye.
16 |
17 | ![][image-1]
18 |
19 | *I keep it at the bottom, so I don't see it if I don't want to.*
20 |
21 |
22 | ***
23 |
24 | # The second script: Compare/Restore Snapshot
25 |
26 | The [second script](2_Compare_or_Restore_Snapshot.md) is for *restoring a snapshot*. When it is activated, it will ask whether you want to compare snapshots using BBEdit (could have used filemerge or something else, but I like BBEdit and you can install it for free) or simply restore to one of the previous snapshots.
27 |
28 | ![][image-2]
29 |
30 | The next dialog will prompt for the desired snapshot to be compared or restored.
31 |
32 |
33 | ![][image-3]
34 |
35 | If you chose to **restore**, that's it. The script will do so by replacing the text of the record by the stored snapshot and it will log the change in DEVONthink (I like how discrete the log is and prefer it over the notification function). If you chose to **compare** instead, you *can* make the changes you want and then *save*.
36 |
37 | *Here is the compare window open in BBEdit.*
38 |
39 | ![][image-4]
40 |
41 | ***
42 |
43 | # A third little script - Restore Directly to v0
44 |
45 | Side-note: I am also keeping a v0, which is sort of a template for the note and which won't be touched by the first script. I also set up a special shortcut to restore directly to this snapshot without any prompts. This will be the [third script](3_Restore_Directly_to_v0.md).
46 |
47 |
48 | [image-1]: img/1.png
49 | [image-2]: img/2.png
50 | [image-3]: img/3.png
51 | [image-4]: img/4.png
52 |
53 | #Applescript #DEVONthink
54 |
--------------------------------------------------------------------------------
/1_Save_Snapshot.md:
--------------------------------------------------------------------------------
1 | # Save Snapshot
2 |
3 | ```applescript
4 |
5 | -- Save Snapshot
6 |
7 | -- bcdavasconcelos 2020-06-09-12-10-14
8 | -- https://github.com/bcdavasconcelos/DEVONthink-3-Snapshot-Mechanism
9 |
10 | -- **Do not use this as a backup mechanism.**
11 | -- These snapshots should be considered *a convenience* for editing plain text.
12 | -- It was not intended to protect from loss of data.
13 |
14 | tell application id "DNtp"
15 | -- set theRecords to the selection
16 | -- repeat with theRecord in theRecords
17 | set theRecord to (content record of think window 1)
18 |
19 | set theText to the plain text of theRecord
20 | set theNewMod to the modification date of theRecord
21 |
22 | set theOldBackup to get custom meta data for "v9" from theRecord default value ""
23 | add custom meta data theOldBackup for "v10" to theRecord
24 |
25 | set theOldBackup to get custom meta data for "v8" from theRecord default value ""
26 | add custom meta data theOldBackup for "v9" to theRecord
27 |
28 | set theOldBackup to get custom meta data for "v7" from theRecord default value ""
29 | add custom meta data theOldBackup for "v8" to theRecord
30 |
31 | set theOldBackup to get custom meta data for "v6" from theRecord default value ""
32 | add custom meta data theOldBackup for "v7" to theRecord
33 |
34 | set theOldBackup to get custom meta data for "v5" from theRecord default value ""
35 | add custom meta data theOldBackup for "v6" to theRecord
36 |
37 | set theOldBackup to get custom meta data for "v4" from theRecord default value ""
38 | add custom meta data theOldBackup for "v5" to theRecord
39 |
40 | set theOldBackup to get custom meta data for "v3" from theRecord default value ""
41 | add custom meta data theOldBackup for "v4" to theRecord
42 |
43 | set theOldBackup to get custom meta data for "v2" from theRecord default value ""
44 | add custom meta data theOldBackup for "v3" to theRecord
45 |
46 | set theOldBackup to get custom meta data for "v1" from theRecord default value ""
47 | add custom meta data theOldBackup for "v2" to theRecord
48 |
49 | set theMod to get custom meta data for "v9" from theRecord default value ""
50 | add custom meta data theMod for "v10" to theRecord
51 |
52 | set theMod to get custom meta data for "d8" from theRecord default value ""
53 | add custom meta data theMod for "d9" to theRecord
54 |
55 | set theMod to get custom meta data for "d7" from theRecord default value ""
56 | add custom meta data theMod for "d8" to theRecord
57 |
58 | set theMod to get custom meta data for "d6" from theRecord default value ""
59 | add custom meta data theMod for "d7" to theRecord
60 |
61 | set theMod to get custom meta data for "d5" from theRecord default value ""
62 | add custom meta data theMod for "d6" to theRecord
63 |
64 | set theMod to get custom meta data for "d4" from theRecord default value ""
65 | add custom meta data theMod for "d5" to theRecord
66 |
67 | set theMod to get custom meta data for "d3" from theRecord default value ""
68 | add custom meta data theMod for "d4" to theRecord
69 |
70 | set theMod to get custom meta data for "d2" from theRecord default value ""
71 | add custom meta data theMod for "d3" to theRecord
72 |
73 | set theMod to get custom meta data for "d1" from theRecord default value ""
74 | add custom meta data theMod for "d2" to theRecord
75 |
76 | add custom meta data theNewMod for "d1" to theRecord
77 | add custom meta data theText for "v1" to theRecord
78 |
79 | log message "New version saved" info "Saved at " & ((current date) as string)
80 |
81 | end tell
82 |
83 | ```
84 |
--------------------------------------------------------------------------------
/2_Compare_or_Restore_Snapshot.md:
--------------------------------------------------------------------------------
1 | # The second script: Compare/Restore Snapshot
2 |
3 | ```applescript
4 |
5 | -- Compare/Restore Snapshot
6 |
7 | -- bcdavasconcelos 2020-06-09-12-12-02
8 | -- https://github.com/bcdavasconcelos/DEVONthink-3-Snapshot-Mechanism
9 |
10 | -- **Do not use this as a backup mechanism.**
11 | -- These snapshots should be considered *a convenience* for editing plain text.
12 | -- It was not intended to protect from loss of data.
13 |
14 |
15 | tell application id "DNtp"
16 | set theRecord to the (content record of think window 1)
17 |
18 |
19 | set theOpts to {"Compare", "Restore", "Cancel"}
20 | set theAnswer1 to the button returned of (display dialog "Hi, I am Hal. What can I do for you?" buttons theOpts default button 1)
21 |
22 | set d0 to get custom meta data for "d0" from theRecord default value "" as string
23 | set myDateString0 to "v0 Template"
24 |
25 | try
26 | set d1 to get custom meta data for "d1" from theRecord default value "" as string
27 | set myDateString1 to ("v1" & " " & (month of d1) & " " & (day of d1) & ", " & (year of d1) & " - " & (time string of d1)) as string
28 | on error
29 | set myDateString1 to ""
30 | end try
31 |
32 | try
33 | set d2 to get custom meta data for "d2" from theRecord default value "" as string
34 | set myDateString2 to ("v2" & " " & (month of d2) & " " & (day of d2) & ", " & (year of d2) & " - " & (time string of d2)) as string
35 | on error
36 | set myDateString2 to ""
37 | end try
38 |
39 | try
40 | set d3 to get custom meta data for "d3" from theRecord default value "" as string
41 | set myDateString3 to ("v3" & " " & (month of d3) & " " & (day of d3) & ", " & (year of d3) & " - " & (time string of d3)) as string
42 | on error
43 | set myDateString3 to ""
44 | end try
45 |
46 | try
47 | set d4 to get custom meta data for "d4" from theRecord default value "" as string
48 | set myDateString4 to ("v4" & " " & (month of d4) & " " & (day of d4) & ", " & (year of d4) & " - " & (time string of d4)) as string
49 | on error
50 | set myDateString4 to ""
51 | end try
52 |
53 | try
54 | set d5 to get custom meta data for "d5" from theRecord default value "" as string
55 | set myDateString5 to ("v5" & " " & (month of d5) & " " & (day of d5) & ", " & (year of d5) & " - " & (time string of d5)) as string
56 | on error
57 | set myDateString5 to ""
58 | end try
59 |
60 | try
61 | set d6 to get custom meta data for "d6" from theRecord default value "" as string
62 | set myDateString6 to ("v6" & " " & (month of d6) & " " & (day of d6) & ", " & (year of d6) & " - " & (time string of d6)) as string
63 | on error
64 | set myDateString6 to ""
65 | end try
66 |
67 | try
68 | set d7 to get custom meta data for "d7" from theRecord default value "" as string
69 | set myDateString7 to ("v7" & " " & (month of d7) & " " & (day of d7) & ", " & (year of d7) & " - " & (time string of d7)) as string
70 | on error
71 | set myDateString7 to ""
72 | end try
73 |
74 | try
75 | set d8 to get custom meta data for "d8" from theRecord default value "" as string
76 | set myDateString8 to ("v8" & " " & (month of d8) & " " & (day of d8) & ", " & (year of d8) & " - " & (time string of d8)) as string
77 | on error
78 | set myDateString8 to ""
79 | end try
80 |
81 | try
82 | set d9 to get custom meta data for "d9" from theRecord default value "" as string
83 | set myDateString9 to ("v9" & " " & (month of d9) & " " & (day of d9) & ", " & (year of d9) & " - " & (time string of d9)) as string
84 | on error
85 | set myDateString9 to ""
86 | end try
87 |
88 |
89 | set l to {myDateString0, myDateString1, myDateString2, myDateString3, myDateString4, myDateString5, myDateString6, myDateString7, myDateString8, myDateString9} as list
90 | set theAnswer to (choose from list l with prompt {"Wise decision.
91 | Now, choose your destiny..."} default items "")
92 |
93 | set theAnswer to item 1 of theAnswer
94 | if theAnswer contains "v0" then set theAnswer to "v0"
95 | if theAnswer contains "v0" then set theTime to "Template"
96 |
97 | if theAnswer contains "v1" then set theAnswer to "v1"
98 | if theAnswer contains "v1" then set theTime to "d1"
99 |
100 | if theAnswer contains "v2" then set theAnswer to "v2"
101 | if theAnswer contains "v2" then set theTime to "d2"
102 |
103 | if theAnswer contains "v3" then set theAnswer to "v3"
104 | if theAnswer contains "v3" then set theTime to "d3"
105 |
106 | if theAnswer contains "v4" then set theAnswer to "v4"
107 | if theAnswer contains "v4" then set theTime to "d4"
108 |
109 | if theAnswer contains "v5" then set theAnswer to "v5"
110 | if theAnswer contains "v5" then set theTime to "d5"
111 |
112 | if theAnswer contains "v6" then set theAnswer to "v6"
113 | if theAnswer contains "v6" then set theTime to "d6"
114 |
115 | if theAnswer contains "v7" then set theAnswer to "v7"
116 | if theAnswer contains "v7" then set theTime to "d7"
117 |
118 | if theAnswer contains "v8" then set theAnswer to "v8"
119 | if theAnswer contains "v8" then set theTime to "d8"
120 |
121 | if theAnswer contains "v9" then set theAnswer to "v9"
122 | if theAnswer contains "v9" then set theTime to "d9"
123 |
124 | set theName to the name of theRecord
125 | set thePath to the path of theRecord -- Get the file path
126 |
127 | set theText to the plain text of theRecord
128 |
129 | set theText to get custom meta data for (theAnswer as text) from theRecord default value ""
130 | try
131 | set theTime to get custom meta data for (theTime as text) from theRecord default value ""
132 | set theTime to ((year of theTime) & "-" & (month of theTime) & "-" & (day of theTime) & "-" & (time string of theTime)) as string
133 | set theTime to my replaceText(theTime, ":", "-")
134 | on error
135 | set theTime to "Template"
136 | end try
137 | -- set docName to theName & " " & theTime as text
138 |
139 | if theAnswer1 is "Restore" then
140 | set the plain text of theRecord to theText
141 | log message "Version restored" info (theAnswer as text) & " " & theTime as text
142 | end if
143 |
144 | if theAnswer1 is "Compare" then
145 | set docName to theTime as text
146 | set _text to theText
147 | tell application "BBEdit"
148 |
149 | set tempFilePath to (path to temporary items as text) & docName
150 | set newDoc to make new document with properties {text:_text} initial save location tempFilePath
151 | save newDoc
152 | close newDoc
153 | -- open newDoc
154 | set theResult to compare file (thePath as POSIX file) against file (tempFilePath as alias)
155 | activate
156 | end tell
157 | end if
158 | end tell
159 |
160 |
161 | on replaceText(theString, old, new)
162 | set {TID, text item delimiters} to {text item delimiters, old}
163 | set theStringItems to text items of theString
164 | set text item delimiters to new
165 | set theString to theStringItems as text
166 | set text item delimiters to TID
167 | return theString
168 | end replaceText
169 | ```
170 |
--------------------------------------------------------------------------------