implement part of google index upload/download

git-svn-id: https://osmand.googlecode.com/svn/trunk@183 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-06-20 11:07:29 +00:00
parent 687096c1ed
commit 9b267f8f3b
4 changed files with 458 additions and 4 deletions

View file

@ -0,0 +1,93 @@
package com.osmand;
/**
* @source http://www.javaworld.com/javaworld/javatips/jw-javatip47.html -- 24.11.2008, (mb)
*/
public class Base64 {
/*******************************************************************************************************************
* BASE 64 encoding of a String or an array of bytes. See also RFC 1421.
*
* @author Unknown
* @author David W. Croft
* @version 1998-06-08
******************************************************************************************************************/
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
public static final char[] alphabet = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 to 7
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 8 to 15
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 16 to 23
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 24 to 31
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 32 to 39
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 40 to 47
'w', 'x', 'y', 'z', '0', '1', '2', '3', // 48 to 55
'4', '5', '6', '7', '8', '9', '+', '/' }; // 56 to 63
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
public static String encode(final String s)
//////////////////////////////////////////////////////////////////////
{
return encode(s.getBytes());
}
public static String encode(final byte[] octetString)
//////////////////////////////////////////////////////////////////////
{
int bits24;
int bits6;
final char[] out = new char[((octetString.length - 1) / 3 + 1) * 4];
int outIndex = 0;
int i = 0;
while ((i + 3) <= octetString.length) {
// store the octets
bits24 = (octetString[i++] & 0xFF) << 16;
bits24 |= (octetString[i++] & 0xFF) << 8;
bits24 |= (octetString[i++] & 0xFF) << 0;
bits6 = (bits24 & 0x00FC0000) >> 18;
out[outIndex++] = alphabet[bits6];
bits6 = (bits24 & 0x0003F000) >> 12;
out[outIndex++] = alphabet[bits6];
bits6 = (bits24 & 0x00000FC0) >> 6;
out[outIndex++] = alphabet[bits6];
bits6 = (bits24 & 0x0000003F);
out[outIndex++] = alphabet[bits6];
}
if (octetString.length - i == 2) {
// store the octets
bits24 = (octetString[i] & 0xFF) << 16;
bits24 |= (octetString[i + 1] & 0xFF) << 8;
bits6 = (bits24 & 0x00FC0000) >> 18;
out[outIndex++] = alphabet[bits6];
bits6 = (bits24 & 0x0003F000) >> 12;
out[outIndex++] = alphabet[bits6];
bits6 = (bits24 & 0x00000FC0) >> 6;
out[outIndex++] = alphabet[bits6];
// padding
out[outIndex++] = '=';
} else if (octetString.length - i == 1) {
// store the octets
bits24 = (octetString[i] & 0xFF) << 16;
bits6 = (bits24 & 0x00FC0000) >> 18;
out[outIndex++] = alphabet[bits6];
bits6 = (bits24 & 0x0003F000) >> 12;
out[outIndex++] = alphabet[bits6];
// padding
out[outIndex++] = '=';
out[outIndex++] = '=';
}
return new String(out);
}
}

View file

