/** * */ package sd.rest.dropbox; import static java.lang.System.out; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.net.MalformedURLException; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.text.ParseException; import java.util.Iterator; import java.util.Scanner; import java.util.TreeSet; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.scribe.builder.ServiceBuilder; import org.scribe.builder.api.DropBoxApi; import org.scribe.model.OAuthRequest; import org.scribe.model.Response; import org.scribe.model.Token; import org.scribe.model.Verb; import org.scribe.model.Verifier; import org.scribe.oauth.OAuthService; import sd.Utilities; import sd.exceptions.NoSuchServerException; import sd.files.EJSONObjectType; import sd.files.FileData; import sd.files.FileInfo; import sd.files.exceptions.FileNotFoundException; import sd.files.exceptions.NoSuchPathException; import sd.rmi.server.Server; /** * Classe que implementa um proxy sobre o servico da Dropbox */ public class DropboxProxy extends Server { private static final String API_KEY = "ximqd3e0gbem0oj"; private static final String API_SECRET = "vmgjflex20o9gyv"; private static final String SCOPE = "app folder"; private static final String AUTHORIZE_URL = "https://www.dropbox.com/1/oauth/authorize?oauth_token="; // private static final String API_KEY = "edy327k7yo0uoze"; // private static final String API_SECRET = "nwyuk7lmqu056jh"; // private static final String SCOPE = "app folder"; // private static final String AUTHORIZE_URL = "https://www.dropbox.com/1/oauth/authorize?oauth_token="; private static final String CONTEXT = "sandbox"; private static final long serialVersionUID = 1147109062589751462L; private OAuthService service; private Token accessToken, requestToken; private JSONParser parser; private static final String typeOfServer= "PROXY"; public final String getType(){ return typeOfServer; } /** * Método que obtem a "autorizacao" para os pedidos. */ private void getAuthorization() { this.service = new ServiceBuilder().provider(DropBoxApi.class).apiKey(API_KEY) .apiSecret(API_SECRET).scope(SCOPE).build(); Scanner in = new Scanner( System.in ); //TODO: ERRO! requestToken = service.getRequestToken(); Verifier verifier = new Verifier(""); // Process browser = Runtime.getRuntime().exec( AUTHORIZE_URL + requestToken.getToken() ); // browser.waitFor(); System.out.println("Autorizacao sobre " + AUTHORIZE_URL + requestToken.getToken() + " e depois pressione [enter]." ); in.nextLine(); verifier = new Verifier( requestToken.getSecret() ); this.accessToken = service.getAccessToken( requestToken, verifier ); } /** * Construtor */ public DropboxProxy(String local_name, String path) throws RemoteException, NullPointerException, MalformedURLException { super(local_name, path); getAuthorization(); this.parser = new JSONParser(); // TODO Verificar se e necessario alguma alteracao adicional sobre o sistema. } /** * Construtor */ public DropboxProxy(String name, String path, String remote_server) throws RemoteException, MalformedURLException, NotBoundException { super(name, path, remote_server); getAuthorization(); this.parser = new JSONParser(); // TODO Verificar se e necessario alguma alteracao adicional sobre o sistema. } /** * Método que obtém a informação sobre determinado ficheiro de nome filename * @param filename - nome do ficheiro a obter informação * @return retval - informação sobre determinado ficheiro */ @Override public FileInfo do_getAttr( String filename ) throws RemoteException { FileInfo retval = null; Response response = null; String p=""; if(current_path.equals(".")) p="/"+filename; OAuthRequest request = new OAuthRequest( Verb.GET, "https://api.dropbox.com/1/metadata/"+ CONTEXT + p ); this.service.signRequest( this.accessToken, request ); response = request.send(); if ( 404 == response.getCode() ) { System.out.println( "[ erro@DropboxProxy.do_getAttr ] : ("+ response.getCode()+") "+ response.getBody() ); throw new FileNotFoundException( response.getBody() ); } else if ( 200 != response.getCode() ) { System.out.println( "[ erro@DropboxProxy.do_getAttr ] : ("+ response.getCode()+") "+ response.getBody() ); throw new RemoteException( response.getCode() + response.getBody() ); } try { retval = new FileInfo( (JSONObject)parser.parse( response.getBody() ), EJSONObjectType.DROPBOX, getName() ); } catch (ParseException e) { System.out.println("[ erro@DropboxProxy.do_getAttr ] : Falhou o parsing da resposta."); e.printStackTrace(); } catch (org.json.simple.parser.ParseException e) { System.out.println("[ erro@DropboxProxy.do_getAttr ] : Falhou o parsing da resposta."); e.printStackTrace(); } return retval; } /** * Método que lista os ficheiros no path "path" * @param path - path a listar * @return retval - retorna a lista de ficheiros */ @Override public TreeSet do_ls( String path ) throws NoSuchPathException, RemoteException { OAuthRequest request = new OAuthRequest( Verb.GET, "https://api.dropbox.com/1/metadata/"+CONTEXT+"/"+this.current_path+path+"&list=true"); this.service.signRequest( this.accessToken, request ); Response response; TreeSet retval = new TreeSet(); response = request.send(); if ( 200 != response.getCode() ) { System.out.println( "[ erro@DropboxProxy.do_getAttr ] : ("+ response.getCode()+") "+ response.getBody() ); if ( 404 == response.getCode() ) throw new NoSuchPathException( "O caminho " + path + " não foi encontrado em " + this.name ); else throw new RemoteException( response.getCode() + response.getBody() ); } Iterator it; JSONArray files; try { files = (JSONArray) ((JSONObject)this.parser.parse( response.getBody() )).get("contents"); } catch (org.json.simple.parser.ParseException e1) { // TODO Auto-generated catch block e1.printStackTrace(); throw new RemoteException( e1.getLocalizedMessage() ); } it = files.iterator(); while( it.hasNext() ) { FileInfo file; try { file = new FileInfo( (JSONObject)it.next(), EJSONObjectType.DROPBOX, this.name ); retval.add( file ); } catch (ParseException e) { // TODO Melhorar esta excepção - mas isto é util caso o meu formato esteja errado e.printStackTrace(); } } return retval; } /** * Método que cria um directorio na root da Dropbox * @param dir_name - nome do directorio a criar * @return retval- true caso haja sucesso, false caso nao haja sucesso */ @Override public boolean do_mkdir( String dir_name ) throws NoSuchPathException, RemoteException { //TODO PATH String https="https://api.dropbox.com/1/fileops/create_folder"; https+="/"; OAuthRequest request = new OAuthRequest( Verb.POST, https); Response response; String path_of_new_dir=current_path; if(path_of_new_dir.equals(".")){ path_of_new_dir="/"+dir_name; } // else if(){ // // } // if ( -1 != dir_name.lastIndexOf('/') ) // path_of_new_dir += dir_name.substring(0, dir_name.lastIndexOf('/') ); System.out.println(path_of_new_dir); request.addBodyParameter("root", CONTEXT); request.addBodyParameter("path", path_of_new_dir); request.addHeader("locale", "en-US"); this.service.signRequest( this.accessToken, request ); response = request.send(); if ( 200 != response.getCode() ) { System.out.println( "[ erro@DropboxProxy.do_getAttr ] : ("+ response.getCode()+") "+ response.getBody() ); if ( 404 == response.getCode() ) throw new NoSuchPathException( "O caminho " + path_of_new_dir + " não foi encontrado em " + this.name ); // else // throw new RemoteException( response.getCode() + response.getBody() ); } return true; } //TODO copy, criar /** * Método que remove o ficheiro com o path "path" * @param path - path do ficheiro a remover * @return false/true - conforme o sucesso da operação */ @Override public boolean do_rm(String path){ // https://api.dropbox.com/1/fileops/delete OAuthRequest request = new OAuthRequest( Verb.POST, "https://api.dropbox.com/1/fileops/delete"); Response response; String p="/"+path; request.addBodyParameter("root", CONTEXT); request.addBodyParameter("path", p ); this.service.signRequest( this.accessToken, request ); response = request.send(); if ( 200 != response.getCode() ) { System.out.println( "[ erro@DropboxProxy.do_rem ] : ("+ response.getCode()+") "+ response.getBody() ); //404 No file wasn't found at the specified path. if ( 404 == response.getCode() ){ try { throw new NoSuchPathException( "O caminho " + path + " não foi encontrado em " + this.name ); } catch (NoSuchPathException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else if(406 == response.getCode()) System.out.println( "Havia demasiados ficheiros envolvidos para se conseguir concluir com sucesso a operação de remoção" ); else{ try { throw new RemoteException( response.getCode() + response.getBody() ); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return false; } System.out.println("Ficheiro/Directório removido com sucesso"); return true; } //TODO para ser usado pelo COPY!!! //TODO VERIFICAR SE E PARA USAR PATH /** *Método que cria um ficheiro na dropbox no path especificado *@param fileData - ficheiro a ser colocado na Dropbox *@param path - path onde o novo ficheiro irá ser criado *@return true/false - conforme o sucesso da operação */ public boolean new_file(FileData fileData, String path){ // https://api-content.dropbox.com/1/files_put//?param=val String https= "https://api-content.dropbox.com/1/files_put/sandbox/"; String p=""; if(path.equals(".")){ p=fileData.getName(); } //cp .@local .@Dropbox else{ p=path+fileData.getName(); } https+=p+"?param=val"; OAuthRequest request = new OAuthRequest( Verb.POST, https); Response response; byte[] payload; payload=fileData.getData(); request.addPayload(payload); request.addHeader("Content-Type", "text/plain"); //'Content-Type: text/plain' this.service.signRequest( this.accessToken, request ); response = request.send(); if ( 200 != response.getCode() ) { System.out.println( "[ erro@DropboxProxy.new_file] : ("+ response.getCode()+") "+ response.getBody() ); if ( 411 == response.getCode() ){ System.out.println( " Missing Content-Length header (this endpoint doesn't support HTTP chunked transfer encoding" ); try { throw new NoSuchPathException( "O caminho " + path + " não foi encontrado em " + this.name ); } catch (NoSuchPathException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else{ try { throw new RemoteException( response.getCode() + response.getBody() ); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return false; } return true; } @Override public boolean cpTo(String server, String path, FileData data) throws RemoteException, IllegalArgumentException { if(server.equals(this.getName())){ return new_file(data, path);} else { if ( !super.known_nodes.containsKey( server ) ) throw new NoSuchServerException("A comparação é feita entre dois servidores desconhecidos à rede."); return super.known_nodes.get( server ).cpTo( server, path, data ); } } @Override public FileData cpFrom(String remote_server, String path) throws RemoteException, IllegalArgumentException, NoSuchServerException { out.println("[ debug @ Server.cpFrom ] : A correr no servidor " + this.name + ", com os argumentos remote_server="+remote_server+" e path="+path); // Verificar argumentos. if ( null == path || null == remote_server ) throw new IllegalArgumentException("O caminho ou o servidor especificado, na chamada a cpFrom, é nulo."); if ( this.name.equals( remote_server ) ){ //https://api-content.dropbox.com/1/files// String https="https://api-content.dropbox.com/1/files/"; https+=CONTEXT; https+="/"+path; System.out.println(https); OAuthRequest request = new OAuthRequest( Verb.GET, https); Response response; request.addBodyParameter("root", CONTEXT); this.service.signRequest( this.accessToken, request ); response = request.send(); if ( 200 != response.getCode() ) { System.out.println( "[ erro@DropboxProxy.do_rem ] : ("+ response.getCode()+") "+ response.getBody() ); } String[] path_elements=path.split("/"); int size_path=path_elements.length; String name_of_file=path_elements[size_path-1]; byte[] f=response.getBody().getBytes(); File file = new File(name_of_file); FileData fd=new FileData(); //? fd.setData(f); fd.setFile(true); fd.setName(name_of_file); fd.setNode(this.getName()); fd.setPath(name_of_file); return fd; } else if ( this.known_nodes.containsKey( remote_server ) ) return this.known_nodes.get( remote_server ).cpFrom(remote_server, path); else throw new NoSuchServerException("O servidor especificado "+remote_server+" não existe na comunidade."); } }