use let* to clean code

This commit is contained in:
Swrup 2022-01-12 15:38:30 +01:00
parent d540e25746
commit 8e44a11067
3 changed files with 171 additions and 252 deletions

View file

@ -32,6 +32,19 @@ type post =
| Op of op | Op of op
| Reply of reply | Reply of reply
(* ('a option, string) result *)
let ( let** ) o f =
match o with
| Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))
| Ok None -> Error (Format.sprintf "db error: value not found")
| Ok (Some x) -> f x
(* ('a, string) result *)
let ( let* ) o f =
match o with
| Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))
| Ok x -> f x
module Q = struct module Q = struct
let create_post_user_table = let create_post_user_table =
Caqti_request.exec Caqti_type.unit Caqti_request.exec Caqti_type.unit
@ -242,101 +255,49 @@ let parse_comment comment =
(comment, cited_posts) (comment, cited_posts)
let view_post post_id = let view_post post_id =
let res_nick = Db.find Q.get_post_nick post_id in let* nick = Db.find Q.get_post_nick post_id in
let res_comment = Db.find Q.get_post_comment post_id in let* comment = Db.find Q.get_post_comment post_id in
let res_date = Db.find Q.get_post_date post_id in let* date = Db.find Q.get_post_date post_id in
let res_image_name = Db.find_opt Q.get_post_image_name post_id in let* image_name = Db.find_opt Q.get_post_image_name post_id in
let res_tags = let* _tags = Db.fold Q.get_post_tags (fun tag acc -> tag :: acc) post_id [] in
Db.fold Q.get_post_tags (fun tag acc -> tag :: acc) post_id [] let* replies =
in
let res_replies =
Db.fold Q.get_post_replies (fun reply_id acc -> reply_id :: acc) post_id [] Db.fold Q.get_post_replies (fun reply_id acc -> reply_id :: acc) post_id []
in in
(* get more stuff for OP *) (* TODO special stuff for OP
let res_subject = Db.find_opt Q.get_post_subject post_id in let* _subject = Db.find_opt Q.get_post_subject post_id in
let res_latlng = Db.find_opt Q.get_post_gps post_id in let* _latlng = Db.find_opt Q.get_post_gps post_id in
*)
(* TODO clean taht idk urghh.. *) let image_view =
let res0 = match image_name with
match List.find_opt Result.is_error [ res_nick; res_comment ] with | Some image_name ->
| Some (Error e) -> Error e (*TODO thumbnails *)
| Some (Ok _) -> assert false Format.sprintf
| None -> Ok () {|
in
let res1 =
match List.find_opt Result.is_error [ res_image_name; res_subject ] with
| Some (Error e) -> Error e
| Some (Ok _) -> assert false
| None -> Ok ()
in
let res2 =
match res_latlng with
| Ok _ -> Ok ()
| Error e -> Error e
in
let res3 =
match List.find_opt Result.is_error [ res_tags; res_replies ] with
| Some (Error e) -> Error e
| Some (Ok _) -> assert false
| None -> Ok ()
in
let res4jpp =
match res_date with
| Ok _ -> Ok ()
| Error e -> Error e
in
match List.find_opt Result.is_error [ res0; res1; res2; res3; res4jpp ] with
| Some (Error e) -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))
| None -> (
match
( res_nick
, res_comment
, res_image_name
, res_date
, res_subject
, res_latlng
, res_tags
, res_replies )
with
| ( Ok nick
, Ok comment
, Ok image_name
, Ok date
, Ok _subject
, Ok _latlng
, Ok _tags
, Ok replies ) ->
let image_view =
match image_name with
| Some image_name ->
(*TODO thumbnails *)
Format.sprintf
{|
<div class="postImage"> <div class="postImage">
<a title="%s" href="/post_pic/%s"> <a title="%s" href="/post_pic/%s">
<img src="/post_pic/%s" style="width:200px;height:200px;" loading="lazy"> <img src="/post_pic/%s" style="width:200px;height:200px;" loading="lazy">
</a> </a>
</div> </div>
|} |}
image_name post_id post_id image_name post_id post_id
| None -> "" | None -> ""
in in
let replies_view = let replies_view =
{|<div class="repliesLink">|} {|<div class="repliesLink">|}
^ String.concat " " ^ String.concat " "
(List.map (List.map
(fun reply_id -> (fun reply_id ->
Format.sprintf {|<a class="replyLink" href="#%s">>>%s</a>|} Format.sprintf {|<a class="replyLink" href="#%s">>>%s</a>|}
reply_id reply_id ) reply_id reply_id )
replies ) replies )
^ {|</div> |} ^ {|</div> |}
in in
(* TODO how to display date, I should probably render everything on the client*) (* TODO how to display date, I should probably render everything on the client*)
let post_info_view = let post_info_view =
Format.sprintf Format.sprintf
{| {|
<div class="postInfo" <div class="postInfo"
<span class=nick>%s</span> <span class=nick>%s</span>
<span class=date unix-time="%d"></span> <span class=date unix-time="%d"></span>
@ -346,12 +307,11 @@ let view_post post_id =
</span> </span>
%s %s
</div>|} </div>|}
nick date post_id post_id post_id replies_view nick date post_id post_id post_id replies_view
in in
let post_view =
Ok Format.sprintf
(Format.sprintf {|
{|
<div class="container"> <div class="container">
<div class="post" id="%s"> <div class="post" id="%s">
%s %s
@ -360,56 +320,46 @@ let view_post post_id =
</div> </div>
</div> </div>
|} |}
post_id post_info_view image_view comment ) post_id post_info_view image_view comment
| _ -> assert false ) in
| _ -> assert false Ok post_view
let view_thread thread_id = let view_thread thread_id =
let res = Db.find_opt Q.is_thread thread_id in let** _ = Db.find_opt Q.is_thread thread_id in
match res with let* thread_posts =
| Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e)) Db.fold Q.get_thread_posts (fun post_id acc -> post_id :: acc) thread_id []
| Ok None -> Error "Not a thread" in
| Ok (Some _) -> ( (*order by date *)
let thread_posts = (*TODO do this more clean *)
Db.fold Q.get_thread_posts let dates =
(fun post_id acc -> post_id :: acc) List.map (fun post_id -> Db.find Q.get_post_date post_id) thread_posts
thread_id [] in
match List.find_opt Result.is_error dates with
| Some (Error e) -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))
| Some (Ok _) -> assert false
| None ->
let dates =
List.map
(function
| Ok date -> date
| Error _ -> assert false )
dates
in
let posts_dates = List.combine thread_posts dates in
let sorted_posts_dates =
List.sort (fun (_, a) (_, b) -> compare a b) posts_dates
in in
match thread_posts with
| Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))
| Ok thread_posts -> (
(*order by date *)
(*TODO do this more clean *)
let dates =
List.map (fun post_id -> Db.find Q.get_post_date post_id) thread_posts
in
match List.find_opt Result.is_error dates with
| Some (Error e) ->
Error (Format.sprintf "db error: %s" (Caqti_error.show e))
| Some (Ok _) -> assert false
| None ->
let dates =
List.map
(function
| Ok date -> date
| Error _ -> assert false )
dates
in
let posts_dates = List.combine thread_posts dates in
let sorted_posts_dates =
List.sort (fun (_, a) (_, b) -> compare a b) posts_dates
in
let posts, _ = List.split sorted_posts_dates in let posts, _ = List.split sorted_posts_dates in
let view_posts = List.map view_post posts in let view_posts = List.map view_post posts in
let view_posts = let view_posts =
List.map List.map
(function (function
| Ok view -> view | Ok view -> view
| Error _ -> assert false ) | Error _ -> assert false )
(List.filter Result.is_ok view_posts) (List.filter Result.is_ok view_posts)
in in
Ok (String.concat "\n\r" view_posts) ) ) Ok (String.concat "\n\r" view_posts)
let upload_post post = let upload_post post =
let post_id, parent_id, date, nick, comment, image, tags, citations, op_data = let post_id, parent_id, date, nick, comment, image, tags, citations, op_data =
@ -442,18 +392,18 @@ let upload_post post =
} -> } ->
(id, parent_id, date, nick, comment, image, tags, citations, None) (id, parent_id, date, nick, comment, image, tags, citations, None)
in in
let res_post_id = Db.exec Q.upload_post_id (post_id, nick) in let* _res_post_id = Db.exec Q.upload_post_id (post_id, nick) in
let res_comment = Db.exec Q.upload_post_comment (post_id, comment) in let* _res_comment = Db.exec Q.upload_post_comment (post_id, comment) in
let res_date = Db.exec Q.upload_post_date (post_id, date) in let* _res_date = Db.exec Q.upload_post_date (post_id, date) in
let res_thread = Db.exec Q.upload_to_thread (parent_id, post_id) in let* _res_thread = Db.exec Q.upload_to_thread (parent_id, post_id) in
let res_image = let* _res_image =
match image with match image with
| None -> Ok () | None -> Ok ()
| Some (image_name, image_content) -> | Some (image_name, image_content) ->
Db.exec Q.upload_post_image (post_id, image_name, image_content) Db.exec Q.upload_post_image (post_id, image_name, image_content)
in in
let res_parent = Db.exec Q.upload_post_parent (post_id, parent_id) in let* _res_parent = Db.exec Q.upload_post_parent (post_id, parent_id) in
let res_tags = let* _res_tags =
match match
List.find_opt Result.is_error List.find_opt Result.is_error
(List.map (fun tag -> Db.exec Q.upload_post_tag (post_id, tag)) tags) (List.map (fun tag -> Db.exec Q.upload_post_tag (post_id, tag)) tags)
@ -462,7 +412,7 @@ let upload_post post =
| Some _ -> assert false | Some _ -> assert false
| None -> Ok () | None -> Ok ()
in in
let res_citations = let* _res_citations =
match match
List.find_opt Result.is_error List.find_opt Result.is_error
(List.map (List.map
@ -473,36 +423,12 @@ let upload_post post =
| Some _ -> assert false | Some _ -> assert false
| None -> Ok () | None -> Ok ()
in in
let res = match op_data with
List.find_opt Result.is_error | None -> Ok post_id
[ res_post_id | Some (subject, lng, lat) ->
; res_comment let* _res_gps = Db.exec Q.upload_post_gps (post_id, lat, lng) in
; res_image let* _res_subject = Db.exec Q.upload_post_subject (post_id, subject) in
; res_tags Ok post_id
; res_date
; res_parent
; res_citations
; res_thread
]
in
match res with
| Some (Error e) ->
(* TODO try to remove post_id from post_user to clean db*)
Error (Format.sprintf "db error: %s" (Caqti_error.show e))
| Some _ -> assert false
| None -> (
match op_data with
| None -> Ok post_id
| Some (subject, lng, lat) -> (
let res_gps = Db.exec Q.upload_post_gps (post_id, lat, lng) in
let res_subject = Db.exec Q.upload_post_subject (post_id, subject) in
let res = List.find_opt Result.is_error [ res_gps; res_subject ] in
match res with
| Some (Error e) ->
(* TODO try to remove post_id from post_user *)
Error (Format.sprintf "db error: %s" (Caqti_error.show e))
| Some _ -> assert false
| None -> Ok post_id ) )
let make_reply ~comment ?image ~tags ~parent_id nick = let make_reply ~comment ?image ~tags ~parent_id nick =
if String.length comment > 10000 then if String.length comment > 10000 then
@ -598,36 +524,33 @@ let make_op ~comment ~image ~tags ~subject ~lat ~lng nick =
(* TODO make this return geojson directly *) (* TODO make this return geojson directly *)
let marker_list () = let marker_list () =
let thread_id_list = let* thread_id_list =
Db.fold Q.list_thread_ids (fun thread_id acc -> thread_id :: acc) () [] Db.fold Q.list_thread_ids (fun thread_id acc -> thread_id :: acc) () []
in in
match thread_id_list with let markers_res =
| Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e)) List.map
| Ok thread_id_list -> (fun thread_id ->
let markers_res = match Db.find_opt Q.get_post_gps thread_id with
List.map | Ok (Some (lat, lng)) ->
(fun thread_id -> let content =
match Db.find_opt Q.get_post_gps thread_id with match view_post thread_id with
| Ok (Some (lat, lng)) -> | Ok s -> s
let content = | Error e -> e
match view_post thread_id with in
| Ok s -> s Ok (lat, lng, content, thread_id)
| Error e -> e | Ok None -> Error "latlng not found"
in | Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))
Ok (lat, lng, content, thread_id) )
| Ok None -> Error "latlng not found" thread_id_list
| Error e -> in
Error (Format.sprintf "db error: %s" (Caqti_error.show e)) ) let markers =
thread_id_list List.map
in (function
let markers = | Ok res -> res
List.map | Error _ -> assert false )
(function (List.filter Result.is_ok markers_res)
| Ok res -> res in
| Error _ -> assert false ) Ok markers
(List.filter Result.is_ok markers_res)
in
Ok markers
let marker_to_geojson marker = let marker_to_geojson marker =
match marker with match marker with
@ -651,10 +574,5 @@ let marker_to_geojson marker =
(Float.to_string lat) (String.escaped content) thread_id (Float.to_string lat) (String.escaped content) thread_id
let get_post_image post_id = let get_post_image post_id =
let res = Db.find_opt Q.get_post_image_content post_id in let** content = Db.find_opt Q.get_post_image_content post_id in
match res with Ok content
| Ok content -> (
match content with
| Some content -> Ok (Some content)
| None -> Error "Image not found" )
| Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))

