mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2026-04-05 08:03:47 -04:00
Merge pull request #1434 from obfusk/refactor-importer-part-2
refactor importer part 2
This commit is contained in:
@@ -19,10 +19,13 @@ import java.io.StringReader;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import protect.card_locker.CatimaBarcode;
|
||||
import protect.card_locker.DBHelper;
|
||||
import protect.card_locker.FormatException;
|
||||
import protect.card_locker.LoyaltyCard;
|
||||
import protect.card_locker.Utils;
|
||||
|
||||
/**
|
||||
@@ -33,6 +36,14 @@ import protect.card_locker.Utils;
|
||||
* A header is expected for the each table showing the names of the columns.
|
||||
*/
|
||||
public class FidmeImporter implements Importer {
|
||||
public static class ImportedData {
|
||||
public final List<LoyaltyCard> cards;
|
||||
|
||||
ImportedData(final List<LoyaltyCard> cards) {
|
||||
this.cards = cards;
|
||||
}
|
||||
}
|
||||
|
||||
public void importData(Context context, SQLiteDatabase database, File inputFile, char[] password) throws IOException, FormatException, JSONException, ParseException {
|
||||
InputStream input = new FileInputStream(inputFile);
|
||||
// We actually retrieve a .zip file
|
||||
@@ -57,10 +68,14 @@ public class FidmeImporter implements Importer {
|
||||
}
|
||||
|
||||
final CSVParser fidmeParser = new CSVParser(new StringReader(loyaltyCards.toString()), CSVFormat.RFC4180.builder().setDelimiter(';').setHeader().build());
|
||||
ImportedData importedData = new ImportedData(new ArrayList<>());
|
||||
|
||||
try {
|
||||
for (CSVRecord record : fidmeParser) {
|
||||
importLoyaltyCard(context, database, record);
|
||||
LoyaltyCard card = importLoyaltyCard(context, record);
|
||||
if (card != null) {
|
||||
importedData.cards.add(card);
|
||||
}
|
||||
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
@@ -74,14 +89,15 @@ public class FidmeImporter implements Importer {
|
||||
|
||||
zipInputStream.close();
|
||||
input.close();
|
||||
|
||||
saveAndDeduplicate(database, importedData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a single loyalty card into the database using the given
|
||||
* session.
|
||||
*/
|
||||
private void importLoyaltyCard(Context context, SQLiteDatabase database, CSVRecord record)
|
||||
throws FormatException {
|
||||
private LoyaltyCard importLoyaltyCard(Context context, CSVRecord record) throws FormatException {
|
||||
// A loyalty card export from Fidme contains the following fields:
|
||||
// Retailer (store name)
|
||||
// Program (program name)
|
||||
@@ -117,7 +133,7 @@ public class FidmeImporter implements Importer {
|
||||
// Fidme deletes the card id if a card is expired
|
||||
// Because Catima considers the card id a required field, we ignore these expired cards
|
||||
// https://github.com/CatimaLoyalty/Android/issues/1005
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Sadly, Fidme exports don't contain the card type
|
||||
@@ -132,6 +148,17 @@ public class FidmeImporter implements Importer {
|
||||
|
||||
// TODO: Front and back image
|
||||
|
||||
DBHelper.insertLoyaltyCard(database, store, note, null, null, BigDecimal.valueOf(0), null, cardId, null, barcodeType, headerColor, starStatus, null,archiveStatus);
|
||||
// use -1 for the ID, it will be ignored when inserting the card into the DB
|
||||
return new LoyaltyCard(-1, store, note, null, null, BigDecimal.valueOf(0), null, cardId, null, barcodeType, headerColor, starStatus, Utils.getUnixTime(), DBHelper.DEFAULT_ZOOM_LEVEL, archiveStatus);
|
||||
}
|
||||
|
||||
public void saveAndDeduplicate(SQLiteDatabase database, final ImportedData data) {
|
||||
// This format does not have IDs that can cause conflicts
|
||||
// Proper deduplication for all formats will be implemented later
|
||||
for (LoyaltyCard card : data.cards) {
|
||||
// Do not use card.id which is set to -1
|
||||
DBHelper.insertLoyaltyCard(database, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,16 @@ import java.io.InputStreamReader;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import protect.card_locker.CatimaBarcode;
|
||||
import protect.card_locker.DBHelper;
|
||||
import protect.card_locker.FormatException;
|
||||
import protect.card_locker.ImageLocationType;
|
||||
import protect.card_locker.LoyaltyCard;
|
||||
import protect.card_locker.R;
|
||||
import protect.card_locker.Utils;
|
||||
import protect.card_locker.ZipUtils;
|
||||
@@ -42,11 +46,30 @@ import protect.card_locker.ZipUtils;
|
||||
* A header is expected for the each table showing the names of the columns.
|
||||
*/
|
||||
public class StocardImporter implements Importer {
|
||||
public static class ZIPData {
|
||||
public final HashMap<String, HashMap<String, Object>> loyaltyCardHashMap;
|
||||
public final HashMap<String, HashMap<String, Object>> providers;
|
||||
|
||||
ZIPData(final HashMap<String, HashMap<String, Object>> loyaltyCardHashMap, final HashMap<String, HashMap<String, Object>> providers) {
|
||||
this.loyaltyCardHashMap = loyaltyCardHashMap;
|
||||
this.providers = providers;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ImportedData {
|
||||
public final List<LoyaltyCard> cards;
|
||||
public final Map<Integer, Map<ImageLocationType, Bitmap>> images;
|
||||
|
||||
ImportedData(final List<LoyaltyCard> cards, final Map<Integer, Map<ImageLocationType, Bitmap>> images) {
|
||||
this.cards = cards;
|
||||
this.images = images;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
public void importData(Context context, SQLiteDatabase database, File inputFile, char[] password) throws IOException, FormatException, JSONException, ParseException {
|
||||
HashMap<String, HashMap<String, Object>> loyaltyCardHashMap = new HashMap<>();
|
||||
HashMap<String, HashMap<String, Object>> providers = new HashMap<>();
|
||||
ZIPData zipData = new ZIPData(new HashMap<>(), new HashMap<>());
|
||||
|
||||
final CSVParser parser = new CSVParser(new InputStreamReader(context.getResources().openRawResource(R.raw.stocard_stores), StandardCharsets.UTF_8), CSVFormat.RFC4180.builder().setHeader().build());
|
||||
|
||||
@@ -56,7 +79,7 @@ public class StocardImporter implements Importer {
|
||||
recordData.put("name", record.get("name"));
|
||||
recordData.put("barcodeFormat", record.get("barcodeFormat"));
|
||||
|
||||
providers.put(record.get("_id"), recordData);
|
||||
zipData.providers.put(record.get("_id"), recordData);
|
||||
}
|
||||
|
||||
parser.close();
|
||||
@@ -66,6 +89,21 @@ public class StocardImporter implements Importer {
|
||||
|
||||
InputStream input = new FileInputStream(inputFile);
|
||||
ZipInputStream zipInputStream = new ZipInputStream(input, password);
|
||||
zipData = importZIP(zipInputStream, zipData);
|
||||
zipInputStream.close();
|
||||
input.close();
|
||||
|
||||
if (zipData.loyaltyCardHashMap.keySet().size() == 0) {
|
||||
throw new FormatException("Couldn't find any loyalty cards in this Stocard export.");
|
||||
}
|
||||
|
||||
ImportedData importedData = importLoyaltyCardHashMap(context, zipData);
|
||||
saveAndDeduplicate(context, database, importedData);
|
||||
}
|
||||
|
||||
public ZIPData importZIP(ZipInputStream zipInputStream, final ZIPData zipData) throws IOException, JSONException {
|
||||
HashMap<String, HashMap<String, Object>> loyaltyCardHashMap = zipData.loyaltyCardHashMap;
|
||||
HashMap<String, HashMap<String, Object>> providers = zipData.providers;
|
||||
|
||||
String[] providersFileName = null;
|
||||
String[] customProvidersBaseName = null;
|
||||
@@ -197,11 +235,14 @@ public class StocardImporter implements Importer {
|
||||
}
|
||||
}
|
||||
|
||||
if (loyaltyCardHashMap.keySet().size() == 0) {
|
||||
throw new FormatException("Couldn't find any loyalty cards in this Stocard export.");
|
||||
}
|
||||
return new ZIPData(loyaltyCardHashMap, providers);
|
||||
}
|
||||
|
||||
for (HashMap<String, Object> loyaltyCardData : loyaltyCardHashMap.values()) {
|
||||
public ImportedData importLoyaltyCardHashMap(Context context, final ZIPData zipData) {
|
||||
ImportedData importedData = new ImportedData(new ArrayList<>(), new HashMap<>());
|
||||
int tempID = 0;
|
||||
|
||||
for (Map<String, Object> loyaltyCardData : zipData.loyaltyCardHashMap.values()) {
|
||||
String providerId = (String) loyaltyCardData.get("_providerId");
|
||||
|
||||
if (providerId == null) {
|
||||
@@ -209,7 +250,7 @@ public class StocardImporter implements Importer {
|
||||
continue;
|
||||
}
|
||||
|
||||
HashMap<String, Object> providerData = providers.get(providerId);
|
||||
HashMap<String, Object> providerData = zipData.providers.get(providerId);
|
||||
|
||||
String store = providerData != null ? providerData.get("name").toString() : providerId;
|
||||
String note = (String) Utils.mapGetOrDefault(loyaltyCardData, "note", "");
|
||||
@@ -233,22 +274,39 @@ public class StocardImporter implements Importer {
|
||||
headerColor = Utils.getHeaderColorFromImage(cardIcon, headerColor);
|
||||
}
|
||||
|
||||
long loyaltyCardInternalId = DBHelper.insertLoyaltyCard(database, store, note, null, null, BigDecimal.valueOf(0), null, cardId, null, barcodeType, headerColor, 0, null,0);
|
||||
LoyaltyCard card = new LoyaltyCard(tempID, store, note, null, null, BigDecimal.valueOf(0), null, cardId, null, barcodeType, headerColor, 0, Utils.getUnixTime(), DBHelper.DEFAULT_ZOOM_LEVEL, 0);
|
||||
importedData.cards.add(card);
|
||||
|
||||
Map<ImageLocationType, Bitmap> images = new HashMap<>();
|
||||
|
||||
if (cardIcon != null) {
|
||||
Utils.saveCardImage(context, cardIcon, (int) loyaltyCardInternalId, ImageLocationType.icon);
|
||||
images.put(ImageLocationType.icon, cardIcon);
|
||||
}
|
||||
|
||||
if (loyaltyCardData.containsKey("frontImage")) {
|
||||
Utils.saveCardImage(context, (Bitmap) loyaltyCardData.get("frontImage"), (int) loyaltyCardInternalId, ImageLocationType.front);
|
||||
images.put(ImageLocationType.front, (Bitmap) loyaltyCardData.get("frontImage"));
|
||||
}
|
||||
if (loyaltyCardData.containsKey("backImage")) {
|
||||
Utils.saveCardImage(context, (Bitmap) loyaltyCardData.get("backImage"), (int) loyaltyCardInternalId, ImageLocationType.back);
|
||||
images.put(ImageLocationType.back, (Bitmap) loyaltyCardData.get("backImage"));
|
||||
}
|
||||
|
||||
importedData.images.put(tempID, images);
|
||||
tempID++;
|
||||
}
|
||||
|
||||
zipInputStream.close();
|
||||
input.close();
|
||||
return importedData;
|
||||
}
|
||||
|
||||
public void saveAndDeduplicate(Context context, SQLiteDatabase database, final ImportedData data) throws IOException {
|
||||
// This format does not have IDs that can cause conflicts
|
||||
// Proper deduplication for all formats will be implemented later
|
||||
for (LoyaltyCard card : data.cards) {
|
||||
// card.id is temporary and only used to index the images Map
|
||||
long id = DBHelper.insertLoyaltyCard(database, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
for (Map.Entry<ImageLocationType, Bitmap> entry : data.images.get(card.id).entrySet()) {
|
||||
Utils.saveCardImage(context, entry.getValue(), (int) id, entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean startsWith(String[] full, String[] start, int minExtraLength) {
|
||||
|
||||
@@ -21,13 +21,16 @@ import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import protect.card_locker.CatimaBarcode;
|
||||
import protect.card_locker.DBHelper;
|
||||
import protect.card_locker.FormatException;
|
||||
import protect.card_locker.LoyaltyCard;
|
||||
import protect.card_locker.Utils;
|
||||
|
||||
/**
|
||||
@@ -38,6 +41,14 @@ import protect.card_locker.Utils;
|
||||
* A header is expected for the each table showing the names of the columns.
|
||||
*/
|
||||
public class VoucherVaultImporter implements Importer {
|
||||
public static class ImportedData {
|
||||
public final List<LoyaltyCard> cards;
|
||||
|
||||
ImportedData(final List<LoyaltyCard> cards) {
|
||||
this.cards = cards;
|
||||
}
|
||||
}
|
||||
|
||||
public void importData(Context context, SQLiteDatabase database, File inputFile, char[] password) throws IOException, FormatException, JSONException, ParseException {
|
||||
InputStream input = new FileInputStream(inputFile);
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
|
||||
@@ -49,6 +60,16 @@ public class VoucherVaultImporter implements Importer {
|
||||
}
|
||||
JSONArray jsonArray = new JSONArray(sb.toString());
|
||||
|
||||
bufferedReader.close();
|
||||
input.close();
|
||||
|
||||
ImportedData importedData = importJSON(jsonArray);
|
||||
saveAndDeduplicate(database, importedData);
|
||||
}
|
||||
|
||||
public ImportedData importJSON(JSONArray jsonArray) throws FormatException, JSONException, ParseException {
|
||||
ImportedData importedData = new ImportedData(new ArrayList<>());
|
||||
|
||||
// See https://github.com/tim-smart/vouchervault/issues/4#issuecomment-788226503 for more info
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject jsonCard = jsonArray.getJSONObject(i);
|
||||
@@ -129,10 +150,20 @@ public class VoucherVaultImporter implements Importer {
|
||||
throw new FormatException("Unknown colour type found: " + colorFromJSON);
|
||||
}
|
||||
|
||||
DBHelper.insertLoyaltyCard(database, store, "", null, expiry, balance, balanceType, cardId, null, barcodeType, headerColor, 0, Utils.getUnixTime(),0);
|
||||
// use -1 for the ID, it will be ignored when inserting the card into the DB
|
||||
importedData.cards.add(new LoyaltyCard(-1, store, "", null, expiry, balance, balanceType, cardId, null, barcodeType, headerColor, 0, Utils.getUnixTime(), DBHelper.DEFAULT_ZOOM_LEVEL, 0));
|
||||
}
|
||||
|
||||
bufferedReader.close();
|
||||
input.close();
|
||||
return importedData;
|
||||
}
|
||||
|
||||
public void saveAndDeduplicate(SQLiteDatabase database, final ImportedData data) {
|
||||
// This format does not have IDs that can cause conflicts
|
||||
// Proper deduplication for all formats will be implemented later
|
||||
for (LoyaltyCard card : data.cards) {
|
||||
// Do not use card.id which is set to -1
|
||||
DBHelper.insertLoyaltyCard(database, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user