mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2025-12-25 08:07:56 -05:00
Compare commits
1 Commits
v2.22.0
...
group_db_i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70cdb18c51 |
@@ -1,9 +1,8 @@
|
||||
# Changelog
|
||||
|
||||
## v2.22.0 - 118
|
||||
## Unreleased - 118
|
||||
|
||||
- Support setting start of card validity
|
||||
- Fix Stocard import (Stocard's export format changed)
|
||||
|
||||
## v2.21.2 - 117
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ android {
|
||||
applicationId "me.hackerchick.catima"
|
||||
minSdk 21
|
||||
targetSdk 33
|
||||
versionCode 118
|
||||
versionName "2.22.0"
|
||||
versionCode 117
|
||||
versionName "2.21.2"
|
||||
|
||||
vectorDrawables.useSupportLibrary true
|
||||
multiDexEnabled true
|
||||
|
||||
@@ -21,11 +21,12 @@ import java.util.List;
|
||||
public class DBHelper extends SQLiteOpenHelper {
|
||||
public static final String DATABASE_NAME = "Catima.db";
|
||||
public static final int ORIGINAL_DATABASE_VERSION = 1;
|
||||
public static final int DATABASE_VERSION = 16;
|
||||
public static final int DATABASE_VERSION = 17;
|
||||
|
||||
public static class LoyaltyCardDbGroups {
|
||||
public static final String TABLE = "groups";
|
||||
public static final String ID = "_id";
|
||||
public static final String NAME = "name";
|
||||
public static final String ORDER = "orderId";
|
||||
}
|
||||
|
||||
@@ -87,7 +88,8 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
// create table for card groups
|
||||
db.execSQL("CREATE TABLE " + LoyaltyCardDbGroups.TABLE + "(" +
|
||||
LoyaltyCardDbGroups.ID + " TEXT primary key not null," +
|
||||
LoyaltyCardDbGroups.ID + " INTEGER primary key autoincrement," +
|
||||
LoyaltyCardDbGroups.NAME + " TEXT not null," +
|
||||
LoyaltyCardDbGroups.ORDER + " INTEGER DEFAULT '0')");
|
||||
|
||||
// create table for cards
|
||||
@@ -112,7 +114,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
// create associative table for cards in groups
|
||||
db.execSQL("CREATE TABLE " + LoyaltyCardDbIdsGroups.TABLE + "(" +
|
||||
LoyaltyCardDbIdsGroups.cardID + " INTEGER," +
|
||||
LoyaltyCardDbIdsGroups.groupID + " TEXT," +
|
||||
LoyaltyCardDbIdsGroups.groupID + " INTEGER," +
|
||||
"primary key (" + LoyaltyCardDbIdsGroups.cardID + "," + LoyaltyCardDbIdsGroups.groupID + "))");
|
||||
|
||||
// create FTS search table
|
||||
@@ -321,6 +323,70 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbIds.VALID_FROM + " INTEGER");
|
||||
}
|
||||
|
||||
if (oldVersion < 17 && newVersion >= 17) {
|
||||
// SQLite doesn't support modify column
|
||||
// So we need to create a temp column to change the key of the group table
|
||||
// https://www.sqlite.org/faq.html#q11
|
||||
db.beginTransaction();
|
||||
|
||||
// Step 1: Migrate LoyaltyCardDbGroups to contain integer ID
|
||||
db.execSQL("CREATE TEMPORARY TABLE tmp (" +
|
||||
LoyaltyCardDbGroups.ID + " INTEGER primary key autoincrement," +
|
||||
LoyaltyCardDbGroups.NAME + " TEXT not null," +
|
||||
LoyaltyCardDbGroups.ORDER + " INTEGER DEFAULT '0')");
|
||||
|
||||
db.execSQL("INSERT INTO tmp (" +
|
||||
LoyaltyCardDbGroups.NAME + " ," +
|
||||
LoyaltyCardDbGroups.ORDER + ")" +
|
||||
" SELECT " +
|
||||
LoyaltyCardDbGroups.NAME + " ," +
|
||||
LoyaltyCardDbGroups.ORDER +
|
||||
" FROM " + LoyaltyCardDbGroups.TABLE);
|
||||
|
||||
db.execSQL("DROP TABLE " + LoyaltyCardDbGroups.TABLE);
|
||||
|
||||
db.execSQL("CREATE TABLE " + LoyaltyCardDbGroups.TABLE + "(" +
|
||||
LoyaltyCardDbGroups.ID + " INTEGER primary key autoincrement," +
|
||||
LoyaltyCardDbGroups.NAME + " TEXT not null," +
|
||||
LoyaltyCardDbGroups.ORDER + " INTEGER DEFAULT '0')");
|
||||
|
||||
db.execSQL("INSERT INTO " + LoyaltyCardDbGroups.TABLE + "(" +
|
||||
LoyaltyCardDbGroups.ID + " ," +
|
||||
LoyaltyCardDbGroups.NAME + " ," +
|
||||
LoyaltyCardDbGroups.ORDER + ")" +
|
||||
" SELECT " +
|
||||
LoyaltyCardDbGroups.ID + " ," +
|
||||
LoyaltyCardDbGroups.NAME + " ," +
|
||||
LoyaltyCardDbGroups.ORDER +
|
||||
" FROM tmp");
|
||||
|
||||
db.execSQL("DROP TABLE tmp");
|
||||
|
||||
// Step 2: Migrate LoyaltyCardDbIdsGroups to link to ID
|
||||
db.execSQL("CREATE TEMPORARY TABLE tmp (" +
|
||||
LoyaltyCardDbIdsGroups.cardID + " INTEGER," +
|
||||
LoyaltyCardDbIdsGroups.groupID + " INTEGER," +
|
||||
"primary key (" + LoyaltyCardDbIdsGroups.cardID + "," + LoyaltyCardDbIdsGroups.groupID + "))");
|
||||
|
||||
|
||||
db.execSQL("INSERT INTO tmp (" +
|
||||
LoyaltyCardDbIdsGroups.cardID + " ," +
|
||||
LoyaltyCardDbIdsGroups.groupID + ")" +
|
||||
" SELECT " +
|
||||
LoyaltyCardDbGroups.NAME + " ," +
|
||||
LoyaltyCardDbGroups.ORDER +
|
||||
" FROM " + LoyaltyCardDbGroups.TABLE);
|
||||
|
||||
//////////
|
||||
db.execSQL("CREATE TABLE " + LoyaltyCardDbIdsGroups.TABLE + "(" +
|
||||
LoyaltyCardDbIdsGroups.cardID + " INTEGER," +
|
||||
LoyaltyCardDbIdsGroups.groupID + " INTEGER," +
|
||||
"primary key (" + LoyaltyCardDbIdsGroups.cardID + "," + LoyaltyCardDbIdsGroups.groupID + "))");
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
private static ContentValues generateFTSContentValues(final int id, final String store, final String note) {
|
||||
|
||||
@@ -74,31 +74,29 @@ public class StocardImporter implements Importer {
|
||||
String fileName = localFileHeader.getFileName();
|
||||
String[] nameParts = fileName.split("/");
|
||||
|
||||
if (nameParts.length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (providersFileName == null) {
|
||||
providersFileName = new String[]{
|
||||
"extracts",
|
||||
nameParts[1],
|
||||
nameParts[0],
|
||||
"sync",
|
||||
"data",
|
||||
"users",
|
||||
nameParts[1],
|
||||
"analytics-properties",
|
||||
"content.json"
|
||||
nameParts[0],
|
||||
"analytics-properties.json"
|
||||
};
|
||||
customProvidersBaseName = new String[]{
|
||||
"extracts",
|
||||
nameParts[1],
|
||||
nameParts[0],
|
||||
"sync",
|
||||
"data",
|
||||
"users",
|
||||
nameParts[1],
|
||||
nameParts[0],
|
||||
"loyalty-card-custom-providers"
|
||||
};
|
||||
cardBaseName = new String[]{
|
||||
"extracts",
|
||||
nameParts[1],
|
||||
nameParts[0],
|
||||
"sync",
|
||||
"data",
|
||||
"users",
|
||||
nameParts[1],
|
||||
nameParts[0],
|
||||
"loyalty-cards"
|
||||
};
|
||||
}
|
||||
@@ -108,15 +106,18 @@ public class StocardImporter implements Importer {
|
||||
customProviderId = nameParts[customProvidersBaseName.length].split("\\.", 2)[0];
|
||||
|
||||
// Name file
|
||||
if (fileName.endsWith(customProviderId + "/content.json")) {
|
||||
JSONObject jsonObject = ZipUtils.readJSON(zipInputStream);
|
||||
if (nameParts.length == customProvidersBaseName.length + 1) {
|
||||
// Ignore the .txt file
|
||||
if (fileName.endsWith(".json")) {
|
||||
JSONObject jsonObject = ZipUtils.readJSON(zipInputStream);
|
||||
|
||||
providers = appendToHashMap(
|
||||
providers,
|
||||
customProviderId,
|
||||
"name",
|
||||
jsonObject.getString("name")
|
||||
);
|
||||
providers = appendToHashMap(
|
||||
providers,
|
||||
customProviderId,
|
||||
"name",
|
||||
jsonObject.getString("name")
|
||||
);
|
||||
}
|
||||
} else if (fileName.endsWith("logo.png")) {
|
||||
providers = appendToHashMap(
|
||||
providers,
|
||||
@@ -132,43 +133,46 @@ public class StocardImporter implements Importer {
|
||||
cardName = nameParts[cardBaseName.length].split("\\.", 2)[0];
|
||||
|
||||
// This is the card itself
|
||||
if (fileName.endsWith(cardName + "/content.json")) {
|
||||
JSONObject jsonObject = ZipUtils.readJSON(zipInputStream);
|
||||
if (nameParts.length == cardBaseName.length + 1) {
|
||||
// Ignore the .txt file
|
||||
if (fileName.endsWith(".json")) {
|
||||
JSONObject jsonObject = ZipUtils.readJSON(zipInputStream);
|
||||
|
||||
loyaltyCardHashMap = appendToHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"cardId",
|
||||
jsonObject.getString("input_id")
|
||||
);
|
||||
|
||||
// Provider ID can be either custom or not, extract whatever version is relevant
|
||||
String customProviderPrefix = "/users/" + nameParts[1] + "/loyalty-card-custom-providers/";
|
||||
String providerId = jsonObject
|
||||
.getJSONObject("input_provider_reference")
|
||||
.getString("identifier");
|
||||
if (providerId.startsWith(customProviderPrefix)) {
|
||||
providerId = providerId.substring(customProviderPrefix.length());
|
||||
} else {
|
||||
providerId = providerId.substring("/loyalty-card-providers/".length());
|
||||
}
|
||||
|
||||
loyaltyCardHashMap = appendToHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"_providerId",
|
||||
providerId
|
||||
);
|
||||
|
||||
if (jsonObject.has("input_barcode_format")) {
|
||||
loyaltyCardHashMap = appendToHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"barcodeType",
|
||||
jsonObject.getString("input_barcode_format")
|
||||
"cardId",
|
||||
jsonObject.getString("input_id")
|
||||
);
|
||||
|
||||
// Provider ID can be either custom or not, extract whatever version is relevant
|
||||
String customProviderPrefix = "/users/" + nameParts[0] + "/loyalty-card-custom-providers/";
|
||||
String providerId = jsonObject
|
||||
.getJSONObject("input_provider_reference")
|
||||
.getString("identifier");
|
||||
if (providerId.startsWith(customProviderPrefix)) {
|
||||
providerId = providerId.substring(customProviderPrefix.length());
|
||||
} else {
|
||||
providerId = providerId.substring("/loyalty-card-providers/".length());
|
||||
}
|
||||
|
||||
loyaltyCardHashMap = appendToHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"_providerId",
|
||||
providerId
|
||||
);
|
||||
|
||||
if (jsonObject.has("input_barcode_format")) {
|
||||
loyaltyCardHashMap = appendToHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"barcodeType",
|
||||
jsonObject.getString("input_barcode_format")
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (fileName.endsWith("notes/default/content.json")) {
|
||||
} else if (fileName.endsWith("notes/default.json")) {
|
||||
loyaltyCardHashMap = appendToHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
|
||||
@@ -2,18 +2,6 @@
|
||||
|
||||
stocard_stores.csv was created by extracting /data/data/de.stocard/de.stocard.stocard/databases/stores on a rooted devices and running the following command over it:
|
||||
|
||||
```
|
||||
sqlite3 -header -csv sync_db "select id,content from synced_resources where collection = '/loyalty-card-providers/'" > stocard_providers.csv
|
||||
while IFS= read -r line; do
|
||||
if [ "$line" = "id,content" ]; then
|
||||
echo "_id,name,barcodeFormat" > stocard_stores.csv
|
||||
else
|
||||
id="$(echo "$line" | cut -d ',' -f1)"
|
||||
name="$(echo "$line" | cut -d ',' -f2- | sed 's/""/"/g' | sed 's/^"//g' | sed 's/"$//g' | jq -r .name)"
|
||||
barcodeFormat="$(echo "$line" | cut -d ',' -f2- | sed 's/""/"/g' | sed 's/^"//g' | sed 's/"$//g' | jq -r .default_barcode_format)"
|
||||
echo "$id,\"$name\",$barcodeFormat" >> stocard_stores.csv
|
||||
fi
|
||||
done < stocard_providers.csv
|
||||
```
|
||||
sqlite3 -header -csv stores "select _id,name,barcodeFormat from stores" > stocard_stores.csv
|
||||
|
||||
Only used for data portability reasons (ensuring importing works). Do NOT copy this anywhere else or use it for any purpose other than ensuring we can import a GDPR-provided export. We want to make sure this stays under fair use.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -290,5 +290,4 @@
|
||||
<string name="noCameraPermissionDirectToSystemSetting">لمسح الباركود، ستحتاج Catima إلى الوصول إلى الكاميرا. اضغط هنا لتغيير إعدادات الأذونات.</string>
|
||||
<string name="updateBalance">تحديث الرصيد</string>
|
||||
<string name="updateBalanceHint">أدخل المبلغ</string>
|
||||
<string name="storageReadPermissionRequired">الصلاحيه للوصل للتخزين مطلوبة لهذا الاجراء</string>
|
||||
</resources>
|
||||
@@ -1222,10 +1222,6 @@ public class ImportExportTest {
|
||||
|
||||
@Test
|
||||
public void importStocard() throws IOException {
|
||||
// FIXME: The provided stocard.zip is a very old export (8 July 2021) manually edited to
|
||||
// look more like the Stocard files provided by users for #1242. It is not an up-to-date
|
||||
// export and the test is possibly unreliable. This should be replaced by an up-to-date
|
||||
// export.
|
||||
InputStream inputStream = getClass().getResourceAsStream("stocard.zip");
|
||||
|
||||
// Import the Stocard data
|
||||
@@ -1275,7 +1271,8 @@ public class ImportExportTest {
|
||||
|
||||
card = DBHelper.getLoyaltyCard(mDatabase, 3);
|
||||
|
||||
assertEquals("jö", card.store);
|
||||
// I don't think we can know this one, but falling back to an unique store name is at least something
|
||||
assertEquals("63536738-d64b-48ae-aeb8-82761523fa67", card.store);
|
||||
assertEquals("", card.note);
|
||||
assertEquals(null, card.validFrom);
|
||||
assertEquals(null, card.expiry);
|
||||
|
||||
Binary file not shown.
@@ -1,2 +1 @@
|
||||
- Support setting start of card validity
|
||||
- Fix Stocard import (Stocard's export format changed)
|
||||
- Support setting start of card validity
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 52 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 50 KiB |
@@ -1,2 +0,0 @@
|
||||
- Correction de la boîte de dialogue de dépense rapide qui ne permettait pas l'utilisation de la virgule comme séparateur
|
||||
- Prise en charge du chargement d'images à partir du gestionnaire de fichiers
|
||||
@@ -1,6 +1,5 @@
|
||||
- При редактировании номера, поле предварительно заполняется текущим. (№94)
|
||||
- Ограничена ширина формируемых штрихкодов для уменьшения потребления памяти. (№103)
|
||||
- Кнопка «Ввести карту» меняется на «Изменить карту», если указанный номер уже используется. (№104)
|
||||
- Цветовая гамма смягчена и сочетается со значком приложения, упрощена страница просмотра карты. (№107)
|
||||
- Сделан вводный мастер для первого запуска приложения. (№108)
|
||||
Все запросы см. в https://github.com/brarcher/loyalty-card-locker/pull/
|
||||
- При редактировании номера карты, поле предварительно заполняется текущим номером. (запрос №94 (https://github.com/brarcher/loyalty-card-locker/pull/94))
|
||||
- Ширина формируемых штрихкодов ограничена для уменьшения потребления памяти и ошибок её нехватки. (запрос №103 (https://github.com/brarcher/loyalty-card-locker/pull/103))
|
||||
- При редактировании карты кнопка ввода карты меняется на кнопку редактирования, если указанный номер уже используется. (запрос №104 (https://github.com/brarcher/loyalty-card-locker/pull/104))
|
||||
- Цветовая гамма изменена на более мягкую и сочетающуюся с значком приложения, упрощена страница просмотра карты. (запрос №107 (https://github.com/brarcher/loyalty-card-locker/pull/107))
|
||||
- Добавлен вводный мастер, включающийся при первом запуске приложения. (запрос №108 (https://github.com/brarcher/loyalty-card-locker/pull/108))
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
- Förbättrat stöd för skärmläsare
|
||||
- Kraschar inte vid försök att öppna en video från galleriet
|
||||
- Svepstöd på lojalitetskortets översiktssida
|
||||
- Nollställ inte grupp vid klickning på tillbakaknappen
|
||||
- Kraschar inte när den försöker öppna en video från galleriet
|
||||
|
||||
Reference in New Issue
Block a user