lastfm test

This commit is contained in:
gdlbo
2022-07-28 00:15:41 +03:00
parent 81c4e1c019
commit 9d3e7c53de
9 changed files with 231 additions and 23 deletions
@@ -1,8 +1,10 @@
package bruhcollective.itaysonlab.libvkx.client;
import static ru.vtosters.lite.music.Scrobbler.scrobbleTrack;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.RemoteException;
@@ -14,22 +16,23 @@ import java.util.List;
import bruhcollective.itaysonlab.libvkx.ILibVkxService;
public class LibVKXClient {
public class LibVKXClient{
@SuppressLint("StaticFieldLeak")
private static LibVKXClientImpl impl;
public static LibVKXClientImpl getInstance(Context context) {
public static LibVKXClientImpl getInstance(Context context){
if (impl == null) {
impl = new LibVKXClientImpl(context);
}
return impl;
}
public static LibVKXClientImpl getInstance() {
public static LibVKXClientImpl getInstance(){
LibVKXClientImpl libVKXClientImpl = impl;
return libVKXClientImpl == null ? getInstance(getGlobalContext()) : libVKXClientImpl;
}
public static boolean isVkxInstalled() {
public static boolean isVkxInstalled(){
try {
getGlobalContext().getPackageManager().getPackageInfo("ua.itaysonlab.vkx", 0);
return true;
@@ -38,11 +41,13 @@ public class LibVKXClient {
}
} // VKX check
public static boolean isIntegrationEnabled() {
public static boolean isIntegrationEnabled(){
return getBoolValue("libvkx_integration", false) && isVkxInstalled();
}
public static boolean play(MusicTrack musicTrack, List<MusicTrack> list, MusicPlaybackLaunchContext playerRefer) {
public static boolean play(MusicTrack musicTrack, List<MusicTrack> list, MusicPlaybackLaunchContext playerRefer){
scrobbleTrack(musicTrack.h, musicTrack.C, musicTrack.f, musicTrack.y1());
if (!isIntegrationEnabled()) {
return false;
}
@@ -52,7 +57,7 @@ public class LibVKXClient {
return getInstance().runOnService(action);
}
public static void lambdaplay(List<MusicTrack> list, MusicTrack musicTrack, ILibVkxService iLibVkxService) {
public static void lambdaplay(List<MusicTrack> list, MusicTrack musicTrack, ILibVkxService iLibVkxService){
int indexOf = list.indexOf(musicTrack);
var ids = new ArrayList<String>();
for (var track : list) {
@@ -69,7 +74,7 @@ public class LibVKXClient {
}
}
private static String asId(MusicTrack musicTrack) {
private static String asId(MusicTrack musicTrack){
String str = musicTrack.e + "_" + musicTrack.d;
if (musicTrack.O == null || musicTrack.O.equals("")) {
return str;
@@ -6,7 +6,7 @@ import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.milkshake;
import static ru.vtosters.lite.utils.Preferences.superapp;
import static ru.vtosters.lite.utils.Preferences.useNewSettings;
import static ru.vtosters.lite.utils.Preferences.videoewcatalog;
import static ru.vtosters.lite.utils.Preferences.videonewcatalog;
import static ru.vtosters.lite.utils.Preferences.vkme;
import com.vk.apps.AppsFragment;
@@ -53,7 +53,7 @@ public class StartFragmentHook {
case "photos":
return PhotosFragment.class;
case "videos":
return videoewcatalog() ? VideoCatalogFragment.class : VideosFragment.class;
return videonewcatalog() ? VideoCatalogFragment.class : VideosFragment.class;
case "settings":
return useNewSettings();
case "apps":
@@ -0,0 +1,126 @@
package ru.vtosters.lite.music;
import static java.lang.String.valueOf;
import static ru.vtosters.lite.utils.AndroidUtils.MD5;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
import ru.vtosters.lite.net.NetCall;
import ru.vtosters.lite.net.NetCallback;
import ru.vtosters.lite.net.NetClient;
import ru.vtosters.lite.net.NetRequest;
import ru.vtosters.lite.net.NetResponse;
import ru.vtosters.lite.utils.Preferences;
public class Scrobbler{
public static final String key = "5965d63402414776c54c266db0211746";
public static final String keysecret = "d982180eed13275bb948e41cf225f88f";
public static final String url = "https://ws.audioscrobbler.com/2.0/";
private static final NetClient client = new NetClient.Builder().build();
public static ArrayList<String> scrobbled = new ArrayList<>();
public static void scrobbleTrack(long duration, String artist, String title, String uid){
var string = getDefaultPrefs().getString("sessionKey", null);
var timestamp = System.currentTimeMillis() / 1000;
Log.d("Scrobbler", "scrobbleTrack: " + title + " - " + artist + " - " + duration + " - " + uid);
if (string == null || !scrobbled.contains(uid) && !getPreferences().getBoolean("lastfm_enabled", false)) {
return;
}
scrobbled.add(uid);
TreeMap<String, String> treeMap = new TreeMap<>();
treeMap.put("method", "track.scrobble");
treeMap.put("sk", string);
treeMap.put("artist[0]", artist);
treeMap.put("track[0]", title);
treeMap.put("timestamp[0]", valueOf(timestamp));
treeMap.put("api_key", key);
treeMap.put("duration[0]", String.valueOf(duration));
treeMap.put("api_sig", signMD5(treeMap));
treeMap.put("format", "json");
client.newCall(new NetRequest.Builder().url(url).post().params(treeMap).build()).enqueue(new NetCallback(){
@Override
public void onFailure(NetCall call, IOException e){
Log.d("Scrobbler", "Error: " + e.getMessage());
}
@Override
public void onResponse(NetCall call, NetResponse response){
Log.d("Scrobbler", "Scrobbled: " + artist + " - " + title);
if (Preferences.dev()) Log.d("Scrobbler", "Response scrobble: " + response.getDataString());
}
});
}
private static String signMD5(Map<String, String> map){
var sb = new StringBuilder();
for (Map.Entry<String, String> entry : map.entrySet()) {
sb.append(entry.getKey());
sb.append(entry.getValue());
}
sb.append(keysecret);
return MD5(sb.toString());
}
public static void auth(String login, String pass){
TreeMap<String, String> treeMap = new TreeMap<>();
treeMap.put("method", "auth.getMobileSession");
treeMap.put("api_key", key);
treeMap.put("username", login);
treeMap.put("password", pass);
treeMap.put("api_sig", signMD5(treeMap));
treeMap.put("format", "json");
client.newCall(new NetRequest.Builder().url(url).post().params(treeMap).build()).enqueue(new NetCallback(){
@Override
public void onFailure(NetCall call, IOException e){
Log.d("Scrobbler", "Auth failed", e);
sendToast("Ошибка входа");
}
@Override
public void onResponse(NetCall call, NetResponse response){
try {
Log.d("Scrobbler", "Auth " + response.getDataString());
JSONObject jSONObject = new JSONObject(response.getDataString()).getJSONObject("session");
String string = jSONObject.getString("name");
getDefaultPrefs().edit().putString("username", string).putString("sessionKey", jSONObject.getString("key")).apply();
sendToast("Успешно вошли как " + string);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
public static void reset(){
edit().remove("username").apply();
edit().remove("sessionKey").apply();
sendToast("Вы успешно вышли из учетной записи");
}
private static String getSessionKey(){
return getDefaultPrefs().getString("sessionKey", null);
}
public static String getUserName(){
return !getSessionKey().isEmpty() ? getDefaultPrefs().getString("username", null) : null;
}
}
@@ -6,7 +6,7 @@ import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.milkshake;
import static ru.vtosters.lite.utils.Preferences.superapp;
import static ru.vtosters.lite.utils.Preferences.useNewSettings;
import static ru.vtosters.lite.utils.Preferences.videoewcatalog;
import static ru.vtosters.lite.utils.Preferences.videonewcatalog;
import static ru.vtosters.lite.utils.Preferences.vkme;
import static ru.vtosters.lite.utils.Preferences.vkme_notifs;
@@ -197,7 +197,7 @@ public class DockBarEditorManager {
R.drawable.ic_video_outline_28,
R.string.videos,
R.id.menu_videos,
videoewcatalog() ? VideoCatalogFragment.class : VideosFragment.class);
videonewcatalog() ? VideoCatalogFragment.class : VideosFragment.class);
case "tab_lives":
return DockBarTab.valuesOf(
"tab_lives",
@@ -1,5 +1,7 @@
package ru.vtosters.lite.ui.fragments;
import static ru.vtosters.lite.ui.PreferencesUtil.getSTextColor;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
@@ -13,6 +15,7 @@ import android.content.DialogInterface;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
@@ -26,6 +29,7 @@ import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
import java.util.Arrays;
import ru.vtosters.lite.downloaders.VideoDownloader;
import ru.vtosters.lite.music.Scrobbler;
import ru.vtosters.lite.ui.adapters.ImagineArrayAdapter;
public class MediaFragment extends MaterialPreferenceToolbarFragment {
@@ -37,21 +41,52 @@ public class MediaFragment extends MaterialPreferenceToolbarFragment {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
input.setTextColor(getTextAttr());
input.setBackgroundTintList(ColorStateList.valueOf(getAccentColor()));
alertDialog.setView(input);
alertDialog.setPositiveButton("Скачать", (dialog, which) -> VideoDownloader.parseVideoLink(input.getText().toString(), ctx));
var alert = alertDialog.create();
alert.show();
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
}
public static void lastfmAuth(Context ctx) {
LinearLayout linearLayout = new LinearLayout(ctx);
linearLayout.setOrientation(LinearLayout.VERTICAL);
final EditText fn = new EditText(ctx);
fn.setHint("Логин");
fn.setTextColor(getTextAttr());
fn.setHintTextColor(getSTextColor(ctx));
fn.setBackgroundTintList(ColorStateList.valueOf(getAccentColor()));
linearLayout.addView(fn);
fn.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
ViewGroup.MarginLayoutParams margin = ((ViewGroup.MarginLayoutParams) fn.getLayoutParams());
margin.setMargins(dp2px(20f), 0, dp2px(20f), 0);
fn.setLayoutParams(margin);
final EditText ln = new EditText(ctx);
ln.setHint("Пароль");
ln.setTextColor(getTextAttr());
ln.setHintTextColor(getSTextColor(ctx));
ln.setBackgroundTintList(ColorStateList.valueOf(getAccentColor()));
linearLayout.addView(ln);
ln.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
ln.setLayoutParams(margin);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(ctx, getAlertStyle());
alertDialog.setTitle("Введите логин и пароль");
alertDialog.setView(linearLayout);
alertDialog.setPositiveButton("Войти", (dialog, which) -> {
String login = fn.getText().toString();
String pass = ln.getText().toString();
Scrobbler.auth(login, pass);
});
var alert = alertDialog.create();
alert.show();
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
}
@@ -65,6 +100,14 @@ public class MediaFragment extends MaterialPreferenceToolbarFragment {
private void prefs() {
findPreference("download_video").setOnPreferenceClickListener(new MediaFragment.download());
findPreference("dateformat").setOnPreferenceChangeListener(new MediaFragment.restart());
findPreference("lastfm_auth").setOnPreferenceClickListener(preference -> {
lastfmAuth(getContext());
return true;
});
findPreference("lastfm_reset").setOnPreferenceClickListener(preference -> {
Scrobbler.reset();
return true;
});
findPreference("select_photo_search_engine").setOnPreferenceClickListener(preference -> {
var items = Arrays.asList(
new ImagineArrayAdapter.ImagineArrayAdapterItem(getIdentifier("yandex", "drawable"), "Yandex"),
@@ -15,6 +15,8 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;
public class AndroidUtils {
@@ -115,4 +117,24 @@ public class AndroidUtils {
public static void sendToast(String text) {
Toast.makeText(getGlobalContext(), text, Toast.LENGTH_SHORT).show();
}
public static String MD5(String s){
try {
var messageDigest = MessageDigest.getInstance("MD5");
var sb = new StringBuilder();
messageDigest.update(s.getBytes());
byte[] digest = messageDigest.digest();
for (byte b : digest) {
String hexString = Integer.toHexString(b & 255);
while(hexString.length() < 2) {
hexString = "0" + hexString;
}
sb.append(hexString);
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
}
@@ -211,8 +211,8 @@ public class Preferences {
return getBoolValue("musicnewcatalog", true);
}
public static boolean videoewcatalog() {
return getBoolValue("videoewcatalog", true);
public static boolean videonewcatalog() {
return getBoolValue("videonewcatalog", true);
}
public static boolean postsredesign() {
+13 -1
View File
@@ -36,6 +36,18 @@
android:summary="Отключение значительно улучшит качество загружаемых видео"
android:title="@string/sett_compress_videos" />
</PreferenceCategory>
<PreferenceCategory android:title="Last.fm">
<Preference
android:key="lastfm_auth"
android:title="Войти в аккаунт" />
<Preference
android:key="lastfm_reset"
android:title="Сбросить настройки аккаунта" />
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="false"
android:key="lastfm_enabled"
android:title="Включить скробблинг" />
</PreferenceCategory>
<PreferenceCategory android:title="Музыка">
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="true"
@@ -56,7 +68,7 @@
android:title="Скачать видео" />
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="true"
android:key="videoewcatalog"
android:key="videonewcatalog"
android:summary="Новый каталог видео раздела с динамическим контентом"
android:title="Новый раздел видео" />
<com.vtosters.lite.ui.MaterialSwitchPreference
@@ -356,7 +356,7 @@
.line 1
invoke-super {p0, p1}, Lcom/vk/navigation/NavigationDelegateActivity;->onCreate(Landroid/os/Bundle;)V
invoke-static {p0}, Lru/vtosters/lite/ui/components/Crashreporter;->init(Landroid/app/Activity;)V
invoke-static {p0}, Lru/vtosters/lite/ui/components/CrashReporter;->init(Landroid/app/Activity;)V
invoke-static {p0}, Lru/vtosters/lite/utils/VTVerifications;->load(Landroid/content/Context;)V