package peergos.shared.user;

import java.nio.file.*;

/** This class stores locations of the different components of a user's profile
 *
 *  Each component is a separate file and can thus be shared or made public individually.
 */
public class ProfilePaths {

    public static final Path ROOT = Paths.get(".profile");
    private static final Path PHOTO = ROOT.resolve("photo");
    public static final Path PHOTO_HIGH_RES = PHOTO.resolve("highres");
    public static final Path BIO = ROOT.resolve("bio");
    public static final Path STATUS = ROOT.resolve("status");
    public static final Path FIRSTNAME = ROOT.resolve("firstname");
    public static final Path LASTNAME = ROOT.resolve("lastname");
    public static final Path PHONE = ROOT.resolve("phone");
    public static final Path EMAIL = ROOT.resolve("email");
    public static final Path WEBROOT = ROOT.resolve("webroot"); // The path in Peergos to this users web root

}

@@ -34,21 +34,165 @@
 ort 
-java.nio.file
+peergos.shared.user.fs.*;%0Aimport peergos.shared.util.*;%0A%0Aimport java.nio.file.*;%0Aimport java.util.*;%0Aimport java.util.concurrent.*;%0Aimport java.util.function
 .*;%0A
@@ -1073,10 +1073,1782 @@
 b root%0A%0A
+    private static %3CV%3E CompletableFuture%3COptional%3CV%3E%3E getAndParse(Path p, Function%3Cbyte%5B%5D, V%3E parser, UserContext viewer) %7B%0A        return viewer.getByPath(p)%0A                .thenCompose(opt -%3E opt.map(f -%3E Serialize.readFully(f, viewer.crypto, viewer.network)%0A                        .thenApply(parser)%0A                        .thenApply(Optional::of))%0A                        .orElse(Futures.of(Optional.empty())));%0A    %7D%0A%0A    private static %3CV%3E CompletableFuture%3CBoolean%3E serializeAndSet(Path p, V val, Function%3CV, byte%5B%5D%3E serialize, UserContext user) %7B%0A        byte%5B%5D raw = serialize.apply(val);%0A        return user.getUserRoot()%0A                .thenCompose(home -%3E home.getOrMkdirs(p.getParent(), user.network, true, user.crypto))%0A                .thenCompose(parent -%3E parent.uploadOrReplaceFile(p.getFileName().toString(),%0A                        AsyncReader.build(raw), raw.length, user.network, user.crypto, x -%3E %7B%7D,%0A                        user.crypto.random.randomBytes(RelativeCapability.MAP_KEY_LENGTH)))%0A                .thenApply(x -%3E true);%0A    %7D%0A%0A    public static CompletableFuture%3COptional%3Cbyte%5B%5D%3E%3E getProfilePhoto(String user, UserContext viewer) %7B%0A        return getAndParse(Paths.get(user).resolve(PHOTO_HIGH_RES), x -%3E x, viewer);%0A    %7D%0A%0A    public static CompletableFuture%3CBoolean%3E setProfilePhoto(UserContext user, byte%5B%5D image) %7B%0A        return serializeAndSet(PHOTO_HIGH_RES, image, x -%3E x, user);%0A    %7D%0A%0A    public static CompletableFuture%3COptional%3CString%3E%3E getBio(String user, UserContext viewer) %7B%0A        return getAndParse(Paths.get(user).resolve(BIO), String::new, viewer);%0A    %7D%0A%0A    public static CompletableFuture%3CBoolean%3E setBio(UserContext user, String bio) %7B%0A        return serializeAndSet(BIO, bio, String::getBytes, user);%0A    %7D%0A
 %7D%0A

Implement first few methods for managing profile data