mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Migrated recentlanguages and repository module from Java to Kotlin (#5948)
* Rename .java to .kt * Migrated recentlanguages module to Kotlin * Rename .java to .kt * Migrated repository module to Kotlin
This commit is contained in:
parent
088dd2479e
commit
fe347c21fd
13 changed files with 825 additions and 798 deletions
|
|
@ -1,122 +0,0 @@
|
|||
package fr.free.nrw.commons.recentlanguages;
|
||||
|
||||
import static fr.free.nrw.commons.recentlanguages.RecentLanguagesDao.Table.COLUMN_NAME;
|
||||
import static fr.free.nrw.commons.recentlanguages.RecentLanguagesDao.Table.TABLE_NAME;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteQueryBuilder;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.NonNull;
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.data.DBOpenHelper;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerContentProvider;
|
||||
import javax.inject.Inject;
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Content provider of recently used languages
|
||||
*/
|
||||
public class RecentLanguagesContentProvider extends CommonsDaggerContentProvider {
|
||||
|
||||
private static final String BASE_PATH = "recent_languages";
|
||||
public static final Uri BASE_URI =
|
||||
Uri.parse("content://" + BuildConfig.RECENT_LANGUAGE_AUTHORITY + "/" + BASE_PATH);
|
||||
|
||||
|
||||
/**
|
||||
* Append language code to the base uri
|
||||
* @param languageCode Code of a language
|
||||
*/
|
||||
public static Uri uriForCode(final String languageCode) {
|
||||
return Uri.parse(BASE_URI + "/" + languageCode);
|
||||
}
|
||||
|
||||
@Inject
|
||||
DBOpenHelper dbOpenHelper;
|
||||
|
||||
@Override
|
||||
public String getType(@NonNull final Uri uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the SQLite database for the recently used languages
|
||||
* @param uri : contains the uri for recently used languages
|
||||
* @param projection : contains the all fields of the table
|
||||
* @param selection : handles Where
|
||||
* @param selectionArgs : the condition of Where clause
|
||||
* @param sortOrder : ascending or descending
|
||||
*/
|
||||
@Override
|
||||
public Cursor query(@NonNull final Uri uri, final String[] projection, final String selection,
|
||||
final String[] selectionArgs, final String sortOrder) {
|
||||
final SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
|
||||
queryBuilder.setTables(TABLE_NAME);
|
||||
final SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
|
||||
final Cursor cursor = queryBuilder.query(db, projection, selection,
|
||||
selectionArgs, null, null, sortOrder);
|
||||
cursor.setNotificationUri(getContext().getContentResolver(), uri);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the update query of local SQLite Database
|
||||
* @param uri : contains the uri for recently used languages
|
||||
* @param contentValues : new values to be entered to db
|
||||
* @param selection : handles Where
|
||||
* @param selectionArgs : the condition of Where clause
|
||||
*/
|
||||
@Override
|
||||
public int update(@NonNull final Uri uri, final ContentValues contentValues,
|
||||
final String selection, final String[] selectionArgs) {
|
||||
final SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
|
||||
final int rowsUpdated;
|
||||
if (TextUtils.isEmpty(selection)) {
|
||||
final int id = Integer.parseInt(uri.getLastPathSegment());
|
||||
rowsUpdated = sqlDB.update(TABLE_NAME,
|
||||
contentValues,
|
||||
COLUMN_NAME + " = ?",
|
||||
new String[]{String.valueOf(id)});
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter `selection` should be empty when updating an ID");
|
||||
}
|
||||
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return rowsUpdated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the insertion of new recently used languages record to local SQLite Database
|
||||
* @param uri : contains the uri for recently used languages
|
||||
* @param contentValues : new values to be entered to db
|
||||
*/
|
||||
@Override
|
||||
public Uri insert(@NonNull final Uri uri, final ContentValues contentValues) {
|
||||
final SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
|
||||
final long id = sqlDB.insert(TABLE_NAME, null, contentValues);
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return Uri.parse(BASE_URI + "/" + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the deletion of new recently used languages record to local SQLite Database
|
||||
* @param uri : contains the uri for recently used languages
|
||||
*/
|
||||
@Override
|
||||
public int delete(@NonNull final Uri uri, final String s, final String[] strings) {
|
||||
final int rows;
|
||||
final SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
|
||||
Timber.d("Deleting recently used language %s", uri.getLastPathSegment());
|
||||
rows = db.delete(
|
||||
TABLE_NAME,
|
||||
"language_code = ?",
|
||||
new String[]{uri.getLastPathSegment()}
|
||||
);
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
package fr.free.nrw.commons.recentlanguages
|
||||
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.database.sqlite.SQLiteQueryBuilder
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import fr.free.nrw.commons.BuildConfig
|
||||
import fr.free.nrw.commons.data.DBOpenHelper
|
||||
import fr.free.nrw.commons.di.CommonsDaggerContentProvider
|
||||
import fr.free.nrw.commons.recentlanguages.RecentLanguagesDao.Table.COLUMN_NAME
|
||||
import fr.free.nrw.commons.recentlanguages.RecentLanguagesDao.Table.TABLE_NAME
|
||||
import javax.inject.Inject
|
||||
import timber.log.Timber
|
||||
|
||||
|
||||
/**
|
||||
* Content provider of recently used languages
|
||||
*/
|
||||
class RecentLanguagesContentProvider : CommonsDaggerContentProvider() {
|
||||
|
||||
companion object {
|
||||
private const val BASE_PATH = "recent_languages"
|
||||
val BASE_URI: Uri =
|
||||
Uri.parse(
|
||||
"content://${BuildConfig.RECENT_LANGUAGE_AUTHORITY}/$BASE_PATH"
|
||||
)
|
||||
|
||||
/**
|
||||
* Append language code to the base URI
|
||||
* @param languageCode Code of a language
|
||||
*/
|
||||
@JvmStatic
|
||||
fun uriForCode(languageCode: String): Uri {
|
||||
return Uri.parse("$BASE_URI/$languageCode")
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
lateinit var dbOpenHelper: DBOpenHelper
|
||||
|
||||
override fun getType(uri: Uri): String? {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the SQLite database for the recently used languages
|
||||
* @param uri : contains the URI for recently used languages
|
||||
* @param projection : contains all fields of the table
|
||||
* @param selection : handles WHERE
|
||||
* @param selectionArgs : the condition of WHERE clause
|
||||
* @param sortOrder : ascending or descending
|
||||
*/
|
||||
override fun query(
|
||||
uri: Uri,
|
||||
projection: Array<String>?,
|
||||
selection: String?,
|
||||
selectionArgs: Array<String>?,
|
||||
sortOrder: String?
|
||||
): Cursor? {
|
||||
val queryBuilder = SQLiteQueryBuilder()
|
||||
queryBuilder.tables = TABLE_NAME
|
||||
val db = dbOpenHelper.readableDatabase
|
||||
val cursor = queryBuilder.query(
|
||||
db,
|
||||
projection,
|
||||
selection,
|
||||
selectionArgs,
|
||||
null,
|
||||
null,
|
||||
sortOrder
|
||||
)
|
||||
cursor.setNotificationUri(context?.contentResolver, uri)
|
||||
return cursor
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the update query of local SQLite Database
|
||||
* @param uri : contains the URI for recently used languages
|
||||
* @param contentValues : new values to be entered to the database
|
||||
* @param selection : handles WHERE
|
||||
* @param selectionArgs : the condition of WHERE clause
|
||||
*/
|
||||
override fun update(
|
||||
uri: Uri,
|
||||
contentValues: ContentValues?,
|
||||
selection: String?,
|
||||
selectionArgs: Array<String>?
|
||||
): Int {
|
||||
val sqlDB = dbOpenHelper.writableDatabase
|
||||
val rowsUpdated: Int
|
||||
if (selection.isNullOrEmpty()) {
|
||||
val id = uri.lastPathSegment?.toInt()
|
||||
?: throw IllegalArgumentException("Invalid URI: $uri")
|
||||
rowsUpdated = sqlDB.update(
|
||||
TABLE_NAME,
|
||||
contentValues,
|
||||
"$COLUMN_NAME = ?",
|
||||
arrayOf(id.toString())
|
||||
)
|
||||
} else {
|
||||
throw IllegalArgumentException("Parameter `selection` should be empty when updating an ID")
|
||||
}
|
||||
|
||||
context?.contentResolver?.notifyChange(uri, null)
|
||||
return rowsUpdated
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the insertion of new recently used languages record to local SQLite Database
|
||||
* @param uri : contains the URI for recently used languages
|
||||
* @param contentValues : new values to be entered to the database
|
||||
*/
|
||||
override fun insert(uri: Uri, contentValues: ContentValues?): Uri? {
|
||||
val sqlDB = dbOpenHelper.writableDatabase
|
||||
val id = sqlDB.insert(
|
||||
TABLE_NAME,
|
||||
null,
|
||||
contentValues
|
||||
)
|
||||
context?.contentResolver?.notifyChange(uri, null)
|
||||
return Uri.parse("$BASE_URI/$id")
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the deletion of a recently used languages record from local SQLite Database
|
||||
* @param uri : contains the URI for recently used languages
|
||||
*/
|
||||
override fun delete(uri: Uri, s: String?, strings: Array<String>?): Int {
|
||||
val db = dbOpenHelper.readableDatabase
|
||||
Timber.d("Deleting recently used language %s", uri.lastPathSegment)
|
||||
val rows = db.delete(
|
||||
TABLE_NAME,
|
||||
"language_code = ?",
|
||||
arrayOf(uri.lastPathSegment)
|
||||
)
|
||||
context?.contentResolver?.notifyChange(uri, null)
|
||||
return rows
|
||||
}
|
||||
}
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
package fr.free.nrw.commons.recentlanguages;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.RemoteException;
|
||||
import androidx.annotation.NonNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Handles database operations for recently used languages
|
||||
*/
|
||||
@Singleton
|
||||
public class RecentLanguagesDao {
|
||||
|
||||
private final Provider<ContentProviderClient> clientProvider;
|
||||
|
||||
@Inject
|
||||
public RecentLanguagesDao
|
||||
(@Named("recent_languages") final Provider<ContentProviderClient> clientProvider) {
|
||||
this.clientProvider = clientProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all persisted recently used languages on database
|
||||
* @return list of recently used languages
|
||||
*/
|
||||
public List<Language> getRecentLanguages() {
|
||||
final List<Language> languages = new ArrayList<>();
|
||||
final ContentProviderClient db = clientProvider.get();
|
||||
try (final Cursor cursor = db.query(
|
||||
RecentLanguagesContentProvider.BASE_URI,
|
||||
RecentLanguagesDao.Table.ALL_FIELDS,
|
||||
null,
|
||||
new String[]{},
|
||||
null)) {
|
||||
if(cursor != null && cursor.moveToLast()) {
|
||||
do {
|
||||
languages.add(fromCursor(cursor));
|
||||
} while (cursor.moveToPrevious());
|
||||
}
|
||||
} catch (final RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
db.release();
|
||||
}
|
||||
return languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Language to database
|
||||
* @param language : Language to add
|
||||
*/
|
||||
public void addRecentLanguage(final Language language) {
|
||||
final ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
db.insert(RecentLanguagesContentProvider.BASE_URI, toContentValues(language));
|
||||
} catch (final RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
db.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a language from database
|
||||
* @param languageCode : code of the Language to delete
|
||||
*/
|
||||
public void deleteRecentLanguage(final String languageCode) {
|
||||
final ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
db.delete(RecentLanguagesContentProvider.uriForCode(languageCode), null, null);
|
||||
} catch (final RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
db.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a language from database based on its name
|
||||
* @param languageCode : code of the Language to find
|
||||
* @return boolean : is language in database ?
|
||||
*/
|
||||
public boolean findRecentLanguage(final String languageCode) {
|
||||
if (languageCode == null) { //Avoiding NPE's
|
||||
return false;
|
||||
}
|
||||
final ContentProviderClient db = clientProvider.get();
|
||||
try (final Cursor cursor = db.query(
|
||||
RecentLanguagesContentProvider.BASE_URI,
|
||||
RecentLanguagesDao.Table.ALL_FIELDS,
|
||||
Table.COLUMN_CODE + "=?",
|
||||
new String[]{languageCode},
|
||||
null
|
||||
)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return true;
|
||||
}
|
||||
} catch (final RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
db.release();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* It creates an Recent Language object from data stored in the SQLite DB by using cursor
|
||||
* @param cursor cursor
|
||||
* @return Language object
|
||||
*/
|
||||
@NonNull
|
||||
@SuppressLint("Range")
|
||||
Language fromCursor(final Cursor cursor) {
|
||||
// Hardcoding column positions!
|
||||
final String languageName = cursor.getString(cursor.getColumnIndex(Table.COLUMN_NAME));
|
||||
final String languageCode = cursor.getString(cursor.getColumnIndex(Table.COLUMN_CODE));
|
||||
return new Language(languageName, languageCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes data from Language and create a content value object
|
||||
* @param recentLanguage recently used language
|
||||
* @return ContentValues
|
||||
*/
|
||||
private ContentValues toContentValues(final Language recentLanguage) {
|
||||
final ContentValues cv = new ContentValues();
|
||||
cv.put(Table.COLUMN_NAME, recentLanguage.getLanguageName());
|
||||
cv.put(Table.COLUMN_CODE, recentLanguage.getLanguageCode());
|
||||
return cv;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class contains the database table architecture for recently used languages,
|
||||
* It also contains queries and logic necessary to the create, update, delete this table.
|
||||
*/
|
||||
public static final class Table {
|
||||
public static final String TABLE_NAME = "recent_languages";
|
||||
static final String COLUMN_NAME = "language_name";
|
||||
static final String COLUMN_CODE = "language_code";
|
||||
|
||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||
public static final String[] ALL_FIELDS = {
|
||||
COLUMN_NAME,
|
||||
COLUMN_CODE
|
||||
};
|
||||
|
||||
static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME;
|
||||
|
||||
static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ COLUMN_NAME + " STRING,"
|
||||
+ COLUMN_CODE + " STRING PRIMARY KEY"
|
||||
+ ");";
|
||||
|
||||
/**
|
||||
* This method creates a LanguagesTable in SQLiteDatabase
|
||||
* @param db SQLiteDatabase
|
||||
*/
|
||||
public static void onCreate(final SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_STATEMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method deletes LanguagesTable from SQLiteDatabase
|
||||
* @param db SQLiteDatabase
|
||||
*/
|
||||
public static void onDelete(final SQLiteDatabase db) {
|
||||
db.execSQL(DROP_TABLE_STATEMENT);
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called on migrating from a older version to a newer version
|
||||
* @param db SQLiteDatabase
|
||||
* @param from Version from which we are migrating
|
||||
* @param to Version to which we are migrating
|
||||
*/
|
||||
public static void onUpdate(final SQLiteDatabase db, int from, final int to) {
|
||||
if (from == to) {
|
||||
return;
|
||||
}
|
||||
if (from < 19) {
|
||||
// doesn't exist yet
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 19) {
|
||||
// table added in version 20
|
||||
onCreate(db);
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
package fr.free.nrw.commons.recentlanguages
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ContentProviderClient
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.os.RemoteException
|
||||
import java.util.ArrayList
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
import javax.inject.Provider
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
||||
/**
|
||||
* Handles database operations for recently used languages
|
||||
*/
|
||||
@Singleton
|
||||
class RecentLanguagesDao @Inject constructor(
|
||||
@Named("recent_languages")
|
||||
private val clientProvider: Provider<ContentProviderClient>
|
||||
) {
|
||||
|
||||
/**
|
||||
* Find all persisted recently used languages on database
|
||||
* @return list of recently used languages
|
||||
*/
|
||||
fun getRecentLanguages(): List<Language> {
|
||||
val languages = mutableListOf<Language>()
|
||||
val db = clientProvider.get()
|
||||
try {
|
||||
db.query(
|
||||
RecentLanguagesContentProvider.BASE_URI,
|
||||
Table.ALL_FIELDS,
|
||||
null,
|
||||
arrayOf(),
|
||||
null
|
||||
)?.use { cursor ->
|
||||
if (cursor.moveToLast()) {
|
||||
do {
|
||||
languages.add(fromCursor(cursor))
|
||||
} while (cursor.moveToPrevious())
|
||||
}
|
||||
}
|
||||
} catch (e: RemoteException) {
|
||||
throw RuntimeException(e)
|
||||
} finally {
|
||||
db.release()
|
||||
}
|
||||
return languages
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Language to database
|
||||
* @param language : Language to add
|
||||
*/
|
||||
fun addRecentLanguage(language: Language) {
|
||||
val db = clientProvider.get()
|
||||
try {
|
||||
db.insert(
|
||||
RecentLanguagesContentProvider.BASE_URI,
|
||||
toContentValues(language)
|
||||
)
|
||||
} catch (e: RemoteException) {
|
||||
throw RuntimeException(e)
|
||||
} finally {
|
||||
db.release()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a language from database
|
||||
* @param languageCode : code of the Language to delete
|
||||
*/
|
||||
fun deleteRecentLanguage(languageCode: String) {
|
||||
val db = clientProvider.get()
|
||||
try {
|
||||
db.delete(
|
||||
RecentLanguagesContentProvider.uriForCode(languageCode),
|
||||
null,
|
||||
null
|
||||
)
|
||||
} catch (e: RemoteException) {
|
||||
throw RuntimeException(e)
|
||||
} finally {
|
||||
db.release()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a language from database based on its name
|
||||
* @param languageCode : code of the Language to find
|
||||
* @return boolean : is language in database ?
|
||||
*/
|
||||
fun findRecentLanguage(languageCode: String?): Boolean {
|
||||
if (languageCode == null) { // Avoiding NPEs
|
||||
return false
|
||||
}
|
||||
val db = clientProvider.get()
|
||||
try {
|
||||
db.query(
|
||||
RecentLanguagesContentProvider.BASE_URI,
|
||||
Table.ALL_FIELDS,
|
||||
"${Table.COLUMN_CODE}=?",
|
||||
arrayOf(languageCode),
|
||||
null
|
||||
)?.use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} catch (e: RemoteException) {
|
||||
throw RuntimeException(e)
|
||||
} finally {
|
||||
db.release()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* It creates an Recent Language object from data stored in the SQLite DB by using cursor
|
||||
* @param cursor cursor
|
||||
* @return Language object
|
||||
*/
|
||||
@SuppressLint("Range")
|
||||
fun fromCursor(cursor: Cursor): Language {
|
||||
// Hardcoding column positions!
|
||||
val languageName = cursor.getString(
|
||||
cursor.getColumnIndex(Table.COLUMN_NAME)
|
||||
)
|
||||
val languageCode = cursor.getString(
|
||||
cursor.getColumnIndex(Table.COLUMN_CODE)
|
||||
)
|
||||
return Language(languageName, languageCode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes data from Language and create a content value object
|
||||
* @param recentLanguage recently used language
|
||||
* @return ContentValues
|
||||
*/
|
||||
private fun toContentValues(recentLanguage: Language): ContentValues {
|
||||
return ContentValues().apply {
|
||||
put(Table.COLUMN_NAME, recentLanguage.languageName)
|
||||
put(Table.COLUMN_CODE, recentLanguage.languageCode)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class contains the database table architecture for recently used languages,
|
||||
* It also contains queries and logic necessary to the create, update, delete this table.
|
||||
*/
|
||||
object Table {
|
||||
const val TABLE_NAME = "recent_languages"
|
||||
const val COLUMN_NAME = "language_name"
|
||||
const val COLUMN_CODE = "language_code"
|
||||
|
||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||
@JvmStatic
|
||||
val ALL_FIELDS = arrayOf(
|
||||
COLUMN_NAME,
|
||||
COLUMN_CODE
|
||||
)
|
||||
|
||||
private const val DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS $TABLE_NAME"
|
||||
|
||||
private const val CREATE_TABLE_STATEMENT = "CREATE TABLE $TABLE_NAME (" +
|
||||
"$COLUMN_NAME STRING," +
|
||||
"$COLUMN_CODE STRING PRIMARY KEY" +
|
||||
");"
|
||||
|
||||
/**
|
||||
* This method creates a LanguagesTable in SQLiteDatabase
|
||||
* @param db SQLiteDatabase
|
||||
*/
|
||||
@SuppressLint("SQLiteString")
|
||||
@JvmStatic
|
||||
fun onCreate(db: SQLiteDatabase) {
|
||||
db.execSQL(CREATE_TABLE_STATEMENT)
|
||||
}
|
||||
|
||||
/**
|
||||
* This method deletes LanguagesTable from SQLiteDatabase
|
||||
* @param db SQLiteDatabase
|
||||
*/
|
||||
@JvmStatic
|
||||
fun onDelete(db: SQLiteDatabase) {
|
||||
db.execSQL(DROP_TABLE_STATEMENT)
|
||||
onCreate(db)
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called on migrating from a older version to a newer version
|
||||
* @param db SQLiteDatabase
|
||||
* @param from Version from which we are migrating
|
||||
* @param to Version to which we are migrating
|
||||
*/
|
||||
@JvmStatic
|
||||
fun onUpdate(db: SQLiteDatabase, from: Int, to: Int) {
|
||||
if (from == to) {
|
||||
return
|
||||
}
|
||||
if (from < 19) {
|
||||
// doesn't exist yet
|
||||
onUpdate(db, from + 1, to)
|
||||
return
|
||||
}
|
||||
if (from == 19) {
|
||||
// table added in version 20
|
||||
onCreate(db)
|
||||
onUpdate(db, from + 1, to)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,423 +0,0 @@
|
|||
package fr.free.nrw.commons.repository;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.category.CategoriesModel;
|
||||
import fr.free.nrw.commons.category.CategoryItem;
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
import fr.free.nrw.commons.contributions.ContributionDao;
|
||||
import fr.free.nrw.commons.filepicker.UploadableFile;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.nearby.NearbyPlaces;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import fr.free.nrw.commons.upload.ImageCoordinates;
|
||||
import fr.free.nrw.commons.upload.SimilarImageInterface;
|
||||
import fr.free.nrw.commons.upload.UploadController;
|
||||
import fr.free.nrw.commons.upload.UploadItem;
|
||||
import fr.free.nrw.commons.upload.UploadModel;
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictModel;
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* The repository class for UploadActivity
|
||||
*/
|
||||
@Singleton
|
||||
public class UploadRepository {
|
||||
|
||||
private final UploadModel uploadModel;
|
||||
private final UploadController uploadController;
|
||||
private final CategoriesModel categoriesModel;
|
||||
private final NearbyPlaces nearbyPlaces;
|
||||
private final DepictModel depictModel;
|
||||
|
||||
private static final double NEARBY_RADIUS_IN_KILO_METERS = 0.1; //100 meters
|
||||
private final ContributionDao contributionDao;
|
||||
|
||||
@Inject
|
||||
public UploadRepository(UploadModel uploadModel,
|
||||
UploadController uploadController,
|
||||
CategoriesModel categoriesModel,
|
||||
NearbyPlaces nearbyPlaces,
|
||||
DepictModel depictModel,
|
||||
ContributionDao contributionDao) {
|
||||
this.uploadModel = uploadModel;
|
||||
this.uploadController = uploadController;
|
||||
this.categoriesModel = categoriesModel;
|
||||
this.nearbyPlaces = nearbyPlaces;
|
||||
this.depictModel = depictModel;
|
||||
this.contributionDao=contributionDao;
|
||||
}
|
||||
|
||||
/**
|
||||
* asks the RemoteDataSource to build contributions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Observable<Contribution> buildContributions() {
|
||||
return uploadModel.buildContributions();
|
||||
}
|
||||
|
||||
/**
|
||||
* asks the RemoteDataSource to start upload for the contribution
|
||||
*
|
||||
* @param contribution
|
||||
*/
|
||||
|
||||
public void prepareMedia(Contribution contribution) {
|
||||
uploadController.prepareMedia(contribution);
|
||||
}
|
||||
|
||||
|
||||
public void saveContribution(Contribution contribution) {
|
||||
contributionDao.save(contribution).blockingAwait();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns all the Upload Items
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<UploadItem> getUploads() {
|
||||
return uploadModel.getUploads();
|
||||
}
|
||||
|
||||
/**
|
||||
*Prepare for a fresh upload
|
||||
*/
|
||||
public void cleanup() {
|
||||
uploadModel.cleanUp();
|
||||
//This needs further refactoring, this should not be here, right now the structure wont suppoort rhis
|
||||
categoriesModel.cleanUp();
|
||||
depictModel.cleanUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the selected categories for the current upload
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<CategoryItem> getSelectedCategories() {
|
||||
return categoriesModel.getSelectedCategories();
|
||||
}
|
||||
|
||||
/**
|
||||
* all categories from MWApi
|
||||
*
|
||||
* @param query
|
||||
* @param imageTitleList
|
||||
* @param selectedDepictions
|
||||
* @return
|
||||
*/
|
||||
public Observable<List<CategoryItem>> searchAll(String query, List<String> imageTitleList,
|
||||
List<DepictedItem> selectedDepictions) {
|
||||
return categoriesModel.searchAll(query, imageTitleList, selectedDepictions);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the list of selected categories for the current upload
|
||||
*
|
||||
* @param categoryStringList
|
||||
*/
|
||||
public void setSelectedCategories(List<String> categoryStringList) {
|
||||
uploadModel.setSelectedCategories(categoryStringList);
|
||||
}
|
||||
|
||||
/**
|
||||
* handles the category selection/deselection
|
||||
*
|
||||
* @param categoryItem
|
||||
*/
|
||||
public void onCategoryClicked(CategoryItem categoryItem, final Media media) {
|
||||
categoriesModel.onCategoryItemClicked(categoryItem, media);
|
||||
}
|
||||
|
||||
/**
|
||||
* prunes the category list for irrelevant categories see #750
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public boolean isSpammyCategory(String name) {
|
||||
return categoriesModel.isSpammyCategory(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* retursn the string list of available license from the LocalDataSource
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<String> getLicenses() {
|
||||
return uploadModel.getLicenses();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the selected license for the current upload
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSelectedLicense() {
|
||||
return uploadModel.getSelectedLicense();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of Upload Items
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getCount() {
|
||||
return uploadModel.getCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* ask the RemoteDataSource to pre process the image
|
||||
*
|
||||
* @param uploadableFile
|
||||
* @param place
|
||||
* @param similarImageInterface
|
||||
* @return
|
||||
*/
|
||||
public Observable<UploadItem> preProcessImage(UploadableFile uploadableFile, Place place,
|
||||
SimilarImageInterface similarImageInterface, LatLng inAppPictureLocation) {
|
||||
return uploadModel.preProcessImage(uploadableFile, place,
|
||||
similarImageInterface, inAppPictureLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* query the RemoteDataSource for image quality
|
||||
*
|
||||
* @param uploadItem UploadItem whose caption is to be checked
|
||||
* @return Quality of UploadItem
|
||||
*/
|
||||
public Single<Integer> getImageQuality(UploadItem uploadItem, LatLng location) {
|
||||
return uploadModel.getImageQuality(uploadItem, location);
|
||||
}
|
||||
|
||||
/**
|
||||
* query the RemoteDataSource for image duplicity check
|
||||
*
|
||||
* @param filePath file to be checked
|
||||
* @return IMAGE_DUPLICATE or IMAGE_OK
|
||||
*/
|
||||
public Single<Integer> checkDuplicateImage(String filePath) {
|
||||
return uploadModel.checkDuplicateImage(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* query the RemoteDataSource for caption quality
|
||||
*
|
||||
* @param uploadItem UploadItem whose caption is to be checked
|
||||
* @return Quality of caption of the UploadItem
|
||||
*/
|
||||
public Single<Integer> getCaptionQuality(UploadItem uploadItem) {
|
||||
return uploadModel.getCaptionQuality(uploadItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* asks the LocalDataSource to delete the file with the given file path
|
||||
*
|
||||
* @param filePath
|
||||
*/
|
||||
public void deletePicture(String filePath) {
|
||||
uploadModel.deletePicture(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches and returns the upload item
|
||||
*
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public UploadItem getUploadItem(int index) {
|
||||
if (index >= 0) {
|
||||
return uploadModel.getItems().get(index);
|
||||
}
|
||||
return null; //There is no item to copy details
|
||||
}
|
||||
|
||||
/**
|
||||
* set selected license for the current upload
|
||||
*
|
||||
* @param licenseName
|
||||
*/
|
||||
public void setSelectedLicense(String licenseName) {
|
||||
uploadModel.setSelectedLicense(licenseName);
|
||||
}
|
||||
|
||||
public void onDepictItemClicked(DepictedItem depictedItem, final Media media) {
|
||||
uploadModel.onDepictItemClicked(depictedItem, media);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the selected depictions for the current upload
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
public List<DepictedItem> getSelectedDepictions() {
|
||||
return uploadModel.getSelectedDepictions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides selected existing depicts
|
||||
*
|
||||
* @return selected existing depicts
|
||||
*/
|
||||
public List<String> getSelectedExistingDepictions() {
|
||||
return uploadModel.getSelectedExistingDepictions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize existing depicts
|
||||
*
|
||||
* @param selectedExistingDepictions existing depicts
|
||||
*/
|
||||
public void setSelectedExistingDepictions(final List<String> selectedExistingDepictions) {
|
||||
uploadModel.setSelectedExistingDepictions(selectedExistingDepictions);
|
||||
}
|
||||
/**
|
||||
* Search all depictions from
|
||||
*
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
|
||||
public Flowable<List<DepictedItem>> searchAllEntities(String query) {
|
||||
return depictModel.searchAllEntities(query, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the depiction for each unique {@link Place} associated with an {@link UploadItem}
|
||||
* from {@link #getUploads()}
|
||||
*
|
||||
* @return a single that provides the depictions
|
||||
*/
|
||||
public Single<List<DepictedItem>> getPlaceDepictions() {
|
||||
final Set<String> qids = new HashSet<>();
|
||||
for (final UploadItem item : getUploads()) {
|
||||
final Place place = item.getPlace();
|
||||
if (place != null) {
|
||||
qids.add(place.getWikiDataEntityId());
|
||||
}
|
||||
}
|
||||
return depictModel.getPlaceDepictions(new ArrayList<>(qids));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the category for each unique {@link Place} associated with an {@link UploadItem}
|
||||
* from {@link #getUploads()}
|
||||
*
|
||||
* @return a single that provides the categories
|
||||
*/
|
||||
public Single<List<CategoryItem>> getPlaceCategories() {
|
||||
final Set<String> qids = new HashSet<>();
|
||||
for (final UploadItem item : getUploads()) {
|
||||
final Place place = item.getPlace();
|
||||
if (place != null) {
|
||||
qids.add(place.getCategory());
|
||||
}
|
||||
}
|
||||
return Single.fromObservable(categoriesModel.getCategoriesByName(new ArrayList<>(qids)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes depict IDs as a parameter, converts into a slash separated String and Gets DepictItem
|
||||
* from the server
|
||||
*
|
||||
* @param depictionsQIDs IDs of Depiction
|
||||
* @return Flowable<List<DepictedItem>>
|
||||
*/
|
||||
public Flowable<List<DepictedItem>> getDepictions(final List<String> depictionsQIDs){
|
||||
final String ids = joinQIDs(depictionsQIDs);
|
||||
return depictModel.getDepictions(ids).toFlowable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a string by joining all IDs divided by "|"
|
||||
*
|
||||
* @param depictionsQIDs IDs of depiction ex. ["Q11023","Q1356"]
|
||||
* @return string ex. "Q11023|Q1356"
|
||||
*/
|
||||
private String joinQIDs(final List<String> depictionsQIDs) {
|
||||
if (depictionsQIDs != null && !depictionsQIDs.isEmpty()) {
|
||||
final StringBuilder buffer = new StringBuilder(depictionsQIDs.get(0));
|
||||
|
||||
if (depictionsQIDs.size() > 1) {
|
||||
for (int i = 1; i < depictionsQIDs.size(); i++) {
|
||||
buffer.append("|");
|
||||
buffer.append(depictionsQIDs.get(i));
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns nearest place matching the passed latitude and longitude
|
||||
*
|
||||
* @param decLatitude
|
||||
* @param decLongitude
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
public Place checkNearbyPlaces(final double decLatitude, final double decLongitude) {
|
||||
try {
|
||||
final List<Place> fromWikidataQuery = nearbyPlaces.getFromWikidataQuery(new LatLng(
|
||||
decLatitude, decLongitude, 0.0f),
|
||||
Locale.getDefault().getLanguage(),
|
||||
NEARBY_RADIUS_IN_KILO_METERS, null);
|
||||
return (fromWikidataQuery != null && fromWikidataQuery.size() > 0) ? fromWikidataQuery
|
||||
.get(0) : null;
|
||||
} catch (final Exception e) {
|
||||
Timber.e("Error fetching nearby places: %s", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void useSimilarPictureCoordinates(ImageCoordinates imageCoordinates, int uploadItemIndex) {
|
||||
uploadModel.useSimilarPictureCoordinates(imageCoordinates, uploadItemIndex);
|
||||
}
|
||||
|
||||
public boolean isWMLSupportedForThisPlace() {
|
||||
return uploadModel.getItems().get(0).isWLMUpload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides selected existing categories
|
||||
*
|
||||
* @return selected existing categories
|
||||
*/
|
||||
public List<String> getSelectedExistingCategories() {
|
||||
return categoriesModel.getSelectedExistingCategories();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize existing categories
|
||||
*
|
||||
* @param selectedExistingCategories existing categories
|
||||
*/
|
||||
public void setSelectedExistingCategories(final List<String> selectedExistingCategories) {
|
||||
categoriesModel.setSelectedExistingCategories(selectedExistingCategories);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes category names and Gets CategoryItem from the server
|
||||
*
|
||||
* @param categories names of Category
|
||||
* @return Observable<List<CategoryItem>>
|
||||
*/
|
||||
public Observable<List<CategoryItem>> getCategories(final List<String> categories){
|
||||
return categoriesModel.getCategoriesByName(categories);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,410 @@
|
|||
package fr.free.nrw.commons.repository
|
||||
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.category.CategoriesModel
|
||||
import fr.free.nrw.commons.category.CategoryItem
|
||||
import fr.free.nrw.commons.contributions.Contribution
|
||||
import fr.free.nrw.commons.contributions.ContributionDao
|
||||
import fr.free.nrw.commons.filepicker.UploadableFile
|
||||
import fr.free.nrw.commons.location.LatLng
|
||||
import fr.free.nrw.commons.nearby.NearbyPlaces
|
||||
import fr.free.nrw.commons.nearby.Place
|
||||
import fr.free.nrw.commons.upload.ImageCoordinates
|
||||
import fr.free.nrw.commons.upload.SimilarImageInterface
|
||||
import fr.free.nrw.commons.upload.UploadController
|
||||
import fr.free.nrw.commons.upload.UploadItem
|
||||
import fr.free.nrw.commons.upload.UploadModel
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictModel
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* The repository class for UploadActivity
|
||||
*/
|
||||
@Singleton
|
||||
class UploadRepository @Inject constructor(
|
||||
private val uploadModel: UploadModel,
|
||||
private val uploadController: UploadController,
|
||||
private val categoriesModel: CategoriesModel,
|
||||
private val nearbyPlaces: NearbyPlaces,
|
||||
private val depictModel: DepictModel,
|
||||
private val contributionDao: ContributionDao
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private const val NEARBY_RADIUS_IN_KILO_METERS = 0.1 // 100 meters
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the RemoteDataSource to build contributions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
fun buildContributions(): Observable<Contribution> {
|
||||
return uploadModel.buildContributions()
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the RemoteDataSource to start upload for the contribution
|
||||
*
|
||||
* @param contribution
|
||||
*/
|
||||
fun prepareMedia(contribution: Contribution) {
|
||||
uploadController.prepareMedia(contribution)
|
||||
}
|
||||
|
||||
fun saveContribution(contribution: Contribution) {
|
||||
contributionDao.save(contribution).blockingAwait()
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns all the Upload Items
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
fun getUploads(): List<UploadItem> {
|
||||
return uploadModel.getUploads()
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for a fresh upload
|
||||
*/
|
||||
fun cleanup() {
|
||||
uploadModel.cleanUp()
|
||||
// This needs further refactoring, this should not be here, right now the structure
|
||||
// won't support this
|
||||
categoriesModel.cleanUp()
|
||||
depictModel.cleanUp()
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the selected categories for the current upload
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
fun getSelectedCategories(): List<CategoryItem> {
|
||||
return categoriesModel.getSelectedCategories()
|
||||
}
|
||||
|
||||
/**
|
||||
* All categories from MWApi
|
||||
*
|
||||
* @param query
|
||||
* @param imageTitleList
|
||||
* @param selectedDepictions
|
||||
* @return
|
||||
*/
|
||||
fun searchAll(
|
||||
query: String,
|
||||
imageTitleList: List<String>,
|
||||
selectedDepictions: List<DepictedItem>
|
||||
): Observable<List<CategoryItem>> {
|
||||
return categoriesModel.searchAll(query, imageTitleList, selectedDepictions)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of selected categories for the current upload
|
||||
*
|
||||
* @param categoryStringList
|
||||
*/
|
||||
fun setSelectedCategories(categoryStringList: List<String>) {
|
||||
uploadModel.setSelectedCategories(categoryStringList)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the category selection/deselection
|
||||
*
|
||||
* @param categoryItem
|
||||
*/
|
||||
fun onCategoryClicked(categoryItem: CategoryItem, media: Media?) {
|
||||
categoriesModel.onCategoryItemClicked(categoryItem, media)
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes the category list for irrelevant categories see #750
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
fun isSpammyCategory(name: String): Boolean {
|
||||
return categoriesModel.isSpammyCategory(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string list of available licenses from the LocalDataSource
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
fun getLicenses(): List<String> {
|
||||
return uploadModel.licenses
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected license for the current upload
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
fun getSelectedLicense(): String {
|
||||
return uploadModel.selectedLicense
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of Upload Items
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
fun getCount(): Int {
|
||||
return uploadModel.count
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the RemoteDataSource to preprocess the image
|
||||
*
|
||||
* @param uploadableFile
|
||||
* @param place
|
||||
* @param similarImageInterface
|
||||
* @param inAppPictureLocation
|
||||
* @return
|
||||
*/
|
||||
fun preProcessImage(
|
||||
uploadableFile: UploadableFile,
|
||||
place: Place?,
|
||||
similarImageInterface: SimilarImageInterface,
|
||||
inAppPictureLocation: LatLng?
|
||||
): Observable<UploadItem> {
|
||||
return uploadModel.preProcessImage(
|
||||
uploadableFile,
|
||||
place,
|
||||
similarImageInterface,
|
||||
inAppPictureLocation
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the RemoteDataSource for image quality
|
||||
*
|
||||
* @param uploadItem UploadItem whose caption is to be checked
|
||||
* @param location Location of the image
|
||||
* @return Quality of UploadItem
|
||||
*/
|
||||
fun getImageQuality(uploadItem: UploadItem, location: LatLng?): Single<Int> {
|
||||
return uploadModel.getImageQuality(uploadItem, location)
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the RemoteDataSource for image duplicity check
|
||||
*
|
||||
* @param filePath file to be checked
|
||||
* @return IMAGE_DUPLICATE or IMAGE_OK
|
||||
*/
|
||||
fun checkDuplicateImage(filePath: String): Single<Int> {
|
||||
return uploadModel.checkDuplicateImage(filePath)
|
||||
}
|
||||
|
||||
/**
|
||||
* query the RemoteDataSource for caption quality
|
||||
*
|
||||
* @param uploadItem UploadItem whose caption is to be checked
|
||||
* @return Quality of caption of the UploadItem
|
||||
*/
|
||||
fun getCaptionQuality(uploadItem: UploadItem): Single<Int> {
|
||||
return uploadModel.getCaptionQuality(uploadItem)
|
||||
}
|
||||
|
||||
/**
|
||||
* asks the LocalDataSource to delete the file with the given file path
|
||||
*
|
||||
* @param filePath
|
||||
*/
|
||||
fun deletePicture(filePath: String) {
|
||||
uploadModel.deletePicture(filePath)
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches and returns the upload item
|
||||
*
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
fun getUploadItem(index: Int): UploadItem? {
|
||||
return if (index >= 0) {
|
||||
uploadModel.items.getOrNull(index)
|
||||
} else null //There is no item to copy details
|
||||
}
|
||||
|
||||
/**
|
||||
* set selected license for the current upload
|
||||
*
|
||||
* @param licenseName
|
||||
*/
|
||||
fun setSelectedLicense(licenseName: String) {
|
||||
uploadModel.selectedLicense = licenseName
|
||||
}
|
||||
|
||||
fun onDepictItemClicked(depictedItem: DepictedItem, media: Media?) {
|
||||
uploadModel.onDepictItemClicked(depictedItem, media)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches and returns the selected depictions for the current upload
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
fun getSelectedDepictions(): List<DepictedItem> {
|
||||
return uploadModel.selectedDepictions
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides selected existing depicts
|
||||
*
|
||||
* @return selected existing depicts
|
||||
*/
|
||||
fun getSelectedExistingDepictions(): List<String> {
|
||||
return uploadModel.selectedExistingDepictions
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize existing depicts
|
||||
*
|
||||
* @param selectedExistingDepictions existing depicts
|
||||
*/
|
||||
fun setSelectedExistingDepictions(selectedExistingDepictions: List<String>) {
|
||||
uploadModel.selectedExistingDepictions = selectedExistingDepictions
|
||||
}
|
||||
|
||||
/**
|
||||
* Search all depictions from
|
||||
*
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
fun searchAllEntities(query: String): Flowable<List<DepictedItem>> {
|
||||
return depictModel.searchAllEntities(query, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the depiction for each unique {@link Place} associated with an {@link UploadItem}
|
||||
* from {@link #getUploads()}
|
||||
*
|
||||
* @return a single that provides the depictions
|
||||
*/
|
||||
fun getPlaceDepictions(): Single<List<DepictedItem>> {
|
||||
val qids = mutableSetOf<String>()
|
||||
getUploads().forEach { item ->
|
||||
item.place?.let {
|
||||
it.wikiDataEntityId?.let { it1 ->
|
||||
qids.add(it1)
|
||||
}
|
||||
}
|
||||
}
|
||||
return depictModel.getPlaceDepictions(qids.toList())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the category for each unique {@link Place} associated with an {@link UploadItem}
|
||||
* from {@link #getUploads()}
|
||||
*
|
||||
* @return a single that provides the categories
|
||||
*/
|
||||
fun getPlaceCategories(): Single<List<CategoryItem>> {
|
||||
val qids = mutableSetOf<String>()
|
||||
getUploads().forEach { item ->
|
||||
item.place?.category?.let { qids.add(it) }
|
||||
}
|
||||
return Single.fromObservable(categoriesModel.getCategoriesByName(qids.toList()))
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes depict IDs as a parameter, converts into a slash separated String and Gets DepictItem
|
||||
* from the server
|
||||
*
|
||||
* @param depictionsQIDs IDs of Depiction
|
||||
* @return Flowable<List<DepictedItem>>
|
||||
*/
|
||||
fun getDepictions(depictionsQIDs: List<String>): Flowable<List<DepictedItem>> {
|
||||
val ids = joinQIDs(depictionsQIDs) ?: ""
|
||||
return depictModel.getDepictions(ids).toFlowable()
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a string by joining all IDs divided by "|"
|
||||
*
|
||||
* @param depictionsQIDs IDs of depiction ex. ["Q11023","Q1356"]
|
||||
* @return string ex. "Q11023|Q1356"
|
||||
*/
|
||||
private fun joinQIDs(depictionsQIDs: List<String>?): String? {
|
||||
return depictionsQIDs?.takeIf {
|
||||
it.isNotEmpty()
|
||||
}?.joinToString("|")
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns nearest place matching the passed latitude and longitude
|
||||
*
|
||||
* @param decLatitude
|
||||
* @param decLongitude
|
||||
* @return
|
||||
*/
|
||||
fun checkNearbyPlaces(decLatitude: Double, decLongitude: Double): Place? {
|
||||
return try {
|
||||
val fromWikidataQuery = nearbyPlaces.getFromWikidataQuery(
|
||||
LatLng(decLatitude, decLongitude, 0.0f),
|
||||
Locale.getDefault().language,
|
||||
NEARBY_RADIUS_IN_KILO_METERS,
|
||||
null
|
||||
)
|
||||
fromWikidataQuery?.firstOrNull()
|
||||
} catch (e: Exception) {
|
||||
Timber.e("Error fetching nearby places: %s", e.message)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun useSimilarPictureCoordinates(imageCoordinates: ImageCoordinates, uploadItemIndex: Int) {
|
||||
uploadModel.useSimilarPictureCoordinates(
|
||||
imageCoordinates,
|
||||
uploadItemIndex
|
||||
)
|
||||
}
|
||||
|
||||
fun isWMLSupportedForThisPlace(): Boolean {
|
||||
return uploadModel.items.firstOrNull()?.isWLMUpload == true
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides selected existing categories
|
||||
*
|
||||
* @return selected existing categories
|
||||
*/
|
||||
fun getSelectedExistingCategories(): List<String> {
|
||||
return categoriesModel.getSelectedExistingCategories()
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize existing categories
|
||||
*
|
||||
* @param selectedExistingCategories existing categories
|
||||
*/
|
||||
fun setSelectedExistingCategories(selectedExistingCategories: List<String>) {
|
||||
categoriesModel.setSelectedExistingCategories(
|
||||
selectedExistingCategories.toMutableList()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes category names and Gets CategoryItem from the server
|
||||
*
|
||||
* @param categories names of Category
|
||||
* @return Observable<List<CategoryItem>>
|
||||
*/
|
||||
fun getCategories(categories: List<String>): Observable<List<CategoryItem>> {
|
||||
return categoriesModel.getCategoriesByName(categories)
|
||||
?.map { it.toList() } ?: Observable.empty()
|
||||
}
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ class CategoriesPresenter
|
|||
.doOnNext {
|
||||
view.showProgress(true)
|
||||
}.switchMap(::searchResults)
|
||||
.map { repository.selectedCategories + it }
|
||||
.map { repository.getSelectedCategories() + it }
|
||||
.map { it.distinctBy { categoryItem -> categoryItem.name } }
|
||||
.observeOn(mainThreadScheduler)
|
||||
.subscribe(
|
||||
|
|
@ -89,7 +89,7 @@ class CategoriesPresenter
|
|||
private fun searchResults(term: String): Observable<List<CategoryItem>>? {
|
||||
if (media == null) {
|
||||
return repository
|
||||
.searchAll(term, getImageTitleList(), repository.selectedDepictions)
|
||||
.searchAll(term, getImageTitleList(), repository.getSelectedDepictions())
|
||||
.subscribeOn(ioScheduler)
|
||||
.map {
|
||||
it.filter { categoryItem ->
|
||||
|
|
@ -101,13 +101,13 @@ class CategoriesPresenter
|
|||
return Observable
|
||||
.zip(
|
||||
repository
|
||||
.getCategories(repository.selectedExistingCategories)
|
||||
.getCategories(repository.getSelectedExistingCategories())
|
||||
.map { list ->
|
||||
list.map {
|
||||
CategoryItem(it.name, it.description, it.thumbnail, true)
|
||||
}
|
||||
},
|
||||
repository.searchAll(term, getImageTitleList(), repository.selectedDepictions),
|
||||
repository.searchAll(term, getImageTitleList(), repository.getSelectedDepictions()),
|
||||
) { it1, it2 ->
|
||||
it1 + it2
|
||||
}.subscribeOn(ioScheduler)
|
||||
|
|
@ -138,7 +138,7 @@ class CategoriesPresenter
|
|||
* @return
|
||||
*/
|
||||
private fun getImageTitleList(): List<String> =
|
||||
repository.uploads
|
||||
repository.getUploads()
|
||||
.map { it.uploadMediaDetails[0].captionText }
|
||||
.filterNot { TextUtils.isEmpty(it) }
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ class CategoriesPresenter
|
|||
* Verifies the number of categories selected, prompts the user if none selected
|
||||
*/
|
||||
override fun verifyCategories() {
|
||||
val selectedCategories = repository.selectedCategories
|
||||
val selectedCategories = repository.getSelectedCategories()
|
||||
if (selectedCategories.isNotEmpty()) {
|
||||
repository.setSelectedCategories(selectedCategories.map { it.name })
|
||||
view.goToNextScreen()
|
||||
|
|
@ -173,14 +173,14 @@ class CategoriesPresenter
|
|||
) {
|
||||
this.view = view
|
||||
this.media = media
|
||||
repository.selectedExistingCategories = view.existingCategories
|
||||
repository.setSelectedExistingCategories(view.existingCategories)
|
||||
compositeDisposable.add(
|
||||
searchTerms
|
||||
.observeOn(mainThreadScheduler)
|
||||
.doOnNext {
|
||||
view.showProgress(true)
|
||||
}.switchMap(::searchResults)
|
||||
.map { repository.selectedCategories + it }
|
||||
.map { repository.getSelectedCategories() + it }
|
||||
.map { it.distinctBy { categoryItem -> categoryItem.name } }
|
||||
.observeOn(mainThreadScheduler)
|
||||
.subscribe(
|
||||
|
|
@ -218,13 +218,21 @@ class CategoriesPresenter
|
|||
wikiText: String,
|
||||
) {
|
||||
// check if view.existingCategories is null
|
||||
if (repository.selectedCategories.isNotEmpty() ||
|
||||
(view.existingCategories != null && repository.selectedExistingCategories.size != view.existingCategories.size)
|
||||
if (
|
||||
repository.getSelectedCategories().isNotEmpty()
|
||||
||
|
||||
(
|
||||
view.existingCategories != null
|
||||
&&
|
||||
repository.getSelectedExistingCategories().size
|
||||
!=
|
||||
view.existingCategories.size
|
||||
)
|
||||
) {
|
||||
val selectedCategories: MutableList<String> =
|
||||
(
|
||||
repository.selectedCategories.map { it.name }.toMutableList() +
|
||||
repository.selectedExistingCategories
|
||||
repository.getSelectedCategories().map { it.name }.toMutableList() +
|
||||
repository.getSelectedExistingCategories()
|
||||
).toMutableList()
|
||||
|
||||
if (selectedCategories.isNotEmpty()) {
|
||||
|
|
@ -305,7 +313,7 @@ class CategoriesPresenter
|
|||
|
||||
override fun selectCategories() {
|
||||
compositeDisposable.add(
|
||||
repository.placeCategories
|
||||
repository.getPlaceCategories()
|
||||
.subscribeOn(ioScheduler)
|
||||
.observeOn(mainThreadScheduler)
|
||||
.subscribe(::selectNewCategories),
|
||||
|
|
|
|||
|
|
@ -93,14 +93,14 @@ class DepictsPresenter
|
|||
return repository
|
||||
.searchAllEntities(querystring)
|
||||
.subscribeOn(ioScheduler)
|
||||
.map { repository.selectedDepictions + it + recentDepictedItemList + controller.loadFavoritesItems() }
|
||||
.map { repository.getSelectedDepictions() + it + recentDepictedItemList + controller.loadFavoritesItems() }
|
||||
.map { it.filterNot { item -> WikidataDisambiguationItems.isDisambiguationItem(item.instanceOfs) } }
|
||||
.map { it.distinctBy(DepictedItem::id) }
|
||||
} else {
|
||||
return Flowable
|
||||
.zip(
|
||||
repository
|
||||
.getDepictions(repository.selectedExistingDepictions)
|
||||
.getDepictions(repository.getSelectedExistingDepictions())
|
||||
.map { list ->
|
||||
list.map {
|
||||
DepictedItem(
|
||||
|
|
@ -118,7 +118,7 @@ class DepictsPresenter
|
|||
) { it1, it2 ->
|
||||
it1 + it2
|
||||
}.subscribeOn(ioScheduler)
|
||||
.map { repository.selectedDepictions + it + recentDepictedItemList + controller.loadFavoritesItems() }
|
||||
.map { repository.getSelectedDepictions() + it + recentDepictedItemList + controller.loadFavoritesItems() }
|
||||
.map { it.filterNot { item -> WikidataDisambiguationItems.isDisambiguationItem(item.instanceOfs) } }
|
||||
.map { it.distinctBy(DepictedItem::id) }
|
||||
}
|
||||
|
|
@ -135,7 +135,7 @@ class DepictsPresenter
|
|||
*/
|
||||
override fun selectPlaceDepictions() {
|
||||
compositeDisposable.add(
|
||||
repository.placeDepictions
|
||||
repository.getPlaceDepictions()
|
||||
.subscribeOn(ioScheduler)
|
||||
.observeOn(mainThreadScheduler)
|
||||
.subscribe(::selectNewDepictions),
|
||||
|
|
@ -188,10 +188,10 @@ class DepictsPresenter
|
|||
* from the depiction list
|
||||
*/
|
||||
override fun verifyDepictions() {
|
||||
if (repository.selectedDepictions.isNotEmpty()) {
|
||||
if (repository.getSelectedDepictions().isNotEmpty()) {
|
||||
if (::depictsDao.isInitialized) {
|
||||
// save all the selected Depicted item in room Database
|
||||
depictsDao.savingDepictsInRoomDataBase(repository.selectedDepictions)
|
||||
depictsDao.savingDepictsInRoomDataBase(repository.getSelectedDepictions())
|
||||
}
|
||||
view.goToNextScreen()
|
||||
} else {
|
||||
|
|
@ -205,20 +205,20 @@ class DepictsPresenter
|
|||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
override fun updateDepictions(media: Media) {
|
||||
if (repository.selectedDepictions.isNotEmpty() ||
|
||||
repository.selectedExistingDepictions.size != view.existingDepictions.size
|
||||
if (repository.getSelectedDepictions().isNotEmpty() ||
|
||||
repository.getSelectedExistingDepictions().size != view.existingDepictions.size
|
||||
) {
|
||||
view.showProgressDialog()
|
||||
val selectedDepictions: MutableList<String> =
|
||||
(
|
||||
repository.selectedDepictions.map { it.id }.toMutableList() +
|
||||
repository.selectedExistingDepictions
|
||||
repository.getSelectedDepictions().map { it.id }.toMutableList() +
|
||||
repository.getSelectedExistingDepictions()
|
||||
).toMutableList()
|
||||
|
||||
if (selectedDepictions.isNotEmpty()) {
|
||||
if (::depictsDao.isInitialized) {
|
||||
// save all the selected Depicted item in room Database
|
||||
depictsDao.savingDepictsInRoomDataBase(repository.selectedDepictions)
|
||||
depictsDao.savingDepictsInRoomDataBase(repository.getSelectedDepictions())
|
||||
}
|
||||
|
||||
compositeDisposable.add(
|
||||
|
|
@ -254,7 +254,7 @@ class DepictsPresenter
|
|||
) {
|
||||
this.view = view
|
||||
this.media = media
|
||||
repository.selectedExistingDepictions = view.existingDepictions
|
||||
repository.setSelectedExistingDepictions(view.existingDepictions)
|
||||
compositeDisposable.add(
|
||||
searchTerm
|
||||
.observeOn(mainThreadScheduler)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class DepictModel
|
|||
for (place in places) {
|
||||
place.wikiDataEntityId?.let { qids.add(it) }
|
||||
}
|
||||
repository.uploads.forEach { item ->
|
||||
repository.getUploads().forEach { item ->
|
||||
if (item.gpsCoords != null && item.gpsCoords.imageCoordsExists) {
|
||||
Coordinates2Country
|
||||
.countryQID(
|
||||
|
|
|
|||
|
|
@ -56,9 +56,9 @@ class CategoriesPresenterTest {
|
|||
@Throws(Exception::class)
|
||||
fun `Test onAttachViewWithMedia when media is not null`() {
|
||||
categoriesPresenter.onAttachViewWithMedia(view, media())
|
||||
whenever(repository.getCategories(repository.selectedExistingCategories))
|
||||
whenever(repository.getCategories(repository.getSelectedExistingCategories()))
|
||||
.thenReturn(Observable.just(mutableListOf(categoryItem())))
|
||||
whenever(repository.searchAll("mock", emptyList(), repository.selectedDepictions))
|
||||
whenever(repository.searchAll("mock", emptyList(), repository.getSelectedDepictions()))
|
||||
.thenReturn(Observable.just(mutableListOf(categoryItem())))
|
||||
val method: Method =
|
||||
CategoriesPresenter::class.java.getDeclaredMethod(
|
||||
|
|
@ -88,7 +88,7 @@ class CategoriesPresenterTest {
|
|||
val emptyCaptionUploadItem = mock<UploadItem>()
|
||||
whenever(emptyCaptionUploadItem.uploadMediaDetails)
|
||||
.thenReturn(listOf(UploadMediaDetail(captionText = "")))
|
||||
whenever(repository.uploads).thenReturn(
|
||||
whenever(repository.getUploads()).thenReturn(
|
||||
listOf(
|
||||
nonEmptyCaptionUploadItem,
|
||||
emptyCaptionUploadItem,
|
||||
|
|
@ -105,7 +105,7 @@ class CategoriesPresenterTest {
|
|||
)
|
||||
whenever(repository.isSpammyCategory("selected")).thenReturn(false)
|
||||
whenever(repository.isSpammyCategory("doesContainYear")).thenReturn(true)
|
||||
whenever(repository.selectedCategories).thenReturn(
|
||||
whenever(repository.getSelectedCategories()).thenReturn(
|
||||
listOf(
|
||||
categoryItem("selected", "", "", true),
|
||||
),
|
||||
|
|
@ -130,7 +130,7 @@ class CategoriesPresenterTest {
|
|||
|
||||
whenever(repository.searchAll(any(), any(), any()))
|
||||
.thenReturn(Observable.just(emptyCategories))
|
||||
whenever(repository.selectedCategories).thenReturn(listOf())
|
||||
whenever(repository.getSelectedCategories()).thenReturn(listOf())
|
||||
categoriesPresenter.searchForCategories(query)
|
||||
testScheduler.triggerActions()
|
||||
val method: Method =
|
||||
|
|
@ -154,7 +154,7 @@ class CategoriesPresenterTest {
|
|||
fun `verifyCategories with non empty selection goes to next screen`() {
|
||||
categoriesPresenter.onAttachView(view)
|
||||
val item = categoryItem()
|
||||
whenever(repository.selectedCategories).thenReturn(listOf(item))
|
||||
whenever(repository.getSelectedCategories()).thenReturn(listOf(item))
|
||||
categoriesPresenter.verifyCategories()
|
||||
verify(repository).setSelectedCategories(listOf(item.name))
|
||||
verify(view).goToNextScreen()
|
||||
|
|
@ -163,7 +163,7 @@ class CategoriesPresenterTest {
|
|||
@Test
|
||||
fun `verifyCategories with empty selection show no category selected`() {
|
||||
categoriesPresenter.onAttachView(view)
|
||||
whenever(repository.selectedCategories).thenReturn(listOf())
|
||||
whenever(repository.getSelectedCategories()).thenReturn(listOf())
|
||||
categoriesPresenter.verifyCategories()
|
||||
verify(view).showNoCategorySelected()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class DepictsPresenterTest {
|
|||
)
|
||||
whenever(repository.searchAllEntities("")).thenReturn(Flowable.just(searchResults))
|
||||
val selectedItem = depictedItem(id = "selected")
|
||||
whenever(repository.selectedDepictions).thenReturn(listOf(selectedItem))
|
||||
whenever(repository.getSelectedDepictions()).thenReturn(listOf(selectedItem))
|
||||
depictsPresenter.searchForDepictions("")
|
||||
testScheduler.triggerActions()
|
||||
verify(view).showProgress(false)
|
||||
|
|
@ -123,14 +123,14 @@ class DepictsPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `verifyDepictions with non empty selectedDepictions goes to next screen`() {
|
||||
whenever(repository.selectedDepictions).thenReturn(listOf(depictedItem()))
|
||||
whenever(repository.getSelectedDepictions()).thenReturn(listOf(depictedItem()))
|
||||
depictsPresenter.verifyDepictions()
|
||||
verify(view).goToNextScreen()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verifyDepictions with empty selectedDepictions goes to noDepictionSelected`() {
|
||||
whenever(repository.selectedDepictions).thenReturn(emptyList())
|
||||
whenever(repository.getSelectedDepictions()).thenReturn(emptyList())
|
||||
depictsPresenter.verifyDepictions()
|
||||
verify(view).noDepictionSelected()
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ class DepictsPresenterTest {
|
|||
@Test
|
||||
fun `Test searchResults when media is not null`() {
|
||||
Whitebox.setInternalState(depictsPresenter, "media", media)
|
||||
whenever(repository.getDepictions(repository.selectedExistingDepictions))
|
||||
whenever(repository.getDepictions(repository.getSelectedExistingDepictions()))
|
||||
.thenReturn(Flowable.just(listOf(depictedItem())))
|
||||
whenever(repository.searchAllEntities("querystring"))
|
||||
.thenReturn(Flowable.just(listOf(depictedItem())))
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class UploadPresenterTest {
|
|||
fun handleSubmitImagesNoLocationWithConsecutiveNoLocationUploads() {
|
||||
`when`(imageCoords.imageCoordsExists).thenReturn(false)
|
||||
`when`(uploadItem.getGpsCoords()).thenReturn(imageCoords)
|
||||
`when`(repository.uploads).thenReturn(uploadableItems)
|
||||
`when`(repository.getUploads()).thenReturn(uploadableItems)
|
||||
uploadableItems.add(uploadItem)
|
||||
|
||||
// test 1 - insufficient count
|
||||
|
|
@ -112,7 +112,7 @@ class UploadPresenterTest {
|
|||
).thenReturn(UploadPresenter.CONSECUTIVE_UPLOADS_WITHOUT_COORDINATES_REMINDER_THRESHOLD)
|
||||
`when`(imageCoords.imageCoordsExists).thenReturn(true)
|
||||
`when`(uploadItem.getGpsCoords()).thenReturn(imageCoords)
|
||||
`when`(repository.uploads).thenReturn(uploadableItems)
|
||||
`when`(repository.getUploads()).thenReturn(uploadableItems)
|
||||
uploadableItems.add(uploadItem)
|
||||
uploadPresenter.handleSubmit()
|
||||
// no alert dialog expected
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testGetUploads() {
|
||||
assertEquals(repository.uploads, uploadModel.uploads)
|
||||
assertEquals(repository.getUploads(), uploadModel.uploads)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -130,7 +130,7 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testGetSelectedCategories() {
|
||||
assertEquals(repository.selectedCategories, categoriesModel.getSelectedCategories())
|
||||
assertEquals(repository.getSelectedCategories(), categoriesModel.getSelectedCategories())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -163,17 +163,17 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testGetLicenses() {
|
||||
assertEquals(repository.licenses, uploadModel.licenses)
|
||||
assertEquals(repository.getLicenses(), uploadModel.licenses)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetSelectedLicense() {
|
||||
assertEquals(repository.selectedLicense, uploadModel.selectedLicense)
|
||||
assertEquals(repository.getSelectedLicense(), uploadModel.selectedLicense)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetCount() {
|
||||
assertEquals(repository.count, uploadModel.count)
|
||||
assertEquals(repository.getCount(), uploadModel.count)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -242,12 +242,12 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testGetSelectedDepictions() {
|
||||
assertEquals(repository.selectedDepictions, uploadModel.selectedDepictions)
|
||||
assertEquals(repository.getSelectedDepictions(), uploadModel.selectedDepictions)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetSelectedExistingDepictions() {
|
||||
assertEquals(repository.selectedExistingDepictions, uploadModel.selectedExistingDepictions)
|
||||
assertEquals(repository.getSelectedExistingDepictions(), uploadModel.selectedExistingDepictions)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -264,7 +264,7 @@ class UploadRepositoryUnitTest {
|
|||
`when`(uploadItem.place).thenReturn(place)
|
||||
`when`(place.wikiDataEntityId).thenReturn("1")
|
||||
assertEquals(
|
||||
repository.placeDepictions,
|
||||
repository.getPlaceDepictions(),
|
||||
depictModel.getPlaceDepictions(listOf("1")),
|
||||
)
|
||||
}
|
||||
|
|
@ -326,7 +326,7 @@ class UploadRepositoryUnitTest {
|
|||
`when`(uploadModel.items).thenReturn(listOf(uploadItem))
|
||||
`when`(uploadItem.isWLMUpload).thenReturn(true)
|
||||
assertEquals(
|
||||
repository.isWMLSupportedForThisPlace,
|
||||
repository.isWMLSupportedForThisPlace(),
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
|
@ -369,7 +369,7 @@ class UploadRepositoryUnitTest {
|
|||
@Test
|
||||
fun testGetSelectedExistingCategories() {
|
||||
assertEquals(
|
||||
repository.selectedExistingCategories,
|
||||
repository.getSelectedExistingCategories(),
|
||||
categoriesModel.getSelectedExistingCategories(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue