Initial
This commit is contained in:
parent
11cb7a4abc
commit
d60ec051e0
12 changed files with 473 additions and 0 deletions
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/*.zip
|
182
combomodule-pyi.py
Normal file
182
combomodule-pyi.py
Normal file
|
@ -0,0 +1,182 @@
|
|||
import subprocess
|
||||
import re
|
||||
import time
|
||||
import sqlite3
|
||||
import os
|
||||
import requests
|
||||
|
||||
def get_working_directory():
|
||||
# If you see this function, that means you are using the pyinstaller. Use this command to create the executable:
|
||||
# pyinstaller -s -F combomodule-pyi.py --runtime-tmpdir /data/local/tmp
|
||||
if os.path.exists("/sdcard/localwrapped"):
|
||||
return "/sdcard/localwrapped"
|
||||
elif os.path.exists("/storage/emulated/0/localwrapped"):
|
||||
return "/storage/emulated/0/localwrapped"
|
||||
elif os.path.exists("/data/media/0/localwrapped"):
|
||||
return "/data/media/0/localwrapped"
|
||||
elif os.path.exists("/mnt/user/0/emulated/0/localwrapped"):
|
||||
return "/mnt/user/0/emulated/0/localwrapped"
|
||||
else:
|
||||
print("Path not found.")
|
||||
try:
|
||||
if os.path.exists("/sdcard"):
|
||||
os.mkdir("/sdcard/localwrapped")
|
||||
return "/sdcard/localwrapped"
|
||||
else:
|
||||
raise Exception
|
||||
except:
|
||||
try:
|
||||
if os.path.exists("/storage/emulated/0"):
|
||||
os.mkdir("/storage/emulated/0/localwrapped")
|
||||
return "/storage/emulated/0/localwrapped"
|
||||
else:
|
||||
raise Exception
|
||||
except:
|
||||
try:
|
||||
if os.path.exists("/data/media/0"):
|
||||
os.mkdir("/data/media/0/localwrapped")
|
||||
return "/data/media/0/localwrapped"
|
||||
else:
|
||||
raise Exception
|
||||
except:
|
||||
try:
|
||||
if os.path.exists("/mnt/user/0/emulated/0"):
|
||||
os.mkdir("/mnt/user/0/emulated/0/localwrapped")
|
||||
return "/mnt/user/0/emulated/0/localwrapped"
|
||||
else:
|
||||
raise Exception
|
||||
except:
|
||||
print("Path not found and could not be created.")
|
||||
exit()
|
||||
|
||||
if not os.path.exists(f"{get_working_directory()}/key.txt"):
|
||||
print("Key not exist")
|
||||
exit()
|
||||
|
||||
def get_verification_code():
|
||||
try:
|
||||
with open(f"{get_working_directory()}/key.txt", "r") as f:
|
||||
key = f.read()
|
||||
try:
|
||||
verifyrequest = requests.post(os.environ["MSSERVER"] + "/verifykey", json={"key": key})
|
||||
if verifyrequest.text == "0":
|
||||
print("Verification failed")
|
||||
return None
|
||||
elif len(verifyrequest.text) == 64:
|
||||
print("Verification success")
|
||||
return verifyrequest.text
|
||||
else:
|
||||
print("Unexpected response")
|
||||
return None
|
||||
except:
|
||||
print("Can't reach the server.")
|
||||
return None
|
||||
except:
|
||||
print("Key not exist")
|
||||
return None
|
||||
|
||||
def get_music():
|
||||
dumpsys_output = subprocess.check_output("dumpsys media_session", shell=True).decode("utf-8").split("\n")
|
||||
if not [line for line in dumpsys_output if "PLAYING" in line]:
|
||||
return None
|
||||
else:
|
||||
description = [line for line in dumpsys_output if "description=" in line]
|
||||
try:
|
||||
return description[0].split("description=")[1]
|
||||
except:
|
||||
return None
|
||||
|
||||
def get_db_values(url: str = "https://halhadus.rocks/assets/localwrapped/music.db"):
|
||||
if not os.path.exists(get_working_directory() + "/music.db"):
|
||||
try:
|
||||
download = requests.get(url)
|
||||
with open(get_working_directory() + "/music.db", "wb") as f:
|
||||
f.write(download.content)
|
||||
except:
|
||||
print("Could not download the database.")
|
||||
exit()
|
||||
musicconn = sqlite3.connect(get_working_directory() + "/music.db")
|
||||
musicc = musicconn.cursor()
|
||||
musicc.execute("SELECT * FROM music")
|
||||
musicrows = musicc.fetchall()
|
||||
musicconn.close()
|
||||
musicvalues = []
|
||||
for row in musicrows:
|
||||
musicvalues.append({
|
||||
"listmusicname": row[0],
|
||||
"fileartistname": row[4],
|
||||
"filealbumname": row[5],
|
||||
"filemusictitle": row[6]
|
||||
})
|
||||
return musicvalues
|
||||
|
||||
if not os.path.exists(get_working_directory() + "/count.db"):
|
||||
countconn = sqlite3.connect(get_working_directory() + "/count.db")
|
||||
countc = countconn.cursor()
|
||||
countc.execute("CREATE TABLE count (musicname TEXT, count INTEGER)")
|
||||
countconn.commit()
|
||||
countconn.close()
|
||||
|
||||
a = 0
|
||||
last_written = None
|
||||
last_sent = None
|
||||
resetstatus = "true"
|
||||
while True:
|
||||
if get_music() == None:
|
||||
continue
|
||||
last_music = get_music()
|
||||
time.sleep(5)
|
||||
if last_music == get_music():
|
||||
if last_written == last_music:
|
||||
continue
|
||||
a += 1
|
||||
if a >= 3:
|
||||
for i in get_db_values():
|
||||
if i["filealbumname"] == None:
|
||||
full_name = i["filemusictitle"] + ", " + i["fileartistname"] + ", " + "Music"
|
||||
else:
|
||||
full_name = i["filemusictitle"] + ", " + i["fileartistname"] + ", " + i["filealbumname"]
|
||||
if full_name == last_music:
|
||||
if a == 12:
|
||||
countconn = sqlite3.connect(get_working_directory() + "/count.db")
|
||||
countc = countconn.cursor()
|
||||
countc.execute("SELECT * FROM count")
|
||||
countdbrows = countc.fetchall()
|
||||
countdbvalues = []
|
||||
for row in countdbrows:
|
||||
countdbvalues.append({
|
||||
"musicname": row[0],
|
||||
"count": row[1]
|
||||
})
|
||||
if not [row for row in countdbvalues if row["musicname"] == i["listmusicname"]]:
|
||||
countc.execute("INSERT INTO count VALUES (?, ?)", (i["listmusicname"], 1))
|
||||
countconn.commit()
|
||||
countconn.close()
|
||||
else:
|
||||
countc.execute("UPDATE count SET count = count + 1 WHERE musicname = ?", (i["listmusicname"],))
|
||||
countconn.commit()
|
||||
countconn.close()
|
||||
print(f"Local Wrapped: {i['listmusicname']} has been played.")
|
||||
os.system(f"echo {i['listmusicname']} has been played. >> /cache/magisk.log")
|
||||
last_written = last_music
|
||||
a = 0
|
||||
else:
|
||||
if last_sent == i["listmusicname"]:
|
||||
continue
|
||||
try:
|
||||
verificationcode = get_verification_code()
|
||||
if verificationcode == None:
|
||||
continue
|
||||
requests.post(os.environ["MSSERVER"] + "/musicstatus.html", json={"music": i["listmusicname"], "time": str(int(time.time())), "verificationcode": verificationcode, "resetstatus": resetstatus})
|
||||
print("Data sent")
|
||||
resetstatus = "false"
|
||||
a += 1
|
||||
last_sent = i["listmusicname"]
|
||||
except:
|
||||
print("Can't reach the server.")
|
||||
a += 1
|
||||
continue
|
||||
else:
|
||||
a = 0
|
||||
continue
|
||||
|
33
magiskmodule/META-INF/com/google/android/update-binary
Normal file
33
magiskmodule/META-INF/com/google/android/update-binary
Normal file
|
@ -0,0 +1,33 @@
|
|||
#!/sbin/sh
|
||||
|
||||
#################
|
||||
# Initialization
|
||||
#################
|
||||
|
||||
umask 022
|
||||
|
||||
# echo before loading util_functions
|
||||
ui_print() { echo "$1"; }
|
||||
|
||||
require_new_magisk() {
|
||||
ui_print "*******************************"
|
||||
ui_print " Please install Magisk v20.4+! "
|
||||
ui_print "*******************************"
|
||||
exit 1
|
||||
}
|
||||
|
||||
#########################
|
||||
# Load util_functions.sh
|
||||
#########################
|
||||
|
||||
OUTFD=$2
|
||||
ZIPFILE=$3
|
||||
|
||||
mount /data 2>/dev/null
|
||||
|
||||
[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
|
||||
. /data/adb/magisk/util_functions.sh
|
||||
[ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk
|
||||
|
||||
install_module
|
||||
exit 0
|
1
magiskmodule/META-INF/com/google/android/updater-script
Normal file
1
magiskmodule/META-INF/com/google/android/updater-script
Normal file
|
@ -0,0 +1 @@
|
|||
#MAGISK
|
20
magiskmodule/Makefile
Normal file
20
magiskmodule/Makefile
Normal file
|
@ -0,0 +1,20 @@
|
|||
getprop = $(shell cat module.prop | grep "^$(1)=" | head -n1 | cut -d'=' -f2)
|
||||
|
||||
MODNAME ?= $(call getprop,id)
|
||||
MODVER ?= $(call getprop,version)
|
||||
ZIP = $(MODNAME)-$(MODVER).zip
|
||||
|
||||
all: $(ZIP)
|
||||
|
||||
zip: $(ZIP)
|
||||
|
||||
%.zip: clean
|
||||
zip -r9 $(ZIP) . -x $(MODNAME)-*.zip LICENSE .gitignore .gitattributes Makefile /.git*
|
||||
|
||||
clean:
|
||||
rm -f *.zip
|
||||
|
||||
update:
|
||||
curl https://raw.githubusercontent.com/topjohnwu/Magisk/master/scripts/module_installer.sh > META-INF/com/google/android/update-binary
|
||||
|
||||
.PHONY: all zip %.zip install clean update
|
15
magiskmodule/customization.sh
Executable file
15
magiskmodule/customization.sh
Executable file
|
@ -0,0 +1,15 @@
|
|||
SKIPMOUNT=false
|
||||
LATESTARTSERVICE=true
|
||||
|
||||
print_modname() {
|
||||
ui_print "Local Wrapped and Music Status Combo Magisk Module"
|
||||
}
|
||||
|
||||
MOD_EXTRACT() {
|
||||
unzip -o "$ZIPFILE" -d $MODPATH >&2
|
||||
}
|
||||
|
||||
set_permissions() {
|
||||
set_perm_recursive $MODPATH 0 0 0755 0755
|
||||
set_perm $MODPATH/system/bin/musiccombo 0 0 0755
|
||||
}
|
6
magiskmodule/module.prop
Normal file
6
magiskmodule/module.prop
Normal file
|
@ -0,0 +1,6 @@
|
|||
id=musiccombo
|
||||
name=Local Wrapped and Music Status Combo Magisk Module
|
||||
version=1.0
|
||||
versionCode=100
|
||||
author=Halhadus (https://halhadus.rocks)
|
||||
description=Magisk Module for Local Wrapped and Music Status
|
21
magiskmodule/service.sh
Normal file
21
magiskmodule/service.sh
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Schedule task
|
||||
|
||||
nohup /bin/sh > /dev/null 2>&1 <<EOF &
|
||||
|
||||
wait_boot_complete()
|
||||
{
|
||||
until [ "x\$(getprop sys.boot_completed)" == "x1" ]
|
||||
do
|
||||
sleep 5
|
||||
done
|
||||
}
|
||||
|
||||
wait_boot_complete
|
||||
|
||||
while true
|
||||
do
|
||||
env MSSERVER="url" /system/bin/musiccombo >> /data/local/tmp/musiccombo.log 2>&1
|
||||
sleep 5
|
||||
done
|
||||
|
||||
EOF
|
BIN
magiskmodule/system/bin/combomodule
Normal file
BIN
magiskmodule/system/bin/combomodule
Normal file
Binary file not shown.
119
musicstatus.py
Normal file
119
musicstatus.py
Normal file
|
@ -0,0 +1,119 @@
|
|||
import subprocess
|
||||
import re
|
||||
import time
|
||||
import sqlite3
|
||||
import os
|
||||
import requests
|
||||
|
||||
def get_working_directory():
|
||||
# If you see this function, that means you are using the pyinstaller. Use this command to create the executable:
|
||||
# pyinstaller -s -F musicstatus-pyi.py --runtime-tmpdir /data/local/tmp
|
||||
if os.path.exists("/sdcard/localwrapped"):
|
||||
return "/sdcard/localwrapped"
|
||||
elif os.path.exists("/storage/emulated/0/localwrapped"):
|
||||
return "/storage/emulated/0/localwrapped"
|
||||
elif os.path.exists("/data/media/0/localwrapped"):
|
||||
return "/data/media/0/localwrapped"
|
||||
elif os.path.exists("/mnt/user/0/emulated/0/localwrapped"):
|
||||
return "/mnt/user/0/emulated/0/localwrapped"
|
||||
else:
|
||||
print("Local Wrapped directory not found.")
|
||||
|
||||
if not os.path.exists(f"{get_working_directory()}/key.txt"):
|
||||
print("Key not exist")
|
||||
exit()
|
||||
|
||||
if not os.path.exists(f"{get_working_directory()}/music.db"):
|
||||
try:
|
||||
getmusicdb = requests.get("https://halhadus.rocks/assets/localwrapped/music.db")
|
||||
with open(f"{get_working_directory()}/music.db", "wb") as f:
|
||||
f.write(getmusicdb.content)
|
||||
except:
|
||||
print("music.db not exist and download failed.")
|
||||
|
||||
def get_verification_code():
|
||||
try:
|
||||
with open(f'{get_working_directory()/key.txt}')
|
||||
key = f.read()
|
||||
try:
|
||||
verifyrequest = requests.post(os.environ["MSSERVER"] + "/verifykey", json={"key": key})
|
||||
if verifyrequest.text == "0":
|
||||
print("Verification failed")
|
||||
return None
|
||||
elif len(verifyrequest.text) == 64:
|
||||
print("Verification success")
|
||||
return verifyrequest.text
|
||||
else:
|
||||
print("Unexpected response")
|
||||
return None
|
||||
except:
|
||||
print("Can't reach the server.")
|
||||
time.sleep(15)
|
||||
get_verification_code()
|
||||
except:
|
||||
print("Key not exist")
|
||||
return None
|
||||
|
||||
def get_music():
|
||||
dumpsys_output = subprocess.check_output("dumpsys media_session", shell=True).decode("utf-8").split("\n")
|
||||
if not [line for line in dumpsys_output if "PLAYING" in line]:
|
||||
return None
|
||||
else:
|
||||
description = [line for line in dumpsys_output if "description=" in line]
|
||||
try:
|
||||
return description[0].split("description=")[1]
|
||||
except:
|
||||
return None
|
||||
|
||||
def get_db_values():
|
||||
musicconn = sqlite3.connect(f"{get_working_directory()}/music.db")
|
||||
musicc = musicconn.cursor()
|
||||
musicc.execute("SELECT * FROM music")
|
||||
musicrows = musicc.fetchall()
|
||||
musicconn.close()
|
||||
musicvalues = []
|
||||
for row in musicrows:
|
||||
musicvalues.append({
|
||||
"listmusicname": row[0],
|
||||
"fileartistname": row[4],
|
||||
"filealbumname": row[5],
|
||||
"filemusictitle": row[6]
|
||||
})
|
||||
return musicvalues
|
||||
|
||||
a = 0
|
||||
last_written = None
|
||||
resetstatus = "true"
|
||||
while True:
|
||||
if get_music() == None:
|
||||
continue
|
||||
last_music = get_music()
|
||||
time.sleep(5)
|
||||
if last_music == get_music():
|
||||
if last_written == last_music:
|
||||
continue
|
||||
a += 1
|
||||
if a == 1:
|
||||
for i in get_db_values():
|
||||
if i["filealbumname"] == None:
|
||||
full_name = i["filemusictitle"] + ", " + i["fileartistname"] + ", " + "Music"
|
||||
else:
|
||||
full_name = i["filemusictitle"] + ", " + i["fileartistname"] + ", " + i["filealbumname"]
|
||||
if full_name == last_music:
|
||||
try:
|
||||
verificationcode = get_verification_code()
|
||||
if verificationcode == None:
|
||||
continue
|
||||
requests.post(os.environ["MSSERVER"] + "/musicstatus.html", json={"music": i["listmusicname"], "time": str(int(time.time())), "verificationcode": verificationcode, "resetstatus": resetstatus})
|
||||
print("Sent")
|
||||
resetstatus = "false"
|
||||
except:
|
||||
print("Can't reach the server.")
|
||||
time.sleep(15)
|
||||
last_written = last_music
|
||||
a = 0
|
||||
continue
|
||||
else:
|
||||
a = 0
|
||||
continue
|
||||
|
73
websitepart.py
Normal file
73
websitepart.py
Normal file
|
@ -0,0 +1,73 @@
|
|||
import flask
|
||||
import datetime
|
||||
import random
|
||||
import string
|
||||
import os
|
||||
|
||||
app = flask.Flask(__name__)
|
||||
|
||||
code = ""
|
||||
history = []
|
||||
|
||||
@app.route('/musicstatus.html', methods=['GET', 'POST'])
|
||||
def musicstatus():
|
||||
global code, history
|
||||
if flask.request.method == 'POST':
|
||||
data = flask.request.get_json()
|
||||
if code == "":
|
||||
return "Verification code not generated"
|
||||
if data['verificationcode'] != code:
|
||||
return "Verification failed"
|
||||
else:
|
||||
musicname = data['music']
|
||||
time = data['time']
|
||||
resetstatus = data['resetstatus']
|
||||
history.append((musicname, time, resetstatus))
|
||||
return f"{musicname} added to history"
|
||||
elif flask.request.method == 'GET':
|
||||
html = '<DOCTYPE html>\n<html>\n'
|
||||
html += '<head>\n<meta charset="UTF-8">\n<link href="https://fonts.googleapis.com/css2?family=Jetbrains+Mono:wght@400;700&display=swap" rel="stylesheet">\n</head>\n'
|
||||
html += '<body style="background-color: #1f1f1f; color: #ffffff; font-family: \'Jetbrains Mono\', monospace;">\n<meta name="viewport" content="width=device-width, initial-scale=1.0">\n'
|
||||
html += '<title>Halhadus\' Music Status</title>\n<link rel="icon" type="image/png" href="assets/favicon.png">\n'
|
||||
html += '<meta name="description" content="Halhadus\' Music Status">\n<meta property="og:title" content="Halhadus\' Music Status">\n'
|
||||
html += '<meta property="og:description" content="Halhadus\' Music Status">\n<meta property="og:image" content="assets/favicon.png">\n'
|
||||
html += '<meta property="og:url" content="https://halhadus.rocks/musicstatus.html">\n'
|
||||
html += '<h1>Halhadus\' Music Status</h1>\n'
|
||||
html += '<a href="https://git.halhadus.rocks/Halhadus/localwrappedmusicstatus-combo-allinonerepo" style="color: #ffffff;">Source Code</a>\n'
|
||||
html += '<h3>Hi guys. I am too lazy to add links to song names. To find which song is it, check <a href="musiclist.html" style="color: #ffffff;">this link</a>.</h3>\n'
|
||||
html += '<form action="index.html">\n<input type="submit" value="Back to main page" style="background-color: #1f1f1f; color: #ffffff; border: 2px solid #ffffff; border-radius: 5px; padding: 10px 20px; margin: 10px 0px;">\n</form>\n'
|
||||
if len(history) > 0:
|
||||
if history[-1][2] == "true":
|
||||
currentbeforereset = history[-1]
|
||||
history = []
|
||||
history.append(currentbeforereset)
|
||||
html += f'<h2>Currently Playing: {history[-1][0]}</h2>\n'
|
||||
html += f'<h2>Last Update Time: {datetime.datetime.fromtimestamp(int(history[-1][1]), datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S")} (UTC +0)</h2>\n'
|
||||
html += '<table style="width: 100%; border-collapse: collapse;">\n<tr>\n<th style="border: 1px solid #ffffff; padding: 10px;">Music Name</th>\n<th style="border: 1px solid #ffffff; padding: 10px;">Time</th>\n</tr>\n'
|
||||
for music in history[::-1]:
|
||||
html += '<tr>\n<td style="border: 1px solid #ffffff; padding: 10px;">' + music[0] + '</td>\n<td style="border: 1px solid #ffffff; padding: 10px;">' + datetime.datetime.fromtimestamp(int(music[1]), datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S") + '</td>\n</tr>\n'
|
||||
html += '</table>\n</body>\n</html>'
|
||||
return html
|
||||
|
||||
@app.route('/verifykey', methods=['GET', 'POST'])
|
||||
def verifycert():
|
||||
global code
|
||||
if flask.request.method == 'POST':
|
||||
data = flask.request.get_json()
|
||||
key = data['key']
|
||||
with open("key.txt", "r") as f:
|
||||
if key == f.read():
|
||||
code = ''.join(random.choices(string.ascii_uppercase + string.digits, k=64))
|
||||
return code
|
||||
else:
|
||||
return "0"
|
||||
elif flask.request.method == 'GET':
|
||||
return "GET method not allowed"
|
||||
|
||||
@app.route('/<path:path>')
|
||||
def catch_all(path):
|
||||
if not path == 'musicstatus.html' or not path == 'verifykey':
|
||||
return flask.redirect(f'https://halhadus.rocks/{path}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=int(os.environ.get('PORT')))
|
Loading…
Reference in a new issue