<commit_before>package com.lightningrod.dropbox;

import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.Session.AccessType;
import com.dropbox.client2.session.WebAuthSession;
import com.dropbox.client2.session.WebAuthSession.WebAuthInfo;
import com.lightningrod.app.BareBonesBrowserLaunch;
import com.lightningrod.io.FileMonitorAdvanced;
import com.lightningrod.gui.DBNode;
import java.io.*;
import java.util.AbstractMap.SimpleEntry;
import java.util.HashSet;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Convenience class for Dropbox methods.
 * @author <NAME>
 */
public class DBApi {
	final static private String APP_KEY = "icbm0h0d2th6cm5";
	final static private String APP_SECRET = "<KEY>";
	
	final static private AccessType ACCESS_TYPE = AccessType.DROPBOX;
	
        final static public String ROOT_FOLDER = "Users/bill/Downloads/testdb";
        
	private DropboxAPI<WebAuthSession> mDBApi;
	private WebAuthSession session;
	private AppKeyPair appKeys;
	private WebAuthInfo auth;
	
	private Entry root;
        private String root_drive;
        private FileMonitorAdvanced monitor;
        
        public HashSet <String>pathnames;
	
        /**
         * 
         */
        public DBApi(String rd, FileMonitorAdvanced monitor) {
		//create dropbox api and session objects based on app key/secret
		this.appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
		this.session = new WebAuthSession(appKeys, ACCESS_TYPE);
		this.mDBApi = new DropboxAPI<WebAuthSession>(session);
                this.pathnames = new HashSet<String>();
                this.root_drive = rd;
                this.monitor = monitor;
	}
	
        /**
         * Login user to Dropbox.
         * @return True if successful, false otherwise.
         */
        public boolean login() {
		if (!this.authorize()) {
			return false;
		} else {
			//TODO stop here so user can confirm app approval 
			Scanner readUserInput=new Scanner(System.in); 
			System.out.println("Press enter after "
                                + "approving Lightning Rod.");
			readUserInput.nextLine(); 
			
			return authenticate();
		}
	}
	
	private boolean authorize() {
		try {
			//construct app authorization URL
			this.auth = this.session.getAuthInfo("http://www.google.com");
			System.out.println("url: " + this.auth.url);
			//launch browser for user to approve app
			BareBonesBrowserLaunch.openURL(this.auth.url);
			
			return true;
		} catch (DropboxException ex) {
			// TODO Auto-generated catch block
			Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
			return false;
		}
		
	}
	
	private boolean authenticate() {
		try {
			session.retrieveWebAccessToken(auth.requestTokenPair);
			return true;
		} catch (DropboxException ex) {
			// TODO Auto-generated catch block
                        Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
			return false;
		}	
	}
	
        /**
         * Construct the tree, using pre-order recursive traversal.
         * @param node The Entry node used to start the traversal.
         * @return The constructed DBNode.
         */
        public DBNode treeDir(Entry node) {
		if (node == null)
			node = updateTree(node);
		else if (node.isDir)
			node = updateTree(node);
		System.out.println(node.fileName());
                //
                DBNode n = new DBNode(node); 
                //File ret = downloadFile(node);
                //if (ret != null) {
                    //this.monitor.addFile(ret, node);
                //}
		if(node.contents == null)
			return n;
		for (Entry e : node.contents) {
			//TODO construct tree for Bill
			//System.out.print("\t");
			n.add(treeDir(e));
		}
                return n;
	}
	
        //
        /**
         * Update tree from node's perspective (just one level of children).
         * @param node Entry node to update.
         * @return The updated Entry node, otherwise null.
         */
        public Entry updateTree(Entry node) {
		String path;
		if (node == null) {
			path = "/";
		} else {
			path = node.path;
			System.out.println(path);
		}
		try {
			return mDBApi.metadata(path, 0, null, true, null);
		} catch (DropboxException ex) {
			Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
			return null;
		}
	}
	