View file

@ -136,21 +136,15 @@ let plant_image request =
let nb = int_of_string (Dream.param "nb" request) in let nb = int_of_string (Dream.param "nb" request) in
let image = Plant.get_plant_image plant_id nb in let image = Plant.get_plant_image plant_id nb in
match image with match image with
| Ok (Some image) -> | Ok image -> Dream.respond ~headers:[ ("Content-Type", "image") ] image
Dream.respond ~headers:[ ("Content-Type", "image") ] image | Error _ -> Dream.empty `Not_Found
| Ok None
| Error _ ->
Dream.empty `Not_Found
let post_image request = let post_image request =
let post_id = Dream.param "post_id" request in let post_id = Dream.param "post_id" request in
let image = Babillard.get_post_image post_id in let image = Babillard.get_post_image post_id in
match image with match image with
| Ok (Some image) -> | Ok image -> Dream.respond ~headers:[ ("Content-Type", "image") ] image
Dream.respond ~headers:[ ("Content-Type", "image") ] image | Error _ -> Dream.empty `Not_Found
| Ok None
| Error _ ->
Dream.empty `Not_Found
let add_plant_get request = let add_plant_get request =
match Dream.session "nick" request with match Dream.session "nick" request with

View file

@ -1,5 +1,18 @@
open Db open Db
(* ('a option, string) result *)
let ( let** ) o f =
match o with
| Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))
| Ok None -> Error (Format.sprintf "db error: value not found")
| Ok (Some x) -> f x
(* ('a, string) result *)
let ( let* ) o f =
match o with
| Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))
| Ok x -> f x
module Q = struct module Q = struct
let create_plant_user_table = let create_plant_user_table =
Caqti_request.exec Caqti_type.unit Caqti_request.exec Caqti_type.unit
@ -118,33 +131,30 @@ let view_plant plant_id =
| Error e -> Format.sprintf "db error: %s" (Caqti_error.show e) | Error e -> Format.sprintf "db error: %s" (Caqti_error.show e)
let marker_list () = let marker_list () =
let plant_id_list = let* plant_id_list =
Db.fold Q.list_plant_ids (fun plant_id acc -> plant_id :: acc) () [] Db.fold Q.list_plant_ids (fun plant_id acc -> plant_id :: acc) () []
in in
match plant_id_list with let markers_res =
| Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e)) List.map
| Ok plant_id_list -> (fun plant_id ->
let markers_res = match Db.find_opt Q.get_plant_gps plant_id with
List.map | Ok (Some (lat, lng)) ->
(fun plant_id -> let content = view_plant plant_id in
match Db.find_opt Q.get_plant_gps plant_id with Ok (lat, lng, content)
| Ok (Some (lat, lng)) -> | Ok None -> Error "latlng not found"
let content = view_plant plant_id in | Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))
Ok (lat, lng, content) )
| Ok None -> Error "latlng not found" plant_id_list
| Error e -> in
Error (Format.sprintf "db error: %s" (Caqti_error.show e)) ) let markers =
plant_id_list List.map
in (fun res ->
let markers = match res with
List.map | Ok res -> res
(fun res -> | Error _ -> assert false )
match res with (List.filter Result.is_ok markers_res)
| Ok res -> res in
| Error _ -> assert false ) Ok markers
(List.filter Result.is_ok markers_res)
in
Ok markers
let marker_to_geojson marker = let marker_to_geojson marker =
match marker with match marker with
@ -167,6 +177,7 @@ let marker_to_geojson marker =
(Float.to_string lng) (Float.to_string lng)
(Float.to_string lat) (String.escaped content) (Float.to_string lat) (String.escaped content)
(* TODO return result *)
let view_user_plant_list nick = let view_user_plant_list nick =
let plant_id_list = let plant_id_list =
Db.fold Q.get_user_plants (fun plant_id acc -> plant_id :: acc) nick [] Db.fold Q.get_user_plants (fun plant_id acc -> plant_id :: acc) nick []
@ -178,14 +189,10 @@ let view_user_plant_list nick =
String.concat "\n" plants String.concat "\n" plants
let get_plant_image plant_id nb = let get_plant_image plant_id nb =
let res = Db.find_opt Q.get_plant_image (plant_id, nb) in let** content = Db.find_opt Q.get_plant_image (plant_id, nb) in
match res with Ok content
| Ok content -> (
match content with
| Some content -> Ok (Some content)
| None -> Error "Image not found" )
| Error e -> Error (Format.sprintf "db error: %s" (Caqti_error.show e))
(*TODO split validation and uploading to db like for babillard *)
let add_plant (lat, lng) tags files nick = let add_plant (lat, lng) tags files nick =
if String.length tags > 1000 then if String.length tags > 1000 then
Error "tags too long" Error "tags too long"