OCaml library for JSONfeed parsing and creation
1(** Example: Creating and serializing a JSON Feed
2
3 This demonstrates:
4 - Creating authors
5 - Creating items with different content types
6 - Creating a complete feed
7 - Serializing to JSON string and file *)
8
9open Jsonfeed
10
11(* Helper to write feed to output channel *)
12let to_file filename feed =
13 let s = Jsonfeed.to_string feed in
14 Out_channel.with_open_gen
15 [Open_wronly; Open_creat; Open_trunc; Open_text]
16 0o644
17 filename
18 (fun oc -> Out_channel.output_string oc s)
19
20let create_blog_feed () =
21 (* Create some authors *)
22 let jane = Author.create
23 ~name:"Jane Doe"
24 ~url:"https://example.com/authors/jane"
25 ~avatar:"https://example.com/avatars/jane.png"
26 () in
27
28 let john = Author.create
29 ~name:"John Smith"
30 ~url:"https://example.com/authors/john"
31 () in
32
33 (* Create items with different content types *)
34 let item1 = Item.create
35 ~id:"https://example.com/posts/1"
36 ~url:"https://example.com/posts/1"
37 ~title:"Introduction to OCaml"
38 ~content:(`Both (
39 "<p>OCaml is a powerful functional programming language.</p>",
40 "OCaml is a powerful functional programming language."
41 ))
42 ~date_published:(Jsonfeed.parse_rfc3339 "2024-11-01T10:00:00Z" |> Option.get)
43 ~date_modified:(Jsonfeed.parse_rfc3339 "2024-11-01T15:30:00Z" |> Option.get)
44 ~authors:[jane]
45 ~tags:["ocaml"; "programming"; "functional"]
46 ~summary:"A beginner's guide to OCaml programming"
47 () in
48
49 let item2 = Item.create
50 ~id:"https://example.com/posts/2"
51 ~url:"https://example.com/posts/2"
52 ~title:"JSON Feed for Syndication"
53 ~content:(`Html "<p>JSON Feed is a modern alternative to RSS and Atom.</p>")
54 ~date_published:(Jsonfeed.parse_rfc3339 "2024-11-02T09:00:00Z" |> Option.get)
55 ~authors:[jane; john]
56 ~tags:["json"; "syndication"; "web"]
57 ~image:"https://example.com/images/jsonfeed.png"
58 () in
59
60 (* Microblog-style item (text only, no title) *)
61 let item3 = Item.create
62 ~id:"https://example.com/micro/42"
63 ~content:(`Text "Just shipped a new feature! 🚀")
64 ~date_published:(Jsonfeed.parse_rfc3339 "2024-11-03T08:15:00Z" |> Option.get)
65 ~tags:["microblog"]
66 () in
67
68 (* Create the complete feed *)
69 let feed = Jsonfeed.create
70 ~title:"Example Blog"
71 ~home_page_url:"https://example.com"
72 ~feed_url:"https://example.com/feed.json"
73 ~description:"A blog about programming, web development, and technology"
74 ~icon:"https://example.com/icon-512.png"
75 ~favicon:"https://example.com/favicon-64.png"
76 ~authors:[jane; john]
77 ~language:"en-US"
78 ~items:[item1; item2; item3]
79 () in
80
81 feed
82
83let create_podcast_feed () =
84 (* Create podcast author *)
85 let host = Author.create
86 ~name:"Podcast Host"
87 ~url:"https://podcast.example.com/host"
88 ~avatar:"https://podcast.example.com/host-avatar.jpg"
89 () in
90
91 (* Create episode with audio attachment *)
92 let attachment = Attachment.create
93 ~url:"https://podcast.example.com/episodes/ep1.mp3"
94 ~mime_type:"audio/mpeg"
95 ~title:"Episode 1: Introduction"
96 ~size_in_bytes:15_728_640L
97 ~duration_in_seconds:1800
98 () in
99
100 let episode = Item.create
101 ~id:"https://podcast.example.com/episodes/1"
102 ~url:"https://podcast.example.com/episodes/1"
103 ~title:"Episode 1: Introduction"
104 ~content:(`Html "<p>Welcome to our first episode!</p>")
105 ~date_published:(Jsonfeed.parse_rfc3339 "2024-11-01T12:00:00Z" |> Option.get)
106 ~attachments:[attachment]
107 ~authors:[host]
108 ~image:"https://podcast.example.com/episodes/ep1-cover.jpg"
109 () in
110
111 (* Create podcast feed with hub for real-time updates *)
112 let hub = Hub.create
113 ~type_:"WebSub"
114 ~url:"https://pubsubhubbub.appspot.com/"
115 () in
116
117 let feed = Jsonfeed.create
118 ~title:"Example Podcast"
119 ~home_page_url:"https://podcast.example.com"
120 ~feed_url:"https://podcast.example.com/feed.json"
121 ~description:"A podcast about interesting topics"
122 ~icon:"https://podcast.example.com/icon.png"
123 ~authors:[host]
124 ~language:"en-US"
125 ~hubs:[hub]
126 ~items:[episode]
127 () in
128
129 feed
130
131let main () =
132 (* Create blog feed *)
133 let blog_feed = create_blog_feed () in
134 Format.printf "Created blog feed: %a\n\n" Jsonfeed.pp blog_feed;
135
136 (* Serialize to string *)
137 let json_string = Jsonfeed.to_string blog_feed in
138 Format.printf "JSON (first 200 chars): %s...\n\n"
139 (String.sub json_string 0 (min 200 (String.length json_string)));
140
141 (* Serialize to file *)
142 to_file "blog-feed.json" blog_feed;
143 Format.printf "Wrote blog feed to blog-feed.json\n\n";
144
145 (* Create podcast feed *)
146 let podcast_feed = create_podcast_feed () in
147 Format.printf "Created podcast feed: %a\n\n" Jsonfeed.pp_summary podcast_feed;
148
149 (* Validate feeds *)
150 (match Jsonfeed.validate blog_feed with
151 | Ok () -> Format.printf "✓ Blog feed is valid\n"
152 | Error errors ->
153 Format.printf "✗ Blog feed validation errors:\n";
154 List.iter (Format.printf " - %s\n") errors);
155
156 (match Jsonfeed.validate podcast_feed with
157 | Ok () -> Format.printf "✓ Podcast feed is valid\n"
158 | Error errors ->
159 Format.printf "✗ Podcast feed validation errors:\n";
160 List.iter (Format.printf " - %s\n") errors)
161
162let () = main ()