        /**
         * Update and return the root Entry node.
         * @return The updated root Entry node.
         */
        public Entry getRoot() {
            return (this.root = updateTree(root));
	}
        
        // Returns the Dropbox free space in Megabytes, or -1 if it was not
        // retrievable.
        public long getDropboxFreeSpace() {
            long freeSpace = -1L;
            try {
                freeSpace = mDBApi.accountInfo().quota -
                                (mDBApi.accountInfo().quotaNormal +
                                 mDBApi.accountInfo().quotaShared);
            } catch (DropboxException e) {
                System.out.println("Unable to retrieve Dropbox free space. "
                        + "Error: " + e.toString());
            }
            return freeSpace;
        }
        
        // Returns the root drive free space in Megabytes, or -1 if it was not
        // retrievable.
        public long getRootFreeSpace() {
            long freeSpace = -1L;
            try {
                freeSpace = (new File(root_drive)).getFreeSpace();
            } catch (SecurityException e) {
                System.out.println("Unable to retrieve root drive free space. "
                        + "Error: " + e.toString());
            }
            return freeSpace;
        }

        //
        //creates parent directories if necessary
        //return new Dropbox entry or null if failed
        /**
         * Add completely new file to Dropbox.
         * @param f The File object to add to Dropbox.
         * @return The Dropbox Entry node for the new file, or null otherwise.
         */
        public Entry addFile(File f) {
            if (f == null) 
                return null;
            String strip = root_drive + ROOT_FOLDER;
            //System.out.println(strip);
            //System.out.println(f.getAbsolutePath());
            String path = f.getAbsolutePath().replaceFirst(strip, "");
            //System.out.println(path);
            if (f.isDirectory()) {
                try {
                    Entry ret = mDBApi.createFolder(path);
                    this.monitor.addFile(f, ret);
                    pathnames.add(ret.path);
                    return ret;
                } catch (DropboxException ex) {
                    Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
            } else {
                try {
                    InputStream in = new FileInputStream(f);
                    Entry ret = mDBApi.putFile(path, in, f.length(), null, null);
                    this.monitor.addFile(f, ret);
                    pathnames.add(ret.path);
                    return ret;
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                } catch (DropboxException ex) {
                    Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
            }
        }
    
        /**
         * Update file on Dropbox based on local modification.
         * @param se Key/value pair for Dropbox Entry and File object to modify.
         * @return True if successful, false otherwise.
         */
        public boolean updateFile(SimpleEntry<Entry, File> se) {
            Entry e = se.getKey();
            File f = se.getValue();
            
            if (e == null || f == null)
                return false;
            
            if (f.isDirectory())
                return false;
            
            try {
                InputStream in = new FileInputStream(f);
                mDBApi.putFile(e.path, in, f.length(), e.rev, null);
                return true;
            } catch (FileNotFoundException ex) {
                Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                return false;
            } catch (DropboxException ex) {
                Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                return false;
            }
        }
            
        /**
         * Delete file from Dropbox's server.
         * @param node The Dropbox Entry node to delete from their server.
         * @return True if successful, false otherwise.
         */
        public boolean deleteFile(Entry node) {
            try {
                mDBApi.delete(node.path);
                return true;
            } catch (DropboxException ex) {
                Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                return false;
            }
        }
        
        /**
         * Delete file from local file system.
         * @param node The Dropbox Entry node to delete from file system.
         * @return True if successful, false otherwise.
         */
        public boolean deleteLocalFile(Entry node) {
            File f = new File(getLocalPath(node.path));
            boolean ret = f.delete();
            this.monitor.removeFile(f);
            return ret;
        }

        /**
         * Download file from Dropbox to local file system.
         * Note: Doesn't take into account whether file already exists or not.
         *      That's up to us to decide whether or not it matters.
         * @param node
         * @return File object of downloaded file, null otherwise.
         */
        public File downloadFile(Entry node) {
            if (node == null)<commit_msg>changed<commit_after>package com.lightningrod.dropbox;

import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.Session.AccessType;
import com.dropbox.client2.session.WebAuthSession;
import com.dropbox.client2.session.WebAuthSession.WebAuthInfo;
import com.lightningrod.app.BareBonesBrowserLaunch;
import com.lightningrod.io.FileMonitorAdvanced;
import com.lightningrod.gui.DBNode;
import java.io.*;
import java.util.AbstractMap.SimpleEntry;
import java.util.HashSet;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Convenience class for Dropbox methods.
 * @author <NAME>
 */
public class DBApi {
	final static private String APP_KEY = "<KEY>";
	final static private String APP_SECRET = "<KEY>";
	
	final static private AccessType ACCESS_TYPE = AccessType.DROPBOX;
	
        final static public String ROOT_FOLDER = "Users/bill/Downloads/testdb";
        
	private DropboxAPI<WebAuthSession> mDBApi;
	private WebAuthSession session;
	private AppKeyPair appKeys;
	private WebAuthInfo auth;
	
	private Entry root;
        private String root_drive;
        private FileMonitorAdvanced monitor;
        
        public HashSet <String>pathnames;
	
        /**
         * 
         */
        public DBApi(String rd, FileMonitorAdvanced monitor) {
		//create dropbox api and session objects based on app key/secret
		this.appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
		this.session = new WebAuthSession(appKeys, ACCESS_TYPE);
		this.mDBApi = new DropboxAPI<WebAuthSession>(session);
                this.pathnames = new HashSet<String>();
                this.root_drive = rd;
                this.monitor = monitor;
	}
	
        /**
         * Login user to Dropbox.
         * @return True if successful, false otherwise.
         */
        public boolean login() {
		if (!this.authorize()) {
			return false;
		} else {
			//TODO stop here so user can confirm app approval 
			Scanner readUserInput=new Scanner(System.in); 
			System.out.println("Press enter after "
                                + "approving Lightning Rod.");
			readUserInput.nextLine(); 
			
			return authenticate();
		}
	}
	
	private boolean authorize() {
		try {
			//construct app authorization URL
			this.auth = this.session.getAuthInfo("http://www.google.com");
			System.out.println("url: " + this.auth.url);
			//launch browser for user to approve app
			BareBonesBrowserLaunch.openURL(this.auth.url);
			
			return true;
		} catch (DropboxException ex) {
			// TODO Auto-generated catch block
			Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
			return false;
		}
		
	}
	
	private boolean authenticate() {
		try {
			session.retrieveWebAccessToken(auth.requestTokenPair);
			return true;
		} catch (DropboxException ex) {
			// TODO Auto-generated catch block
                        Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
			return false;
		}	
	}
	
        /**
         * Construct the tree, using pre-order recursive traversal.
         * @param node The Entry node used to start the traversal.
         * @return The constructed DBNode.
         */
        public DBNode treeDir(Entry node) {
		if (node == null)
			node = updateTree(node);
		else if (node.isDir)
			node = updateTree(node);
		System.out.println(node.fileName());
                //
                DBNode n = new DBNode(node); 
                //File ret = downloadFile(node);
                //if (ret != null) {
                    //this.monitor.addFile(ret, node);
                //}
		if(node.contents == null)
			return n;
		for (Entry e : node.contents) {
			//TODO construct tree for Bill
			//System.out.print("\t");
			n.add(treeDir(e));
		}
                return n;
	}
	
        //
        /**
         * Update tree from node's perspective (just one level of children).
         * @param node Entry node to update.
         * @return The updated Entry node, otherwise null.
         */
        public Entry updateTree(Entry node) {
		String path;
		if (node == null) {
			path = "/";
		} else {
			path = node.path;
			System.out.println(path);
		}
		try {
			return mDBApi.metadata(path, 0, null, true, null);
		} catch (DropboxException ex) {
			Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
			return null;
		}
	}
	
        /**
         * Update and return the root Entry node.
         * @return The updated root Entry node.
         */
        public Entry getRoot() {
            return (this.root = updateTree(root));
	}
        
        // Returns the Dropbox free space in Megabytes, or -1 if it was not
        // retrievable.
        public long getDropboxFreeSpace() {
            long freeSpace = -1L;
            try {
                freeSpace = mDBApi.accountInfo().quota -
                                (mDBApi.accountInfo().quotaNormal +
                                 mDBApi.accountInfo().quotaShared);
            } catch (DropboxException e) {
                System.out.println("Unable to retrieve Dropbox free space. "
                        + "Error: " + e.toString());
            }
            return freeSpace;
        }
        
        // Returns the root drive free space in Megabytes, or -1 if it was not
        // retrievable.
        public long getRootFreeSpace() {
            long freeSpace = -1L;
            try {
                freeSpace = (new File(root_drive)).getFreeSpace();
            } catch (SecurityException e) {
                System.out.println("Unable to retrieve root drive free space. "
                        + "Error: " + e.toString());
            }
            return freeSpace;
        }

        //
        //creates parent directories if necessary
        //return new Dropbox entry or null if failed
        /**
         * Add completely new file to Dropbox.
         * @param f The File object to add to Dropbox.
         * @return The Dropbox Entry node for the new file, or null otherwise.
         */
        public Entry addFile(File f) {
            if (f == null) 
                return null;
            String strip = root_drive + ROOT_FOLDER;
            //System.out.println(strip);
            //System.out.println(f.getAbsolutePath());
            String path = f.getAbsolutePath().replaceFirst(strip, "");
            //System.out.println(path);
            if (f.isDirectory()) {
                try {
                    Entry ret = mDBApi.createFolder(path);
                    this.monitor.addFile(f, ret);
                    pathnames.add(ret.path);
                    return ret;
                } catch (DropboxException ex) {
                    Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
            } else {
                try {
                    InputStream in = new FileInputStream(f);
                    Entry ret = mDBApi.putFile(path, in, f.length(), null, null);
                    this.monitor.addFile(f, ret);
                    pathnames.add(ret.path);
                    return ret;
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                } catch (DropboxException ex) {
                    Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
            }
        }
    
        /**
         * Update file on Dropbox based on local modification.
         * @param se Key/value pair for Dropbox Entry and File object to modify.
         * @return True if successful, false otherwise.
         */
        public boolean updateFile(SimpleEntry<Entry, File> se) {
            Entry e = se.getKey();
            File f = se.getValue();
            
            if (e == null || f == null)
                return false;
            
            if (f.isDirectory())
                return false;
            
            try {
                InputStream in = new FileInputStream(f);
                mDBApi.putFile(e.path, in, f.length(), e.rev, null);
                return true;
            } catch (FileNotFoundException ex) {
                Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                return false;
            } catch (DropboxException ex) {
                Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                return false;
            }
        }
            
        /**
         * Delete file from Dropbox's server.
         * @param node The Dropbox Entry node to delete from their server.
         * @return True if successful, false otherwise.
         */
        public boolean deleteFile(Entry node) {
            try {
                mDBApi.delete(node.path);
                return true;
            } catch (DropboxException ex) {
                Logger.getLogger(DBApi.class.getName()).log(Level.SEVERE, null, ex);
                return false;
            }
        }
        
        /**
         * Delete file from local file system.
         * @param node The Dropbox Entry node to delete from file system.
         * @return True if successful, false otherwise.
         */
        public boolean deleteLocalFile(Entry node) {
            File f = new File(getLocalPath(node.path));
            this.monitor.removeFile(f);
            boolean ret = f.delete();
            return ret;
        }

        /**
         * Download file from Dropbox to local file system.
         * Note: Doesn't take into account whether file already exists or not.
         *      That's up to us to decide whether or not it matters.
         * @param node
         * @return File object of downloaded file, null otherwise.
         */
        public File downloadFile(Entry node) {
            if (node == null)
{'fraction_non_alphanumeric': 0.10056699492688749, 'fraction_numerical': 0.0014423555157664378, 'mean_word_length': 1.7226811103588355, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4925199', 'n_tokens_mistral': 5753, 'n_tokens_neox': 5389, 'n_words': 1479}