|
| 1 | +/* |
| 2 | + * SPDX-FileCopyrightText: 2018-2026 NewPipe contributors <https://newpipe.net> |
| 3 | + * SPDX-License-Identifier: GPL-3.0-or-later |
| 4 | + */ |
| 5 | + |
| 6 | +package org.schabi.newpipe.util |
| 7 | + |
| 8 | +import android.content.Context |
| 9 | +import androidx.annotation.DrawableRes |
| 10 | +import androidx.annotation.StringRes |
| 11 | +import androidx.core.content.edit |
| 12 | +import androidx.preference.PreferenceManager |
| 13 | +import com.grack.nanojson.JsonObject |
| 14 | +import com.grack.nanojson.JsonParser |
| 15 | +import com.grack.nanojson.JsonParserException |
| 16 | +import java.util.concurrent.TimeUnit |
| 17 | +import org.schabi.newpipe.R |
| 18 | +import org.schabi.newpipe.extractor.NewPipe |
| 19 | +import org.schabi.newpipe.extractor.ServiceList |
| 20 | +import org.schabi.newpipe.extractor.StreamingService |
| 21 | +import org.schabi.newpipe.extractor.exceptions.ExtractionException |
| 22 | +import org.schabi.newpipe.extractor.services.peertube.PeertubeInstance |
| 23 | +import org.schabi.newpipe.ktx.getStringSafe |
| 24 | + |
| 25 | +object ServiceHelper { |
| 26 | + private val DEFAULT_FALLBACK_SERVICE: StreamingService = ServiceList.YouTube |
| 27 | + |
| 28 | + @JvmStatic |
| 29 | + @DrawableRes |
| 30 | + fun getIcon(serviceId: Int): Int { |
| 31 | + return when (serviceId) { |
| 32 | + 0 -> R.drawable.ic_smart_display |
| 33 | + 1 -> R.drawable.ic_cloud |
| 34 | + 2 -> R.drawable.ic_placeholder_media_ccc |
| 35 | + 3 -> R.drawable.ic_placeholder_peertube |
| 36 | + 4 -> R.drawable.ic_placeholder_bandcamp |
| 37 | + else -> R.drawable.ic_circle |
| 38 | + } |
| 39 | + } |
| 40 | + |
| 41 | + @JvmStatic |
| 42 | + fun getTranslatedFilterString(filter: String, context: Context): String { |
| 43 | + return when (filter) { |
| 44 | + "all" -> context.getString(R.string.all) |
| 45 | + "videos", "sepia_videos", "music_videos" -> context.getString(R.string.videos_string) |
| 46 | + "channels" -> context.getString(R.string.channels) |
| 47 | + "playlists", "music_playlists" -> context.getString(R.string.playlists) |
| 48 | + "tracks" -> context.getString(R.string.tracks) |
| 49 | + "users" -> context.getString(R.string.users) |
| 50 | + "conferences" -> context.getString(R.string.conferences) |
| 51 | + "events" -> context.getString(R.string.events) |
| 52 | + "music_songs" -> context.getString(R.string.songs) |
| 53 | + "music_albums" -> context.getString(R.string.albums) |
| 54 | + "music_artists" -> context.getString(R.string.artists) |
| 55 | + else -> filter |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + /** |
| 60 | + * Get a resource string with instructions for importing subscriptions for each service. |
| 61 | + * |
| 62 | + * @param serviceId service to get the instructions for |
| 63 | + * @return the string resource containing the instructions or -1 if the service don't support it |
| 64 | + */ |
| 65 | + @JvmStatic |
| 66 | + @StringRes |
| 67 | + fun getImportInstructions(serviceId: Int): Int { |
| 68 | + return when (serviceId) { |
| 69 | + 0 -> R.string.import_youtube_instructions |
| 70 | + 1 -> R.string.import_soundcloud_instructions |
| 71 | + else -> -1 |
| 72 | + } |
| 73 | + } |
| 74 | + |
| 75 | + /** |
| 76 | + * For services that support importing from a channel url, return a hint that will |
| 77 | + * be used in the EditText that the user will type in his channel url. |
| 78 | + * |
| 79 | + * @param serviceId service to get the hint for |
| 80 | + * @return the hint's string resource or -1 if the service don't support it |
| 81 | + */ |
| 82 | + @JvmStatic |
| 83 | + @StringRes |
| 84 | + fun getImportInstructionsHint(serviceId: Int): Int { |
| 85 | + return when (serviceId) { |
| 86 | + 1 -> R.string.import_soundcloud_instructions_hint |
| 87 | + else -> -1 |
| 88 | + } |
| 89 | + } |
| 90 | + |
| 91 | + @JvmStatic |
| 92 | + fun getSelectedServiceId(context: Context): Int { |
| 93 | + return (getSelectedService(context) ?: DEFAULT_FALLBACK_SERVICE).serviceId |
| 94 | + } |
| 95 | + |
| 96 | + @JvmStatic |
| 97 | + fun getSelectedService(context: Context): StreamingService? { |
| 98 | + val serviceName: String = PreferenceManager.getDefaultSharedPreferences(context) |
| 99 | + .getStringSafe( |
| 100 | + context.getString(R.string.current_service_key), |
| 101 | + context.getString(R.string.default_service_value) |
| 102 | + ) |
| 103 | + |
| 104 | + return runCatching { NewPipe.getService(serviceName) }.getOrNull() |
| 105 | + } |
| 106 | + |
| 107 | + @JvmStatic |
| 108 | + fun getNameOfServiceById(serviceId: Int): String { |
| 109 | + return ServiceList.all().stream() |
| 110 | + .filter { it.serviceId == serviceId } |
| 111 | + .findFirst() |
| 112 | + .map(StreamingService::getServiceInfo) |
| 113 | + .map(StreamingService.ServiceInfo::getName) |
| 114 | + .orElse("<unknown>") |
| 115 | + } |
| 116 | + |
| 117 | + /** |
| 118 | + * @param serviceId the id of the service |
| 119 | + * @return the service corresponding to the provided id |
| 120 | + * @throws java.util.NoSuchElementException if there is no service with the provided id |
| 121 | + */ |
| 122 | + @JvmStatic |
| 123 | + fun getServiceById(serviceId: Int): StreamingService { |
| 124 | + return ServiceList.all().firstNotNullOf { it.takeIf { it.serviceId == serviceId } } |
| 125 | + } |
| 126 | + |
| 127 | + @JvmStatic |
| 128 | + fun setSelectedServiceId(context: Context, serviceId: Int) { |
| 129 | + val serviceName = runCatching { NewPipe.getService(serviceId).serviceInfo.name } |
| 130 | + .getOrDefault(DEFAULT_FALLBACK_SERVICE.serviceInfo.name) |
| 131 | + |
| 132 | + setSelectedServicePreferences(context, serviceName) |
| 133 | + } |
| 134 | + |
| 135 | + private fun setSelectedServicePreferences(context: Context, serviceName: String?) { |
| 136 | + val sp = PreferenceManager.getDefaultSharedPreferences(context) |
| 137 | + sp.edit { putString(context.getString(R.string.current_service_key), serviceName) } |
| 138 | + } |
| 139 | + |
| 140 | + @JvmStatic |
| 141 | + fun getCacheExpirationMillis(serviceId: Int): Long { |
| 142 | + return if (serviceId == ServiceList.SoundCloud.serviceId) { |
| 143 | + TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES) |
| 144 | + } else { |
| 145 | + TimeUnit.MILLISECONDS.convert(1, TimeUnit.HOURS) |
| 146 | + } |
| 147 | + } |
| 148 | + |
| 149 | + fun initService(context: Context, serviceId: Int) { |
| 150 | + if (serviceId == ServiceList.PeerTube.serviceId) { |
| 151 | + val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) |
| 152 | + val json = sharedPreferences.getString( |
| 153 | + context.getString(R.string.peertube_selected_instance_key), |
| 154 | + null |
| 155 | + ) |
| 156 | + if (null == json) { |
| 157 | + return |
| 158 | + } |
| 159 | + |
| 160 | + val jsonObject = runCatching { JsonParser.`object`().from(json) } |
| 161 | + .getOrElse { return@initService } |
| 162 | + |
| 163 | + val name = jsonObject.getString("name") |
| 164 | + val url = jsonObject.getString("url") |
| 165 | + ServiceList.PeerTube.instance = PeertubeInstance(url, name) |
| 166 | + } |
| 167 | + } |
| 168 | + |
| 169 | + @JvmStatic |
| 170 | + fun initServices(context: Context) { |
| 171 | + ServiceList.all().forEach { initService(context, it.serviceId) } |
| 172 | + } |
| 173 | +} |
0 commit comments