@@ -151,32 +151,49 @@ pub fn populate_base_models(store: &impl Storelike) -> AtomicResult<()> {
151151 Ok ( ( ) )
152152}
153153
154- /// Creates a Drive resource at the base URL. Does not set rights. Use set_drive_rights for that.
155- pub fn create_drive ( store : & impl Storelike ) -> AtomicResult < ( ) > {
156- let self_url = store
157- . get_self_url ( )
158- . ok_or ( "No self_url set, cannot populate store with Drive" ) ?;
159- let mut drive = store. get_resource_new ( & self_url) ;
154+ /// Creates a Drive resource at the base URL if no name is passed.
155+ #[ tracing:: instrument( skip( store) , level = "info" ) ]
156+ pub fn create_drive (
157+ store : & impl Storelike ,
158+ drive_name : Option < & str > ,
159+ for_agent : & str ,
160+ public_read : bool ,
161+ ) -> AtomicResult < Resource > {
162+ let mut self_url = if let Some ( url) = store. get_self_url ( ) {
163+ url. to_owned ( )
164+ } else {
165+ return Err ( "No self URL set. Cannot create drive." . into ( ) ) ;
166+ } ;
167+ let drive_subject: String = if let Some ( name) = drive_name {
168+ // Let's make a subdomain
169+ let host = self_url. host ( ) . expect ( "No host in server_url" ) ;
170+ let subdomain_host = format ! ( "{}.{}" , name, host) ;
171+ self_url. set_host ( Some ( & subdomain_host) ) ?;
172+ self_url. to_string ( )
173+ } else {
174+ self_url. to_string ( )
175+ } ;
176+
177+ let mut drive = if drive_name. is_some ( ) {
178+ if store. get_resource ( & drive_subject) . is_ok ( ) {
179+ return Err ( "Drive URL is already taken" . into ( ) ) ;
180+ }
181+ Resource :: new ( drive_subject)
182+ } else {
183+ // Only for the base URL (of no drive name is passed), we should not check if the drive exists.
184+ // This is because we use `create_drive` in the `--initialize` command.
185+ store. get_resource_new ( & drive_subject)
186+ } ;
160187 drive. set_class ( urls:: DRIVE ) ;
161- let server_url = url:: Url :: parse ( store. get_server_url ( ) ) ?;
162188 drive. set_propval_string (
163189 urls:: NAME . into ( ) ,
164- server_url . host_str ( ) . ok_or ( "Can't use current base URL" ) ? ,
190+ drive_name . unwrap_or_else ( || self_url . host_str ( ) . unwrap ( ) ) ,
165191 store,
166192 ) ?;
167- drive. save_locally ( store) ?;
168- Ok ( ( ) )
169- }
170193
171- /// Adds rights to the default agent to the Drive resource (at the base URL). Optionally give Public Read rights.
172- pub fn set_drive_rights ( store : & impl Storelike , public_read : bool ) -> AtomicResult < ( ) > {
173- // Now let's add the agent as the Root user and provide write access
174- let mut drive = store. get_resource ( store. get_server_url ( ) ) ?;
175- let write_agent = store. get_default_agent ( ) ?. subject ;
176- let read_agent = write_agent. clone ( ) ;
177-
178- drive. push_propval ( urls:: WRITE , write_agent. into ( ) , true ) ?;
179- drive. push_propval ( urls:: READ , read_agent. into ( ) , true ) ?;
194+ // Set rights
195+ drive. push_propval ( urls:: WRITE , for_agent. into ( ) , true ) ?;
196+ drive. push_propval ( urls:: READ , for_agent. into ( ) , true ) ?;
180197 if public_read {
181198 drive. push_propval ( urls:: READ , urls:: PUBLIC_AGENT . into ( ) , true ) ?;
182199 }
@@ -189,8 +206,10 @@ Register your Agent by visiting [`/setup`]({}/setup). After that, edit this page
189206Note 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`.
190207"# , store. get_server_url( ) ) , store) ?;
191208 }
209+
192210 drive. save_locally ( store) ?;
193- Ok ( ( ) )
211+
212+ Ok ( drive)
194213}
195214
196215/// Imports the Atomic Data Core items (the entire atomicdata.dev Ontology / Vocabulary)
@@ -251,9 +270,13 @@ pub fn populate_importer(store: &crate::Db) -> AtomicResult<()> {
251270 let base = store
252271 . get_self_url ( )
253272 . ok_or ( "No self URL in this Store - required for populating importer" ) ?;
254- let mut importer = Resource :: new ( urls:: construct_path_import ( & base) ) ;
273+ let mut importer = Resource :: new ( urls:: construct_path_import ( base) ) ;
255274 importer. set_class ( urls:: IMPORTER ) ;
256- importer. set_propval ( urls:: PARENT . into ( ) , Value :: AtomicUrl ( base) , store) ?;
275+ importer. set_propval (
276+ urls:: PARENT . into ( ) ,
277+ Value :: AtomicUrl ( base. to_string ( ) ) ,
278+ store,
279+ ) ?;
257280 importer. set_propval ( urls:: NAME . into ( ) , Value :: String ( "Import" . into ( ) ) , store) ?;
258281 importer. save_locally ( store) ?;
259282 Ok ( ( ) )
@@ -264,7 +287,7 @@ pub fn populate_importer(store: &crate::Db) -> AtomicResult<()> {
264287/// Useful for helping a new user get started.
265288pub fn populate_sidebar_items ( store : & crate :: Db ) -> AtomicResult < ( ) > {
266289 let base = store. get_self_url ( ) . ok_or ( "No self_url" ) ?;
267- let mut drive = store. get_resource ( & base) ?;
290+ let mut drive = store. get_resource ( base. as_str ( ) ) ?;
268291 let arr = vec ! [
269292 format!( "{}/setup" , base) ,
270293 format!( "{}/import" , base) ,
0 commit comments