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