Skip to content

Commit b87d87f

Browse files
authored
[200_64] posthog集成 (#3273)
1 parent 0fa545d commit b87d87f

10 files changed

Lines changed: 710 additions & 5 deletions

File tree

TeXmacs/progs/generic/generic-edit.scm

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
(utils edit variants)
1818
(utils misc tooltip)
1919
(bibtex bib-complete)
20-
(source macro-search)))
20+
(source macro-search)
21+
(telemetry telemetry-track)))
2122

2223
(tm-define (generic-context? t) #t) ;; overridden in, e.g., graphics mode
2324

@@ -749,13 +750,23 @@ TODO: 在文本模式中,可以自动识别剪贴板中的内容,并智能
749750
|#
750751
(tm-define (kbd-magic-paste)
751752
(if (string-starts? (qt-clipboard-format) "image")
752-
(ocr-paste)
753+
(begin
754+
(ocr-paste)
755+
(when (not (community-stem?))
756+
(track-event "OCR_RECOGNIZE" '())))
753757
(with mode (get-env "mode")
754758
(cond ((== mode "prog")
755-
(clipboard-paste-import "code" "primary"))
759+
(clipboard-paste-import "code" "primary")
760+
(when (not (community-stem?))
761+
(track-event "MAGIC_PASTE" '(("mode" . "prog")))))
756762
((== mode "math")
757-
(clipboard-paste-import "latex" "primary"))
758-
(else (smart-format-paste)))))
763+
(clipboard-paste-import "latex" "primary")
764+
(when (not (community-stem?))
765+
(track-event "MAGIC_PASTE" '(("mode" . "math")))))
766+
(else
767+
(smart-format-paste)
768+
(when (not (community-stem?))
769+
(track-event "MAGIC_PASTE" '(("mode" . "text"))))))))
759770
(when (defined? 'tutorial-notify-action)
760771
(tutorial-notify-action "ocr-paste")))
761772

TeXmacs/progs/init-research.scm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,15 @@
470470
(autosave-delayed))
471471
(delayed (:pause 30000)
472472
(auto-backup-delayed))
473+
(catch #t
474+
(lambda ()
475+
(use-modules (telemetry telemetry-utils))
476+
(use-modules (telemetry telemetry-track))
477+
(use-modules (telemetry init-telemetry))
478+
(init-telemetry))
479+
(lambda args
480+
(display (string-append "[telemetry] error: init failed: "
481+
(object->string args) "\n"))))
473482
(texmacs-banner)
474483
(display "Initialization done\n")
475484

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3+
;;
4+
;; MODULE : init-telemetry.scm
5+
;; DESCRIPTION : Telemetry initialization and periodic flush
6+
;; COPYRIGHT : (C) 2026 Yuki Lu
7+
;;
8+
;; This software falls under the GNU general public license version 3 or later.
9+
;; It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
10+
;; in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
11+
;;
12+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13+
14+
(texmacs-module (telemetry init-telemetry)
15+
(:use (telemetry telemetry-track)
16+
(telemetry telemetry-utils)))
17+
18+
(import (scheme base))
19+
20+
(define telemetry-scheduled? #f)
21+
22+
(define (telemetry-scheduler-step)
23+
(when (telemetry-enabled?)
24+
(telemetry-flush-if-needed))
25+
(telemetry-delayed))
26+
27+
(define (telemetry-delayed)
28+
(delayed
29+
(:pause (telemetry-get-flush-interval))
30+
(telemetry-scheduler-step)))
31+
32+
(define-public (init-telemetry)
33+
(if telemetry-scheduled?
34+
(display "[telemetry] init: already initialized\n")
35+
(if (telemetry-enabled?)
36+
(begin
37+
(set! telemetry-scheduled? #t)
38+
(display (string-append "[telemetry] init: enabled, buffer="
39+
(number->string (telemetry-get-buffer-size))
40+
", interval="
41+
(number->string (telemetry-get-flush-interval))
42+
"ms\n"))
43+
(on-exit
44+
(catch #t
45+
(lambda () (telemetry-flush-if-needed))
46+
(lambda args
47+
(display (string-append "[telemetry] error: exit flush failed: "
48+
(object->string args) "\n")))))
49+
(telemetry-delayed))
50+
(display "[telemetry] init: disabled\n"))))
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
2+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3+
;;
4+
;; MODULE : telemetry-track.scm
5+
;; DESCRIPTION : Telemetry event tracking with memory queue and flush
6+
;; COPYRIGHT : (C) 2026 Yuki Lu
7+
;;
8+
;; This software falls under the GNU general public license version 3 or later.
9+
;; It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
10+
;; in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
11+
;;
12+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13+
14+
(texmacs-module (telemetry telemetry-track)
15+
(:use (telemetry telemetry-utils)))
16+
17+
(import (scheme base)
18+
(liii base)
19+
(liii json)
20+
(liii os)
21+
(liii path)
22+
(liii string)
23+
(liii list)
24+
)
25+
26+
(define-public *telemetry-event-queue* '())
27+
28+
(define-public (track-event event-type properties)
29+
(if (not (telemetry-enabled?))
30+
#f
31+
(if (and (string? event-type) (not (string-null? event-type)))
32+
(begin
33+
(set! *telemetry-event-queue*
34+
(cons (telemetry-make-event event-type properties)
35+
*telemetry-event-queue*))
36+
(let ((len (length *telemetry-event-queue*)))
37+
(display (string-append "[telemetry] track: " event-type
38+
" (queue: " (number->string len)
39+
"/" (number->string (telemetry-get-buffer-size)) ")\n"))
40+
(if (> len telemetry-max-queue-size)
41+
(set! *telemetry-event-queue*
42+
(list-head *telemetry-event-queue* telemetry-max-queue-size)))
43+
(if (>= len (telemetry-get-buffer-size))
44+
(telemetry-flush)))
45+
#t)
46+
#f)))
47+
48+
(define-public (telemetry-queue-length)
49+
(length *telemetry-event-queue*))
50+
51+
(define-public (telemetry-flush-if-needed)
52+
(if (not (telemetry-enabled?))
53+
#t
54+
(if (not (null? *telemetry-event-queue*))
55+
(telemetry-flush)
56+
#t)))
57+
58+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
59+
;; Flush implementation: lightweight append-only file writes
60+
;; Complex logic (size limits, stale filtering) handled by liii subprocess
61+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62+
63+
(define telemetry-lock-timeout-seconds 30)
64+
65+
(define (telemetry-lock-info owner now)
66+
`(("owner" . ,owner) ("created_at" . ,now)))
67+
68+
(define (telemetry-read-lock-info)
69+
(catch #t
70+
(lambda ()
71+
(let ((text (string-load (system->url (telemetry-lock-info-path)))))
72+
(if (and (string? text) (> (string-length text) 0))
73+
(string->json text)
74+
#f)))
75+
(lambda args #f)))
76+
77+
(define (telemetry-lock-expired? now)
78+
(let ((info (telemetry-read-lock-info)))
79+
(if info
80+
(let ((created (json-ref-number info "created_at" 0)))
81+
(> (- now created) telemetry-lock-timeout-seconds))
82+
#t)))
83+
84+
(define (telemetry-remove-lock)
85+
(catch #t
86+
(lambda ()
87+
(path-unlink (telemetry-lock-info-path) #t)
88+
(rmdir (telemetry-lock-path)))
89+
(lambda args #f)))
90+
91+
(define (telemetry-acquire-lock)
92+
(telemetry-ensure-dir)
93+
(let ((owner (telemetry-lock-owner))
94+
(now (inexact->exact (truncate (current-time)))))
95+
(catch #t
96+
(lambda ()
97+
(mkdir (telemetry-lock-path))
98+
(string-save
99+
(json->string (telemetry-lock-info owner now))
100+
(system->url (telemetry-lock-info-path)))
101+
owner)
102+
(lambda args
103+
(if (telemetry-lock-expired? now)
104+
(begin
105+
(telemetry-remove-lock)
106+
(catch #t
107+
(lambda ()
108+
(mkdir (telemetry-lock-path))
109+
(string-save
110+
(json->string (telemetry-lock-info owner now))
111+
(system->url (telemetry-lock-info-path)))
112+
owner)
113+
(lambda args2 #f)))
114+
#f)))))
115+
116+
(define (telemetry-release-lock owner)
117+
(let ((info (telemetry-read-lock-info)))
118+
(if (and info
119+
(string=? (json-ref-string info "owner" "") owner))
120+
(telemetry-remove-lock)
121+
(begin
122+
(display (string-append "[telemetry] warn: lock owner mismatch, skipping release "
123+
"(expected " owner ", got "
124+
(if info (json-ref-string info "owner" "") "none") ")\n"))
125+
#f))))
126+
127+
(define-public (telemetry-write-pending events)
128+
(if (null? events)
129+
#t
130+
(let ((path (telemetry-pending-path))
131+
(lines (map json->string events)))
132+
(catch #t
133+
(lambda ()
134+
(let ((text (string-append (string-join lines "\n") "\n")))
135+
(string-append-to-file text (system->url path))
136+
(display (string-append "[telemetry] flush: "
137+
(number->string (length events))
138+
" events -> "
139+
path "\n"))
140+
#t))
141+
(lambda args
142+
(display (string-append "[telemetry] error: write failed: "
143+
(object->string args) "\n"))
144+
#f)))))
145+
146+
(define-public (telemetry-flush)
147+
(if (null? *telemetry-event-queue*)
148+
#t
149+
(let ((owner (telemetry-acquire-lock)))
150+
(if owner
151+
(let ((ok? (telemetry-write-pending (reverse *telemetry-event-queue*))))
152+
(if ok?
153+
(begin
154+
(set! *telemetry-event-queue* '())
155+
(telemetry-release-lock owner)
156+
#t)
157+
(begin
158+
(display (string-append "[telemetry] error: flush failed, keeping "
159+
(number->string (length *telemetry-event-queue*))
160+
" events in memory queue\n"))
161+
(telemetry-release-lock owner)
162+
#f)))
163+
#f))))
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
2+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3+
;;
4+
;; MODULE : telemetry-utils.scm
5+
;; DESCRIPTION : Telemetry utilities for paths, config, and device info
6+
;; COPYRIGHT : (C) 2026 Yuki Lu
7+
;;
8+
;; This software falls under the GNU general public license version 3 or later.
9+
;; It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
10+
;; in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
11+
;;
12+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13+
14+
(texmacs-module (telemetry telemetry-utils))
15+
16+
(import (scheme base)
17+
(liii base)
18+
(liii os)
19+
(liii path)
20+
(liii string)
21+
(liii uuid)
22+
)
23+
24+
(import (only (srfi srfi-19)
25+
current-date date-zone-offset))
26+
27+
(define telemetry-buffer-size 30)
28+
(define telemetry-flush-interval-ms 60000)
29+
(define-public telemetry-max-queue-size 1000)
30+
31+
(define-public (telemetry-get-buffer-size)
32+
telemetry-buffer-size)
33+
34+
(define-public (telemetry-set-buffer-size! size)
35+
(set! telemetry-buffer-size size))
36+
37+
(define-public (telemetry-get-flush-interval)
38+
telemetry-flush-interval-ms)
39+
40+
(define-public (telemetry-set-flush-interval! interval)
41+
(set! telemetry-flush-interval-ms interval))
42+
43+
(define-public (telemetry-enabled?)
44+
(if (community-stem?) #f
45+
(let ((pref (get-preference "telemetry")))
46+
(not (or (== pref "off") (== pref "0"))))))
47+
48+
(define (telemetry-home-path)
49+
(url->system (get-texmacs-home-path)))
50+
51+
(define-public (telemetry-dir)
52+
(let ((dir (string-append (telemetry-home-path) "/system/telemetry")))
53+
(if (not (path-exists? dir))
54+
(mkdir dir))
55+
dir))
56+
57+
(define-public (telemetry-pending-path)
58+
(string-append (telemetry-dir) "/telemetry-pending.jsonl"))
59+
60+
(define-public (telemetry-lock-path)
61+
(string-append (telemetry-dir) "/.lock"))
62+
63+
(define-public (telemetry-lock-info-path)
64+
(string-append (telemetry-lock-path) "/owner.json"))
65+
66+
(define-public (telemetry-ensure-dir)
67+
(let ((dir (telemetry-dir)))
68+
(if (not (path-exists? dir))
69+
(mkdir dir))))
70+
71+
(define-public (telemetry-lock-owner)
72+
(string-append "telemetry-" (number->string (getpid))))
73+
74+
(define-public (telemetry-device-id)
75+
(let ((id (stem-device-id)))
76+
(if (string? id) id "unknown")))
77+
78+
(define-public (telemetry-session-id)
79+
(uuid4))
80+
81+
(define-public (telemetry-app-version)
82+
(xmacs-version))
83+
84+
(define-public (telemetry-platform)
85+
(cond ((os-macos?) "macos")
86+
((or (os-win32?) (os-mingw?)) "windows")
87+
(else "linux")))
88+
89+
(define-public (telemetry-language)
90+
(let ((lang (or (system-getenv "LANG") "en_US")))
91+
(if (string-contains? lang ".")
92+
(car (string-split lang #\.))
93+
lang)))
94+
95+
(define-public (telemetry-timezone)
96+
(catch #t
97+
(lambda ()
98+
(let ((offset (date-zone-offset (current-date))))
99+
(if (zero? offset)
100+
"UTC"
101+
(let* ((sign (if (>= offset 0) "+" "-"))
102+
(abs-offset (abs offset))
103+
(hours (quotient abs-offset 3600))
104+
(minutes (quotient (remainder abs-offset 3600) 60)))
105+
(string-append sign
106+
(if (< hours 10) "0" "")
107+
(number->string hours)
108+
":"
109+
(if (< minutes 10) "0" "")
110+
(number->string minutes))))))
111+
(lambda args "UTC")))
112+
113+
(define-public (telemetry-now)
114+
(inexact->exact (truncate (current-time))))
115+
116+
(define-public *telemetry-session-id* (telemetry-session-id))
117+
118+
(define-public (telemetry-make-event event-type properties)
119+
`(("eventType" . ,event-type)
120+
("timestamp" . ,(telemetry-now))
121+
("distinctId" . ,(telemetry-device-id))
122+
("sessionId" . ,*telemetry-session-id*)
123+
("eventId" . ,(uuid4))
124+
("appVersion" . ,(telemetry-app-version))
125+
("deviceId" . ,(telemetry-device-id))
126+
("platform" . ,(telemetry-platform))
127+
("language" . ,(telemetry-language))
128+
("timezone" . ,(telemetry-timezone))
129+
("properties" . ,(if (null? properties) '(()) properties))))

0 commit comments

Comments
 (0)