Skip to content

Commit

Permalink
Base URL に Basic認証情報が含まれる場合、それを利用してAPI発行やサムネイル取得を行うよう修正
Browse files Browse the repository at this point in the history
  • Loading branch information
daigorian committed Jul 26, 2021
1 parent 5c9c543 commit 3e1ed27
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 31 deletions.
26 changes: 24 additions & 2 deletions app/src/main/java/com/daigorian/epcltvapp/CardPresenter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.util.Log
import android.view.ViewGroup

import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import com.daigorian.epcltvapp.epgstationcaller.EpgStation
import com.daigorian.epcltvapp.epgstationcaller.GetRecordedParam
import com.daigorian.epcltvapp.epgstationcaller.RecordedProgram
Expand Down Expand Up @@ -63,9 +64,17 @@ class CardPresenter : Presenter() {
// EPGStation Version 1.x.x
cardView.titleText = item.name
cardView.contentText = item.description
val thumbnailURL = EpgStation.getThumbnailURL(item.id.toString())

//Glideでイメージを取得する際にBasic認証が必要な場合はヘッダを付与してやる
val glideUrl = if(EpgStation.authForGlide!=null){
GlideUrl ( thumbnailURL, EpgStation.authForGlide)
}else{
GlideUrl ( thumbnailURL)
}
//録画中なら録画中アイコンを出す。
Glide.with(viewHolder.view.context)
.load(EpgStation.getThumbnailURL(item.id.toString()))
.load(glideUrl)
.centerCrop()
.error(if(item.recording){mOnRecordingCardImage}else{mDefaultCardImage})
.into(cardView.mainImageView)
Expand All @@ -76,8 +85,21 @@ class CardPresenter : Presenter() {
cardView.titleText = item.name
cardView.contentText = item.description
//サムネのURLから画像をロードする。失敗した場合、録画中なら録画中アイコンを出す。そうでなければNO IMAGEアイコン。

val thumbnailURL = if(!item.thumbnails.isNullOrEmpty()){
EpgStationV2.getThumbnailURL(item.thumbnails[0].toString())
}else{
""
}
//Glideでイメージを取得する際にBasic認証が必要な場合はヘッダを付与してやる
val glideUrl = if(EpgStationV2.authForGlide!=null){
GlideUrl ( thumbnailURL, EpgStationV2.authForGlide)
}else{
GlideUrl ( thumbnailURL)
}

Glide.with(viewHolder.view.context)
.load(if(!item.thumbnails.isNullOrEmpty()){EpgStationV2.getThumbnailURL(item.thumbnails[0].toString())}else{""})
.load(glideUrl)
.centerCrop()
.error(if(item.isRecording){mOnRecordingCardImage}else{mDefaultCardImage})
.into(cardView.mainImageView)
Expand Down
21 changes: 15 additions & 6 deletions app/src/main/java/com/daigorian/epcltvapp/MainFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.leanback.app.BrowseSupportFragment
import androidx.leanback.widget.*
import androidx.preference.PreferenceManager
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import java.util.*
Expand Down Expand Up @@ -116,11 +117,9 @@ class MainFragment : BrowseSupportFragment() {
val useCustomBaseURL = pref.getBoolean(getString(R.string.pref_key_use_custom_base_url),false)

//base URL
var baseUrl = getString(R.string.pref_val_custom_base_url_default)

if (useCustomBaseURL) {
val baseUrl = if (useCustomBaseURL) {
//カスタムURL ON の時はそちらを読み込む
baseUrl = pref.getString(
pref.getString(
getString(R.string.pref_key_custom_base_url),
getString(R.string.pref_val_custom_base_url_default)
)!!
Expand All @@ -135,7 +134,7 @@ class MainFragment : BrowseSupportFragment() {
getString(R.string.pref_key_port_num),
getString(R.string.pref_val_port_num_default)
)!!
baseUrl = "http://$ipAddress:$port/api/"
"http://$ipAddress:$port/api/"
}

//バージョンチェックして適切なバージョンのAPIを初期化
Expand Down Expand Up @@ -614,8 +613,18 @@ class MainFragment : BrowseSupportFragment() {
private fun updateBackground(uri: String?) {
val width = mMetrics.widthPixels
val height = mMetrics.heightPixels

//Glideでイメージを取得する際にBasic認証が必要な場合はヘッダを付与してやる
val glideUrl = if(EpgStation.api!=null && EpgStation.authForGlide!=null){
GlideUrl( uri, EpgStation.authForGlide)
}else if(EpgStationV2.api!=null && EpgStationV2.authForGlide!=null){
GlideUrl( uri, EpgStationV2.authForGlide)
}else{
GlideUrl ( uri )
}

Glide.with(requireContext())
.load(uri)
.load(glideUrl)
.centerCrop()
.error(mDefaultBackground)
.into<CustomTarget<Drawable>>(
Expand Down
25 changes: 23 additions & 2 deletions app/src/main/java/com/daigorian/epcltvapp/VideoDetailsFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.leanback.app.DetailsSupportFragmentBackgroundController
import androidx.leanback.widget.*
import androidx.preference.PreferenceManager
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.daigorian.epcltvapp.epgstationcaller.EpgStation
Expand Down Expand Up @@ -95,11 +96,21 @@ class VideoDetailsFragment : DetailsSupportFragment() {

private fun initializeBackground(imageURL: String) {
mDetailsBackground.enableParallax()

//Glideでイメージを取得する際にBasic認証が必要な場合はヘッダを付与してやる
val glideUrl = if(EpgStation.api!=null && EpgStation.authForGlide!=null){
GlideUrl( imageURL, EpgStation.authForGlide)
}else if(EpgStationV2.api!=null && EpgStationV2.authForGlide!=null){
GlideUrl( imageURL, EpgStationV2.authForGlide)
}else{
GlideUrl ( imageURL )
}

Glide.with(requireContext())
.asBitmap()
.centerCrop()
.error(R.drawable.default_background)
.load(imageURL)
.load(glideUrl)
.into<CustomTarget<Bitmap>>(object : CustomTarget<Bitmap>() {
override fun onResourceReady(
bitmap: Bitmap,
Expand Down Expand Up @@ -140,8 +151,18 @@ class VideoDetailsFragment : DetailsSupportFragment() {
row.imageDrawable = ContextCompat.getDrawable(requireContext(), R.drawable.default_background)
val width = convertDpToPixel(requireContext(), DETAIL_THUMB_WIDTH)
val height = convertDpToPixel(requireContext(), DETAIL_THUMB_HEIGHT)

//Glideでイメージを取得する際にBasic認証が必要な場合はヘッダを付与してやる
val glideUrl = if(EpgStation.api!=null && EpgStation.authForGlide!=null){
GlideUrl( urlString, EpgStation.authForGlide)
}else if(EpgStationV2.api!=null && EpgStationV2.authForGlide!=null){
GlideUrl( urlString, EpgStationV2.authForGlide)
}else{
GlideUrl ( urlString )
}

Glide.with(requireContext())
.load(urlString)
.load(glideUrl)
.centerCrop()
.error(R.drawable.default_background)
.into<CustomTarget<Drawable>>(object : CustomTarget<Drawable>(width, height) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package com.daigorian.epcltvapp.epgstationcaller

import android.R.attr
import android.util.Base64
import com.bumptech.glide.load.model.LazyHeaderFactory
import com.bumptech.glide.load.model.LazyHeaders
import okhttp3.Credentials
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import retrofit2.Call
import retrofit2.Retrofit.Builder
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.*
import retrofit2.http.GET
import retrofit2.http.Query
import java.io.IOException
import java.net.URL
import java.util.concurrent.TimeUnit


object EpgStation {
interface ApiInterface {
@GET("recorded")
Expand All @@ -27,25 +38,65 @@ object EpgStation {
}

private var baseUrl:String = "http://192.168.0.0:8888/api/"
var default_limit:String = "24"
const val default_limit:String = "24"

private var okHttpClient: OkHttpClient = OkHttpClient.Builder()
private var okHttpClientBuilder = OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.writeTimeout(5, TimeUnit.SECONDS)
.build()


var api: ApiInterface? = null

var authForGlide : LazyHeaders? = null

fun initAPI(_baseUrl:String){
baseUrl = _baseUrl
api = Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClient)
.build().create(ApiInterface::class.java)
val userInfo:String? = URL(baseUrl).userInfo
if(userInfo != null && userInfo.matches(Regex("^[^:]+:[^:]+$")) ) {
//Basic認証情報を含むURLである
val username = userInfo.split(":")[0]
val password = userInfo.split(":")[1]
api = Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClientBuilder.addInterceptor(BasicAuthInterceptor(username, password)).build())
.build().create(ApiInterface::class.java)

//サムネ読み込みなどで使われるGlideのヘッダを準備してやる
authForGlide = LazyHeaders.Builder()
.addHeader("Authorization", BasicAuthorization(username, password))
.build()
}else{
//Basic認証情報を含まないURLである
api = Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClientBuilder.build())
.build().create(ApiInterface::class.java)
}
}
class BasicAuthInterceptor(user: String, password: String) : Interceptor {
private val credentials: String = Credentials.basic(user, password)

@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val authenticatedRequest = request.newBuilder()
.header("Authorization", credentials).build()
return chain.proceed(authenticatedRequest)
}
}

class BasicAuthorization(private val username: String, private val password: String) :
LazyHeaderFactory {
override fun buildHeader(): String {
return "Basic " + Base64.encodeToString(
"$username:$password".toByteArray(),
Base64.NO_WRAP
)
}
}

fun getThumbnailURL(id:String):String{
return baseUrl + "recorded/" + id + "/thumbnail"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package com.daigorian.epcltvapp.epgstationv2caller

import com.bumptech.glide.load.model.LazyHeaders
import com.daigorian.epcltvapp.epgstationcaller.EpgStation
import okhttp3.Credentials
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import retrofit2.Call
import retrofit2.Retrofit.Builder
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.*
import java.io.IOException
import java.util.concurrent.TimeUnit
import java.net.URL

object EpgStationV2 {
interface ApiInterface {
Expand Down Expand Up @@ -45,23 +52,54 @@ object EpgStationV2 {


private var baseUrl:String = "http://192.168.0.0:8888/api/"
var default_limit:String = "24"
const val default_limit:String = "24"

private var okHttpClient: OkHttpClient = OkHttpClient.Builder()


private var okHttpClientBuilder = OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.writeTimeout(5, TimeUnit.SECONDS)
.build()

var api: ApiInterface? = null
var authForGlide : LazyHeaders? = null

fun initAPI(_baseUrl:String){
baseUrl = _baseUrl
api = Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClient)
.build().create(ApiInterface::class.java)
val userInfo:String? = URL(baseUrl).userInfo
if(userInfo != null && userInfo.matches(Regex("^[^:]+:[^:]+$")) ) {
//Basic認証情報を含むURLである
val username = userInfo.split(":")[0]
val password = userInfo.split(":")[1]
api = Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClientBuilder.addInterceptor(BasicAuthInterceptor(username, password)).build())
.build().create(ApiInterface::class.java)

//サムネ読み込みなどで使われるGlideのヘッダを準備してやる
authForGlide = LazyHeaders.Builder()
.addHeader("Authorization", EpgStation.BasicAuthorization(username, password))
.build()
}else{
//Basic認証情報を含まないURLである
api = Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClientBuilder.build())
.build().create(ApiInterface::class.java)
}
}
class BasicAuthInterceptor(user: String, password: String) : Interceptor {
private val credentials: String = Credentials.basic(user, password)

@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val authenticatedRequest = request.newBuilder()
.header("Authorization", credentials).build()
return chain.proceed(authenticatedRequest)
}
}

fun getThumbnailURL(id:String):String{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.daigorian.epcltvapp.epgstationv2caller

import okhttp3.Credentials
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import retrofit2.Call
import retrofit2.Retrofit.Builder
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.*
import java.io.IOException
import java.net.URL
import java.util.concurrent.TimeUnit

class EpgStationV2VersionChecker(
Expand All @@ -16,16 +21,42 @@ class EpgStationV2VersionChecker(
): Call<Version>
}

private var okHttpClient: OkHttpClient = OkHttpClient.Builder()
private var okHttpClientBuilder = OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.writeTimeout(5, TimeUnit.SECONDS)
.build()

val api: ApiInterface = Builder()

private val userinfo:String? = URL(baseUrl).userInfo
val api: ApiInterface = if(userinfo!= null && userinfo.matches(Regex("^[^:]+:[^:]+$"))) {
Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClientBuilder.addInterceptor(
EpgStationV2.BasicAuthInterceptor(
userinfo.split(":")[0],
userinfo.split(":")[1]
)
).build())
.build().create(ApiInterface::class.java)
}else {
Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClient)
.client(okHttpClientBuilder.build())
.build().create(ApiInterface::class.java)
}

class BasicAuthInterceptor(user: String, password: String) : Interceptor {
private val credentials: String = Credentials.basic(user, password)

@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val authenticatedRequest = request.newBuilder()
.header("Authorization", credentials).build()
return chain.proceed(authenticatedRequest)
}
}

}

0 comments on commit 3e1ed27

Please sign in to comment.