1
1
import {
2
+ apiVersion ,
2
3
App ,
4
+ FileSystemAdapter ,
3
5
Plugin ,
4
6
PluginSettingTab ,
5
7
request ,
6
8
RequestUrlParam ,
7
- Setting ,
8
- apiVersion ,
9
- FileSystemAdapter
9
+ Setting , TAbstractFile
10
10
} from 'obsidian' ;
11
11
import * as os from "os" ;
12
12
13
+ type Nullable < T > = T | null ;
13
14
14
15
class AWrequest implements RequestUrlParam {
15
16
body : string | ArrayBuffer ;
@@ -33,7 +34,6 @@ const DEFAULT_SETTINGS: ActivityWatcherSettings = {
33
34
devServer : false
34
35
}
35
36
36
-
37
37
export default class ActivityWatchPlugin extends Plugin {
38
38
settings : ActivityWatcherSettings ;
39
39
hostname : string = os . hostname ( )
@@ -57,15 +57,15 @@ export default class ActivityWatchPlugin extends Plugin {
57
57
console . log ( `endpoint_url is ${ this . endpoint_url } ` )
58
58
}
59
59
60
- await this . create_bucket ( this . bucket_id , "app.editor.activity" )
60
+ await this . createBucket ( this . bucket_id , "app.editor.activity" )
61
61
this . statusBarItemEl . setText ( 'ActivityWatch active' ) ;
62
62
}
63
63
64
64
async post ( endpoint : string , data : object ) {
65
65
await request ( new AWrequest ( this . endpoint_url + endpoint , JSON . stringify ( data ) ) )
66
66
}
67
67
68
- async create_bucket ( id : string , event_type : string ) {
68
+ async createBucket ( id : string , event_type : string ) {
69
69
const data = {
70
70
"client" : this . watcher_name ,
71
71
"hostname" : this . hostname ,
@@ -74,32 +74,72 @@ export default class ActivityWatchPlugin extends Plugin {
74
74
await this . post ( `buckets/${ id } ` , data )
75
75
}
76
76
77
- async send_heartbeat_data ( id : string , heartbeat_data : object , pulsetime : number ) {
77
+ async sendHeartbeatData ( id : string , heartbeat_data : object , pulsetime : number ) {
78
78
const endpoint = `buckets/${ id } /heartbeat?pulsetime=${ pulsetime } `
79
79
const t = new Date ( ) . toISOString ( ) . slice ( 0 , - 1 )
80
80
await this . post ( endpoint , { "timestamp" : t , "duration" : 0 , "data" : heartbeat_data } )
81
81
}
82
82
83
+ async sendAbstractFileEvent ( file : Nullable < TAbstractFile > , extraData : Nullable < object > , pulseTime : number ) {
84
+ if ( file ) {
85
+ await this . sendHeartbeatData ( this . bucket_id , {
86
+ "file" : "/" + file . path ,
87
+ "project" : file . vault . getName ( ) ,
88
+ "language" : "Markdown" , // todo: map file extension to language
89
+ "projectPath" : file . vault . adapter instanceof FileSystemAdapter ? file . vault . adapter . getBasePath ( ) : "unknown vault path" ,
90
+ "editor" : "Obsidian" ,
91
+ "editorVersion" : apiVersion ,
92
+ ...( extraData ? extraData : { } )
93
+ } , pulseTime )
94
+ }
95
+ }
96
+
97
+ async sendFileHeartbeatEvent ( file : Nullable < TAbstractFile > ) {
98
+ await this . sendAbstractFileEvent ( file , {
99
+ "eventType" : "foss.grimmauld.aw.watcher.obsidian.activeFileHeartbeatEvent"
100
+ } , this . sleeptime + 1 )
101
+ }
102
+
103
+ async sendFileRenameEvent ( file : Nullable < TAbstractFile > , oldPath : string ) {
104
+ await this . sendAbstractFileEvent ( file , {
105
+ "eventType" : "foss.grimmauld.aw.watcher.obsidian.renameFileEvent" ,
106
+ "oldPath" : oldPath
107
+ } , 0 ) ;
108
+ }
109
+
110
+ async sendFileDeleteEvent ( oldPath : Nullable < TAbstractFile > ) {
111
+ await this . sendAbstractFileEvent ( oldPath , {
112
+ "eventType" : "foss.grimmauld.aw.watcher.obsidian.deleteFileEvent" ,
113
+ } , 0 ) ;
114
+ }
115
+
116
+ async sendFileCreateEvent ( oldPath : Nullable < TAbstractFile > ) {
117
+ await this . sendAbstractFileEvent ( oldPath , {
118
+ "eventType" : "foss.grimmauld.aw.watcher.obsidian.createFileEvent" ,
119
+ } , 0 ) ;
120
+ }
121
+
83
122
async onload ( ) {
84
123
this . statusBarItemEl = this . addStatusBarItem ( ) ;
85
124
await this . loadSettings ( ) ;
86
125
await this . init ( )
87
126
127
+ this . registerEvent ( app . vault . on ( 'rename' , ( file , oldPath ) =>
128
+ this . sendFileRenameEvent ( file , oldPath )
129
+ ) ) ;
130
+
131
+ this . registerEvent ( app . vault . on ( 'delete' , oldFile =>
132
+ this . sendFileDeleteEvent ( oldFile )
133
+ ) ) ;
134
+
135
+ this . registerEvent ( app . vault . on ( 'create' , oldFile =>
136
+ this . sendFileCreateEvent ( oldFile )
137
+ ) ) ;
138
+
88
139
this . addSettingTab ( new ObsidianWatcherSettingTab ( this . app , this ) ) ;
89
140
90
141
this . registerInterval ( window . setInterval ( ( ) => {
91
- const file = this . app . workspace . getActiveFile ( ) ;
92
- const adapter = this . app . vault . adapter ;
93
- if ( file ) {
94
- this . send_heartbeat_data ( this . bucket_id , {
95
- "file" : "/" + file . path ,
96
- "project" : file . vault . getName ( ) ,
97
- "language" : "Markdown" , // todo: map file extension to language
98
- "projectPath" : adapter instanceof FileSystemAdapter ? adapter . getBasePath ( ) : "unknown vault path" ,
99
- "editor" : "Obsidian" ,
100
- "editorVersion" : apiVersion
101
- } , this . sleeptime + 1 )
102
- }
142
+ this . sendFileHeartbeatEvent ( this . app . workspace . getActiveFile ( ) ) ;
103
143
} , this . sleeptime * 1000 ) ) ;
104
144
}
105
145
0 commit comments