Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62f35d6e authored by vince-bourgmayer's avatar vince-bourgmayer
Browse files

check remoteFile Observation. Implement local file observation but there is a...

 check remoteFile Observation. Implement local file observation but there is a problem with folder for which there isn't any hash or element to now if it  has change. A temp fix has been set in CommonUtils.findDifferences. Start to implement work with operation.
parent 4c6243db
Loading
Loading
Loading
Loading
Loading

android-nc-lib @ a86f6d38

Original line number Diff line number Diff line
Subproject commit 7e1c148eea56ba0b078d41e08002de4cf7d2e084
Subproject commit a86f6d38600b74dd697bcd8ad410a93a7c4637f1
+1 −6
Original line number Diff line number Diff line
@@ -133,24 +133,19 @@ class SyncedFolderDAO {
    * @return List of all syncedFolder
    */
    List<SyncedFolder> getSyncedFolderList(String selection, String[] args) {
        Log.i(TAG, "getSyncedFolderList("+selection+", "+args+")");
        List<SyncedFolder> syncedFolders = new ArrayList<SyncedFolder>();

        Cursor cursor = mDB.query(TABLE_NAME, allColumns, selection,args, null, null,
                null);

        cursor.moveToFirst();

        while ( !cursor.isAfterLast() ) {
            SyncedFolder syncedFolder = cursorToSyncedFolder(cursor);
            if(syncedFolder == null ){
                Log.e(TAG, "getAllSyncedFolders : current Folder is null");
            }else {
            if(syncedFolder != null ){
                syncedFolders.add(syncedFolder);
            }
            cursor.moveToNext();
        }
        // assurez-vous de la fermeture du curseur
        cursor.close();
        return syncedFolders;
    }
+151 −48
Original line number Diff line number Diff line
@@ -39,11 +39,14 @@ import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.eelo.drive.database.DbHelper;
import io.eelo.drive.fileFilters.FileFilterFactory;
import io.eelo.drive.fileFilters.OnlyFileFilter;
import io.eelo.drive.models.Operation;
import io.eelo.drive.models.SyncedFolder;
import io.eelo.drive.operations.ListRemoteFileOperation_v2;
import io.eelo.drive.utils.AppConstants;
@@ -53,6 +56,7 @@ import io.eelo.drive.utils.SpecificFileGenerator;

import static com.owncloud.android.lib.resources.files.FileUtils.PATH_SEPARATOR;
import static io.eelo.drive.utils.AppConstants.INITIALIZATION_HAS_BEEN_DONE;
import static io.eelo.drive.utils.CommonUtils.getOtherPath;


/**
@@ -230,6 +234,7 @@ public class ObserverServiceV2 extends Service implements OnRemoteOperationListe
     * @return empty list if no file does not exist or if error occurs
     */
    private List<RemoteFile> loadPreviousServerContent(){
        //Code Verified!
        List<RemoteFile> result = new ArrayList<>();
        Type type = Types.newParameterizedType(List.class, RemoteFile.class);
        Moshi moshi = new Moshi.Builder().build();
@@ -247,16 +252,15 @@ public class ObserverServiceV2 extends Service implements OnRemoteOperationListe
        return result;
    }



    /**
     * Get list of file path to ignore
     * @param lookForRemotePath if true return list of remote path else a list of local path
     * @return
     */
    private ArrayList<String> getIgnoredPathList(boolean lookForRemotePath){
    private ArrayList<String> getIgnoredPathList(boolean lookForRemotePath, List<SyncedFolder> folders){
        //CODE VERIFIED!
        ArrayList<String> result = new ArrayList<>();
        for(SyncedFolder sf : DbHelper.getAllSyncedFolders(this)){
        for(SyncedFolder sf : folders){
            if(sf.isMediaType() && !CommonUtils.isMediaSyncEnabled(mAccount)){
                result.add(lookForRemotePath ? sf.getRemoteFolder() : sf.getLocalFolder());
            }else if(!sf.isMediaType() && !CommonUtils.isSettingsSyncEnabled(mAccount)){
@@ -266,10 +270,6 @@ public class ObserverServiceV2 extends Service implements OnRemoteOperationListe
        return result;
    }





    /**
     * Handle end of remote Operation
     * @param operation The RemoteOperation which ends and call this methods
@@ -277,70 +277,139 @@ public class ObserverServiceV2 extends Service implements OnRemoteOperationListe
     */
    @Override
    public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result ) {
        //CODE VERIFIED!
        Log.i( TAG, "onRemoteOperationFinish()" );
        if( operation instanceof ListRemoteFileOperation_v2){
            HashMap<String, Operation> operationList;
            final List<SyncedFolder> syncedFolders = DbHelper.getAllSyncedFolders(this);
            if( result.isSuccess() ){
                List<RemoteFile> newServerContent = new ArrayList();

                List<RemoteFile> newServerContent = new ArrayList<>();
                try {
                    newServerContent = new ArrayList((List<RemoteFile>) (List) result.getData());
                }catch (Exception e){
                    Log.e(TAG, e.toString() );
                }

                /*String displayNew = "New List before filtering: \n";
                for(RemoteFile o : resultDatas){
                    displayNew+= o.getRemotePath()+",\n";
                }
                Log.d(TAG, displayNew);

                String displayOld = " Old List before filtering: \n";*/
                List<RemoteFile> previousServerContent = loadPreviousServerContent();
                /*for(RemoteFile o : previousServerContent){
                    displayOld+= o.getRemotePath()+",\n";
                }
                Log.d(TAG, displayOld);
                List<String> pathToIgnoreList = getIgnoredPathList(true, syncedFolders);

                if(!newServerContent.isEmpty() && !previousServerContent.isEmpty()){

                Log.d(TAG, "[Before]\npath to ignore: "+pathToIgnoreList);*/
                List<String> pathToIgnoreList = getIgnoredPathList(true);
                    if( previousServerContent.get(0).getHash().equals(newServerContent.get(0).getHash() ) ){
                        pathToIgnoreList.add(previousServerContent.get(0).getPath());
                        previousServerContent.clear();
                        newServerContent.clear();
                    }else {
                        previousServerContent.remove(0);
                        newServerContent.remove(0);
                        CommonUtils.findDifferences(pathToIgnoreList, previousServerContent, newServerContent);

                /*Log.d(TAG, "[After]\npath to ignore: "+pathToIgnoreList);
                displayNew = "New List after filtering: \n";
                for(RemoteFile o : resultDatas){
                    displayNew+= o.getRemotePath()+",\n";
                    }
                Log.d(TAG, displayNew);

                 displayOld = " Old List after filtering: \n";
                for(RemoteFile o : previousServerContent){
                    displayOld+= o.getRemotePath()+",\n";
                }
                Log.d(TAG, displayOld);*/

                //@TODO need to look for folder inside OldOperation and new Operation (question when folder creation  ?, how to differenciate really new folder  from modified folder ?)


                /*String displayOperationList ="OperationList: \n";
                for(Map.Entry<String, Operation> entry : operationList.entrySet()){
                    displayOperationList+= entry.getKey()+", "+entry.getValue().getOperationCode()+",\n";
                }
                Log.d(TAG, displayOperationList);*/
                SpecificFileGenerator.saveServerContentToInternalFile(this, (List<RemoteFile>) (List) result.getData());
                operationList = buildRemoteOperationList(newServerContent, previousServerContent, syncedFolders);
            }else {
                operationList = new HashMap<>();

            }
            this.startLocalScan();
            this.startLocalScan(syncedFolders, operationList);
            this.stopSelf();
        }
    }


    /**
     *  Change the list obtained from scanning phone or server into a list of operation todo
     * Todo:
     *  - implement the "catch(Exception)" around getCanonicalPath.
     *
     * @return HashMap<String, Operation>
     */
    public HashMap<String, Operation> buildRemoteOperationList(List<RemoteFile> newList, List<RemoteFile> oldList, List<SyncedFolder> initialFolder){
        //Code nearly OK. just Missing Folder creation/deletion

        HashMap<String, Operation> operationToDo = new HashMap<String, Operation>();
        //Handle change found on server
        for(RemoteFile r : newList){
            if(!r.getMimeType().equals("DIR")) { //No need to handle "DIR" type because they will be automaticaly added when creating new File
                operationToDo.put(getOtherPath(r, initialFolder), new Operation(r, Operation.OPERATION_DOWNLOAD)); //May be replace getOtherPath by r.getRemotePath
                //System.out.println(getOtherPath(r));
            }
        }

        for(RemoteFile r : oldList){
            operationToDo.put(getOtherPath(r, initialFolder), new Operation( r, Operation.OPERATION_REMOVE_LOCAL)); //May be replace getOtherPath by r.getRemotePath
            //System.out.println(getOtherPath(r));
        }

        return operationToDo;
    }





    /* end of methods related to server scanning */

    /* Methods related to device Scanning */

    public void startLocalScan(){

    /**TODO: don't forget to add operationList **/
    public void startLocalScan(List<SyncedFolder> initialFolder, HashMap<String, Operation> operationToDo){
        if(CommonUtils.isSettingsSyncEnabled(mAccount) ) SpecificFileGenerator.writeAppListFile(this);
        List<SynchronizableFileInfo> newDeviceContent = readLocalFilesInfo();

        List<SynchronizableFileInfo> newDeviceContent = readLocalFilesInfo();
        List<SynchronizableFileInfo> oldDeviceContent = loadPreviousDeviceContent();
        List<String> pathListToIgnore = getIgnoredPathList(false, initialFolder);

        List<String> pathListToIgnore = getIgnoredPathList(false);
            //Just display
            String displayNew = " New List before filtering: \n";
            for(SynchronizableFileInfo o : newDeviceContent){
                displayNew+= o.getPath()+", "+o.getLastModified()+"\n";
            }

            String displayOld = " Old List before filtering: \n";
            for(SynchronizableFileInfo o : oldDeviceContent){
                displayOld+= o.getPath()+", "+o.getLastModified()+",\n";
            }

            Log.d(TAG, displayNew);
            Log.d(TAG, displayOld);
            Log.d(TAG, "[Before] path to ignore: \n"+pathListToIgnore);
        SpecificFileGenerator.saveDeviceContentToInternalFile(this, new ArrayList<SynchronizableFileInfo>( newDeviceContent));

        if(!newDeviceContent.isEmpty() && !oldDeviceContent.isEmpty()){

            CommonUtils.findDifferences(pathListToIgnore, oldDeviceContent, newDeviceContent);

                //Just display
                displayNew = " New List after filtering: \n";
                for(SynchronizableFileInfo o : newDeviceContent){
                    displayNew+= o.getPath()+","+o.getLastModified()+"\n";
                }

                displayOld = " Old List after filtering: \n";
                for(SynchronizableFileInfo o : oldDeviceContent){
                    displayOld+= o.getPath()+","+o.getLastModified()+"\n";
                }
                Log.d(TAG, displayOld);
                Log.d(TAG, displayNew);
                Log.d(TAG, "[After]path to ignore: \n"+pathListToIgnore);
        }

         buildLocalOperationList(newDeviceContent, oldDeviceContent, initialFolder, operationToDo);


    }

    /**
@@ -352,7 +421,6 @@ public class ObserverServiceV2 extends Service implements OnRemoteOperationListe
        Type type = Types.newParameterizedType(List.class, SynchronizableFileInfo.class);
        Moshi moshi = new Moshi.Builder().build();
        JsonAdapter<List<SynchronizableFileInfo>> jsonAdapter = moshi.adapter(type);

        try{
            String filePath = getFilesDir().getCanonicalPath() + PATH_SEPARATOR + AppConstants.DEVICE_CONTENT_FILE_NAME;
            if(new File(filePath).exists()) {
@@ -365,10 +433,12 @@ public class ObserverServiceV2 extends Service implements OnRemoteOperationListe
        return result;
    }




    /**
     * Get list of all file on device
     * @return
     */
    public List<SynchronizableFileInfo>  readLocalFilesInfo(){
        Log.i(TAG, "readLocalFilesInfo()");
        ArrayList<SynchronizableFileInfo> fileInfos = new ArrayList<>();
        List<SyncedFolder> mSyncedFolders;
        boolean mediaSyncEnabled = CommonUtils.isMediaSyncEnabled(mAccount);
@@ -384,18 +454,51 @@ public class ObserverServiceV2 extends Service implements OnRemoteOperationListe
            mSyncedFolders = new ArrayList<SyncedFolder>();
        }
        for(SyncedFolder root : mSyncedFolders){

            File rootFile = new File(root.getLocalFolder()+PATH_SEPARATOR);
            Log.d(TAG, "readLocalFilesInfo()"+rootFile.getAbsolutePath());


            FileFilter filter = FileFilterFactory.getFileFilter(root.getLibelle());
            fileInfos.addAll( CommonUtils.getSubFiles(rootFile, filter) );

        }
        return fileInfos;
    }

    /**
     *  Change the list obtained from scanning phone or server into a list of operation todo
     * Todo:
     *  - implement the "catch(Exception)" around getCanonicalPath.
     *
     * @return HashMap<String, Operation>
     */
    public HashMap<String, Operation> buildLocalOperationList(List<SynchronizableFileInfo> newList, List<SynchronizableFileInfo> oldList, List<SyncedFolder> initialFolder, HashMap<String, Operation> operationsToDo){
        //Code nearly OK. just Missing Folder creation/deletion

        //Handle change found on device
        for(SynchronizableFileInfo sf : newList){
            try {
                String localPath = sf.getPath();
                Operation operation = operationsToDo.get(localPath);
                if (operation != null && operation.getFile().getLastModified() <= sf.getLastModified()) {
                    operationsToDo.remove(localPath);
                    operationsToDo.put(getOtherPath(sf, initialFolder), new Operation(sf, sf.isDir()? Operation.OPERATION_MKCOL:Operation.OPERATION_UPLOAD));
                }
            }catch(Exception e){
                //Todo
            }
        }

        for(SynchronizableFileInfo sf : oldList){
            try {
                String localPath = sf.getPath();
                Operation operation = operationsToDo.get(localPath);
                if (operation != null && operation.getFile().getLastModified() <= sf.getLastModified()) {
                    operationsToDo.remove(localPath);
                    operationsToDo.put(getOtherPath(sf, initialFolder), new Operation(sf, Operation.OPERATION_REMOVE_REMOTE));
                }
            }catch(Exception e){
                //Todo
            }
        }
        return operationsToDo;
    }



+37 −18
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.util.Log;
import android.webkit.MimeTypeMap;
import com.owncloud.android.lib.resources.files.FileUtils;
import com.owncloud.android.lib.resources.files.model.ISynchronizableContent;
import com.owncloud.android.lib.resources.files.model.RemoteFile;
import com.owncloud.android.lib.resources.files.model.SynchronizableFileInfo;

import java.io.File;
@@ -35,6 +36,7 @@ import java.util.List;
import java.util.ListIterator;


import io.eelo.drive.models.SyncedFolder;
import io.eelo.drive.receivers.ScreenOffReceiver;

import static io.eelo.drive.utils.AppConstants.MEDIASYNC_PROVIDER_AUTHORITY;
@@ -51,18 +53,6 @@ public abstract class CommonUtils {

    public static void findDifferences(List<String> pathListToIgnore, List<? extends ISynchronizableContent> oldList, List<? extends ISynchronizableContent> newList){

        if(newList.isEmpty() || oldList.isEmpty()) return;

        if(oldList.get(0).getHash().equals(newList.get(0).getHash() )){
            pathListToIgnore.add(oldList.get(0).getPath());
            oldList.clear();
            newList.clear();
            return;
        }

        oldList.remove(0);
        newList.remove(0);

        ListIterator<? extends ISynchronizableContent> oldIterator = oldList.listIterator();
        boolean equivalentFound =false;
        boolean ignoreOld = false;
@@ -99,7 +89,10 @@ public abstract class CommonUtils {
                        //This is a folder
                        if (oldversion.getHash().equals(newVersion.getHash())) {
                            //Which hasn't change'
                            pathListToIgnore.add(oldPath);
                            //@todo: The if for class is temporal fix while looking for how to find changed directory
                            //when content change two or more subfile deeper.

                            if(oldversion.getClass().equals(RemoteFile.class) ) pathListToIgnore.add(oldPath);
                        }
                        newIterator.remove();
                        oldIterator.remove();
@@ -347,13 +340,39 @@ public abstract class CommonUtils {
        ArrayList<SynchronizableFileInfo> inFiles = new ArrayList<>();
        inFiles.add(new SynchronizableFileInfo( rootDir ));

        for (File file : rootDir.listFiles(filter) ) {
        File[] subFileList = rootDir.listFiles(filter);
        if(subFileList!= null) {
            for (File file : subFileList) {
                if (file.isDirectory()) {
                    inFiles.addAll(getSubFiles(file, filter));
                } else {
                    inFiles.add(new SynchronizableFileInfo(file));
                }
            }
        }
        return inFiles;
    }

    public static String getOtherPath(@NonNull ISynchronizableContent file, List<SyncedFolder> initialFolder) throws IllegalArgumentException{
        if(file == null) throw new IllegalArgumentException();

        String path  = file.getPath();
        if(path == null) throw new IllegalArgumentException();

        for(SyncedFolder sf : initialFolder){
            String FolderPath;
            String newPath;
            if(file.getClass().equals(SynchronizableFileInfo.class) ){
                FolderPath = sf.getLocalFolder();
                newPath = sf.getRemoteFolder();
            }else{
                FolderPath = sf.getRemoteFolder();
                newPath = sf.getLocalFolder();
            }
            if(path.startsWith(FolderPath)){
                return newPath+path.substring( FolderPath.length(), path.length());
            }
        }
        return null;
    }
}
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ public class SpecificFileGenerator {
     * @param deviceContent List<RemoteFile> got from server
     */
    public static boolean saveDeviceContentToInternalFile(Context context, List<SynchronizableFileInfo> deviceContent){
        Log.i(TAG, "saveServerContentToInternalFile(...)");
        Log.i(TAG, "saveDeviceContentToInternalFile(...)");
        Type type = Types.newParameterizedType(List.class, SynchronizableFileInfo.class);
        Moshi moshi = new Moshi.Builder().build();
        JsonAdapter<List<SynchronizableFileInfo>> jsonAdapter = moshi.adapter(type);
Loading