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 ()