tangled
alpha
login
or
join now
anil.recoil.org
/
ocaml-karakeep
0
fork
atom
OCaml CLI and library to the Karakeep bookmarking app
0
fork
atom
overview
issues
pulls
pipelines
fix search
anil.recoil.org
11 months ago
9e060290
c3ebe38d
+135
-100
6 changed files
expand all
collapse all
unified
split
lib
karakeep.ml
run_tests.sh
test
asset_test.ml
create_test.ml
dune
test.ml
+1
-1
lib/karakeep.ml
reviewed
···
703
703
^ String.concat "&"
704
704
(List.map (fun (k, v) -> k ^ "=" ^ Uri.pct_encode v) params)
705
705
in
706
706
-
let url = base_url ^ "/api/v1/search" ^ query_str in
706
706
+
let url = base_url ^ "/api/v1/bookmarks/search" ^ query_str in
707
707
708
708
(* Make the request *)
709
709
make_request ~api_key ~method_:`GET url >>= fun (resp, body) ->
+3
run_tests.sh
reviewed
···
13
13
echo -e "\n=== Running asset test ===\n"
14
14
opam exec -- dune exec test/asset_test.exe
15
15
16
16
+
echo -e "\n=== Running search bookmarks test ===\n"
17
17
+
opam exec -- dune exec test/search_test.exe
18
18
+
16
19
echo -e "\nAll tests passed!"
+60
-49
test/asset_test.ml
reviewed
···
22
22
(* First get a bookmark with assets *)
23
23
Printf.printf "Fetching bookmarks with assets...\n";
24
24
25
25
-
fetch_bookmarks ~api_key ~limit:5 base_url >>= fun response ->
26
26
-
(* Find a bookmark with assets *)
27
27
-
let bookmark_with_assets =
28
28
-
List.find_opt (fun b -> List.length b.assets > 0) response.bookmarks
29
29
-
in
30
30
-
31
31
-
match bookmark_with_assets with
32
32
-
| None ->
33
33
-
Printf.printf "No bookmarks with assets found in the first 5 results.\n";
34
34
-
Lwt.return_unit
35
35
-
| Some bookmark -> (
36
36
-
(* Print assets info *)
37
37
-
let bookmark_title_str = bookmark_title bookmark in
38
38
-
let url =
39
39
-
match bookmark.content with
40
40
-
| Link lc -> lc.url
41
41
-
| Text tc -> Option.value tc.source_url ~default:"(text content)"
42
42
-
| Asset ac -> Option.value ac.source_url ~default:"(asset content)"
43
43
-
| Unknown -> "(unknown content)"
25
25
+
Lwt.catch
26
26
+
(fun () ->
27
27
+
fetch_bookmarks ~api_key ~limit:5 base_url >>= fun response ->
28
28
+
(* Find a bookmark with assets *)
29
29
+
let bookmark_with_assets =
30
30
+
List.find_opt (fun b -> List.length b.assets > 0) response.bookmarks
44
31
in
45
45
-
Printf.printf "Found bookmark \"%s\" with %d assets: %s\n"
46
46
-
bookmark_title_str
47
47
-
(List.length bookmark.assets)
48
48
-
url;
49
32
50
50
-
List.iter
51
51
-
(fun asset ->
52
52
-
let asset_type_str =
53
53
-
match asset.asset_type with
54
54
-
| Screenshot -> "screenshot"
55
55
-
| AssetScreenshot -> "assetScreenshot"
56
56
-
| BannerImage -> "bannerImage"
57
57
-
| FullPageArchive -> "fullPageArchive"
58
58
-
| Video -> "video"
59
59
-
| BookmarkAsset -> "bookmarkAsset"
60
60
-
| PrecrawledArchive -> "precrawledArchive"
61
61
-
| Unknown -> "unknown"
33
33
+
match bookmark_with_assets with
34
34
+
| None ->
35
35
+
Printf.printf "No bookmarks with assets found in the first 5 results.\n";
36
36
+
Lwt.return_unit
37
37
+
| Some bookmark -> (
38
38
+
(* Print assets info *)
39
39
+
let bookmark_title_str = bookmark_title bookmark in
40
40
+
let url =
41
41
+
match bookmark.content with
42
42
+
| Link lc -> lc.url
43
43
+
| Text tc -> Option.value tc.source_url ~default:"(text content)"
44
44
+
| Asset ac -> Option.value ac.source_url ~default:"(asset content)"
45
45
+
| Unknown -> "(unknown content)"
62
46
in
63
63
-
Printf.printf "- Asset ID: %s, Type: %s\n" asset.id asset_type_str;
47
47
+
Printf.printf "Found bookmark \"%s\" with %d assets: %s\n"
48
48
+
bookmark_title_str
49
49
+
(List.length bookmark.assets)
50
50
+
url;
64
51
65
65
-
(* Get asset URL *)
66
66
-
let asset_url = get_asset_url base_url asset.id in
67
67
-
Printf.printf " URL: %s\n" asset_url)
68
68
-
bookmark.assets;
52
52
+
List.iter
53
53
+
(fun asset ->
54
54
+
let asset_type_str =
55
55
+
match asset.asset_type with
56
56
+
| Screenshot -> "screenshot"
57
57
+
| AssetScreenshot -> "assetScreenshot"
58
58
+
| BannerImage -> "bannerImage"
59
59
+
| FullPageArchive -> "fullPageArchive"
60
60
+
| Video -> "video"
61
61
+
| BookmarkAsset -> "bookmarkAsset"
62
62
+
| PrecrawledArchive -> "precrawledArchive"
63
63
+
| Unknown -> "unknown"
64
64
+
in
65
65
+
Printf.printf "- Asset ID: %s, Type: %s\n" asset.id asset_type_str;
69
66
70
70
-
(* Optionally fetch one asset to verify it works *)
71
71
-
match bookmark.assets with
72
72
-
| asset :: _ ->
73
73
-
Printf.printf "\nFetching asset %s...\n" asset.id;
74
74
-
fetch_asset ~api_key base_url asset.id >>= fun data ->
75
75
-
Printf.printf "Successfully fetched asset. Size: %d bytes\n"
76
76
-
(String.length data);
77
77
-
Lwt.return_unit
78
78
-
| [] -> Lwt.return_unit)
67
67
+
(* Get asset URL *)
68
68
+
let asset_url = get_asset_url base_url asset.id in
69
69
+
Printf.printf " URL: %s\n" asset_url)
70
70
+
bookmark.assets;
71
71
+
72
72
+
(* Optionally fetch one asset to verify it works *)
73
73
+
match bookmark.assets with
74
74
+
| asset :: _ ->
75
75
+
Printf.printf "\nFetching asset %s...\n" asset.id;
76
76
+
Lwt.catch
77
77
+
(fun () ->
78
78
+
fetch_asset ~api_key base_url asset.id >>= fun data ->
79
79
+
Printf.printf "Successfully fetched asset. Size: %d bytes\n"
80
80
+
(String.length data);
81
81
+
Lwt.return_unit)
82
82
+
(fun e ->
83
83
+
Printf.printf "Error fetching asset: %s\n" (Printexc.to_string e);
84
84
+
Lwt.return_unit)
85
85
+
| [] -> Lwt.return_unit))
86
86
+
(fun e ->
87
87
+
Printf.printf "Error in asset test: %s\n" (Printexc.to_string e);
88
88
+
Printf.printf "Skipping the asset test due to API error.\n";
89
89
+
Lwt.return_unit)
79
90
in
80
91
81
92
(* Run test *)
+23
-17
test/create_test.ml
reviewed
···
25
25
let title = "OCaml Programming Language" in
26
26
let tags = [ "programming"; "ocaml"; "functional" ] in
27
27
28
28
-
create_bookmark ~api_key ~url ~title ~tags base_url >>= fun bookmark ->
29
29
-
Printf.printf "Successfully created bookmark:\n";
30
30
-
Printf.printf "- ID: %s\n" bookmark.id;
31
31
-
Printf.printf "- Title: %s\n" (bookmark_title bookmark);
28
28
+
Lwt.catch
29
29
+
(fun () ->
30
30
+
create_bookmark ~api_key ~url ~title ~tags base_url >>= fun bookmark ->
31
31
+
Printf.printf "Successfully created bookmark:\n";
32
32
+
Printf.printf "- ID: %s\n" bookmark.id;
33
33
+
Printf.printf "- Title: %s\n" (bookmark_title bookmark);
32
34
33
33
-
let url =
34
34
-
match bookmark.content with
35
35
-
| Link lc -> lc.url
36
36
-
| Text tc -> Option.value tc.source_url ~default:"(text content)"
37
37
-
| Asset ac -> Option.value ac.source_url ~default:"(asset content)"
38
38
-
| Unknown -> "(unknown content)"
39
39
-
in
40
40
-
Printf.printf "- URL: %s\n" url;
41
41
-
Printf.printf "- Created: %s\n" (Ptime.to_rfc3339 bookmark.created_at);
42
42
-
Printf.printf "- Tags: %s\n"
43
43
-
(String.concat ", "
44
44
-
(List.map (fun (tag : bookmark_tag) -> tag.name) bookmark.tags));
35
35
+
let url =
36
36
+
match bookmark.content with
37
37
+
| Link lc -> lc.url
38
38
+
| Text tc -> Option.value tc.source_url ~default:"(text content)"
39
39
+
| Asset ac -> Option.value ac.source_url ~default:"(asset content)"
40
40
+
| Unknown -> "(unknown content)"
41
41
+
in
42
42
+
Printf.printf "- URL: %s\n" url;
43
43
+
Printf.printf "- Created: %s\n" (Ptime.to_rfc3339 bookmark.created_at);
44
44
+
Printf.printf "- Tags: %s\n"
45
45
+
(String.concat ", "
46
46
+
(List.map (fun (tag : bookmark_tag) -> tag.name) bookmark.tags));
45
47
46
46
-
Lwt.return_unit
48
48
+
Lwt.return_unit)
49
49
+
(fun e ->
50
50
+
Printf.printf "Error creating bookmark: %s\n" (Printexc.to_string e);
51
51
+
Printf.printf "Skipping the creation test due to API error.\n";
52
52
+
Lwt.return_unit)
47
53
in
48
54
49
55
(* Run test *)
+4
test/dune
reviewed
···
9
9
(executable
10
10
(name asset_test)
11
11
(libraries karakeep lwt.unix))
12
12
+
13
13
+
(executable
14
14
+
(name search_test)
15
15
+
(libraries karakeep lwt.unix))
+44
-33
test/test.ml
reviewed
···
36
36
37
37
(* Test both fetch methods *)
38
38
let run_tests () =
39
39
-
(* Test 1: fetch_bookmarks - get a single page with pagination info *)
40
40
-
Printf.printf "=== Test 1: fetch_bookmarks (paginated) ===\n";
41
41
-
fetch_bookmarks ~api_key ~limit:3 base_url >>= fun response ->
42
42
-
Printf.printf "Found bookmarks, showing %d (page 1)\n"
43
43
-
(List.length response.bookmarks);
44
44
-
Printf.printf "Next cursor: %s\n\n"
45
45
-
(match response.next_cursor with Some c -> c | None -> "none");
39
39
+
Lwt.catch
40
40
+
(fun () ->
41
41
+
(* Test 1: fetch_bookmarks - get a single page with pagination info *)
42
42
+
Printf.printf "=== Test 1: fetch_bookmarks (paginated) ===\n";
43
43
+
fetch_bookmarks ~api_key ~limit:3 base_url >>= fun response ->
44
44
+
Printf.printf "Found bookmarks, showing %d (page 1)\n"
45
45
+
(List.length response.bookmarks);
46
46
+
Printf.printf "Next cursor: %s\n\n"
47
47
+
(match response.next_cursor with Some c -> c | None -> "none");
46
48
47
47
-
List.iter print_bookmark response.bookmarks;
49
49
+
List.iter print_bookmark response.bookmarks;
48
50
49
49
-
(* Test 2: fetch_all_bookmarks - get multiple pages automatically *)
50
50
-
Printf.printf "=== Test 2: fetch_all_bookmarks (with limit) ===\n";
51
51
-
fetch_all_bookmarks ~api_key ~page_size:2 ~max_pages:2 base_url
52
52
-
>>= fun all_bookmarks ->
53
53
-
Printf.printf "Fetched %d bookmarks from up to 2 pages\n\n"
54
54
-
(List.length all_bookmarks);
51
51
+
(* Test 2: fetch_all_bookmarks - get multiple pages automatically *)
52
52
+
Printf.printf "=== Test 2: fetch_all_bookmarks (with limit) ===\n";
53
53
+
fetch_all_bookmarks ~api_key ~page_size:2 ~max_pages:2 base_url
54
54
+
>>= fun all_bookmarks ->
55
55
+
Printf.printf "Fetched %d bookmarks from up to 2 pages\n\n"
56
56
+
(List.length all_bookmarks);
55
57
56
56
-
List.iter print_bookmark
57
57
-
(List.fold_left
58
58
-
(fun acc x -> if List.length acc < 4 then acc @ [ x ] else acc)
59
59
-
[] all_bookmarks);
60
60
-
Printf.printf "... and %d more bookmarks\n\n"
61
61
-
(max 0 (List.length all_bookmarks - 4));
58
58
+
List.iter print_bookmark
59
59
+
(List.fold_left
60
60
+
(fun acc x -> if List.length acc < 4 then acc @ [ x ] else acc)
61
61
+
[] all_bookmarks);
62
62
+
Printf.printf "... and %d more bookmarks\n\n"
63
63
+
(max 0 (List.length all_bookmarks - 4));
62
64
63
63
-
(* Test 3: fetch_bookmark_details - get a specific bookmark *)
64
64
-
match response.bookmarks with
65
65
-
| first_bookmark :: _ ->
66
66
-
Printf.printf "=== Test 3: fetch_bookmark_details ===\n";
67
67
-
Printf.printf "Fetching details for bookmark ID: %s\n\n"
68
68
-
first_bookmark.id;
65
65
+
(* Test 3: fetch_bookmark_details - get a specific bookmark *)
66
66
+
match response.bookmarks with
67
67
+
| first_bookmark :: _ ->
68
68
+
Printf.printf "=== Test 3: fetch_bookmark_details ===\n";
69
69
+
Printf.printf "Fetching details for bookmark ID: %s\n\n"
70
70
+
first_bookmark.id;
69
71
70
70
-
fetch_bookmark_details ~api_key base_url first_bookmark.id
71
71
-
>>= fun bookmark ->
72
72
-
print_bookmark bookmark;
73
73
-
Lwt.return_unit
74
74
-
| [] ->
75
75
-
Printf.printf "No bookmarks found to test fetch_bookmark_details\n";
76
76
-
Lwt.return_unit
72
72
+
Lwt.catch
73
73
+
(fun () ->
74
74
+
fetch_bookmark_details ~api_key base_url first_bookmark.id
75
75
+
>>= fun bookmark ->
76
76
+
print_bookmark bookmark;
77
77
+
Lwt.return_unit)
78
78
+
(fun e ->
79
79
+
Printf.printf "Error fetching bookmark details: %s\n" (Printexc.to_string e);
80
80
+
Lwt.return_unit)
81
81
+
| [] ->
82
82
+
Printf.printf "No bookmarks found to test fetch_bookmark_details\n";
83
83
+
Lwt.return_unit)
84
84
+
(fun e ->
85
85
+
Printf.printf "Error in basic tests: %s\n" (Printexc.to_string e);
86
86
+
Printf.printf "Skipping remaining tests due to API error.\n";
87
87
+
Lwt.return_unit)
77
88
in
78
89
79
90
(* Run all tests *)