Moderate amount of progress today 💯

Commit
4d38a55e52bbb88cacb8c5f5a996c7cdbfcc75bb
Author
Marius Peter <marius.peter@tutanota.com>
Author date
Committer
Marius Peter <marius.peter@tutanota.com>
Committer date
Changed files
lib/config.ml
index d47101fb..61810fa4 100644..100644
@@ -1,2 +1,2 @@
1 Removed: let git_directory = Filename.concat (Unix.getenv "HOME") "git"
1 Added: let git_directory = Filename.concat (Unix.getenv "HOME") "git.test"
2 2 let author = "Marius Peter"
lib/handlers.ml
index 3211929d..d50eca87 100644..100644
@@ -1,4 +1,3 @@
1 Removed: (* Handlers for different routes *)
2 1 let ogit_root _req = Views.Ogit_root.render () |> Dream_html.respond
3 2
4 3 let repo_root req =
@@ -7,19 +6,22 @@
7 6
8 7 let repo_tree req =
9 8 let repo_name = Dream.param req "repo_name" in
10 Removed: let dir_path = Dream.param req "**" in
9 Added: let dir_path = Dream.query req "path" |> Option.value ~default:"" in
11 10 Views.Repo_tree.render repo_name dir_path |> Dream_html.respond
12 11
13 12 let repo_blob req =
14 13 let repo_name = Dream.param req "repo_name" in
15 Removed: let blob_name = Dream.param req "blob_name" in
16 Removed: Views.Repo_blob.render repo_name blob_name |> Dream_html.respond
14 Added: let blob_path = Dream.query req "path" |> Option.value ~default:"" in
15 Added: Views.Repo_blob.render repo_name blob_path |> Dream_html.respond
17 16
18 Removed: (* Route definitions *)
19 Removed: let all_handlers = [
20 Removed: Dream.get "/" ogit_root;
21 Removed: Dream.get "/:repo_name" repo_root;
22 Removed: Dream.get "/:repo_name/tree/**" repo_tree;
23 Removed: Dream.get "/:repo_name/blob/:blob_name" repo_blob;
24 Removed: Dream.get "/static/**" (Dream.static "./lib/static");
25 Removed: ]
17 Added: let all_handlers =
18 Added: [
19 Added: Dream.get "/" ogit_root;
20 Added: Dream.scope "/:repo_name" []
21 Added: [
22 Added: Dream.get "/" repo_root;
23 Added: Dream.get "/tree" repo_tree;
24 Added: Dream.get "/blob" repo_blob;
25 Added: ];
26 Added: Dream.get "/static/**" (Dream.static "./lib/static");
27 Added: ]
lib/views.ml
index d09892b1..66218316 100644..100644
@@ -29,7 +29,8 @@
29 29 [
30 30 title [] "%s" head_data.page_title;
31 31 link [ rel "stylesheet"; href "/static/styles.css" ];
32 Removed: link [ rel "icon"; type_ "image/x-icon"; href "/static/git_icon.svg"];
32 Added: link
33 Added: [ rel "icon"; type_ "image/x-icon"; href "/static/git_icon.svg" ];
33 34 ];
34 35 body []
35 36 [
@@ -50,7 +51,7 @@
50 51 let is_active = path = current_path in
51 52 let attrs = if is_active then [ id "active" ] else [] in
52 53 let url =
53 Removed: if String.length path = 0 then Printf.sprintf "/%s" repo_path
54 Added: if String.equal path "/" then Printf.sprintf "/%s/" repo_path
54 55 else Printf.sprintf "/%s/%s" repo_path path
55 56 in
56 57 li attrs [ a [ href "%s" url ] [ txt text ] ]
@@ -61,7 +62,7 @@
61 62 ul []
62 63 @@ List.map li_of_a
63 64 [
64 Removed: ("", "summary");
65 Added: ("/", "summary");
65 66 ("refs", "refs");
66 67 ("log", "log");
67 68 ("tree", "tree");
@@ -129,15 +130,14 @@
129 130 open Dream_html
130 131 open HTML
131 132
132 Removed: let full_path repo_path dir_path =
133 Removed: Filename.concat (Filename.concat Config.git_directory repo_path) dir_path
133 Added: let full_path repo_name dir_path =
134 Added: Filename.concat (Filename.concat Config.git_directory repo_name) dir_path
134 135
135 136 (* Helper function to list contents of a given directory *)
136 Removed: let ls_dir repo_path dir_path =
137 Removed: let dir_full_path = full_path repo_path dir_path in
137 Added: let ls_dir repo_name dir_path =
138 Added: let dir_full_path = full_path repo_name dir_path in
138 139 try
139 Removed: Sys.readdir dir_full_path
140 Removed: |> Array.to_list
140 Added: Sys.readdir dir_full_path |> Array.to_list
141 141 |> List.filter (fun name -> name <> ".git") (* Exclude .git *)
142 142 |> List.map (fun entry ->
143 143 let entry_rel_path = Filename.concat dir_path entry in
@@ -145,34 +145,70 @@
145 145 (entry, entry_rel_path, Sys.is_directory full_entry_path))
146 146 |> List.sort (fun (a, _, is_dir_a) (b, _, is_dir_b) ->
147 147 match (is_dir_a, is_dir_b) with
148 Removed: | true, false -> -1 (* Directories first *)
148 Added: | true, false -> -1 (* Directories first *)
149 149 | false, true -> 1
150 150 | _ -> String.compare a b)
151 151 with Sys_error _ -> []
152 152
153 153 (* Function to create a link based on file type *)
154 Removed: let link_for_entry repo_path (entry, entry_rel_path, is_dir) =
154 Added: let link_for_entry repo_name (entry, entry_rel_path, is_dir) =
155 155 let link =
156 Removed: if is_dir then Printf.sprintf "/%s/tree/%s" repo_path entry_rel_path
157 Removed: else Printf.sprintf "/%s/blob/%s" repo_path entry_rel_path
156 Added: if is_dir then Printf.sprintf "/%s/tree?path=%s" repo_name entry_rel_path
157 Added: else Printf.sprintf "/%s/blob?path=%s" repo_name entry_rel_path
158 158 in
159 Removed: li [] [ a [ href "%s" link ] [ txt "%s" entry ] ]
159 Added: let display_name = if is_dir then entry ^ "/" else entry in
160 Added: li [] [ a [ href "%s" link ] [ txt "%s" display_name ] ]
160 161
161 Removed: (* Render function, now supporting nested directories *)
162 Removed: let render repo_path dir_path =
163 Removed: let title = Filename.concat repo_path dir_path in
164 Removed: let subtitle = "Repository Files" in
162 Added: (* Generate breadcrumb navigation for the directory path *)
163 Added: let breadcrumb_navigation repo_name dir_path =
164 Added: let parts = String.split_on_char '/' dir_path in
165 165
166 Removed: let repo_entries = ls_dir repo_path dir_path in
166 Added: let rec build_paths acc paths =
167 Added: match paths with
168 Added: | [] -> List.rev acc
169 Added: | part :: rest ->
170 Added: let new_path =
171 Added: match acc with [] -> part | _ -> List.hd acc ^ "/" ^ part
172 Added: in
173 Added: build_paths (new_path :: acc) rest
174 Added: in
175 Added:
176 Added: let breadcrumb_links =
177 Added: build_paths [] parts
178 Added: |> List.mapi (fun i path ->
179 Added: let display_name = List.nth parts i in
180 Added: a
181 Added: [ href "%s" (Printf.sprintf "/%s/tree?path=%s" repo_name path) ]
182 Added: [ txt "%s" display_name ])
183 Added: in
184 Added:
185 Added: (* Manually intersperse " / " separators *)
186 Added: let rec intersperse sep = function
187 Added: | [] -> []
188 Added: | [ x ] -> [ x ]
189 Added: | x :: xs -> x :: txt sep :: intersperse sep xs
190 Added: in
191 Added:
192 Added: match breadcrumb_links with
193 Added: | [] -> txt "/"
194 Added: | _ -> span [] (intersperse " / " breadcrumb_links)
195 Added:
196 Added: (* Render function *)
197 Added: let render repo_name dir_path =
198 Added: let title = repo_name in
199 Added: (* Only display the repo name as the title *)
200 Added: let subtitle = "Files" in
201 Added:
202 Added: let repo_entries = ls_dir repo_name dir_path in
167 203 let content =
168 204 [
169 Removed: h3 [] [ txt "%s" (Printf.sprintf "Contents of /%s" dir_path) ];
170 Removed: ul [] (List.map (link_for_entry repo_path) repo_entries);
205 Added: h3 [] [ breadcrumb_navigation repo_name dir_path ];
206 Added: ul [] (List.map (link_for_entry repo_name) repo_entries);
171 207 ]
172 208 in
173 209
174 210 let body_data =
175 Removed: { title; subtitle; topnav = Topnav.repo repo_path "tree"; content }
211 Added: { title; subtitle; topnav = Topnav.repo repo_name "tree"; content }
176 212 in
177 213 Layout.application body_data
178 214 end
@@ -187,7 +223,8 @@
187 223 let read_blob repo_path blob_name =
188 224 let file_path = Filename.concat (full_path repo_path) blob_name in
189 225 try Some (In_channel.with_open_text file_path In_channel.input_all)
190 Removed: with _ -> None (* Handle cases where the file doesn't exist or can't be read *)
226 Added: with _ ->
227 Added: None (* Handle cases where the file doesn't exist or can't be read *)
191 228
192 229 (* Render function *)
193 230 let render repo_path blob_name =
@@ -196,17 +233,25 @@
196 233
197 234 match read_blob repo_path blob_name with
198 235 | Some content ->
199 Removed: let content_display =
200 Removed: pre [] [ code [] [ txt "%s" content ] ] (* Render as code block *)
201 Removed: in
236 Added: let content_display = pre [] [ code [] [ txt "%s" content ] ] in
202 237 let body_data =
203 Removed: { title; subtitle; topnav = Topnav.repo repo_path "blob"; content = [content_display] }
238 Added: {
239 Added: title;
240 Added: subtitle;
241 Added: topnav = Topnav.repo repo_path "blob";
242 Added: content = [ content_display ];
243 Added: }
204 244 in
205 245 Layout.application body_data
206 246 | None ->
207 247 let error_message = p [] [ txt "Error: Unable to read file." ] in
208 248 let body_data =
209 Removed: { title; subtitle; topnav = Topnav.repo repo_path "blob"; content = [error_message] }
249 Added: {
250 Added: title;
251 Added: subtitle;
252 Added: topnav = Topnav.repo repo_path "blob";
253 Added: content = [ error_message ];
254 Added: }
210 255 in
211 256 Layout.application body_data
212 257 end