2021-11-05 16:55:19 +01:00
|
|
|
let get_title content =
|
|
|
|
|
let open Soup in
|
|
|
|
|
try
|
|
|
|
|
let soup = content |> parse in
|
|
|
|
|
soup $ "h1" |> R.leaf_text
|
|
|
|
|
with
|
|
|
|
|
| Failure _e -> "Permap"
|
|
|
|
|
|
2021-11-07 10:21:01 +01:00
|
|
|
let render ?title content request =
|
2021-11-05 16:55:19 +01:00
|
|
|
let title =
|
|
|
|
|
match title with
|
|
|
|
|
| None -> get_title content
|
|
|
|
|
| Some title -> title
|
|
|
|
|
in
|
|
|
|
|
Dream.html
|
|
|
|
|
@@ Template.render_unsafe ~title:(Dream.html_escape title)
|
|
|
|
|
~content:(Dream.html_escape content)
|
2021-11-07 10:21:01 +01:00
|
|
|
request
|
2021-11-05 16:55:19 +01:00
|
|
|
|
2021-11-07 10:21:01 +01:00
|
|
|
let render_unsafe ?title content request =
|
2021-11-05 16:55:19 +01:00
|
|
|
let title =
|
|
|
|
|
match title with
|
|
|
|
|
| None -> get_title content
|
|
|
|
|
| Some title -> title
|
|
|
|
|
in
|
2021-11-07 10:21:01 +01:00
|
|
|
Dream.html @@ Template.render_unsafe ~title ~content request
|
2021-11-05 16:55:19 +01:00
|
|
|
|
|
|
|
|
let asset_loader _root path _request =
|
|
|
|
|
match Content.read ("assets/" ^ path) with
|
|
|
|
|
| None -> Dream.empty `Not_Found
|
|
|
|
|
| Some asset -> Dream.respond asset
|
|
|
|
|
|
2021-11-07 10:38:19 +01:00
|
|
|
let page name request =
|
|
|
|
|
match Content.read (name ^ ".md") with
|
2021-11-05 16:55:19 +01:00
|
|
|
| None -> Dream.empty `Not_Found
|
2021-11-07 10:38:19 +01:00
|
|
|
| Some page ->
|
|
|
|
|
let content = Omd.of_string page |> Omd.to_html in
|
|
|
|
|
render_unsafe content request
|
2021-11-05 16:55:19 +01:00
|
|
|
|
2022-02-16 17:00:29 +01:00
|
|
|
let about request = page "about" request
|
2021-11-05 16:55:19 +01:00
|
|
|
|
2021-11-07 10:21:01 +01:00
|
|
|
let register_get request = render_unsafe (Register.f request) request
|
2021-11-07 01:32:38 +01:00
|
|
|
|
|
|
|
|
let register_post request =
|
|
|
|
|
match%lwt Dream.form request with
|
|
|
|
|
| `Ok [ ("email", email); ("nick", nick); ("password", password) ] ->
|
2021-11-07 10:21:01 +01:00
|
|
|
render_unsafe (Register.f ~nick ~email ~password request) request
|
2021-11-08 15:24:10 +01:00
|
|
|
| `Ok _
|
|
|
|
|
| `Many_tokens _
|
|
|
|
|
| `Missing_token _
|
|
|
|
|
| `Invalid_token _
|
|
|
|
|
| `Wrong_session _
|
|
|
|
|
| `Expired _
|
|
|
|
|
| `Wrong_content_type ->
|
|
|
|
|
assert false
|
2021-11-07 01:32:38 +01:00
|
|
|
|
2021-11-07 10:21:01 +01:00
|
|
|
let login_get request = render_unsafe (Login.f request) request
|
2021-11-07 01:32:38 +01:00
|
|
|
|
|
|
|
|
let login_post request =
|
|
|
|
|
match%lwt Dream.form request with
|
|
|
|
|
| `Ok [ ("nick", nick); ("password", password) ] ->
|
2021-11-07 10:21:01 +01:00
|
|
|
render_unsafe (Login.f ~nick ~password request) request
|
2021-11-07 01:32:38 +01:00
|
|
|
| _ -> assert false
|
|
|
|
|
|
2022-01-14 21:36:25 +01:00
|
|
|
let user request =
|
2022-02-18 01:37:25 +01:00
|
|
|
render_unsafe (Result.fold ~ok:Fun.id ~error:Fun.id (User.list ())) request
|
2021-11-07 01:42:18 +01:00
|
|
|
|
2022-01-14 21:36:25 +01:00
|
|
|
let user_profile request =
|
|
|
|
|
render_unsafe
|
2022-02-18 01:37:25 +01:00
|
|
|
(Result.fold ~ok:Fun.id ~error:Fun.id (User.public_profile request))
|
2022-01-14 21:36:25 +01:00
|
|
|
request
|
2021-11-05 16:55:19 +01:00
|
|
|
|
2021-11-07 10:26:50 +01:00
|
|
|
let logout request =
|
|
|
|
|
let _ = Dream.invalidate_session request in
|
|
|
|
|
let content = "Logged out !" in
|
|
|
|
|
render_unsafe content request
|
|
|
|
|
|
2021-11-08 15:24:10 +01:00
|
|
|
let profile_get request =
|
|
|
|
|
match Dream.session "nick" request with
|
|
|
|
|
| None -> render_unsafe "Not logged in" request
|
|
|
|
|
| Some nick ->
|
|
|
|
|
let bio =
|
|
|
|
|
match User.get_bio nick with
|
|
|
|
|
| Ok bio -> bio
|
|
|
|
|
| Error e -> e
|
|
|
|
|
in
|
|
|
|
|
render_unsafe (User_profile.f nick bio request) request
|
2021-11-07 18:52:31 +01:00
|
|
|
|
|
|
|
|
let profile_post request =
|
2021-11-08 15:24:10 +01:00
|
|
|
match Dream.session "nick" request with
|
|
|
|
|
| None -> render_unsafe "Not logged in" request
|
|
|
|
|
| Some nick -> (
|
|
|
|
|
match%lwt Dream.form request with
|
2022-01-14 21:36:25 +01:00
|
|
|
| `Ok [ ("bio", bio) ] -> (
|
|
|
|
|
match User.update_bio bio nick with
|
|
|
|
|
| Ok () ->
|
|
|
|
|
Dream.respond ~status:`See_Other
|
|
|
|
|
~headers:[ ("Location", "/profile") ]
|
|
|
|
|
"Your bio was updated!"
|
|
|
|
|
| Error e -> render_unsafe e request )
|
2021-11-08 15:24:10 +01:00
|
|
|
| `Ok _
|
|
|
|
|
| `Many_tokens _
|
|
|
|
|
| `Missing_token _
|
|
|
|
|
| `Invalid_token _
|
|
|
|
|
| `Wrong_session _
|
|
|
|
|
| `Expired _
|
|
|
|
|
| `Wrong_content_type -> (
|
|
|
|
|
match%lwt Dream.multipart request with
|
2022-01-14 21:36:25 +01:00
|
|
|
| `Ok [ ("file", file) ] -> (
|
|
|
|
|
match User.upload_avatar file nick with
|
|
|
|
|
| Ok () ->
|
|
|
|
|
Dream.respond ~status:`See_Other
|
|
|
|
|
~headers:[ ("Location", "/profile") ]
|
|
|
|
|
"Your avatar was updated!"
|
|
|
|
|
| Error e -> render_unsafe e request )
|
2021-11-08 15:24:10 +01:00
|
|
|
| `Ok _ -> Dream.empty `Bad_Request
|
|
|
|
|
| `Expired _
|
|
|
|
|
| `Many_tokens _
|
|
|
|
|
| `Missing_token _
|
|
|
|
|
| `Invalid_token _
|
|
|
|
|
| `Wrong_session _
|
|
|
|
|
| `Wrong_content_type ->
|
|
|
|
|
Dream.empty `Bad_Request ) )
|
|
|
|
|
|
|
|
|
|
let avatar_image request =
|
|
|
|
|
let nick = Dream.param "user" request in
|
|
|
|
|
let avatar = User.get_avatar nick in
|
|
|
|
|
match avatar with
|
|
|
|
|
| Ok (Some avatar) ->
|
|
|
|
|
Dream.respond ~headers:[ ("Content-Type", "image") ] avatar
|
|
|
|
|
| Ok None
|
|
|
|
|
| Error _ -> (
|
|
|
|
|
match Content.read "/assets/img/default_avatar.png" with
|
|
|
|
|
| None -> Dream.empty `Not_Found
|
|
|
|
|
| Some avatar -> Dream.respond ~headers:[ ("Content-Type", "image") ] avatar
|
|
|
|
|
)
|
2021-11-07 10:32:17 +01:00
|
|
|
|
2021-12-29 21:07:17 +01:00
|
|
|
let post_image request =
|
|
|
|
|
let post_id = Dream.param "post_id" request in
|
2022-01-29 09:23:57 +01:00
|
|
|
let image = Babillard.get_post_image_content post_id in
|
2021-12-29 21:07:17 +01:00
|
|
|
match image with
|
2022-01-12 15:38:30 +01:00
|
|
|
| Ok image -> Dream.respond ~headers:[ ("Content-Type", "image") ] image
|
|
|
|
|
| Error _ -> Dream.empty `Not_Found
|
2021-12-29 21:07:17 +01:00
|
|
|
|
2022-02-17 03:59:23 +01:00
|
|
|
let markers request =
|
|
|
|
|
let markers = Pp_babillard.get_markers () in
|
2022-01-14 13:23:45 +01:00
|
|
|
match markers with
|
|
|
|
|
| Ok markers ->
|
|
|
|
|
Dream.respond ~headers:[ ("Content-Type", "application/json") ] markers
|
2021-12-29 21:07:17 +01:00
|
|
|
| Error e -> render_unsafe e request
|
|
|
|
|
|
2022-02-17 03:59:23 +01:00
|
|
|
let babillard_get request = render_unsafe (Babillard_page.f request) request
|
2021-12-29 21:07:17 +01:00
|
|
|
|
2022-02-17 03:59:23 +01:00
|
|
|
let newthread_get request = render_unsafe (Newthread_page.f request) request
|
2022-01-09 11:28:18 +01:00
|
|
|
|
2022-02-17 03:59:23 +01:00
|
|
|
let newthread_post request =
|
2021-12-29 21:07:17 +01:00
|
|
|
match Dream.session "nick" request with
|
|
|
|
|
| None -> render_unsafe "Not logged in" request
|
|
|
|
|
| Some nick -> (
|
|
|
|
|
match%lwt Dream.multipart request with
|
|
|
|
|
| `Ok
|
2022-01-25 14:07:28 +01:00
|
|
|
[ ("alt", [ (_, alt) ])
|
|
|
|
|
; ("file", file)
|
2021-12-29 21:07:17 +01:00
|
|
|
; ("lat_input", [ (_, lat) ])
|
|
|
|
|
; ("lng_input", [ (_, lng) ])
|
|
|
|
|
; ("subject", [ (_, subject) ])
|
|
|
|
|
; ("tags", [ (_, tags) ])
|
|
|
|
|
; ("threadComment", [ (_, comment) ])
|
2022-01-29 10:11:36 +01:00
|
|
|
] -> (
|
2021-12-29 21:07:17 +01:00
|
|
|
match (Float.of_string_opt lat, Float.of_string_opt lng) with
|
|
|
|
|
| None, _ -> render_unsafe "Invalide coordinate" request
|
|
|
|
|
| _, None -> render_unsafe "Invalide coordinate" request
|
|
|
|
|
| Some lat, Some lng -> (
|
2022-01-29 10:21:53 +01:00
|
|
|
let res =
|
|
|
|
|
match file with
|
2022-02-17 03:59:23 +01:00
|
|
|
| [] -> Babillard.make_op ~comment ~lat ~lng ~subject ~tags nick
|
2022-01-29 10:21:53 +01:00
|
|
|
| _ :: _ :: _ -> Error "More than one image"
|
|
|
|
|
| [ (image_name, image_content) ] ->
|
|
|
|
|
let image = (image_name, image_content, alt) in
|
2022-02-17 03:59:23 +01:00
|
|
|
Babillard.make_op ~comment ~image ~lat ~lng ~subject ~tags nick
|
2022-01-29 10:21:53 +01:00
|
|
|
in
|
|
|
|
|
match res with
|
|
|
|
|
| Ok thread_id ->
|
2022-02-17 03:59:23 +01:00
|
|
|
let adress = Format.asprintf "/babillard/%s" thread_id in
|
2022-01-29 10:21:53 +01:00
|
|
|
Dream.respond ~status:`See_Other
|
|
|
|
|
~headers:[ ("Location", adress) ]
|
|
|
|
|
"Your thread was posted!"
|
|
|
|
|
| Error e -> render_unsafe e request ) )
|
2021-12-29 21:07:17 +01:00
|
|
|
| `Ok _ -> Dream.empty `Bad_Request
|
|
|
|
|
| `Expired _
|
|
|
|
|
| `Many_tokens _
|
|
|
|
|
| `Missing_token _
|
|
|
|
|
| `Invalid_token _
|
|
|
|
|
| `Wrong_session _
|
|
|
|
|
| `Wrong_content_type ->
|
|
|
|
|
Dream.empty `Bad_Request )
|
|
|
|
|
|
|
|
|
|
let thread_get request =
|
|
|
|
|
let thread_id = Dream.param "thread_id" request in
|
2022-01-29 09:34:57 +01:00
|
|
|
let thread_view = Pp_babillard.view_thread thread_id in
|
2021-12-29 21:07:17 +01:00
|
|
|
match thread_view with
|
|
|
|
|
| Error e -> render_unsafe e request
|
|
|
|
|
| Ok thread_view ->
|
|
|
|
|
render_unsafe (Thread_page.f thread_view thread_id request) request
|
|
|
|
|
|
|
|
|
|
(* get thread view but not wrapped in template, so we can display it on /babillard*)
|
|
|
|
|
let thread_view request =
|
|
|
|
|
let thread_id = Dream.param "thread_id" request in
|
2022-01-29 09:34:57 +01:00
|
|
|
let thread_view = Pp_babillard.view_thread thread_id in
|
2021-12-29 21:07:17 +01:00
|
|
|
match thread_view with
|
|
|
|
|
| Error e -> render_unsafe e request
|
2022-01-10 18:39:29 +01:00
|
|
|
| Ok thread_view -> Dream.html (Thread_page.f thread_view thread_id request)
|
2021-12-29 21:07:17 +01:00
|
|
|
|
|
|
|
|
(*form to reply to a thread *)
|
2022-01-12 19:34:55 +01:00
|
|
|
let reply_post request =
|
2021-12-29 21:07:17 +01:00
|
|
|
match Dream.session "nick" request with
|
|
|
|
|
| None -> render_unsafe "Not logged in" request
|
|
|
|
|
| Some nick -> (
|
|
|
|
|
match%lwt Dream.multipart request with
|
|
|
|
|
| `Ok
|
2022-01-25 14:07:28 +01:00
|
|
|
[ ("alt", [ (_, alt) ])
|
|
|
|
|
; ("file", file)
|
2021-12-29 21:07:17 +01:00
|
|
|
; ("replyComment", [ (_, comment) ])
|
|
|
|
|
; ("tags", [ (_, tags) ])
|
2022-01-29 10:11:36 +01:00
|
|
|
] -> (
|
2021-12-29 21:07:17 +01:00
|
|
|
let parent_id = Dream.param "thread_id" request in
|
|
|
|
|
let res =
|
|
|
|
|
match file with
|
2022-01-11 15:01:59 +01:00
|
|
|
| [] -> Babillard.make_reply ~comment ~tags ~parent_id nick
|
2022-01-25 14:07:28 +01:00
|
|
|
| [ (image_name, image_content) ] ->
|
|
|
|
|
let image = (image_name, image_content, alt) in
|
|
|
|
|
Babillard.make_reply ~comment ~image ~tags ~parent_id nick
|
2021-12-29 21:07:17 +01:00
|
|
|
| _ :: _ :: _ -> Error "More than one image"
|
|
|
|
|
in
|
2022-01-10 18:39:29 +01:00
|
|
|
match res with
|
|
|
|
|
| Ok post_id ->
|
|
|
|
|
let adress = Format.sprintf "/babillard/%s#%s" parent_id post_id in
|
2022-01-17 21:55:09 +01:00
|
|
|
Dream.respond ~status:`See_Other
|
|
|
|
|
~headers:[ ("Location", adress) ]
|
2022-01-14 21:36:25 +01:00
|
|
|
"Your reply was posted!"
|
2022-01-10 18:39:29 +01:00
|
|
|
| Error e -> render_unsafe e request )
|
2021-12-29 21:07:17 +01:00
|
|
|
| `Ok _ -> Dream.empty `Bad_Request
|
|
|
|
|
| `Expired _
|
|
|
|
|
| `Many_tokens _
|
|
|
|
|
| `Missing_token _
|
|
|
|
|
| `Invalid_token _
|
|
|
|
|
| `Wrong_session _
|
|
|
|
|
| `Wrong_content_type ->
|
|
|
|
|
Dream.empty `Bad_Request )
|
|
|
|
|
|
2022-02-16 17:00:29 +01:00
|
|
|
let redirect_to_babillard _request =
|
|
|
|
|
Dream.respond ~status:`Moved_Permanently
|
|
|
|
|
~headers:[ ("Location", "/babillard") ]
|
|
|
|
|
""
|
|
|
|
|
|
2021-11-05 16:55:19 +01:00
|
|
|
let () =
|
2021-11-07 10:26:50 +01:00
|
|
|
Dream.run @@ Dream.logger @@ Dream.memory_sessions
|
2021-11-05 16:55:19 +01:00
|
|
|
@@ Dream.router
|
|
|
|
|
[ Dream.get "/assets/**" (Dream.static ~loader:asset_loader "")
|
2022-02-16 17:00:29 +01:00
|
|
|
; Dream.get "/" redirect_to_babillard
|
|
|
|
|
; Dream.get "/about" about
|
2021-11-07 01:32:38 +01:00
|
|
|
; Dream.get "/register" register_get
|
|
|
|
|
; Dream.post "/register" register_post
|
|
|
|
|
; Dream.get "/login" login_get
|
|
|
|
|
; Dream.post "/login" login_post
|
|
|
|
|
; Dream.get "/user" user
|
2021-11-07 01:42:18 +01:00
|
|
|
; Dream.get "/user/:user" user_profile
|
2021-11-08 15:24:10 +01:00
|
|
|
; Dream.get "/user/:user/avatar" avatar_image
|
2021-11-07 10:26:50 +01:00
|
|
|
; Dream.get "/logout" logout
|
2021-11-07 18:52:31 +01:00
|
|
|
; Dream.get "/profile" profile_get
|
|
|
|
|
; Dream.post "/profile" profile_post
|
2021-12-29 21:07:17 +01:00
|
|
|
; Dream.get "/thread_view/:thread_id" thread_view
|
2022-02-17 03:59:23 +01:00
|
|
|
; Dream.get "/babillard/markers" markers
|
2022-01-12 19:34:55 +01:00
|
|
|
; Dream.get "/post_pic/:post_id" post_image
|
2022-02-17 03:59:23 +01:00
|
|
|
; Dream.get "/babillard" babillard_get
|
|
|
|
|
; Dream.get "/babillard/new_thread" newthread_get
|
|
|
|
|
; Dream.post "/babillard/new_thread" newthread_post
|
2022-01-12 19:34:55 +01:00
|
|
|
; Dream.get "/babillard/:thread_id" thread_get
|
|
|
|
|
; Dream.post "/reply/:thread_id" reply_post
|
2021-12-29 21:07:17 +01:00
|
|
|
; Dream.get "/post_pic/:post_id" post_image
|
2021-11-05 16:55:19 +01:00
|
|
|
]
|
|
|
|
|
@@ Dream.not_found
|