OCaml library for JSONfeed parsing and creation
at v1.1.0 6.0 kB view raw
1(** Example: Parsing and analyzing JSON Feeds 2 3 This demonstrates: 4 - Parsing feeds from files 5 - Analyzing feed metadata 6 - Iterating over items 7 - Working with dates and content *) 8 9open Jsonfeed 10 11(* Helper to read feed from file *) 12let of_file filename = 13 let content = In_channel.with_open_text filename In_channel.input_all in 14 Jsonfeed.of_string content 15 16let print_feed_info feed = 17 Format.printf "Feed Information:\n"; 18 Format.printf " Title: %s\n" (Jsonfeed.title feed); 19 Format.printf " Version: %s\n" (Jsonfeed.version feed); 20 21 (match Jsonfeed.home_page_url feed with 22 | Some url -> Format.printf " Home Page: %s\n" url 23 | None -> ()); 24 25 (match Jsonfeed.feed_url feed with 26 | Some url -> Format.printf " Feed URL: %s\n" url 27 | None -> ()); 28 29 (match Jsonfeed.description feed with 30 | Some desc -> Format.printf " Description: %s\n" desc 31 | None -> ()); 32 33 (match Jsonfeed.language feed with 34 | Some lang -> Format.printf " Language: %s\n" lang 35 | None -> ()); 36 37 (match Jsonfeed.authors feed with 38 | Some authors -> 39 Format.printf " Authors:\n"; 40 List.iter 41 (fun author -> 42 match Author.name author with 43 | Some name -> 44 Format.printf " - %s" name; 45 (match Author.url author with 46 | Some url -> Format.printf " (%s)" url 47 | None -> ()); 48 Format.printf "\n" 49 | None -> ()) 50 authors 51 | None -> ()); 52 53 Format.printf " Items: %d\n\n" (List.length (Jsonfeed.items feed)) 54 55let print_item_details item = 56 Format.printf "Item: %s\n" (Item.id item); 57 58 (match Item.title item with 59 | Some title -> Format.printf " Title: %s\n" title 60 | None -> Format.printf " (No title - microblog entry)\n"); 61 62 (match Item.url item with 63 | Some url -> Format.printf " URL: %s\n" url 64 | None -> ()); 65 66 (* Print content info *) 67 (match Item.content item with 68 | `Html html -> 69 Format.printf " Content: HTML only (%d chars)\n" (String.length html) 70 | `Text text -> 71 Format.printf " Content: Text only (%d chars)\n" (String.length text) 72 | `Both (html, text) -> 73 Format.printf " Content: Both HTML (%d chars) and Text (%d chars)\n" 74 (String.length html) (String.length text)); 75 76 (* Print dates *) 77 (match Item.date_published item with 78 | Some date -> 79 Format.printf " Published: %s\n" (Jsonfeed.Rfc3339.format date) 80 | None -> ()); 81 82 (match Item.date_modified item with 83 | Some date -> Format.printf " Modified: %s\n" (Jsonfeed.Rfc3339.format date) 84 | None -> ()); 85 86 (* Print tags *) 87 (match Item.tags item with 88 | Some tags when tags <> [] -> 89 Format.printf " Tags: %s\n" (String.concat ", " tags) 90 | _ -> ()); 91 92 (* Print attachments *) 93 (match Item.attachments item with 94 | Some attachments when attachments <> [] -> 95 Format.printf " Attachments:\n"; 96 List.iter 97 (fun att -> 98 Format.printf " - %s (%s)\n" (Attachment.url att) 99 (Attachment.mime_type att); 100 (match Attachment.size_in_bytes att with 101 | Some size -> 102 let mb = Int64.to_float size /. (1024. *. 1024.) in 103 Format.printf " Size: %.2f MB\n" mb 104 | None -> ()); 105 match Attachment.duration_in_seconds att with 106 | Some duration -> 107 let mins = duration / 60 in 108 let secs = duration mod 60 in 109 Format.printf " Duration: %dm%ds\n" mins secs 110 | None -> ()) 111 attachments 112 | _ -> ()); 113 114 Format.printf "\n" 115 116let analyze_feed feed = 117 let items = Jsonfeed.items feed in 118 119 Format.printf "\n=== Feed Analysis ===\n\n"; 120 121 (* Count content types *) 122 let html_only = ref 0 in 123 let text_only = ref 0 in 124 let both = ref 0 in 125 126 List.iter 127 (fun item -> 128 match Item.content item with 129 | `Html _ -> incr html_only 130 | `Text _ -> incr text_only 131 | `Both _ -> incr both) 132 items; 133 134 Format.printf "Content Types:\n"; 135 Format.printf " HTML only: %d\n" !html_only; 136 Format.printf " Text only: %d\n" !text_only; 137 Format.printf " Both: %d\n\n" !both; 138 139 (* Find items with attachments *) 140 let with_attachments = 141 List.filter 142 (fun item -> 143 match Item.attachments item with 144 | Some att when att <> [] -> true 145 | _ -> false) 146 items 147 in 148 149 Format.printf "Items with attachments: %d\n\n" (List.length with_attachments); 150 151 (* Collect all unique tags *) 152 let all_tags = 153 List.fold_left 154 (fun acc item -> 155 match Item.tags item with Some tags -> acc @ tags | None -> acc) 156 [] items 157 in 158 let unique_tags = List.sort_uniq String.compare all_tags in 159 160 if unique_tags <> [] then 161 Format.printf "All tags used: %s\n\n" (String.concat ", " unique_tags) 162 163let main () = 164 (* Parse from example_feed.json file *) 165 Format.printf "=== Parsing JSON Feed from example_feed.json ===\n\n"; 166 167 try 168 match of_file "example/example_feed.json" with 169 | Ok feed -> ( 170 print_feed_info feed; 171 172 Format.printf "=== Items ===\n\n"; 173 List.iter print_item_details (Jsonfeed.items feed); 174 175 analyze_feed feed; 176 177 (* Demonstrate round-trip parsing *) 178 Format.printf "\n=== Round-trip Test ===\n\n"; 179 match Jsonfeed.to_string feed with 180 | Error e -> 181 Printf.eprintf "Error serializing feed: %s\n" 182 (Jsont.Error.to_string e); 183 exit 1 184 | Ok json -> ( 185 match Jsonfeed.of_string json with 186 | Ok feed2 -> 187 if Jsonfeed.equal feed feed2 then 188 Format.printf "✓ Round-trip successful: feeds are equal\n" 189 else Format.printf "✗ Round-trip failed: feeds differ\n" 190 | Error err -> 191 Format.eprintf "✗ Round-trip failed: %s\n" 192 (Jsont.Error.to_string err))) 193 | Error err -> 194 Format.eprintf "Error parsing feed: %s\n" (Jsont.Error.to_string err) 195 with Sys_error msg -> Format.eprintf "Error reading file: %s\n" msg 196 197let () = main ()