2016-04-21 20:28:01 -03:00
|
|
|
package us.shandian.giga.util;
|
|
|
|
|
|
|
|
import android.content.ClipData;
|
2017-06-28 07:27:32 +02:00
|
|
|
import android.content.ClipboardManager;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.content.Context;
|
2018-11-24 00:14:37 -03:00
|
|
|
import android.os.Build;
|
2019-10-09 23:49:23 -03:00
|
|
|
import android.util.Log;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
2019-10-04 14:59:08 +02:00
|
|
|
import androidx.annotation.ColorInt;
|
|
|
|
import androidx.annotation.DrawableRes;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import androidx.core.content.ContextCompat;
|
2016-04-21 20:28:01 -03:00
|
|
|
|
2017-06-28 07:27:32 +02:00
|
|
|
import org.schabi.newpipe.R;
|
2019-04-05 14:45:39 -03:00
|
|
|
import org.schabi.newpipe.streams.io.SharpStream;
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2018-05-18 18:23:32 +02:00
|
|
|
import java.io.BufferedOutputStream;
|
2018-11-08 19:03:30 -03:00
|
|
|
import java.io.File;
|
2016-04-21 20:28:01 -03:00
|
|
|
import java.io.FileInputStream;
|
2017-06-28 07:27:32 +02:00
|
|
|
import java.io.FileOutputStream;
|
2016-04-21 20:28:01 -03:00
|
|
|
import java.io.IOException;
|
2018-04-29 01:06:34 +02:00
|
|
|
import java.io.ObjectInputStream;
|
|
|
|
import java.io.ObjectOutputStream;
|
|
|
|
import java.io.Serializable;
|
2018-11-24 00:14:37 -03:00
|
|
|
import java.net.HttpURLConnection;
|
2016-04-21 20:28:01 -03:00
|
|
|
import java.security.MessageDigest;
|
|
|
|
import java.security.NoSuchAlgorithmException;
|
2019-10-09 23:49:23 -03:00
|
|
|
import java.util.Locale;
|
2019-04-05 14:45:39 -03:00
|
|
|
|
2020-06-14 19:37:45 +02:00
|
|
|
import org.schabi.newpipe.streams.io.StoredFileHelper;
|
2016-04-21 20:28:01 -03:00
|
|
|
|
2017-06-28 07:27:32 +02:00
|
|
|
public class Utility {
|
|
|
|
|
|
|
|
public enum FileType {
|
|
|
|
VIDEO,
|
|
|
|
MUSIC,
|
2018-09-23 15:12:23 -03:00
|
|
|
SUBTITLE,
|
2017-06-28 07:27:32 +02:00
|
|
|
UNKNOWN
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String formatBytes(long bytes) {
|
2019-10-09 23:49:23 -03:00
|
|
|
Locale locale = Locale.getDefault();
|
2017-06-28 07:27:32 +02:00
|
|
|
if (bytes < 1024) {
|
2019-10-09 23:49:23 -03:00
|
|
|
return String.format(locale, "%d B", bytes);
|
2017-06-28 07:27:32 +02:00
|
|
|
} else if (bytes < 1024 * 1024) {
|
2019-10-09 23:49:23 -03:00
|
|
|
return String.format(locale, "%.2f kB", bytes / 1024d);
|
2017-06-28 07:27:32 +02:00
|
|
|
} else if (bytes < 1024 * 1024 * 1024) {
|
2019-10-09 23:49:23 -03:00
|
|
|
return String.format(locale, "%.2f MB", bytes / 1024d / 1024d);
|
2017-06-28 07:27:32 +02:00
|
|
|
} else {
|
2019-10-09 23:49:23 -03:00
|
|
|
return String.format(locale, "%.2f GB", bytes / 1024d / 1024d / 1024d);
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-09 23:49:23 -03:00
|
|
|
public static String formatSpeed(double speed) {
|
|
|
|
Locale locale = Locale.getDefault();
|
2017-06-28 07:27:32 +02:00
|
|
|
if (speed < 1024) {
|
2019-10-09 23:49:23 -03:00
|
|
|
return String.format(locale, "%.2f B/s", speed);
|
2017-06-28 07:27:32 +02:00
|
|
|
} else if (speed < 1024 * 1024) {
|
2019-10-09 23:49:23 -03:00
|
|
|
return String.format(locale, "%.2f kB/s", speed / 1024);
|
2017-06-28 07:27:32 +02:00
|
|
|
} else if (speed < 1024 * 1024 * 1024) {
|
2019-10-09 23:49:23 -03:00
|
|
|
return String.format(locale, "%.2f MB/s", speed / 1024 / 1024);
|
2017-06-28 07:27:32 +02:00
|
|
|
} else {
|
2019-10-09 23:49:23 -03:00
|
|
|
return String.format(locale, "%.2f GB/s", speed / 1024 / 1024 / 1024);
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
public static void writeToFile(@NonNull File file, @NonNull Serializable serializable) {
|
2018-04-29 01:06:34 +02:00
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
|
2018-04-29 01:06:34 +02:00
|
|
|
objectOutputStream.writeObject(serializable);
|
2017-06-28 07:27:32 +02:00
|
|
|
} catch (Exception e) {
|
2018-04-29 01:06:34 +02:00
|
|
|
//nothing to do
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
//nothing to do
|
2018-04-29 01:06:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
@SuppressWarnings("unchecked")
|
2018-09-23 15:12:23 -03:00
|
|
|
public static <T> T readFromFile(File file) {
|
|
|
|
T object;
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2020-11-06 06:16:13 +05:30
|
|
|
try (ObjectInputStream objectInputStream =
|
|
|
|
new ObjectInputStream(new FileInputStream(file))) {
|
2018-04-29 01:06:34 +02:00
|
|
|
object = (T) objectInputStream.readObject();
|
2017-06-28 07:27:32 +02:00
|
|
|
} catch (Exception e) {
|
2019-04-09 18:38:34 -03:00
|
|
|
Log.e("Utility", "Failed to deserialize the object", e);
|
2018-09-23 15:12:23 -03:00
|
|
|
object = null;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
2018-04-29 01:06:34 +02:00
|
|
|
return object;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
public static String getFileExt(String url) {
|
|
|
|
int index;
|
|
|
|
if ((index = url.indexOf("?")) > -1) {
|
|
|
|
url = url.substring(0, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
index = url.lastIndexOf(".");
|
|
|
|
if (index == -1) {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
String ext = url.substring(index);
|
|
|
|
if ((index = ext.indexOf("%")) > -1) {
|
|
|
|
ext = ext.substring(0, index);
|
|
|
|
}
|
|
|
|
if ((index = ext.indexOf("/")) > -1) {
|
|
|
|
ext = ext.substring(0, index);
|
|
|
|
}
|
|
|
|
return ext.toLowerCase();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
public static FileType getFileType(char kind, String file) {
|
|
|
|
switch (kind) {
|
|
|
|
case 'v':
|
|
|
|
return FileType.VIDEO;
|
|
|
|
case 'a':
|
|
|
|
return FileType.MUSIC;
|
|
|
|
case 's':
|
|
|
|
return FileType.SUBTITLE;
|
|
|
|
//default '?':
|
|
|
|
}
|
|
|
|
|
|
|
|
if (file.endsWith(".srt") || file.endsWith(".vtt") || file.endsWith(".ssa")) {
|
|
|
|
return FileType.SUBTITLE;
|
|
|
|
} else if (file.endsWith(".mp3") || file.endsWith(".wav") || file.endsWith(".flac") || file.endsWith(".m4a") || file.endsWith(".opus")) {
|
2017-06-28 07:27:32 +02:00
|
|
|
return FileType.MUSIC;
|
|
|
|
} else if (file.endsWith(".mp4") || file.endsWith(".mpeg") || file.endsWith(".rm") || file.endsWith(".rmvb")
|
|
|
|
|| file.endsWith(".flv") || file.endsWith(".webp") || file.endsWith(".webm")) {
|
|
|
|
return FileType.VIDEO;
|
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
return FileType.UNKNOWN;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
@ColorInt
|
|
|
|
public static int getBackgroundForFileType(Context ctx, FileType type) {
|
|
|
|
int colorRes;
|
2017-06-28 07:27:32 +02:00
|
|
|
switch (type) {
|
|
|
|
case MUSIC:
|
2018-09-23 15:12:23 -03:00
|
|
|
colorRes = R.color.audio_left_to_load_color;
|
|
|
|
break;
|
2017-06-28 07:27:32 +02:00
|
|
|
case VIDEO:
|
2018-09-23 15:12:23 -03:00
|
|
|
colorRes = R.color.video_left_to_load_color;
|
|
|
|
break;
|
|
|
|
case SUBTITLE:
|
|
|
|
colorRes = R.color.subtitle_left_to_load_color;
|
|
|
|
break;
|
2017-06-28 07:27:32 +02:00
|
|
|
default:
|
2018-09-23 15:12:23 -03:00
|
|
|
colorRes = R.color.gray;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
return ContextCompat.getColor(ctx, colorRes);
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
@ColorInt
|
|
|
|
public static int getForegroundForFileType(Context ctx, FileType type) {
|
|
|
|
int colorRes;
|
2017-06-28 07:27:32 +02:00
|
|
|
switch (type) {
|
|
|
|
case MUSIC:
|
2018-09-23 15:12:23 -03:00
|
|
|
colorRes = R.color.audio_already_load_color;
|
|
|
|
break;
|
2017-06-28 07:27:32 +02:00
|
|
|
case VIDEO:
|
2018-09-23 15:12:23 -03:00
|
|
|
colorRes = R.color.video_already_load_color;
|
|
|
|
break;
|
|
|
|
case SUBTITLE:
|
|
|
|
colorRes = R.color.subtitle_already_load_color;
|
|
|
|
break;
|
2017-06-28 07:27:32 +02:00
|
|
|
default:
|
2018-09-23 15:12:23 -03:00
|
|
|
colorRes = R.color.gray;
|
|
|
|
break;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
return ContextCompat.getColor(ctx, colorRes);
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@DrawableRes
|
|
|
|
public static int getIconForFileType(FileType type) {
|
|
|
|
switch (type) {
|
|
|
|
case MUSIC:
|
2021-03-27 17:45:49 +03:00
|
|
|
return R.drawable.ic_headset;
|
2019-10-09 23:49:23 -03:00
|
|
|
default:
|
2017-06-28 07:27:32 +02:00
|
|
|
case VIDEO:
|
2021-03-27 17:45:49 +03:00
|
|
|
return R.drawable.ic_movie;
|
2018-09-23 15:12:23 -03:00
|
|
|
case SUBTITLE:
|
2021-03-27 17:45:49 +03:00
|
|
|
return R.drawable.ic_subtitles;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void copyToClipboard(Context context, String str) {
|
2020-09-13 17:20:29 +05:30
|
|
|
ClipboardManager cm = ContextCompat.getSystemService(context, ClipboardManager.class);
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
if (cm == null) {
|
|
|
|
Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_LONG).show();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-28 07:27:32 +02:00
|
|
|
cm.setPrimaryClip(ClipData.newPlainText("text", str));
|
|
|
|
Toast.makeText(context, R.string.msg_copied, Toast.LENGTH_SHORT).show();
|
|
|
|
}
|
|
|
|
|
2019-04-05 14:45:39 -03:00
|
|
|
public static String checksum(StoredFileHelper source, String algorithm) {
|
2018-09-23 15:12:23 -03:00
|
|
|
MessageDigest md;
|
2017-06-28 07:27:32 +02:00
|
|
|
|
|
|
|
try {
|
|
|
|
md = MessageDigest.getInstance(algorithm);
|
|
|
|
} catch (NoSuchAlgorithmException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
|
2019-04-05 14:45:39 -03:00
|
|
|
SharpStream i;
|
2017-06-28 07:27:32 +02:00
|
|
|
|
|
|
|
try {
|
2019-04-05 14:45:39 -03:00
|
|
|
i = source.getStream();
|
|
|
|
} catch (Exception e) {
|
2017-06-28 07:27:32 +02:00
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
byte[] buf = new byte[1024];
|
2018-09-23 15:12:23 -03:00
|
|
|
int len;
|
2017-06-28 07:27:32 +02:00
|
|
|
|
|
|
|
try {
|
|
|
|
while ((len = i.read(buf)) != -1) {
|
|
|
|
md.update(buf, 0, len);
|
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
} catch (IOException e) {
|
|
|
|
// nothing to do
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
byte[] digest = md.digest();
|
|
|
|
|
|
|
|
// HEX
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
for (byte b : digest) {
|
|
|
|
sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
|
|
|
|
}
|
|
|
|
|
|
|
|
return sb.toString();
|
2016-04-21 20:28:01 -03:00
|
|
|
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
2019-04-05 14:45:39 -03:00
|
|
|
public static boolean mkdir(File p, boolean allDirs) {
|
|
|
|
if (p.exists()) return true;
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
if (allDirs)
|
2019-04-05 14:45:39 -03:00
|
|
|
p.mkdirs();
|
2018-09-23 15:12:23 -03:00
|
|
|
else
|
2019-04-05 14:45:39 -03:00
|
|
|
p.mkdir();
|
2018-09-23 15:12:23 -03:00
|
|
|
|
2019-04-05 14:45:39 -03:00
|
|
|
return p.exists();
|
2018-09-23 15:12:23 -03:00
|
|
|
}
|
2018-11-24 00:14:37 -03:00
|
|
|
|
|
|
|
public static long getContentLength(HttpURLConnection connection) {
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
|
|
return connection.getContentLengthLong();
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2019-04-25 00:34:29 -03:00
|
|
|
return Long.parseLong(connection.getHeaderField("Content-Length"));
|
2018-11-24 00:14:37 -03:00
|
|
|
} catch (Exception err) {
|
|
|
|
// nothing to do
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2019-10-09 23:49:23 -03:00
|
|
|
|
|
|
|
private static String pad(int number) {
|
|
|
|
return number < 10 ? ("0" + number) : String.valueOf(number);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String stringifySeconds(double seconds) {
|
|
|
|
int h = (int) Math.floor(seconds / 3600);
|
|
|
|
int m = (int) Math.floor((seconds - (h * 3600)) / 60);
|
|
|
|
int s = (int) (seconds - (h * 3600) - (m * 60));
|
|
|
|
|
|
|
|
String str = "";
|
|
|
|
|
|
|
|
if (h < 1 && m < 1) {
|
|
|
|
str = "00:";
|
|
|
|
} else {
|
|
|
|
if (h > 0) str = pad(h) + ":";
|
|
|
|
if (m > 0) str += pad(m) + ":";
|
|
|
|
}
|
|
|
|
|
|
|
|
return str + pad(s);
|
|
|
|
}
|
2016-04-21 20:28:01 -03:00
|
|
|
}
|