@@ -150,32 +150,49 @@ pub fn populate_base_models(store: &impl Storelike) -> AtomicResult<()> {
150150 Ok ( ( ) )
151151}
152152
153- /// Creates a Drive resource at the base URL. Does not set rights. Use set_drive_rights for that.
154- pub fn create_drive ( store : & impl Storelike ) -> AtomicResult < ( ) > {
155- let self_url = store
156- . get_self_url ( )
157- . ok_or ( "No self_url set, cannot populate store with Drive" ) ?;
158- let mut drive = store. get_resource_new ( & self_url) ;
153+ /// Creates a Drive resource at the base URL if no name is passed.
154+ #[ tracing:: instrument( skip( store) , level = "info" ) ]
155+ pub fn create_drive (
156+ store : & impl Storelike ,
157+ drive_name : Option < & str > ,
158+ for_agent : & str ,
159+ public_read : bool ,
160+ ) -> AtomicResult < Resource > {
161+ let mut self_url = if let Some ( url) = store. get_self_url ( ) {
162+ url. to_owned ( )
163+ } else {
164+ return Err ( "No self URL set. Cannot create drive." . into ( ) ) ;
165+ } ;
166+ let drive_subject: String = if let Some ( name) = drive_name {
167+ // Let's make a subdomain
168+ let host = self_url. host ( ) . expect ( "No host in server_url" ) ;
169+ let subdomain_host = format ! ( "{}.{}" , name, host) ;
170+ self_url. set_host ( Some ( & subdomain_host) ) ?;
171+ self_url. to_string ( )
172+ } else {
173+ self_url. to_string ( )
174+ } ;
175+
176+ let mut drive = if drive_name. is_some ( ) {
177+ if store. get_resource ( & drive_subject) . is_ok ( ) {
178+ return Err ( "Drive URL is already taken" . into ( ) ) ;
179+ }
180+ Resource :: new ( drive_subject)
181+ } else {
182+ // Only for the base URL (of no drive name is passed), we should not check if the drive exists.
183+ // This is because we use `create_drive` in the `--initialize` command.
184+ store. get_resource_new ( & drive_subject)
185+ } ;
159186 drive. set_class ( urls:: DRIVE ) ;
160- let server_url = url:: Url :: parse ( store. get_server_url ( ) ) ?;
161187 drive. set_propval_string (
162188 urls:: NAME . into ( ) ,
163- server_url . host_str ( ) . ok_or ( "Can't use current base URL" ) ? ,
189+ drive_name . unwrap_or_else ( || self_url . host_str ( ) . unwrap ( ) ) ,
164190 store,
165191 ) ?;
166- drive. save_locally ( store) ?;
167- Ok ( ( ) )
168- }
169192
170- /// Adds rights to the default agent to the Drive resource (at the base URL). Optionally give Public Read rights.
171- pub fn set_drive_rights ( store : & impl Storelike , public_read : bool ) -> AtomicResult < ( ) > {
172- // Now let's add the agent as the Root user and provide write access
173- let mut drive = store. get_resource ( store. get_server_url ( ) ) ?;
174- let write_agent = store. get_default_agent ( ) ?. subject ;
175- let read_agent = write_agent. clone ( ) ;
176-
177- drive. push_propval ( urls:: WRITE , write_agent. into ( ) , true ) ?;
178- drive. push_propval ( urls:: READ , read_agent. into ( ) , true ) ?;
193+ // Set rights
194+ drive. push_propval ( urls:: WRITE , for_agent. into ( ) , true ) ?;
195+ drive. push_propval ( urls:: READ , for_agent. into ( ) , true ) ?;
179196 if public_read {
180197 drive. push_propval ( urls:: READ , urls:: PUBLIC_AGENT . into ( ) , true ) ?;
181198 }
@@ -188,8 +205,10 @@ Register your Agent by visiting [`/setup`]({}/setup). After that, edit this page
188205Note that, by default, all resources are `public`. You can edit this by opening the context menu (the three dots in the navigation bar), and going to `share`.
189206"# , store. get_server_url( ) ) , store) ?;
190207 }
208+
191209 drive. save_locally ( store) ?;
192- Ok ( ( ) )
210+
211+ Ok ( drive)
193212}
194213
195214/// Imports the Atomic Data Core items (the entire atomicdata.dev Ontology / Vocabulary)
@@ -255,9 +274,13 @@ pub fn populate_importer(store: &crate::Db) -> AtomicResult<()> {
255274 let base = store
256275 . get_self_url ( )
257276 . ok_or ( "No self URL in this Store - required for populating importer" ) ?;
258- let mut importer = Resource :: new ( urls:: construct_path_import ( & base) ) ;
277+ let mut importer = Resource :: new ( urls:: construct_path_import ( base) ) ;
259278 importer. set_class ( urls:: IMPORTER ) ;
260- importer. set_propval ( urls:: PARENT . into ( ) , Value :: AtomicUrl ( base) , store) ?;
279+ importer. set_propval (
280+ urls:: PARENT . into ( ) ,
281+ Value :: AtomicUrl ( base. to_string ( ) ) ,
282+ store,
283+ ) ?;
261284 importer. set_propval ( urls:: NAME . into ( ) , Value :: String ( "Import" . into ( ) ) , store) ?;
262285 importer. save_locally ( store) ?;
263286 Ok ( ( ) )
@@ -268,7 +291,7 @@ pub fn populate_importer(store: &crate::Db) -> AtomicResult<()> {
268291/// Useful for helping a new user get started.
269292pub fn populate_sidebar_items ( store : & crate :: Db ) -> AtomicResult < ( ) > {
270293 let base = store. get_self_url ( ) . ok_or ( "No self_url" ) ?;
271- let mut drive = store. get_resource ( & base) ?;
294+ let mut drive = store. get_resource ( base. as_str ( ) ) ?;
272295 let arr = vec ! [
273296 format!( "{}/setup" , base) ,
274297 format!( "{}/import" , base) ,
0 commit comments