mirror of
https://github.com/etesync/android
synced 2024-11-22 16:08:13 +00:00
Log resource detection results to viewable string
* new StringLogger * DavResourceFinder: log to StringLogger; if no collections are found, logs can be views * DebugInfoActivity: show passed logs * script to fetch translations from Transifex * increase version to 0.9-beta2
This commit is contained in:
parent
58f05986c9
commit
4b5cb30762
@ -17,8 +17,8 @@ android {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 23
|
||||
|
||||
versionCode 76
|
||||
versionName "0.9-beta1"
|
||||
versionCode 77
|
||||
versionName "0.9-beta2"
|
||||
|
||||
buildConfigField "java.util.Date", "buildTime", "new java.util.Date()"
|
||||
}
|
||||
|
@ -8,9 +8,14 @@
|
||||
|
||||
package at.bitfire.davdroid.log;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.Marker;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* A DAVdroid logger base class that wraps all calls around some standard log() calls.
|
||||
* @throws UnsupportedOperationException for all methods with Marker
|
||||
@ -25,13 +30,39 @@ public abstract class CustomLogger implements Logger {
|
||||
PREFIX_DEBUG = "[debug] ",
|
||||
PREFIX_TRACE = "[trace] ";
|
||||
|
||||
@Getter
|
||||
protected String name;
|
||||
|
||||
protected PrintWriter writer;
|
||||
protected boolean verbose;
|
||||
|
||||
protected abstract void log(String prefix, String msg);
|
||||
protected abstract void log(String prefix, String format, Object arg);
|
||||
protected abstract void log(String prefix, String format, Object arg1, Object arg2);
|
||||
protected abstract void log(String prefix, String format, Object... args);
|
||||
protected abstract void log(String prefix, String msg, Throwable t);
|
||||
|
||||
// CUSTOM LOGGING METHODS
|
||||
|
||||
protected void log(String prefix, String msg) {
|
||||
writer.write(prefix + msg + "\n");
|
||||
}
|
||||
|
||||
protected void log(String prefix, String format, Object arg) {
|
||||
writer.write(prefix + format.replace("{}", arg.toString()) + "\n");
|
||||
}
|
||||
|
||||
protected void log(String prefix, String format, Object arg1, Object arg2) {
|
||||
writer.write(prefix + format.replaceFirst("\\{\\}", arg1.toString()).replaceFirst("\\{\\}", arg2.toString()) + "\n");
|
||||
}
|
||||
|
||||
protected void log(String prefix, String format, Object... args) {
|
||||
String message = prefix;
|
||||
for (Object arg : args)
|
||||
format.replaceFirst("\\{\\}", arg.toString());
|
||||
writer.write(prefix + format + "\n");
|
||||
}
|
||||
|
||||
protected void log(String prefix, String msg, Throwable t) {
|
||||
writer.write(prefix + msg + " - EXCEPTION:\n");
|
||||
t.printStackTrace(writer);
|
||||
ExceptionUtils.printRootCauseStackTrace(t, writer);
|
||||
}
|
||||
|
||||
|
||||
// STANDARD CALLS
|
||||
|
@ -10,21 +10,13 @@ package at.bitfire.davdroid.log;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class ExternalFileLogger extends CustomLogger implements Closeable {
|
||||
|
||||
@Getter protected final String name;
|
||||
|
||||
protected final PrintWriter writer;
|
||||
|
||||
public ExternalFileLogger(Context context, String fileName, boolean verbose) throws IOException {
|
||||
this.verbose = verbose;
|
||||
|
||||
@ -41,35 +33,5 @@ public class ExternalFileLogger extends CustomLogger implements Closeable {
|
||||
writer.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void log(String prefix, String msg) {
|
||||
writer.write(prefix + msg + "\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void log(String prefix, String format, Object arg) {
|
||||
writer.write(prefix + format.replace("{}", arg.toString()) + "\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void log(String prefix, String format, Object arg1, Object arg2) {
|
||||
writer.write(prefix + format.replaceFirst("\\{\\}", arg1.toString()).replaceFirst("\\{\\}", arg2.toString()) + "\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void log(String prefix, String format, Object... args) {
|
||||
String message = prefix;
|
||||
for (Object arg : args)
|
||||
format.replaceFirst("\\{\\}", arg.toString());
|
||||
writer.write(prefix + format + "\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void log(String prefix, String msg, Throwable t) {
|
||||
writer.write(prefix + msg + " - EXCEPTION:");
|
||||
t.printStackTrace(writer);
|
||||
writer.write("CAUSED BY:\n");
|
||||
ExceptionUtils.printRootCauseStackTrace(t, writer);
|
||||
}
|
||||
|
||||
}
|
||||
|
35
app/src/main/java/at/bitfire/davdroid/log/StringLogger.java
Normal file
35
app/src/main/java/at/bitfire/davdroid/log/StringLogger.java
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Public License v3.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.log;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class StringLogger extends CustomLogger {
|
||||
|
||||
@Getter protected final String name;
|
||||
|
||||
protected final StringWriter stringWriter = new StringWriter();
|
||||
|
||||
|
||||
public StringLogger(String name, boolean verbose) {
|
||||
this.name = name;
|
||||
this.verbose = verbose;
|
||||
|
||||
writer = new PrintWriter(stringWriter);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return stringWriter.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -44,7 +44,6 @@ import at.bitfire.dav4android.property.CurrentUserPrivilegeSet;
|
||||
import at.bitfire.dav4android.property.DisplayName;
|
||||
import at.bitfire.dav4android.property.ResourceType;
|
||||
import at.bitfire.dav4android.property.SupportedCalendarComponentSet;
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.HttpClient;
|
||||
import lombok.NonNull;
|
||||
|
||||
@ -77,12 +76,16 @@ public class DavResourceFinder {
|
||||
httpClient = new HttpClient(log, context, serverInfo.getUserName(), serverInfo.getPassword(), serverInfo.authPreemptive);
|
||||
}
|
||||
|
||||
public void findResources() throws URISyntaxException, IOException, HttpException, DavException {
|
||||
findResources(Service.CARDDAV);
|
||||
findResources(Service.CALDAV);
|
||||
public void findResources() {
|
||||
try {
|
||||
findResources(Service.CARDDAV);
|
||||
findResources(Service.CALDAV);
|
||||
} catch(URISyntaxException e) {
|
||||
log.warn("Invalid user-given URI", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void findResources(Service service) throws URISyntaxException, IOException, HttpException, DavException {
|
||||
public void findResources(Service service) throws URISyntaxException {
|
||||
URI baseURI = serverInfo.getBaseURI();
|
||||
String domain = null;
|
||||
|
||||
@ -95,7 +98,7 @@ public class DavResourceFinder {
|
||||
} else if (service == Service.CARDDAV)
|
||||
addressbooks.clear();
|
||||
|
||||
Constants.log.info("*** STARTING COLLECTION DISCOVERY FOR SERVICE " + service.name.toUpperCase() + "***");
|
||||
log.info("*** STARTING COLLECTION DISCOVERY FOR SERVICE " + service.name.toUpperCase() + "***");
|
||||
if ("http".equals(baseURI.getScheme()) || "https".equals(baseURI.getScheme())) {
|
||||
HttpUrl userURL = HttpUrl.get(baseURI);
|
||||
|
||||
@ -103,7 +106,7 @@ public class DavResourceFinder {
|
||||
1. user-given URL is a calendar
|
||||
2. user-given URL has a calendar-home-set property (i.e. is a principal URL)
|
||||
*/
|
||||
Constants.log.info("Check whether user-given URL is a calendar collection and/or contains <calendar-home-set> and/or has <current-user-principal>");
|
||||
log.info("Check whether user-given URL is a calendar collection and/or contains <calendar-home-set> and/or has <current-user-principal>");
|
||||
DavResource davBase = new DavResource(log, httpClient, userURL);
|
||||
try {
|
||||
if (service == Service.CALDAV) {
|
||||
@ -122,13 +125,13 @@ public class DavResourceFinder {
|
||||
addIfAddressBook(davBase);
|
||||
}
|
||||
} catch (IOException|HttpException|DavException e) {
|
||||
Constants.log.debug("PROPFIND on user-given URL failed", e);
|
||||
log.debug("PROPFIND on user-given URL failed", e);
|
||||
}
|
||||
|
||||
if (service == Service.CALDAV) {
|
||||
CalendarHomeSet calendarHomeSet = (CalendarHomeSet)davBase.properties.get(CalendarHomeSet.NAME);
|
||||
if (calendarHomeSet != null) {
|
||||
Constants.log.info("Found <calendar-home-set> at user-given URL");
|
||||
log.info("Found <calendar-home-set> at user-given URL");
|
||||
for (String href : calendarHomeSet.hrefs) {
|
||||
HttpUrl url = userURL.resolve(href);
|
||||
if (url != null)
|
||||
@ -138,7 +141,7 @@ public class DavResourceFinder {
|
||||
} else if (service == Service.CARDDAV) {
|
||||
AddressbookHomeSet addressbookHomeSet = (AddressbookHomeSet) davBase.properties.get(AddressbookHomeSet.NAME);
|
||||
if (addressbookHomeSet != null) {
|
||||
Constants.log.info("Found <addressbook-home-set> at user-given URL");
|
||||
log.info("Found <addressbook-home-set> at user-given URL");
|
||||
for (String href : addressbookHomeSet.hrefs) {
|
||||
HttpUrl url = userURL.resolve(href);
|
||||
if (url != null)
|
||||
@ -153,7 +156,7 @@ public class DavResourceFinder {
|
||||
* Keep in mind that the CalDAV principal URL must not be the CardDAV principal URL! */
|
||||
if (homeSets.isEmpty())
|
||||
try {
|
||||
Constants.log.info("No home sets found, looking for <current-user-principal>");
|
||||
log.info("No home sets found, looking for <current-user-principal>");
|
||||
|
||||
davBase.options();
|
||||
if ((service == Service.CALDAV && davBase.capabilities.contains("calendar-access")) ||
|
||||
@ -163,15 +166,15 @@ public class DavResourceFinder {
|
||||
principalUrl = davBase.location.resolve(currentUserPrincipal.href);
|
||||
}
|
||||
} catch(IOException|HttpException|DavException e) {
|
||||
Constants.log.debug("Couldn't find <current-user-principal> at user-given URL", e);
|
||||
log.debug("Couldn't find <current-user-principal> at user-given URL", e);
|
||||
}
|
||||
|
||||
if (principalUrl == null)
|
||||
try {
|
||||
Constants.log.info("User-given URL doesn't contain <current-user-principal>, trying /.well-known/" + service.name);
|
||||
log.info("User-given URL doesn't contain <current-user-principal>, trying /.well-known/" + service.name);
|
||||
principalUrl = getCurrentUserPrincipal(userURL.resolve("/.well-known/" + service.name));
|
||||
} catch(IOException|HttpException e) {
|
||||
Constants.log.debug("Couldn't determine <current-user-principal> from well-known " + service + " path", e);
|
||||
} catch(IOException|HttpException|DavException e) {
|
||||
log.debug("Couldn't determine <current-user-principal> from well-known " + service + " path", e);
|
||||
}
|
||||
|
||||
if (principalUrl == null)
|
||||
@ -190,13 +193,17 @@ public class DavResourceFinder {
|
||||
}
|
||||
|
||||
if (principalUrl == null && domain != null) {
|
||||
Constants.log.info("No principal URL yet, trying SRV/TXT records with domain " + domain);
|
||||
principalUrl = discoverPrincipalUrl(domain, service);
|
||||
log.info("No principal URL yet, trying SRV/TXT records with domain " + domain);
|
||||
try {
|
||||
principalUrl = discoverPrincipalUrl(domain, service);
|
||||
} catch (IOException|HttpException|DavException e) {
|
||||
log.info("Couldn't find principal URL using service discovery");
|
||||
}
|
||||
}
|
||||
|
||||
// principal URL has been found, get addressbook-home-set/calendar-home-set
|
||||
if (principalUrl != null) {
|
||||
Constants.log.info("Principal URL=" + principalUrl + ", getting <calendar-home-set>");
|
||||
log.info("Principal URL=" + principalUrl + ", getting <calendar-home-set>");
|
||||
try {
|
||||
DavResource principal = new DavResource(log, httpClient, principalUrl);
|
||||
|
||||
@ -204,7 +211,7 @@ public class DavResourceFinder {
|
||||
principal.propfind(0, CalendarHomeSet.NAME);
|
||||
CalendarHomeSet calendarHomeSet = (CalendarHomeSet) principal.properties.get(CalendarHomeSet.NAME);
|
||||
if (calendarHomeSet != null) {
|
||||
Constants.log.info("Found <calendar-home-set> at principal URL");
|
||||
log.info("Found <calendar-home-set> at principal URL");
|
||||
for (String href : calendarHomeSet.hrefs) {
|
||||
HttpUrl url = principal.location.resolve(href);
|
||||
if (url != null)
|
||||
@ -215,7 +222,7 @@ public class DavResourceFinder {
|
||||
principal.propfind(0, AddressbookHomeSet.NAME);
|
||||
AddressbookHomeSet addressbookHomeSet = (AddressbookHomeSet) principal.properties.get(AddressbookHomeSet.NAME);
|
||||
if (addressbookHomeSet != null) {
|
||||
Constants.log.info("Found <addressbook-home-set> at principal URL");
|
||||
log.info("Found <addressbook-home-set> at principal URL");
|
||||
for (String href : addressbookHomeSet.hrefs) {
|
||||
HttpUrl url = principal.location.resolve(href);
|
||||
if (url != null)
|
||||
@ -225,7 +232,7 @@ public class DavResourceFinder {
|
||||
}
|
||||
|
||||
} catch (IOException|HttpException|DavException e) {
|
||||
Constants.log.debug("PROPFIND on " + principalUrl + " failed", e);
|
||||
log.debug("PROPFIND on " + principalUrl + " failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +240,7 @@ public class DavResourceFinder {
|
||||
for (HttpUrl url : homeSets)
|
||||
if (service == Service.CALDAV)
|
||||
try {
|
||||
Constants.log.info("Listing calendar collections in home set " + url);
|
||||
log.info("Listing calendar collections in home set " + url);
|
||||
DavResource homeSet = new DavResource(log, httpClient, url);
|
||||
homeSet.propfind(1, SupportedCalendarComponentSet.NAME, ResourceType.NAME, DisplayName.NAME, CurrentUserPrivilegeSet.NAME,
|
||||
CalendarColor.NAME, CalendarDescription.NAME, CalendarTimezone.NAME);
|
||||
@ -245,11 +252,11 @@ public class DavResourceFinder {
|
||||
for (DavResource member : homeSet.members)
|
||||
addIfCalendar(member);
|
||||
} catch (IOException | HttpException | DavException e) {
|
||||
Constants.log.debug("PROPFIND on " + url + " failed", e);
|
||||
log.debug("PROPFIND on " + url + " failed", e);
|
||||
}
|
||||
else if (service == Service.CARDDAV)
|
||||
try {
|
||||
Constants.log.info("Listing address books in home set " + url);
|
||||
log.info("Listing address books in home set " + url);
|
||||
DavResource homeSet = new DavResource(log, httpClient, url);
|
||||
homeSet.propfind(1, ResourceType.NAME, DisplayName.NAME, CurrentUserPrivilegeSet.NAME, AddressbookDescription.NAME);
|
||||
|
||||
@ -260,7 +267,7 @@ public class DavResourceFinder {
|
||||
for (DavResource member : homeSet.members)
|
||||
addIfAddressBook(member);
|
||||
} catch (IOException | HttpException | DavException e) {
|
||||
Constants.log.debug("PROPFIND on " + url + " failed", e);
|
||||
log.debug("PROPFIND on " + url + " failed", e);
|
||||
}
|
||||
|
||||
// TODO notify user on errors?
|
||||
@ -280,7 +287,7 @@ public class DavResourceFinder {
|
||||
ResourceType resourceType = (ResourceType)dav.properties.get(ResourceType.NAME);
|
||||
if (resourceType != null && resourceType.types.contains(ResourceType.ADDRESSBOOK)) {
|
||||
dav.location = UrlUtils.withTrailingSlash(dav.location);
|
||||
Constants.log.info("Found address book at " + dav.location);
|
||||
log.info("Found address book at " + dav.location);
|
||||
|
||||
addressbooks.put(dav.location, resourceInfo(dav, ServerInfo.ResourceInfo.Type.ADDRESS_BOOK));
|
||||
}
|
||||
@ -298,7 +305,7 @@ public class DavResourceFinder {
|
||||
ResourceType resourceType = (ResourceType)dav.properties.get(ResourceType.NAME);
|
||||
if (resourceType != null && resourceType.types.contains(ResourceType.CALENDAR)) {
|
||||
dav.location = UrlUtils.withTrailingSlash(dav.location);
|
||||
Constants.log.info("Found calendar collection at " + dav.location);
|
||||
log.info("Found calendar collection at " + dav.location);
|
||||
|
||||
boolean supportsEvents = true, supportsTasks = true;
|
||||
SupportedCalendarComponentSet supportedCalendarComponentSet = (SupportedCalendarComponentSet)dav.properties.get(SupportedCalendarComponentSet.NAME);
|
||||
@ -376,7 +383,7 @@ public class DavResourceFinder {
|
||||
List<String> paths = new LinkedList<>(); // there may be multiple paths to try
|
||||
|
||||
final String query = "_" + service.name + "s._tcp." + domain;
|
||||
Constants.log.debug("Looking up SRV records for " + query);
|
||||
log.debug("Looking up SRV records for " + query);
|
||||
Record[] records = new Lookup(query, Type.SRV).run();
|
||||
if (records != null && records.length >= 1) {
|
||||
// choose SRV record to use (query may return multiple SRV records)
|
||||
@ -385,7 +392,7 @@ public class DavResourceFinder {
|
||||
scheme = "https";
|
||||
fqdn = srv.getTarget().toString(true);
|
||||
port = srv.getPort();
|
||||
Constants.log.info("Found " + service + " service: fqdn=" + fqdn + ", port=" + port);
|
||||
log.info("Found " + service + " service: fqdn=" + fqdn + ", port=" + port);
|
||||
|
||||
// look for TXT record too (for initial context path)
|
||||
records = new Lookup(domain, Type.TXT).run();
|
||||
@ -394,7 +401,7 @@ public class DavResourceFinder {
|
||||
for (String segment : (String[])txt.getStrings().toArray(new String[0]))
|
||||
if (segment.startsWith("path=")) {
|
||||
paths.add(segment.substring(5));
|
||||
Constants.log.info("Found TXT record; initial context path=" + paths);
|
||||
log.info("Found TXT record; initial context path=" + paths);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -413,7 +420,7 @@ public class DavResourceFinder {
|
||||
.encodedPath(path)
|
||||
.build();
|
||||
|
||||
Constants.log.info("Trying to determine principal from initial context path=" + initialContextPath);
|
||||
log.info("Trying to determine principal from initial context path=" + initialContextPath);
|
||||
HttpUrl principal = getCurrentUserPrincipal(initialContextPath);
|
||||
if (principal != null)
|
||||
return principal;
|
||||
@ -434,7 +441,7 @@ public class DavResourceFinder {
|
||||
if (currentUserPrincipal != null && currentUserPrincipal.href != null) {
|
||||
HttpUrl principal = url.resolve(currentUserPrincipal.href);
|
||||
if (principal != null) {
|
||||
Constants.log.info("Found current-user-principal: " + principal);
|
||||
log.info("Found current-user-principal: " + principal);
|
||||
return principal;
|
||||
}
|
||||
}
|
||||
@ -446,7 +453,7 @@ public class DavResourceFinder {
|
||||
|
||||
private SRVRecord selectSRVRecord(Record[] records) {
|
||||
if (records.length > 1)
|
||||
Constants.log.warn("Multiple SRV records not supported yet; using first one");
|
||||
log.warn("Multiple SRV records not supported yet; using first one");
|
||||
return (SRVRecord)records[0];
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ public class ServerInfo implements Serializable {
|
||||
final private String userName, password;
|
||||
final boolean authPreemptive;
|
||||
|
||||
private String errorMessage;
|
||||
private String logs;
|
||||
|
||||
private ResourceInfo
|
||||
addressBooks[] = new ResourceInfo[0],
|
||||
@ -40,8 +40,12 @@ public class ServerInfo implements Serializable {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return addressBooks.length == 0 && calendars.length == 0 && taskLists.length == 0;
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor(suppressConstructorProperties=true)
|
||||
|
||||
@RequiredArgsConstructor(suppressConstructorProperties=true)
|
||||
@Data
|
||||
public static class ResourceInfo implements Serializable {
|
||||
|
||||
|
@ -39,6 +39,7 @@ import at.bitfire.davdroid.R;
|
||||
public class DebugInfoActivity extends Activity implements LoaderManager.LoaderCallbacks<String> {
|
||||
public static final String
|
||||
KEY_EXCEPTION = "exception",
|
||||
KEY_LOGS = "logs",
|
||||
KEY_ACCOUNT = "account",
|
||||
KEY_AUTHORITY = "authority",
|
||||
KEY_PHASE = "phase";
|
||||
@ -109,22 +110,24 @@ public class DebugInfoActivity extends Activity implements LoaderManager.LoaderC
|
||||
@Override
|
||||
public String loadInBackground() {
|
||||
Exception exception = null;
|
||||
String authority = null;
|
||||
String logs = null,
|
||||
authority = null;
|
||||
Account account = null;
|
||||
Integer phase = null;
|
||||
int phase = -1;
|
||||
|
||||
if (extras != null) {
|
||||
exception = (Exception)extras.getSerializable(KEY_EXCEPTION);
|
||||
logs = extras.getString(KEY_LOGS);
|
||||
account = extras.getParcelable(KEY_ACCOUNT);
|
||||
authority = extras.getString(KEY_AUTHORITY);
|
||||
phase = extras.getInt(KEY_PHASE);
|
||||
phase = extras.getInt(KEY_PHASE, -1);
|
||||
}
|
||||
|
||||
StringBuilder report = new StringBuilder();
|
||||
|
||||
// begin with most specific information
|
||||
|
||||
if (phase != null)
|
||||
if (phase != -1)
|
||||
report.append("SYNCHRONIZATION INFO\nSynchronization phase: " + phase + "\n");
|
||||
if (account != null)
|
||||
report.append("Account name: " + account.name + "\n");
|
||||
@ -146,6 +149,9 @@ public class DebugInfoActivity extends Activity implements LoaderManager.LoaderC
|
||||
report.append("\n");
|
||||
}
|
||||
|
||||
if (logs != null)
|
||||
report.append("LOGS:\n" + logs + "\n");
|
||||
|
||||
try {
|
||||
PackageManager pm = getContext().getPackageManager();
|
||||
String installedFrom = pm.getInstallerPackageName(BuildConfig.APPLICATION_ID);
|
||||
|
@ -9,7 +9,6 @@ package at.bitfire.davdroid.ui.setup;
|
||||
|
||||
import android.app.DialogFragment;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
@ -24,7 +23,9 @@ import android.widget.EditText;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.resource.ServerInfo;
|
||||
|
||||
public class LoginEmailFragment extends Fragment implements TextWatcher {
|
||||
|
||||
@ -53,18 +54,22 @@ public class LoginEmailFragment extends Fragment implements TextWatcher {
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.next:
|
||||
FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
String email = editEmail.getText().toString();
|
||||
args.putString(QueryServerDialogFragment.EXTRA_BASE_URI, "mailto:" + email);
|
||||
args.putString(QueryServerDialogFragment.EXTRA_USER_NAME, email);
|
||||
args.putString(QueryServerDialogFragment.EXTRA_PASSWORD, editPassword.getText().toString());
|
||||
args.putBoolean(QueryServerDialogFragment.EXTRA_AUTH_PREEMPTIVE, true);
|
||||
|
||||
DialogFragment dialog = new QueryServerDialogFragment();
|
||||
dialog.setArguments(args);
|
||||
dialog.show(ft, QueryServerDialogFragment.class.getName());
|
||||
try {
|
||||
String email = editEmail.getText().toString();
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable(QueryServerDialogFragment.KEY_SERVER_INFO, new ServerInfo(
|
||||
new URI("mailto:" + email),
|
||||
email,
|
||||
editPassword.getText().toString(),
|
||||
true
|
||||
));
|
||||
|
||||
DialogFragment dialog = new QueryServerDialogFragment();
|
||||
dialog.setArguments(args);
|
||||
dialog.show(getFragmentManager(), QueryServerDialogFragment.class.getName());
|
||||
} catch(URISyntaxException e) {
|
||||
Constants.log.debug("Invalid email address", e);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
@ -30,7 +30,9 @@ import android.widget.TextView;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.resource.ServerInfo;
|
||||
|
||||
public class LoginURLFragment extends Fragment implements TextWatcher {
|
||||
|
||||
@ -88,20 +90,21 @@ public class LoginURLFragment extends Fragment implements TextWatcher {
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.next:
|
||||
FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
try {
|
||||
args.putString(QueryServerDialogFragment.EXTRA_BASE_URI, getBaseURI().toString());
|
||||
} catch (URISyntaxException e) {
|
||||
}
|
||||
args.putString(QueryServerDialogFragment.EXTRA_USER_NAME, editUserName.getText().toString());
|
||||
args.putString(QueryServerDialogFragment.EXTRA_PASSWORD, editPassword.getText().toString());
|
||||
args.putBoolean(QueryServerDialogFragment.EXTRA_AUTH_PREEMPTIVE, checkboxPreemptive.isChecked());
|
||||
|
||||
DialogFragment dialog = new QueryServerDialogFragment();
|
||||
dialog.setArguments(args);
|
||||
dialog.show(ft, QueryServerDialogFragment.class.getName());
|
||||
try {
|
||||
ServerInfo serverInfo = new ServerInfo(
|
||||
getBaseURI(),
|
||||
editUserName.getText().toString(),
|
||||
editPassword.getText().toString(),
|
||||
checkboxPreemptive.isChecked()
|
||||
);
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable(QueryServerDialogFragment.KEY_SERVER_INFO, serverInfo);
|
||||
DialogFragment dialog = new QueryServerDialogFragment();
|
||||
dialog.setArguments(args);
|
||||
dialog.show(getFragmentManager(), null);
|
||||
} catch(URISyntaxException e) {
|
||||
Constants.log.debug("Invalid URI", e);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
@ -7,87 +7,126 @@
|
||||
*/
|
||||
package at.bitfire.davdroid.ui.setup;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.Fragment;
|
||||
import android.app.LoaderManager.LoaderCallbacks;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.AsyncTaskLoader;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.Loader;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import at.bitfire.dav4android.exception.DavException;
|
||||
import at.bitfire.dav4android.exception.HttpException;
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.log.StringLogger;
|
||||
import at.bitfire.davdroid.resource.DavResourceFinder;
|
||||
import at.bitfire.davdroid.resource.LocalTaskList;
|
||||
import at.bitfire.davdroid.resource.ServerInfo;
|
||||
import at.bitfire.davdroid.ui.DebugInfoActivity;
|
||||
|
||||
public class QueryServerDialogFragment extends DialogFragment implements LoaderCallbacks<ServerInfo> {
|
||||
private static final String TAG = "davdroid.QueryServer";
|
||||
public static final String
|
||||
EXTRA_BASE_URI = "base_uri",
|
||||
EXTRA_USER_NAME = "user_name",
|
||||
EXTRA_PASSWORD = "password",
|
||||
EXTRA_AUTH_PREEMPTIVE = "auth_preemptive";
|
||||
public static final String KEY_SERVER_INFO = "server_info";
|
||||
|
||||
@Override
|
||||
public static QueryServerDialogFragment newInstance(ServerInfo serverInfo) {
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable(KEY_SERVER_INFO, serverInfo);
|
||||
QueryServerDialogFragment fragment = new QueryServerDialogFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
ProgressDialog dialog = new ProgressDialog(getActivity());
|
||||
dialog.setCancelable(false);
|
||||
dialog.setTitle(R.string.setup_resource_detection);
|
||||
dialog.setIndeterminate(true);
|
||||
dialog.setMessage(getString(R.string.setup_querying_server));
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog);
|
||||
setCancelable(false);
|
||||
|
||||
Loader<ServerInfo> loader = getLoaderManager().initLoader(0, getArguments(), this);
|
||||
if (savedInstanceState == null) // http://code.google.com/p/android/issues/detail?id=14944
|
||||
loader.forceLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.setup_query_server, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<ServerInfo> onCreateLoader(int id, Bundle args) {
|
||||
Log.i(TAG, "onCreateLoader");
|
||||
return new ServerInfoLoader(getActivity(), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<ServerInfo> loader, ServerInfo serverInfo) {
|
||||
if (serverInfo.getErrorMessage() != null)
|
||||
Toast.makeText(getActivity(), serverInfo.getErrorMessage(), Toast.LENGTH_LONG).show();
|
||||
else {
|
||||
((AddAccountActivity)getActivity()).serverInfo = serverInfo;
|
||||
if (serverInfo.isEmpty()) {
|
||||
// resource detection didn't find anything
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(NothingDetectedFragment.newInstance(serverInfo.getLogs()), null)
|
||||
.commitAllowingStateLoss();
|
||||
|
||||
Fragment nextFragment;
|
||||
if (serverInfo.getTaskLists().length > 0 && !LocalTaskList.tasksProviderAvailable(getActivity().getContentResolver()))
|
||||
nextFragment = new InstallAppsFragment();
|
||||
else
|
||||
nextFragment = new SelectCollectionsFragment();
|
||||
} else {
|
||||
((AddAccountActivity) getActivity()).serverInfo = serverInfo;
|
||||
|
||||
// resource detection brought some results
|
||||
Fragment nextFragment;
|
||||
if (serverInfo.getTaskLists().length > 0 && !LocalTaskList.tasksProviderAvailable(getActivity().getContentResolver()))
|
||||
nextFragment = new InstallAppsFragment();
|
||||
else
|
||||
nextFragment = new SelectCollectionsFragment();
|
||||
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(R.id.right_pane, nextFragment)
|
||||
.addToBackStack(null)
|
||||
.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(R.id.right_pane, nextFragment)
|
||||
.addToBackStack(null)
|
||||
.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
getDialog().dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<ServerInfo> arg0) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class NothingDetectedFragment extends DialogFragment {
|
||||
private static String KEY_LOGS = "logs";
|
||||
|
||||
public static NothingDetectedFragment newInstance(String logs) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(KEY_LOGS, logs);
|
||||
NothingDetectedFragment fragment = new NothingDetectedFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.setup_resource_detection)
|
||||
.setIcon(android.R.drawable.ic_dialog_info)
|
||||
.setMessage(R.string.setup_no_collections_found)
|
||||
.setNeutralButton(R.string.setup_view_logs, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent intent = new Intent(getActivity(), DebugInfoActivity.class);
|
||||
intent.putExtra(DebugInfoActivity.KEY_LOGS, getArguments().getString(KEY_LOGS));
|
||||
startActivity(intent);
|
||||
}
|
||||
})
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
// dismiss
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
static class ServerInfoLoader extends AsyncTaskLoader<ServerInfo> {
|
||||
private static final String TAG = "davdroid.ServerInfoLoader";
|
||||
@ -100,36 +139,22 @@ public class QueryServerDialogFragment extends DialogFragment implements LoaderC
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerInfo loadInBackground() {
|
||||
ServerInfo serverInfo = new ServerInfo(
|
||||
URI.create(args.getString(EXTRA_BASE_URI)),
|
||||
args.getString(EXTRA_USER_NAME),
|
||||
args.getString(EXTRA_PASSWORD),
|
||||
args.getBoolean(EXTRA_AUTH_PREEMPTIVE)
|
||||
);
|
||||
|
||||
try {
|
||||
DavResourceFinder finder = new DavResourceFinder(null, context, serverInfo);
|
||||
finder.findResources();
|
||||
} catch (URISyntaxException e) {
|
||||
serverInfo.setErrorMessage(getContext().getString(R.string.exception_uri_syntax, e.getMessage()));
|
||||
} catch (IOException e) {
|
||||
// general message
|
||||
serverInfo.setErrorMessage(getContext().getString(R.string.exception_io, e.getLocalizedMessage()));
|
||||
// overwrite by more specific message, if possible
|
||||
/*if (ExceptionUtils.indexOfType(e, CertPathValidatorException.class) != -1)
|
||||
serverInfo.setErrorMessage(getContext().getString(R.string.exception_cert_path_validation, e.getMessage()));*/
|
||||
} catch (HttpException e) {
|
||||
Constants.log.error("HTTP error while querying server info", e);
|
||||
serverInfo.setErrorMessage(getContext().getString(R.string.exception_http, e.getLocalizedMessage()));
|
||||
} catch (DavException e) {
|
||||
Constants.log.error("DAV error while querying server info", e);
|
||||
serverInfo.setErrorMessage(getContext().getString(R.string.exception_incapable_resource, e.getLocalizedMessage()));
|
||||
}
|
||||
|
||||
ServerInfo serverInfo = (ServerInfo)args.getSerializable(KEY_SERVER_INFO);
|
||||
|
||||
StringLogger logger = new StringLogger("DavResourceFinder", true);
|
||||
DavResourceFinder finder = new DavResourceFinder(logger, context, serverInfo);
|
||||
finder.findResources();
|
||||
|
||||
serverInfo.setLogs(logger.toString());
|
||||
return serverInfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -169,8 +169,10 @@
|
||||
<string name="settings_version_update_title">Settings have been updated</string>
|
||||
<string name="settings_version_update_description">Internal settings have been updated. If there are problems, please delete your DAVdroid accounts and add them again.</string>
|
||||
|
||||
<string name="setup_resource_detection">Resource detection</string>
|
||||
<string name="setup_no_collections_found">No address books or calendars were found.</string>
|
||||
<string name="setup_view_logs">View logs</string>
|
||||
<string name="setup_select_collections">DAVdroid: Select collections</string>
|
||||
<string name="setup_neither_caldav_nor_carddav">No CalDAV-/CardDAV service is available at this location.</string>
|
||||
<string name="setup_add_account">Add account</string>
|
||||
<string name="setup_querying_server">Querying server. Please wait…</string>
|
||||
<string name="setup_install_apps_info">Plain Android doesn\'t support to-do lists (in contrast to contacts and calendars).</string>
|
||||
|
11
scripts/fetch-translations.sh
Executable file
11
scripts/fetch-translations.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
declare -A android
|
||||
android=([ca]=ca [cs]=cs [de]=de [es]=es [fr]=fr [hu]=hu [nl]=nl [pl]=pl [pt]=pt [ru]=ru [sr]=sr [uk]=uk [zh_CN]=zh-rcn)
|
||||
|
||||
for lang in ${!android[@]}
|
||||
do
|
||||
target=../app/src/main/res/values-${android[$lang]}
|
||||
mkdir -p $target
|
||||
curl -n "https://www.transifex.com/api/2/project/davdroid/resource/davdroid/translation/$lang?file" >$target/strings.xml
|
||||
done
|
Loading…
Reference in New Issue
Block a user