import subscription

This commit is contained in:
rimthekid 2022-03-31 10:34:19 -07:00
parent 347179b59a
commit 6688e7a5de
9 changed files with 105 additions and 66 deletions

View File

@ -10,8 +10,8 @@ android {
applicationId 'com.github.libretube'
minSdk 21
targetSdk 31
versionCode 6
versionName '0.2.4'
versionCode 7
versionName '0.2.5'
multiDexEnabled true
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
resValue "string", "app_name", "LibreTube"

View File

@ -16,23 +16,10 @@
}
],
"attributes": [],
"versionCode": 6,
"versionName": "0.2.4",
"versionCode": 7,
"versionName": "0.2.5",
"outputFile": "app-x86_64-release.apk"
},
{
"type": "ONE_OF_MANY",
"filters": [
{
"filterType": "ABI",
"value": "arm64-v8a"
}
],
"attributes": [],
"versionCode": 6,
"versionName": "0.2.4",
"outputFile": "app-arm64-v8a-release.apk"
},
{
"type": "ONE_OF_MANY",
"filters": [
@ -42,10 +29,23 @@
}
],
"attributes": [],
"versionCode": 6,
"versionName": "0.2.4",
"versionCode": 7,
"versionName": "0.2.5",
"outputFile": "app-x86-release.apk"
},
{
"type": "ONE_OF_MANY",
"filters": [
{
"filterType": "ABI",
"value": "arm64-v8a"
}
],
"attributes": [],
"versionCode": 7,
"versionName": "0.2.5",
"outputFile": "app-arm64-v8a-release.apk"
},
{
"type": "ONE_OF_MANY",
"filters": [
@ -55,8 +55,8 @@
}
],
"attributes": [],
"versionCode": 6,
"versionName": "0.2.4",
"versionCode": 7,
"versionName": "0.2.5",
"outputFile": "app-armeabi-v7a-release.apk"
}
],

View File

@ -7,6 +7,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application
android:allowBackup="true"

View File

