-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfiles.eliom
157 lines (134 loc) · 5.51 KB
/
files.eliom
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
[%%shared
open Lwt
open Eliom_lib
open Eliom_content
]
module Files(E:App_stub.ENV) : App_stub.FILES with type volume = E.Data.volume = struct
open E.Data
type volume = E.Data.volume
let serv_volume = Hashtbl.create 10
exception Volume_unknown_to_files of string
let service =
Eliom_service.App.service
~path: ["v"]
~get_params: Eliom_parameter.(suffix @@ string "volume") ()
let service_for_volume n =
try
Hashtbl.find serv_volume (E.Data.volume_id n)
with
| Not_found -> raise (Volume_unknown_to_files (E.Data.volume_id n))
let () =
Eliom_registration.Any.register
~service
(fun (volume_id:string) () ->
try%lwt
let open Widgets in
let volume = E.Data.volume_from_id volume_id in
let current_folder_client = Eliom_react.Up.create (Eliom_parameter.ocaml "a" Deriving_Json.Json_string.t) in
let current_folder, current_folder_send = React.S.create "" in
(* FIXME: that's a memory leak, we need to figure out how to keep it in the closure of the user session *)
let () =
Eliom_react.Up.to_react current_folder_client
|> React.E.map current_folder_send
|> Lwt_react.E.keep in
let whole_file_list = E.Data.volume_list_files volume in
let file_list =
let open Shared in
(* combining the two signals: either the file list changed, or the current folder changed *)
React.S.l2 (fun a b ->
List.filter (fun f ->
Shared.file_parent_path f = b) a
) whole_file_list current_folder
|> Eliom_react.S.Down.of_react
in
let (volume_service:App_stub.path_service) = service_for_volume volume in
let file_list = [%client
React.S.map (fun l ->
let all_files =
l |> List.map (fun s ->
let open Shared in
if not s.is_folder then
let serv = (Eliom_service.preapply ~service:~%volume_service [s.name]) in
Html5.F.li [Html5.F.(a ~service:serv [pcdata s.name] ())]
else
let link = Widgets.C.link (fun () ->
~%current_folder_client s.name
) [Html5.F.(pcdata s.name)] in
Html5.F.li [link]
)
in
let top = Widgets.C.link (fun () ->
~%current_folder_client ""
) [Html5.F.(pcdata "..")] in
Html5.F.li [top] :: all_files
) ~%file_list
|> React.S.map (fun l ->
Widgets.F.list_view l)
|> Html5.R.node]
in
let ev = Eliom_react.S.Down.of_react Devices.all_devices in
let (ul: Widgets.div_content
Eliom_pervasives.client_value) = [%client
React.S.map (fun l ->
List.map (fun l -> Html5.F.(li [span [pcdata l]])) l) ~%ev
|>
React.S.map (fun l -> Widgets.F.list_view l)
|> Html5.R.node]
in
E.F.main_box_sidebar [Widgets.F.two_panes (Html5.C.node file_list) (Html5.C.node ul)]
>>= E.Config.App.send ~headers:Http_headers.(add (name "Cache-Control") "max-age=6000" empty)
with
| E.Data.Volume_not_found _ ->
E.F.main_box [Html5.F.p [Html5.F.pcdata "This volume does not seem to exist."]]
>>= E.Config.App.send ~headers:Http_headers.(add (name "Cache-Control") "max-age=6000" empty)
)
let register_service_for_volume n =
Eliom_service.preapply ~service (E.Data.volume_id n)
|> E.Mimes.register_public ("volume: " ^ E.Data.volume_id n)
let on_new_volume vol =
if public_volume vol then
(* FIXME: Check if this path is available. This service needs to be saved in
* order to be deleted afterwards. *)
let service = Eliom_service.App.service
~path:["f";volume_id vol]
~get_params:Eliom_parameter.(suffix (all_suffix "path"))
()
in
Eliom_registration.File.register
~service
(fun s () ->
let s = Ocsigen_lib_base.Url_base.remove_dotdot s in
return (volume_path vol ^ Ocsigen_lib.Url.string_of_url_path ~encode:false s));
Hashtbl.add serv_volume (E.Data.volume_id vol) service
;
register_service_for_volume vol
let download_path vol filename =
[filename]
let _ =
let _ = List.map on_new_volume (React.S.value E.Data.all_volumes) in
React.E.map on_new_volume E.Data.new_volume_loaded
|> Lwt_react.E.keep
let () =
E.Mimes.register_sidebar "volumes" (fun () ->
let all_volumes_ev =
React.S.map (fun all_volumes ->
List.map E.Data.volume_id all_volumes) E.Data.all_volumes
|> Eliom_react.S.Down.of_react in
let volume_list =
[%client
let v:Html5_types.div_content_fun Eliom_content.Html5.F.elt =
~%all_volumes_ev
|> React.S.map (fun all_volumes ->
all_volumes
|> List.map (fun l ->
let service = Eliom_service.preapply ~%service l in
Html5.F.(li [a ~service [pcdata l] ()]))
|> Widgets.F.list_view)
|> Html5.R.node
in
v
] |> Html5.C.node
in
let h:Html5_types.div_content_fun Eliom_content.Html5.F.elt = Html5.F.(h1 [pcdata "volumes"]) in
Lwt.return Html5.F.(div [h; volume_list]))
end