From 2a27bce1ddc48eb25716f36c202ea1f60cceac32 Mon Sep 17 00:00:00 2001 From: cjurjiu Date: Sat, 29 Dec 2018 15:28:05 +0200 Subject: [PATCH] Migrate to CoinMarketCap professional API. Update README to reflect that the project is no longer under active development. Fix wrong title being displayed in the selection dialog. --- README.md | 26 +++++++++++---- .../view/CoinDisplayOptionsToolbar.kt | 2 ++ .../selectiondialog/view/SelectionDialog.kt | 15 ++++++++- .../res/layout/layout_selection_dialog.xml | 5 ++- app/src/main/res/values/strings.xml | 3 +- build.gradle | 3 ++ .../converter/CryptoCoinConverters.kt | 2 +- .../businesslayer/model/BookmarksCoin.kt | 2 +- .../businesslayer/model/CryptoCoin.kt | 2 +- .../businesslayer/model/CryptoCoinDetails.kt | 2 +- .../businesslayer/model/PriceData.kt | 2 +- .../CoinMarketCapBookmarksRepository.kt | 4 +-- .../CoinMarketCapCoinsRepository.kt | 8 ++--- datalayer/build.gradle | 4 ++- .../database/models/DbPartialCryptoCoin.kt | 2 +- .../datalayer/database/models/DbPriceData.kt | 2 +- .../datalayer/network/NetworkingConfig.kt | 33 ++++++++++++------- .../coinmarketcap/CoinMarketCapApiService.kt | 15 +++++---- .../model/CoinMarketCapCoinList.kt | 4 +-- .../model/CoinMarketCapCryptoCoin.kt | 8 ++--- .../model/CoinMarketCapCryptoCoinDetails.kt | 9 ++--- 21 files changed, 99 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 4a94af2..02e025f 100644 --- a/README.md +++ b/README.md @@ -5,23 +5,35 @@ Open Source cryptocurrency viewer for Android, written in Kotlin. MVP architectu ## Purpose -This project is mainly used as a playground to validate architecture concepts, to learn working with new libraries & frameworks and to play with various ideas & widgets. +This project was mainly used as a playground outside work to validate architecture concepts, to learn working with new libraries and to explore various ideas & widgets. Currently the project is no longer under active development, as it achieved its initial purpose. -Currently the project is not published to the Google Play store, though it will certainly be published at some point. - -New features will be added as time progresses. +It is not published to the Google Play store, and there are no plans to publish it anytime soon. ## Tech stack -The project is written fully in Kotlin and is structured in 3 layers: presentation, business & data. Eacy layer belongs to its own Gradle module. +The project is written fully in Kotlin and is structured in 3 layers: presentation, business & data. Each layer belongs to its own Gradle module. The interactions between layers respects Bob C. Martin's [dependency rule](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html#the-dependency-rule). Namely, "inner" layers know nothing about any of the outer layers (for instance, the data layer knows nothing about the business layer). The presentation layer uses the MVP architecture. Presenters are persisted across configuration changes & are re-attached to the new view instance after a configuration change occurs. -Data is fetched from CoinMarketCap's [public API](https://coinmarketcap.com/api/) using Retrofit. +Certain things have been left out intentionally (such as proper error handling). + +## Data + +Retrofit is used to fetch cryptocurrency data from CoinMarketCap's [professional API](https://coinmarketcap.com/api/). Only free to use endpoints are used, but an API key is required. Once you obtain your API key, add it to `local.properties`: + +``` +coinMarketCapApiKey="" +``` + +A read-to-use apk (for demo purposes) which uses a valid API-key can be found in the latest release. + +Cryptocurrency icons are fetched via Glide from [here](https://github.com/cjurjiu/cryptocurrency-icons). + +## Tools: -Tools used: +The following tools/tech is used in KairosCrypto: - [Kotlin](https://kotlinlang.org/) - [RxJava2](https://github.com/ReactiveX/RxJava) (with RxJava's Android extensions) - [RxRelay](https://github.com/JakeWharton/RxRelay) diff --git a/app/src/main/kotlin/com/catalinjurjiu/kairoscrypto/presentationlayer/features/coindisplayoptions/view/CoinDisplayOptionsToolbar.kt b/app/src/main/kotlin/com/catalinjurjiu/kairoscrypto/presentationlayer/features/coindisplayoptions/view/CoinDisplayOptionsToolbar.kt index 0b4eb52..1315232 100644 --- a/app/src/main/kotlin/com/catalinjurjiu/kairoscrypto/presentationlayer/features/coindisplayoptions/view/CoinDisplayOptionsToolbar.kt +++ b/app/src/main/kotlin/com/catalinjurjiu/kairoscrypto/presentationlayer/features/coindisplayoptions/view/CoinDisplayOptionsToolbar.kt @@ -70,6 +70,7 @@ class CoinDisplayOptionsToolbar @JvmOverloads constructor(context: Context?, override fun openChangeCurrencyDialog(selectionItems: List) { SelectionDialog.showCancelable(dialogIdentifier = CoinListSelectionDialogType.ChangeCurrency, fragmentManager = fragmentManager, + title = context.getString(R.string.dialog_pick_currency), data = selectionItems, listenerFactory = ::getListenerForDialogType) } @@ -77,6 +78,7 @@ class CoinDisplayOptionsToolbar @JvmOverloads constructor(context: Context?, override fun openSelectSnapshotDialog(selectionItems: List) { SelectionDialog.showCancelable(dialogIdentifier = CoinListSelectionDialogType.SelectSnapshot, fragmentManager = fragmentManager, + title = context.getString(R.string.dialog_pick_period), data = selectionItems, listenerFactory = ::getListenerForDialogType) } diff --git a/app/src/main/kotlin/com/catalinjurjiu/kairoscrypto/presentationlayer/features/widgets/selectiondialog/view/SelectionDialog.kt b/app/src/main/kotlin/com/catalinjurjiu/kairoscrypto/presentationlayer/features/widgets/selectiondialog/view/SelectionDialog.kt index 3bcc513..9579a9f 100644 --- a/app/src/main/kotlin/com/catalinjurjiu/kairoscrypto/presentationlayer/features/widgets/selectiondialog/view/SelectionDialog.kt +++ b/app/src/main/kotlin/com/catalinjurjiu/kairoscrypto/presentationlayer/features/widgets/selectiondialog/view/SelectionDialog.kt @@ -54,6 +54,7 @@ class SelectionDialog : DialogFragment() { .setView(view) .setCancelable(isDialogCancelable) .create() + view.dialog_title.text = arguments?.getString(KEY_TITLE).orEmpty() initRecyclerView(view = view) initCancelButton(view = view) return dialog @@ -123,8 +124,14 @@ class SelectionDialog : DialogFragment() { class Builder { private var selectionListener: OnItemSelectedListener? = null private var data: ArrayList? = null + private var dialogTitle: String = "" private var isCancelable: Boolean = true + fun title(title: String): Builder { + this.dialogTitle = title + return this + } + fun data(data: List): Builder { val parcelableData = ArrayList(data.map { it.toParcelableSelectionItem() @@ -148,8 +155,9 @@ class SelectionDialog : DialogFragment() { val arguments = Bundle() data?.let { arguments.putParcelableArrayList(KEY_DATA, data) - arguments.putBoolean(KEY_CANCELABLE, isCancelable) } + arguments.putBoolean(KEY_CANCELABLE, isCancelable) + arguments.putString(KEY_TITLE, dialogTitle) selectionListener?.let { dialog.selectionListener = selectionListener } @@ -159,25 +167,30 @@ class SelectionDialog : DialogFragment() { } companion object { + private const val KEY_TITLE = "SelectionDialog::Arguments::title" private const val KEY_DATA = "SelectionDialog::Arguments::data" private const val KEY_CANCELABLE = "SelectionDialog::Arguments::isCancelable" fun showCancelable(dialogIdentifier: T, fragmentManager: FragmentManager?, + title: String = "", data: List, listenerFactory: ListenerFactory) = SelectionDialog.Builder() .selectionListener(selectionListener = listenerFactory.invoke(dialogIdentifier)) + .title(title = title) .data(data = data) .build() .show(fragmentManager, dialogIdentifier.identifier) fun showNonCancelable(dialogIdentifier: T, fragmentManager: FragmentManager?, + title: String = "", data: List, listenerFactory: ListenerFactory) = SelectionDialog.Builder() .selectionListener(selectionListener = listenerFactory.invoke(dialogIdentifier)) + .title(title = title) .data(data = data) .cancelable(cancelable = false) .build() diff --git a/app/src/main/res/layout/layout_selection_dialog.xml b/app/src/main/res/layout/layout_selection_dialog.xml index 5d377ac..ad63942 100644 --- a/app/src/main/res/layout/layout_selection_dialog.xml +++ b/app/src/main/res/layout/layout_selection_dialog.xml @@ -10,8 +10,7 @@ style="@style/KairosCrypto.Style.Dialog.TitleText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/dialog_pick_transform_type" - tools:text="@string/dialog_pick_transform_type" /> + tools:text="@string/dialog_pick_currency" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2770ac0..50716cf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4,7 +4,8 @@ Bookmarks List Settings - Pick a currency + Pick a currency + Pick a period Done Cancel diff --git a/build.gradle b/build.gradle index 09be83b..55b60bf 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,9 @@ apply from: 'config/config.gradle' +ext.localProperties = new Properties() +localProperties.load(project.rootProject.file('local.properties').newDataInputStream()) + subprojects { buildscript { repositories { diff --git a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/converter/CryptoCoinConverters.kt b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/converter/CryptoCoinConverters.kt index 01fdc5a..9f82a18 100644 --- a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/converter/CryptoCoinConverters.kt +++ b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/converter/CryptoCoinConverters.kt @@ -128,4 +128,4 @@ private val EmptyPriceData = PriceData( percentChange1h = 0F, percentChange24h = 0F, percentChange7d = 0F, - lastUpdated = 0L) \ No newline at end of file + lastUpdated = "") \ No newline at end of file diff --git a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/BookmarksCoin.kt b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/BookmarksCoin.kt index 3e30120..1e14fcc 100644 --- a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/BookmarksCoin.kt +++ b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/BookmarksCoin.kt @@ -12,7 +12,7 @@ data class BookmarksCoin(val id: String, val totalSupply: Double, val maxSupply: Double, var priceData: Map, - val lastUpdated: Long, + val lastUpdated: String, val isLoading: Boolean) inline fun CryptoCoin.toBookmarksCoin(isLoading: Boolean = false): BookmarksCoin { diff --git a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/CryptoCoin.kt b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/CryptoCoin.kt index 7eaf97f..f96c4de 100644 --- a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/CryptoCoin.kt +++ b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/CryptoCoin.kt @@ -12,4 +12,4 @@ data class CryptoCoin(val id: String, val totalSupply: Double, val maxSupply: Double, var priceData: Map, - val lastUpdated: Long) \ No newline at end of file + val lastUpdated: String) \ No newline at end of file diff --git a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/CryptoCoinDetails.kt b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/CryptoCoinDetails.kt index cd8a057..a6b78ab 100644 --- a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/CryptoCoinDetails.kt +++ b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/CryptoCoinDetails.kt @@ -12,4 +12,4 @@ data class CryptoCoinDetails(val id: String, val totalSupply: Double, val maxSupply: Double, var priceData: Map, - val lastUpdated: Long) \ No newline at end of file + val lastUpdated: String) \ No newline at end of file diff --git a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/PriceData.kt b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/PriceData.kt index 22bc9c3..5945ad5 100644 --- a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/PriceData.kt +++ b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/model/PriceData.kt @@ -11,4 +11,4 @@ data class PriceData(val currency: String, val percentChange1h: Float, val percentChange24h: Float, val percentChange7d: Float, - val lastUpdated: Long = -1) \ No newline at end of file + val lastUpdated: String = "") \ No newline at end of file diff --git a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/repository/coinmarketcap/CoinMarketCapBookmarksRepository.kt b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/repository/coinmarketcap/CoinMarketCapBookmarksRepository.kt index 98eae9a..1588849 100644 --- a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/repository/coinmarketcap/CoinMarketCapBookmarksRepository.kt +++ b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/repository/coinmarketcap/CoinMarketCapBookmarksRepository.kt @@ -95,7 +95,7 @@ class CoinMarketCapBookmarksRepository(private val kairosCryptoDb: KairosCryptoD requestsObservable.subscribe({ request -> //onNext request.response.subscribe { coinDetailsResponse -> - val coinDetails = coinDetailsResponse.data + val coinDetails = coinDetailsResponse.data.entries.first().value val coinId = kairosCryptoDb.getPlainCryptoCoinDao().insert(coinDetails.toDataLayerCoin()) val priceDetailsIds = kairosCryptoDb.getCoinMarketCapPriceDataDao().insert(coinDetails.toDataLayerPriceData()) Log.d(TAG, "Repo refreshBookmarks response. inserted coin with id: " + @@ -135,7 +135,7 @@ class CoinMarketCapBookmarksRepository(private val kairosCryptoDb: KairosCryptoD //setup request.response.subscribe { coinDetailsResponse -> //onNext - val coinDetails = coinDetailsResponse.data + val coinDetails = coinDetailsResponse.data.entries.first().value //also remove the coin from the list of loading coins before inserting into //DB, to prevent db change notifications before the list is updated loadingCoinsList.remove(coin.symbol) diff --git a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/repository/coinmarketcap/CoinMarketCapCoinsRepository.kt b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/repository/coinmarketcap/CoinMarketCapCoinsRepository.kt index fa76e21..2b7c868 100644 --- a/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/repository/coinmarketcap/CoinMarketCapCoinsRepository.kt +++ b/businesslayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/businesslayer/repository/coinmarketcap/CoinMarketCapCoinsRepository.kt @@ -80,16 +80,16 @@ class CoinMarketCapCoinsRepository(private val kairosCryptoDb: KairosCryptoDb, coinMarketCapApiService = coinMarketCapApiService) val resultSubject: PublishSubject = PublishSubject.create() - apiRequest.response.observeOn(Schedulers.io()).subscribe { + apiRequest.response.observeOn(Schedulers.io()).subscribe { response -> //network coins from the response - val networkCoins: List = it.data.map { coin -> coin.value } + val networkCoins: List = response.data //db coins & insert val dbCoins: List = networkCoins.map { coin -> coin.toDataLayerCoin() } kairosCryptoDb.getPlainCryptoCoinDao().insert(dbCoins) //price data val coinsPriceData = networkCoins.flatMap { it.toDataLayerPriceData() } val insertedDataIds = kairosCryptoDb.getCoinMarketCapPriceDataDao().insert(coinsPriceData) - Log.d(TAG, "Repo getFreshCoins response AFTER do next coins size:" + it.data.size + "" + + Log.d(TAG, "Repo getFreshCoins response AFTER do next coins size:" + response.data.size + "" + "inserted ids:" + insertedDataIds) resultSubject.onNext(pageIndex + numberOfPages - 1) resultSubject.onComplete() @@ -162,7 +162,7 @@ class CoinMarketCapCoinsRepository(private val kairosCryptoDb: KairosCryptoDb, .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe { coinResponse -> - val coin = coinResponse.data + val coin = coinResponse.data.entries.first().value val dbCoin: DbPartialCryptoCoin = coin.toDataLayerCoin() kairosCryptoDb.getPlainCryptoCoinDao().insert(dbCoin) val dbPriceData = coin.toDataLayerPriceData() diff --git a/datalayer/build.gradle b/datalayer/build.gradle index b4b0f52..f1f617d 100644 --- a/datalayer/build.gradle +++ b/datalayer/build.gradle @@ -10,8 +10,9 @@ android { targetSdkVersion 27 versionCode 1 versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + //add the api key + buildConfigField("String", "COINMARKETCAP_API_KEY", localProperties.getProperty("coinMarketCapApiKey")) } sourceSets { @@ -58,6 +59,7 @@ dependencies { //jsoup implementation "org.jsoup:jsoup:$config.lib_versions.jsoup" + //testing stuff testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' diff --git a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/database/models/DbPartialCryptoCoin.kt b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/database/models/DbPartialCryptoCoin.kt index ce2cb62..06346f5 100644 --- a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/database/models/DbPartialCryptoCoin.kt +++ b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/database/models/DbPartialCryptoCoin.kt @@ -51,7 +51,7 @@ data class DbPartialCryptoCoin( @ColumnInfo(name = ColumnNames.MAX_SUPPLY) val maxSupply: Double, @ColumnInfo(name = ColumnNames.LAST_UPDATED) - val lastUpdated: Long) { + val lastUpdated: String) { companion object { const val COIN_TABLE_NAME: String = "coins" diff --git a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/database/models/DbPriceData.kt b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/database/models/DbPriceData.kt index 3945d01..2297fdb 100644 --- a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/database/models/DbPriceData.kt +++ b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/database/models/DbPriceData.kt @@ -61,7 +61,7 @@ data class DbPriceData( @ColumnInfo(name = ColumnNames.PERCENT_CHANGE_7D) val percentChange7d: Float, @ColumnInfo(name = ColumnNames.LAST_UPDATED) - val lastUpdated: Long = -1) { + val lastUpdated: String = "") { companion object { const val PRICE_DATA_TABLE_NAME = "price_data" diff --git a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/NetworkingConfig.kt b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/NetworkingConfig.kt index 13159a1..7d399d2 100644 --- a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/NetworkingConfig.kt +++ b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/NetworkingConfig.kt @@ -1,8 +1,10 @@ package com.catalinjurjiu.kairoscrypto.datalayer.network +import com.catalinjurjiu.kairoscrypto.datalayer.BuildConfig import com.catalinjurjiu.kairoscrypto.datalayer.network.coinmarketcap.CoinMarketCapApiService import com.catalinjurjiu.kairoscrypto.datalayer.network.coinmarketcap.CoinMarketCapHtmlService import okhttp3.OkHttpClient +import okhttp3.Request import retrofit2.Converter import retrofit2.Retrofit import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory @@ -11,20 +13,34 @@ import retrofit2.converter.scalars.ScalarsConverterFactory object RestServiceFactory { - private val retrofit: Retrofit = RetrofitFactory(baseUrl = CoinMarketCapApiService.BASE_URL, - okHttpClient = OkHttpFactory.okHttpClient, - converterFactory = GsonConverterFactory.create()) - .build() + private val retrofit2: Retrofit + + init { + val httpClient: OkHttpClient.Builder = OkHttpClient.Builder() + httpClient.addInterceptor { chain -> + val original = chain.request() + val request: Request = original.newBuilder() + .header(CoinMarketCapApiService.API_KEY_HEADER, BuildConfig.COINMARKETCAP_API_KEY) + .method(original.method(), original.body()) + .build() + chain.proceed(request) + } + + retrofit2 = RetrofitFactory(baseUrl = CoinMarketCapApiService.BASE_URL, + okHttpClient = httpClient.build(), + converterFactory = GsonConverterFactory.create()) + .build() + } fun getCoinsRestServiceApi(): CoinMarketCapApiService { - return retrofit.create(CoinMarketCapApiService::class.java) + return retrofit2.create(CoinMarketCapApiService::class.java) } } object HtmlServiceFactory { private val retrofit: Retrofit = RetrofitFactory(baseUrl = CoinMarketCapHtmlService.BASE_URL, - okHttpClient = OkHttpFactory.okHttpClient, + okHttpClient = OkHttpClient.Builder().build(), converterFactory = ScalarsConverterFactory.create()) .build() @@ -33,10 +49,6 @@ object HtmlServiceFactory { } } -object OkHttpFactory { - val okHttpClient = OkHttpClient.Builder().build() -} - private class RetrofitFactory(private val baseUrl: String, private val okHttpClient: OkHttpClient, private val converterFactory: Converter.Factory) { @@ -47,5 +59,4 @@ private class RetrofitFactory(private val baseUrl: String, .addConverterFactory(converterFactory) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build() - } \ No newline at end of file diff --git a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/CoinMarketCapApiService.kt b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/CoinMarketCapApiService.kt index 5174c3a..a96a78e 100644 --- a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/CoinMarketCapApiService.kt +++ b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/CoinMarketCapApiService.kt @@ -5,7 +5,6 @@ import com.catalinjurjiu.kairoscrypto.datalayer.network.coinmarketcap.model.Coin import com.catalinjurjiu.kairoscrypto.datalayer.network.coinmarketcap.model.CoinMarketCapCryptoCoinListResponse import io.reactivex.Observable import retrofit2.http.GET -import retrofit2.http.Path import retrofit2.http.Query /** @@ -26,7 +25,7 @@ interface CoinMarketCapApiService { * @return an [Observable] which emits one [CoinMarketCapCryptoCoinListResponse] when the request * has finished */ - @GET(V2_TICKER_ENDPOINT) + @GET("$V1_CRYPTOCURRENCY_ENDPOINT/listings/latest") fun fetchCoinsList(@Query(START_URL_PARAM) start: Int = 0, @Query(LIMIT_URL_PARAM) limit: Int = 0, @Query(CONVERT_URL_PARAM) currency: String = CurrencyRepresentation.USD.currency) @@ -42,8 +41,8 @@ interface CoinMarketCapApiService { * @return an [Observable] which emits one [CoinMarketCapCryptoCoinDetails] when the request * has finished */ - @GET("$V2_TICKER_ENDPOINT/{$PATH_COIN_ID}") - fun fetchCoinDetails(@Path(PATH_COIN_ID) + @GET("$V1_CRYPTOCURRENCY_ENDPOINT/quotes/latest") + fun fetchCoinDetails(@Query(COIN_ID) coinId: String, @Query(CONVERT_URL_PARAM) currency: String = CurrencyRepresentation.USD.currency): Observable @@ -52,11 +51,13 @@ interface CoinMarketCapApiService { /** * Base url for the Rest API of cointmarketcap.com */ - const val BASE_URL: String = "https://api.coinmarketcap.com" + const val BASE_URL: String = "https://pro-api.coinmarketcap.com" + //custom header which will store the API KEY + const val API_KEY_HEADER: String = "X-CMC_PRO_API_KEY" //ticker endpoint - private const val V2_TICKER_ENDPOINT: String = "/v2/ticker" + private const val V1_CRYPTOCURRENCY_ENDPOINT: String = "/v1/cryptocurrency" //serverId of the coin which we want to retrieve - private const val PATH_COIN_ID = "serverId" + private const val COIN_ID = "id" //coin nr limit private const val LIMIT_URL_PARAM: String = "limit" //list coins start diff --git a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCoinList.kt b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCoinList.kt index 07c0cab..788a9b5 100644 --- a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCoinList.kt +++ b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCoinList.kt @@ -9,12 +9,12 @@ import com.google.gson.annotations.SerializedName * Created by catalinj on 27.01.2018. */ data class CoinMarketCapCryptoCoinListResponse( - @SerializedName("data") val data: Map, + @SerializedName("data") val data: List, @SerializedName("metadata") val metadata: CoinMarketCapCryptoCoinListMetadata ) data class CoinMarketCapCryptoCoinListMetadata( - @SerializedName("timestamp") val timestamp: Long, + @SerializedName("timestamp") val timestamp: String, @SerializedName("num_cryptocurrencies") val numCryptocurrencies: Int, @SerializedName("error") val error: String ) \ No newline at end of file diff --git a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCryptoCoin.kt b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCryptoCoin.kt index a586546..18a8cbb 100644 --- a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCryptoCoin.kt +++ b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCryptoCoin.kt @@ -11,13 +11,13 @@ data class CoinMarketCapCryptoCoin( @SerializedName("id") val id: String, @SerializedName("name") val name: String, @SerializedName("symbol") val symbol: String, - @SerializedName("website_slug") val websiteSlug: String, - @SerializedName("rank") val rank: Int, + @SerializedName("slug") val websiteSlug: String, + @SerializedName("cmc_rank") val rank: Int, @SerializedName("circulating_supply") val circulatingSupply: Double, @SerializedName("total_supply") val totalSupply: Double, @SerializedName("max_supply") val maxSupply: Double, - @SerializedName("quotes") val quotes: Map, - @SerializedName("last_updated") val lastUpdated: Long + @SerializedName("quote") val quotes: Map, + @SerializedName("last_updated") val lastUpdated: String ) data class Quote( diff --git a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCryptoCoinDetails.kt b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCryptoCoinDetails.kt index 4b748ee..54149f5 100644 --- a/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCryptoCoinDetails.kt +++ b/datalayer/src/main/kotlin/com/catalinjurjiu/kairoscrypto/datalayer/network/coinmarketcap/model/CoinMarketCapCryptoCoinDetails.kt @@ -8,11 +8,12 @@ import com.google.gson.annotations.SerializedName * Created by catalinj on 27.01.2018. */ data class CoinMarketCapCryptoCoinDetails( - @SerializedName("data") val data: CoinMarketCapCryptoCoin, - @SerializedName("metadata") val metadata: CoinMarketCapCryptoCoinDetailsMetadata + @SerializedName("data") val data: Map, + @SerializedName("status") val metadata: CoinMarketCapCryptoCoinDetailsMetadata ) data class CoinMarketCapCryptoCoinDetailsMetadata( - @SerializedName("timestamp") val timestamp: Long, - @SerializedName("error") val error: String + @SerializedName("timestamp") val timestamp: String, + @SerializedName("errorCode") val errorCode: Int, + @SerializedName("errorMessage") val errorMessage: String ) \ No newline at end of file