-
Notifications
You must be signed in to change notification settings - Fork 0
/
Obsidian-Notification.js
184 lines (151 loc) · 5.55 KB
/
Obsidian-Notification.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//User constants
const NotificationTime = "09:00" // When do I want to be notified about all tasks
const NotificationGroup = "Obsidian" // Title of the Notification
const FileBookmark = "Obsidian" //File Bookmark in scriptable
const TaskIdentifier = ["#todo"] // only use tasks with these elements
const IgnoreIdentifier = [] // if certain tasks should be ignored
//Technical constants
const fmgr = FileManager.local()
const LineBreaks = "\n"
const ignore_files = [".git",".gitignore",".obsidian"] //if file contains these strings
const search_task = ["- [ ] ","- [/] "]
const search_date = "📅"
const date_format = "yyyy-MM-dd HH:mm"
function readTasksConfig(){
//TODO: read out taskidentifier
//path = ".obsidian/plugins/obsidian-tasks-plugin"
}
// Hash function for Notification Identifier (atm the path is used as short hash)
function hashCode(s) {
let h;
for(let i = 0; i < s.length; i++)
h = Math.imul(31, h) + s.charCodeAt(i) | 0;
return Math.abs(h).toString(16);
}
function checkSetup(){
if(fmgr.bookmarkExists(FileBookmark)){
return obsi_root = fmgr.bookmarkedPath(FileBookmark)
}else{
console.error("Did not found Scriptable Bookmark: " + FileBookmark)
Script.complete()
}
}
function makeArray(item){
if(typeof item == "string"){
item = [item]
}else if(! Array.isArray(item)){
console.error("Unknown item type: " + typeof item + " - " + item)
Script.complete()
}
return item
}
function filter_in_array(array, pattern_list){
//keep items when pattern found
pattern_list = makeArray(pattern_list)
return array.filter(element =>
pattern_list.some(pattern => element.includes(pattern))
);
}
function filter_not_in_array(array, pattern_list){
//keep items when pattern not found
pattern_list = makeArray(pattern_list)
return array.filter(element =>
!pattern_list.some(pattern => element.includes(pattern))
);
}
function getTasks(file){
if(file.endsWith(".md")){
let data = fmgr.read(file).toRawString()
let items = data.split(LineBreaks)
// just keep relevant items
// finished item not needed, cause it has - [x]
items = filter_in_array(items, search_task)
items = filter_in_array(items, search_date)
if(TaskIdentifier.length > 0){
items = filter_in_array(items, TaskIdentifier)
}
if(IgnoreIdentifier.length > 0){
items = filter_not_in_array(items, IgnoreIdentifier)
}
return items
}else{
//console.log("skip non MD File: " + file)
return []
}
}
function Notification_create(title, body, date, identifier){
let today = new Date()
let fmt = new DateFormatter()
fmt.dateFormat = date_format
let date_target = date + " " + NotificationTime
date_target = fmt.date(date_target)
//if Task is in the past, remind tomorrow
if(date_target < today){
today.setDate(today.getDate() + 1)
let notification_hours = NotificationTime.split(":")
today.setHours(notification_hours[0],notification_hours[1])
date_target = today
}
let note = new Notification()
note.identifier = identifier
note.title = NotificationGroup
note.subtitle = title
note.body = body
note.setTriggerDate(date_target)
note.schedule()
}
function iterateFiles(root_path) {
let task_count = 0
let files = [root_path]
while (files.length > 0) {
let item = files.pop()
if (fmgr.isDirectory(item)) {
let list_files = fmgr.listContents(item)
//Filter .git + .obsidian files
list_files = filter_not_in_array(list_files, ignore_files)
//merge files with path
list_files = list_files.map(i => item + "/" + i)
files.push.apply(files, list_files)
}else if(fmgr.fileExists(item)){
let tasks = getTasks(item)
if (tasks.length > 0) {
task_count += tasks.length
tasks.forEach(task => {
let pos_date = task.indexOf(search_date)
let date = task.substring(pos_date+2, pos_date+2+11)
let pos_task = search_task.findIndex(pattern => task.includes(pattern))
let body = task.substring(pos_task+5, pos_date)
let identifier = hashCode(item) + "-" + hashCode(body)
//Create Task Title based on "First Directory/Filename"
let item_splitter = item.split("/")
let note_title = item_splitter[root_path.split("/").length]
let note_file = item_splitter[item_splitter.length-1]
if(note_title == note_file){
note_title = "Root"
}
note_title += "/" + note_file
Notification_create(note_title, body, date, identifier)
});
}
}else{
console.error("Shouldnt be happen on " + item)
}
}
let msg_done = "Notification created: " + task_count.toString()
console.log(msg_done)
return msg_done
}
async function main(){
let path_root = checkSetup()
//remove current state of Obsidian Notifications
let pend = await Notification.allPending()
pend.forEach(note => {
if(note.title == NotificationGroup){
note.remove()
}
});
//iterate Files and create notifications
return iterateFiles(path_root)
}
return main()
Script.complete()