@ -30,10 +30,6 @@ public class ToDoConstants {
// DONE : MiniMap done, Routing settings done, RouteLayer done, RoutingHelper done. // DONE : MiniMap done, Routing settings done, RouteLayer done, RoutingHelper done.
// TODO : Test again? // TODO : Test again?
// 37. Get rid of exit button (!). Think about when notification should go & how clear resources if it is necessary
// DONE :
// TODO : add to app settings preference (Refresh indexes).
// 42. Revise UI (icons/layouts). Support different devices. Add inactive/focus(!) icon versions. // 42. Revise UI (icons/layouts). Support different devices. Add inactive/focus(!) icon versions.
// Some icons are not fine (as back menu from map - it is blured). // Some icons are not fine (as back menu from map - it is blured).
@ -80,6 +76,8 @@ public class ToDoConstants {
// BUGS Swing // BUGS Swing
// DONE ANDROID : // DONE ANDROID :
// 37. Get rid of exit button (!). Think about when notification should go & how clear resources if it is necessary
// DONE : add to app settings preference (Refresh indexes).
// DONE SWING // DONE SWING

View file

@ -0,0 +1,112 @@
package com.osmand.data.index;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import com.osmand.LogUtil;
public class DownloaderIndexFromGoogleCode {
private final static Log log = LogUtil.getLog(DownloaderIndexFromGoogleCode.class);
/**
* @param args
* @throws URISyntaxException
* @throws IOException
*/
public static void main(String[] args) throws URISyntaxException, IOException {
System.out.println(getIndexFiles(new String[] {".addr.odb",".poi.odb"}, new String[] {"0", "0"})); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
private static StringBuilder getContent() {
try {
URL url = new URL("http://code.google.com/p/osmand/downloads/list"); //$NON-NLS-1$
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder b = new StringBuilder();
String s = null;
while ((s = reader.readLine()) != null) {
b.append(s);
}
return b;
} catch (MalformedURLException e) {
log.error("Unexpected exception", e); //$NON-NLS-1$
return null;
} catch (IOException e) {
log.error("Input/Output exception", e); //$NON-NLS-1$
return null;
}
}
private static void getIndexFiles(Map<String, String> files , StringBuilder content, String ext, String version){
int i = 0;
int prevI = -1;
String prevFile = null;
while ((i = content.indexOf(ext, i)) != -1) {
if(prevI > i){
files.put(prevFile, null);
prevI = i;
}
int j = i - 1;
while (content.charAt(j) == '_' || Character.isLetterOrDigit(content.charAt(j))) {
j--;
}
if(!content.substring(j + 1, i).endsWith("_"+version)){ //$NON-NLS-1$
i++;
continue;
}
prevFile = content.substring(j + 1, i) + ext;
String description = null;
prevI = content.indexOf("{", i); //$NON-NLS-1$
if(prevI > 0){
j = content.indexOf("}", prevI); //$NON-NLS-1$
if(j > 0 && j - prevI < 40){
description = content.substring(prevI + 1, j);
}
}
if(!files.containsKey(prevFile) || files.get(prevFile) == null){
files.put(prevFile, description);
} else {
prevI = i;
}
i++;
}
}
public static Map<String, String> getIndexFiles(String[] ext, String[] version){
StringBuilder content = getContent();
if(content == null){
return null;
}
Map<String, String> files = new TreeMap<String, String>();
for(int i=0; i<ext.length; i++){
getIndexFiles(files, content, ext[i], version[i]);
}
return files;
}
public static Map<String, String> getIndexFiles(String ext, String version){
StringBuilder content = getContent();
if(content == null){
return null;
}
Map<String, String> files = new TreeMap<String, String>();
getIndexFiles(files, content, ext, version);
return files;
}
public static InputStream getInputStreamToLoadIndex(String indexName) throws IOException{
URL url = new URL("http://osmand.googlecode.com/files/"+indexName); //$NON-NLS-1$
return url.openStream();
}
}

View file

@ -0,0 +1,251 @@
/*
* Created on May 24, 2007
*
* This code belongs to Jonathan Fuerth
*/
package com.osmand.data.index;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.logging.Log;
import com.osmand.Base64;
import com.osmand.LogUtil;
/**
* Initially was taken from GoogleCodeUploadTask
*/
public class GoogleCodeUploadIndex {
private final static Log log = LogUtil.getLog(GoogleCodeUploadIndex.class);
/**
* Google user name to authenticate as (this is just the username part;
* don't include the @gmail.com part).
*/
private String userName;
/**
* Coogle Code password (not the same as the gmail password) !!!!
*/
private String password;
/**
* Google Code project name to upload to.
*/
private String projectName;
/**
* The local path of the file to upload.
*/
private String fileName;
/**
* The file name that this file will be given on Google Code.
*/
private String targetFileName;
/**
* Summary of the upload.
*/
private String summary;
/**
* The labels that the download should have, separated by commas. Extra
* whitespace before and after each label name will not be considered part
* of the label name.
*/
private String labels;
private void log(String e){
log.info(e);
}
/**
* Uploads the contents of the file {@link #fileName} to the project's
* Google Code upload url. Performs the basic http authentication required
* by Google Code.
*/
public void upload() throws IOException {
System.clearProperty("javax.net.ssl.trustStoreProvider"); // fixes open-jdk-issue //$NON-NLS-1$
System.clearProperty("javax.net.ssl.trustStoreType"); //$NON-NLS-1$
final String BOUNDARY = "CowMooCowMooCowCowCow"; //$NON-NLS-1$
URL url = createUploadURL();
log("The upload URL is " + url); //$NON-NLS-1$
InputStream in = new BufferedInputStream(new FileInputStream(fileName));
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Basic " + createAuthToken(userName, password)); //$NON-NLS-1$ //$NON-NLS-2$
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); //$NON-NLS-1$ //$NON-NLS-2$
conn.setRequestProperty("User-Agent", "Google Code Upload Ant Task 0.1"); //$NON-NLS-1$ //$NON-NLS-2$
log("Attempting to connect (username is " + userName + ")..."); //$NON-NLS-1$ //$NON-NLS-2$
conn.connect();
log("Sending request parameters..."); //$NON-NLS-1$
OutputStream out = conn.getOutputStream();
sendLine(out, "--" + BOUNDARY); //$NON-NLS-1$
sendLine(out, "content-disposition: form-data; name=\"summary\""); //$NON-NLS-1$
sendLine(out, ""); //$NON-NLS-1$
sendLine(out, summary);
if (labels != null) {
String[] labelArray = labels.split("\\,"); //$NON-NLS-1$
if (labelArray != null && labelArray.length > 0) {
log("Setting "+labelArray.length+" label(s)"); //$NON-NLS-1$ //$NON-NLS-2$
for (int n = 0, i = labelArray.length; n < i; n++) {
sendLine(out, "--" + BOUNDARY); //$NON-NLS-1$
sendLine(out, "content-disposition: form-data; name=\"label\""); //$NON-NLS-1$
sendLine(out, ""); //$NON-NLS-1$
sendLine(out, labelArray[n].trim());
}
}
}
log("Sending file... "+targetFileName); //$NON-NLS-1$
sendLine(out, "--" + BOUNDARY); //$NON-NLS-1$
sendLine(out, "content-disposition: form-data; name=\"filename\"; filename=\"" + targetFileName + "\""); //$NON-NLS-1$ //$NON-NLS-2$
sendLine(out, "Content-Type: application/octet-stream"); //$NON-NLS-1$
sendLine(out, ""); //$NON-NLS-1$
int count;
byte[] buf = new byte[8192];
while ( (count = in.read(buf)) >= 0 ) {
out.write(buf, 0, count);
}
in.close();
sendLine(out, ""); //$NON-NLS-1$
sendLine(out, "--" + BOUNDARY + "--"); //$NON-NLS-1$ //$NON-NLS-2$
out.flush();
out.close();
// For whatever reason, you have to read from the input stream before
// the url connection will start sending
in = conn.getInputStream();
log("Upload finished. Reading response."); //$NON-NLS-1$
log("HTTP Response Headers: " + conn.getHeaderFields()); //$NON-NLS-1$
StringBuilder responseBody = new StringBuilder();
while ( (count = in.read(buf)) >= 0 ) {
responseBody.append(new String(buf, 0, count, "ascii")); //$NON-NLS-1$
}
log(responseBody.toString());
in.close();
conn.disconnect();
}
/**
* Just sends an ASCII version of the given string, followed by a CRLF line terminator,
* to the given output stream.
*/
private void sendLine(OutputStream out, String string) throws IOException {
out.write(string.getBytes("ascii")); //$NON-NLS-1$
out.write("\r\n".getBytes("ascii")); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Creates a (base64-encoded) HTTP basic authentication token for the
* given user name and password.
*/
private static String createAuthToken(String userName, String password) {
String string = (userName + ":" + password); //$NON-NLS-1$
try {
return Base64.encode(string.getBytes("UTF-8")); //$NON-NLS-1$
}
catch (java.io.UnsupportedEncodingException notreached){
throw new InternalError(notreached.toString());
}
}
/**
* Creates the correct URL for uploading to the named google code project.
* If uploadUrl is not set (this is the standard case), the correct URL will
* be generated based on the {@link #projectName}. Otherwise, if uploadUrl
* is set, it will be used and the project name setting will be ignored.
*/
private URL createUploadURL() throws MalformedURLException {
if (projectName == null) {
throw new NullPointerException("projectName must be set"); //$NON-NLS-1$
}
return new URL("https", projectName + ".googlecode.com", "/files"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
}
// ============ Getters and Setters ==============
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getTargetFileName() {
return targetFileName;
}
public void setTargetFileName(String targetFileName) {
this.targetFileName = targetFileName;
}
public String getLabels() {
return labels;
}
public void setLabels(String labels) {
this.labels = labels;
}
}