@ -15,6 +15,7 @@ import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.widget.Toolbar
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.constraintlayout.widget.ConstraintLayout
@ -49,6 +50,11 @@ class MainActivity : AppCompatActivity() {
RetrofitInstance.url=sharedPreferences.getString("instance", "https://pipedapi.kavin.rocks/")!!
DynamicColors.applyToActivitiesIfAvailable(application)
setContentView(R.layout.activity_main)
when (sharedPreferences.getString("theme_togglee", "A")!!) {
"A" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
"L" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
"D" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
bottomNavigationView = findViewById(R.id.bottomNav)

View File

@ -52,8 +52,13 @@ interface PipedApi {
@POST("unsubscribe")
suspend fun unsubscribe(@Header("Authorization") token: String, @Body subscribe: Subscribe): Message
@POST("import")
suspend fun importSubscriptions(@Header("Authorization") token: String, @Body channels: List<String>): Message
//only for fetching servers list
@GET
suspend fun getInstances(@Url url: String): List<Instances>
}

View File

@ -125,4 +125,8 @@ class SearchFragment : Fragment() {
requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
}
override fun onStop() {
super.onStop()
hideKeyboard()
}
}

View File

@ -1,13 +1,12 @@
package com.github.libretube
import android.Manifest
import android.content.ContentValues.TAG
import android.content.ContentResolver
import android.content.Context
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
@ -15,67 +14,83 @@ import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
import com.blankj.utilcode.util.UriUtils
import com.github.libretube.obj.Subscribe
import retrofit2.HttpException
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.*
import java.util.zip.ZipFile
class Settings : PreferenceFragmentCompat() {
val TAG = "Settings"
companion object {
lateinit var getContent: ActivityResultLauncher<String>
}
override fun onCreate(savedInstanceState: Bundle?) {
getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
if (uri != null) {
try{
Log.d(TAG,UriUtils.uri2File(uri).toString())
val file = UriUtils.uri2File(uri)
var inputStream: InputStream? = null
if (file.extension == "zip") {
var zipfile = ZipFile(file)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
var zipentry =
zipfile.getEntry("Takeout/YouTube and YouTube Music/subscriptions/subscriptions.csv")
// Open a specific media item using ParcelFileDescriptor.
val resolver: ContentResolver =
requireActivity()
.contentResolver
inputStream = zipfile.getInputStream(zipentry)
}else if(file.extension == "csv"){
inputStream = file.inputStream()
}
val baos = ByteArrayOutputStream()
inputStream?.use { it.copyTo(baos) }
var subscriptions = baos.toByteArray().decodeToString()
var subscribedCount = 0
for (text in subscriptions.lines()) {
if (text.take(24) != "Channel Id,Channel Url,C" && text.take(24).isNotEmpty()) {
subscribe(text.take(24))
subscribedCount++
Log.d(TAG, "subscribed: " + text + " total: " + subscribedCount)
// "rw" for read-and-write;
// "rwt" for truncating or overwriting existing file contents.
val readOnlyMode = "r"
// uri - I have got from onActivityResult
//uri = data.getData();
val parcelFile = resolver.openFileDescriptor(uri, readOnlyMode)
val fileReader = FileReader(parcelFile!!.fileDescriptor)
val reader = BufferedReader(fileReader)
var line: String?
while (reader.readLine().also { line = it } != null) {
Log.d(TAG,reader.readLine())
}
}
reader.close()
fileReader.close()
}else{
Log.d(TAG,UriUtils.uri2File(uri).toString())
val file = UriUtils.uri2File(uri)
var inputStream: InputStream? = null
if (file.extension == "zip") {
var zipfile = ZipFile(file)
Toast.makeText(
context,
"Subscribed to " + subscribedCount + " channels.",
Toast.LENGTH_SHORT
).show()
var zipentry =
zipfile.getEntry("Takeout/YouTube and YouTube Music/subscriptions/subscriptions.csv")
inputStream = zipfile.getInputStream(zipentry)
}else if(file.extension == "csv"){
inputStream = file.inputStream()
}
val baos = ByteArrayOutputStream()
inputStream?.use { it.copyTo(baos) }
var subscriptions = baos.toByteArray().decodeToString()
var channels: MutableList<String> = emptyList<String>().toMutableList()
var subscribedCount = 0
for (text in subscriptions.lines().subList(1,subscriptions.lines().size)) {
if (text.replace(" ","") != "") {
val channel = text.split(",")[0]
channels.add(channel)
subscribedCount++
Log.d(TAG, "subscribed: " + text + " total: " + subscribedCount)
}
}
subscribe(channels)
}
}catch (e: Exception){
Log.e(TAG,e.toString())
Toast.makeText(
context,
R.string.error,
@ -121,7 +136,9 @@ class Settings : PreferenceFragmentCompat() {
//check StorageAccess
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Log.d("myz", "" + Build.VERSION.SDK_INT)
if (!Environment.isExternalStorageManager()) {
if (ContextCompat.checkSelfPermission(this.requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this.requireActivity(), arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
@ -218,15 +235,12 @@ class Settings : PreferenceFragmentCompat() {
}
private fun subscribe(channel_id: String) {
private fun subscribe(channels: List<String>) {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
RetrofitInstance.api.subscribe(
sharedPref?.getString("token", "")!!,
Subscribe(channel_id)
)
RetrofitInstance.api.importSubscriptions(sharedPref?.getString("token", "")!!,channels)
} catch (e: IOException) {
Log.e(TAG, "IOException, you might not have internet connection")
return@launchWhenCreated
@ -234,9 +248,17 @@ class Settings : PreferenceFragmentCompat() {
Log.e(TAG, "HttpException, unexpected response$e")
return@launchWhenCreated
}
if(response.message == "ok"){
Toast.makeText(
context,
R.string.importsuccess,
Toast.LENGTH_SHORT
).show()
}
}
}
run()
}
}

View File

@ -23,6 +23,7 @@
<string name="region">Choose a region</string>
<string name="login_register">Login/Register</string>
<string name="please_login">Please Login or Register from the settings to show your Subscriptions!</string>
<string name="importsuccess">Subscribed successfully!</string>
<string name="subscribeIsEmpty">Subscribe to some channels first!</string>
<string name="cannotDownload">Can\'t Download this stream!</string>
<string name="dlcomplete">Download is completed!</string>

View File

@ -59,7 +59,7 @@
app:key="grid"
app:entries="@array/grid"
app:entryValues="@array/grid"
app:defaultValue=""
app:defaultValue="@integer/grid_items"
android:icon="@drawable/ic_column"
app:useSimpleSummaryProvider="true"
/>