Skip to content

Commit

Permalink
Merge branch 'hotfix/6.6.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
ccomeaux committed May 6, 2018
2 parents 960087e + 3a931ae commit 716a3fa
Show file tree
Hide file tree
Showing 22 changed files with 210 additions and 241 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Release Notes
=============

Version 6.6.1
-------------
* Restore missing checkboxes for collection statuses
* Improved sync notifications
* Bug fixes

Version 6.6
-----------
* More UI polish
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ buildscript {

def versionMajor = 6
def versionMinor = 6
def versionPatch = 0
def versionBuild = 4
def versionPatch = 1
def versionBuild = 2

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/boardgamegeek/auth/AccountUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.crashlytics.android.Crashlytics;

Expand All @@ -24,7 +25,8 @@ public static void clearFields(final Context context) {

public static void setUsername(final Context context, final String username) {
setString(context, username, KEY_USERNAME);
Crashlytics.setUserIdentifier(username);
if (!TextUtils.isEmpty(username))
Crashlytics.setUserIdentifier(String.valueOf(username.hashCode()));
}

public static void setFullName(final Context context, String fullName) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package com.boardgamegeek.events

class ExportFinishedEvent(val type: String, val errorMessage: String)
class ExportFinishedEvent(val type: String, val errorMessage: String?)
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package com.boardgamegeek.events

class ImportFinishedEvent(val type: String, val errorMessage: String)
class ImportFinishedEvent(val type: String, val errorMessage: String?)
3 changes: 2 additions & 1 deletion app/src/main/java/com/boardgamegeek/io/AuthInterceptor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ class AuthInterceptor(private val context: Context?) : Interceptor {
if (account != null) {
try {
val password = accountManager.blockingGetAuthToken(account, Authenticator.AUTH_TOKEN_TYPE, true)
if (account.name.isNotBlank() && password.isNotBlank()) {
if (account.name != null && account.name.isNotBlank() &&
password != null && password.isNotBlank()) {
val username = HttpUtils.encode(account.name)
val cookieValue = "bggusername=$username; bggpassword=$password"
val request = originalRequest.newBuilder().addHeader("Cookie", cookieValue).build()
Expand Down
21 changes: 2 additions & 19 deletions app/src/main/java/com/boardgamegeek/model/Buddy.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
package com.boardgamegeek.model;

import com.boardgamegeek.provider.BggContract;
import com.boardgamegeek.util.StringUtils;

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Root;

@Root(name = "buddy")
public class Buddy {
@Attribute
private String id;

@Attribute
public String name;

public int getId() {
return StringUtils.parseInt(id, BggContract.INVALID_ID);
}

public static Buddy fromUser(User user) {
Buddy buddy = new Buddy();
buddy.id = String.valueOf(user.getId());
buddy.name = user.name;
return buddy;
}
@Attribute public String id;
@Attribute public String name;
}
11 changes: 1 addition & 10 deletions app/src/main/java/com/boardgamegeek/model/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Path;

import java.util.ArrayList;

public class User {
@Attribute
private String id;
Expand Down Expand Up @@ -73,16 +71,9 @@ public class User {
private String tradeRating;

@Element(required = false)
private Buddies buddies;
public Buddies buddies;

public int getId() {
return StringUtils.parseInt(id, BggContract.INVALID_ID);
}

public ArrayList<Buddy> getBuddies() {
if (buddies == null || buddies.buddies == null) {
return new ArrayList<>();
}
return new ArrayList<>(buddies.buddies);
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
package com.boardgamegeek.model.persister;

import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;

import com.boardgamegeek.model.Buddy;
import com.boardgamegeek.model.User;
import com.boardgamegeek.provider.BggContract;
import com.boardgamegeek.provider.BggContract.Avatars;
import com.boardgamegeek.provider.BggContract.Buddies;
import com.boardgamegeek.util.FileUtils;
import com.boardgamegeek.util.ResolverUtils;

import java.util.ArrayList;
import java.util.List;

import timber.log.Timber;

public class BuddyPersister {
Expand All @@ -39,14 +33,10 @@ public void resetTimestamp() {
}

public int saveUser(User buddy) {
ContentResolver resolver = context.getContentResolver();
ArrayList<ContentProviderOperation> batch = new ArrayList<>();
StringBuilder debugMessage = new StringBuilder();
if (buddy != null && !TextUtils.isEmpty(buddy.name)) {
Uri uri = Buddies.buildBuddyUri(buddy.name);
ContentValues values = new ContentValues();
values.put(Buddies.UPDATED, updateTime);
int oldSyncHashCode = ResolverUtils.queryInt(resolver, uri, Buddies.SYNC_HASH_CODE);
int oldSyncHashCode = ResolverUtils.queryInt(context.getContentResolver(), Buddies.buildBuddyUri(buddy.name), Buddies.SYNC_HASH_CODE);
int newSyncHashCode = generateSyncHashCode(buddy);
if (oldSyncHashCode != newSyncHashCode) {
values.put(Buddies.BUDDY_ID, buddy.getId());
Expand All @@ -56,74 +46,48 @@ public int saveUser(User buddy) {
values.put(Buddies.AVATAR_URL, buddy.avatarUrl);
values.put(Buddies.SYNC_HASH_CODE, newSyncHashCode);
}
debugMessage.append("Saving ").append(uri).append("; ");
addToBatch(resolver, values, batch, uri, debugMessage);
return upsert(values);
}
ContentProviderResult[] result = ResolverUtils.applyBatch(context, batch, debugMessage.toString());
return result == null ? 0 : result.length;
return 0;
}

public int saveBuddy(Buddy buddy) {
ContentResolver resolver = context.getContentResolver();
if (buddy.getId() != BggContract.INVALID_ID && !TextUtils.isEmpty(buddy.name)) {
Uri uri = Buddies.buildBuddyUri(buddy.name);
ContentValues values = toValues(buddy);
if (!ResolverUtils.rowExists(resolver, uri)) {
Uri insertedUri = resolver.insert(Buddies.CONTENT_URI, values);
Timber.d("Inserted buddy at %s", insertedUri);
return 1;
} else {
int count = resolver.update(uri, values, null, null);
Timber.d("Updated %,d buddy at %s", count, uri);
return count;
}
public int saveBuddy(int userId, String username, boolean isBuddy) {
if (userId != BggContract.INVALID_ID && !TextUtils.isEmpty(username)) {
ContentValues values = new ContentValues();
values.put(Buddies.BUDDY_ID, userId);
values.put(Buddies.BUDDY_NAME, username);
values.put(Buddies.BUDDY_FLAG, isBuddy ? 1 : 0);
values.put(Buddies.UPDATED_LIST, updateTime);

return upsert(values);
} else {
Timber.i("Un-savable buddy %s (%d)", username, userId);
}
return 0;
}

public int saveBuddies(List<Buddy> buddies) {
private int upsert(ContentValues values) {
ContentResolver resolver = context.getContentResolver();
ArrayList<ContentProviderOperation> batch = new ArrayList<>();
StringBuilder debugMessage = new StringBuilder();
if (buddies != null) {
for (Buddy buddy : buddies) {
if (buddy.getId() != BggContract.INVALID_ID && !TextUtils.isEmpty(buddy.name)) {
ContentValues values = toValues(buddy);
addToBatch(resolver, values, batch, Buddies.buildBuddyUri(buddy.name), debugMessage);
}
}
}
ContentProviderResult[] result = ResolverUtils.applyBatch(context, batch, debugMessage.toString());
return result == null ? 0 : result.length;
}

private void addToBatch(ContentResolver resolver, ContentValues values, ArrayList<ContentProviderOperation> batch, Uri uri, StringBuilder debugMessage) {
if (!ResolverUtils.rowExists(resolver, uri)) {
debugMessage.append("Inserting ").append(uri).append("; ");
values.put(Buddies.UPDATED_LIST, updateTime);
batch.add(ContentProviderOperation.newInsert(Buddies.CONTENT_URI).withValues(values).build());
} else {
debugMessage.append("Updating ").append(uri).append("; ");
maybeDeleteAvatar(values, uri, resolver);
String username = values.getAsString(Buddies.BUDDY_NAME);
Uri uri = Buddies.buildBuddyUri(username);
if (ResolverUtils.rowExists(resolver, uri)) {
values.remove(Buddies.BUDDY_NAME);
batch.add(ContentProviderOperation.newUpdate(uri).withValues(values).build());
int count = resolver.update(uri, values, null, null);
Timber.d("Updated %,d buddy rows at %s", count, uri);
maybeDeleteAvatar(values, uri);
return count;
} else {
Uri insertedUri = resolver.insert(Buddies.CONTENT_URI, values);
Timber.d("Inserted buddy at %s", insertedUri);
return 1;
}
}

private ContentValues toValues(Buddy buddy) {
ContentValues values = new ContentValues();
values.put(Buddies.BUDDY_ID, buddy.getId());
values.put(Buddies.BUDDY_NAME, buddy.name);
values.put(Buddies.UPDATED_LIST, updateTime);
values.put(Buddies.BUDDY_FLAG, 1);
return values;
}

private static int generateSyncHashCode(User buddy) {
return (buddy.firstName + "\n" + buddy.lastName + "\n" + buddy.avatarUrl + "\n").hashCode();
}

private static void maybeDeleteAvatar(ContentValues values, Uri uri, ContentResolver resolver) {
private void maybeDeleteAvatar(ContentValues values, Uri uri) {
if (!values.containsKey(Buddies.AVATAR_URL)) {
// nothing to do - no avatar
return;
Expand All @@ -134,16 +98,15 @@ private static void maybeDeleteAvatar(ContentValues values, Uri uri, ContentReso
newAvatarUrl = "";
}

String oldAvatarUrl = ResolverUtils.queryString(resolver, uri, Buddies.AVATAR_URL);
String oldAvatarUrl = ResolverUtils.queryString(context.getContentResolver(), uri, Buddies.AVATAR_URL);
if (newAvatarUrl.equals(oldAvatarUrl)) {
// nothing to do - avatar hasn't changed
return;
}

String avatarFileName = FileUtils.getFileNameFromUrl(oldAvatarUrl);
if (!TextUtils.isEmpty(avatarFileName)) {
// TODO: use batch
resolver.delete(Avatars.buildUri(avatarFileName), null, null);
context.getContentResolver().delete(Avatars.buildUri(avatarFileName), null, null);
}
}
}
20 changes: 9 additions & 11 deletions app/src/main/java/com/boardgamegeek/service/SyncBuddiesDetail.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import timber.log.Timber
import java.io.IOException

abstract class SyncBuddiesDetail(context: Context, service: BggService, syncResult: SyncResult) : SyncTask(context, service, syncResult) {
private var notificationMessage: String? = null
private var notificationMessage: String = ""

/**
* Returns a log message to use for debugging purposes.
Expand Down Expand Up @@ -54,7 +54,7 @@ abstract class SyncBuddiesDetail(context: Context, service: BggService, syncResu
syncResult.stats.numUpdates++
count++

if (wasSleepInterrupted(fetchPauseMillis)) break
if (wasSleepInterrupted(fetchPauseMillis, showNotification = false)) break
}
} else {
Timber.i("...no buddies to update")
Expand All @@ -66,22 +66,20 @@ abstract class SyncBuddiesDetail(context: Context, service: BggService, syncResu
}

private fun requestUser(name: String): User? {
var user: User? = null
try {
val call = service.user(name)
val response = call.execute()
if (!response.isSuccessful) {
showError(notificationMessage!!, response.code())
syncResult.stats.numIoExceptions++
cancel()
}
user = response.body()
if (response.isSuccessful) return response.body()
showError(notificationMessage, response.code())
syncResult.stats.numIoExceptions++
cancel()
return response.body()
} catch (e: IOException) {
showError(notificationMessage!!, e)
showError(notificationMessage, e)
syncResult.stats.numIoExceptions++
cancel()
}

return user
return null
}
}
19 changes: 11 additions & 8 deletions app/src/main/java/com/boardgamegeek/service/SyncBuddiesList.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ import com.boardgamegeek.model.Buddy
import com.boardgamegeek.model.User
import com.boardgamegeek.model.persister.BuddyPersister
import com.boardgamegeek.pref.SyncPrefs
import com.boardgamegeek.provider.BggContract
import com.boardgamegeek.provider.BggContract.Buddies
import com.boardgamegeek.util.DateTimeUtils
import com.boardgamegeek.util.PreferencesUtils
import com.boardgamegeek.util.PresentationUtils
import com.boardgamegeek.util.RemoteConfig
import com.boardgamegeek.util.*
import timber.log.Timber
import java.io.IOException

Expand Down Expand Up @@ -67,7 +65,7 @@ class SyncBuddiesList(context: Context, service: BggService, syncResult: SyncRes
}

private fun updateNotification(@StringRes detailResId: Int) {
currentDetailResId = R.string.sync_notification_buddies_list_downloading
currentDetailResId = detailResId
updateProgressNotification(context.getString(detailResId))
}

Expand Down Expand Up @@ -99,9 +97,14 @@ class SyncBuddiesList(context: Context, service: BggService, syncResult: SyncRes
}

private fun persistUser(user: User) {
var count = 0
count += persister.saveBuddy(Buddy.fromUser(user))
count += persister.saveBuddies(user.buddies)
var count = persister.saveBuddy(user.id, user.name, false)

val buddies = user.buddies?.buddies ?: listOf<Buddy>()
for (buddy in buddies) {
val userId = StringUtils.parseInt(buddy.id, BggContract.INVALID_ID)
count += persister.saveBuddy(userId, buddy.name, true)
}

syncResult.stats.numEntries += count.toLong()
Timber.i("Synced %,d buddies", count)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import hugo.weaving.DebugLog
import timber.log.Timber
import java.io.IOException
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.collections.set

/**
Expand Down Expand Up @@ -79,15 +80,13 @@ class SyncCollectionComplete(context: Context, service: BggService, syncResult:
Timber.i("...cancelled")
return
}
updateProgressNotification()
if (wasSleepInterrupted(5000)) return
if (wasSleepInterrupted(5, TimeUnit.SECONDS)) return
}

val excludedStatuses = (0 until i).map { statuses[it] }
syncByStatus("", statuses[i], *excludedStatuses.toTypedArray())

updateProgressNotification()
if (wasSleepInterrupted(5000)) return
if (wasSleepInterrupted(5, TimeUnit.SECONDS)) return

syncByStatus(BggService.THING_SUBTYPE_BOARDGAME_ACCESSORY, statuses[i], *excludedStatuses.toTypedArray())
}
Expand Down

0 comments on commit 716a3fa

Please sign in to comment.