Revert "Merge pull request #35 from nyrrion/main"

This reverts commit e8921dd0a6, reversing
changes made to 09a1222d0f.
This commit is contained in:
vyvir
2024-09-26 15:26:00 +03:00
parent e8921dd0a6
commit f9efafc3e3
+340 -322
View File
@@ -39,8 +39,14 @@ computer_cpu_platform = platform.machine()
def resource_path(relative_path): def resource_path(relative_path):
global installedcheck global installedcheck
installedcheck = subprocess.run("test -e /usr/lib/althea/althea", shell=True).returncode == 0 CheckRun10 = subprocess.run(
base_path = "/usr/lib/althea" if installedcheck else os.path.abspath(".") f"find /usr/lib/althea/althea > /dev/null 2>&1", shell=True
)
if CheckRun10.returncode == 0:
installedcheck = True
base_path = "/usr/lib/althea"
else:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path) return os.path.join(base_path, relative_path)
@@ -82,29 +88,44 @@ def connectioncheck():
def menu(): def menu():
menu = Gtk.Menu() menu = Gtk.Menu()
if notify(): if (notify()) == True:
command_upd = Gtk.MenuItem(label="Download Update") command_upd = Gtk.MenuItem(label="Download Update")
command_upd.connect("activate", showurl) command_upd.connect("activate", showurl)
menu.append(command_upd) menu.append(command_upd)
menu.append(Gtk.SeparatorMenuItem()) menu.append(Gtk.SeparatorMenuItem())
commands = [ command_one = Gtk.MenuItem(label="About althea")
("About althea", on_abtdlg), command_one.connect("activate", on_abtdlg)
("Install AltStore", altstoreinstall), menu.append(command_one)
("Install an IPA file", altserverfile),
("Pair", lambda x: openwindow(PairWindow)),
("Restart AltServer", restartaltserver)
]
for label, callback in commands: menu.append(Gtk.SeparatorMenuItem())
command = Gtk.MenuItem(label=label)
command.connect("activate", callback)
menu.append(command)
menu.append(Gtk.SeparatorMenuItem())
if subprocess.run("test -e /usr/lib/althea/althea", shell=True).returncode == 0: command_two = Gtk.MenuItem(label="Install AltStore")
command_two.connect("activate", altstoreinstall)
menu.append(command_two)
command_three = Gtk.MenuItem(label="Install an IPA file")
command_three.connect("activate", altserverfile)
menu.append(command_three)
command_four = Gtk.MenuItem(label="Pair")
command_four.connect("activate", lambda x: openwindow(PairWindow))
menu.append(command_four)
command_five = Gtk.MenuItem(label="Restart AltServer")
command_five.connect("activate", restartaltserver)
menu.append(command_five)
menu.append(Gtk.SeparatorMenuItem())
CheckRun11 = subprocess.run(f"test -e /usr/lib/althea/althea", shell=True)
if CheckRun11.returncode == 0:
global command_six global command_six
if subprocess.run("test -e $HOME/.config/autostart/althea.desktop", shell=True).returncode == 0: CheckRun12 = subprocess.run(
f"test -e $HOME/.config/autostart/althea.desktop", shell=True
)
if CheckRun12.returncode == 0:
command_six.set_active(command_six) command_six.set_active(command_six)
command_six.connect("activate", launchatlogin1) command_six.connect("activate", launchatlogin1)
menu.append(command_six) menu.append(command_six)
@@ -209,27 +230,25 @@ def openwindow(window):
w = window() w = window()
w.show_all() w.show_all()
def kill_processes():
for process in [AltServer, AnisetteServer]:
subprocess.run(["killall", process], check=False)
def quitit(): def quitit():
kill_processes() subprocess.run(f"killall {AltServer}", shell=True)
subprocess.run(f"killall {AnisetteServer}", shell=True)
Gtk.main_quit() Gtk.main_quit()
os.kill(os.getpid(), signal.SIGKILL) os.kill(os.getpid(), signal.SIGKILL)
def restartaltserver(_): def restartaltserver(_):
kill_processes() subprocess.run(f"killall {AltServer}", shell=True)
subprocess.run("idevicepair pair", shell=True, check=False) subprocess.run(f"killall {AnisetteServer}", shell=True)
subprocess.Popen( subprocess.run("idevicepair pair", shell=True)
f"{altheapath}/AltServer", subprocess.run(
env=dict(os.environ, ALTSERVER_ANISETTE_SERVER='http://127.0.0.1:6969'), f"""export ALTSERVER_ANISETTE_SERVER='http://127.0.0.1:6969' ; {(altheapath)}/AltServer &""",
shell=True shell=True,
) )
def winerm(): def winerm():
silent_remove(f"{altheapath}/log.txt") silent_remove(f"{(altheapath)}/log.txt")
dialog = Gtk.MessageDialog( dialog = Gtk.MessageDialog(
# transient_for=self,
flags=0, flags=0,
message_type=Gtk.MessageType.QUESTION, message_type=Gtk.MessageType.QUESTION,
buttons=Gtk.ButtonsType.YES_NO, buttons=Gtk.ButtonsType.YES_NO,
@@ -237,71 +256,86 @@ def winerm():
) )
dialog.format_secondary_text("Your login and password have been saved earlier.") dialog.format_secondary_text("Your login and password have been saved earlier.")
response = dialog.run() response = dialog.run()
if response == Gtk.ResponseType.YES: if response == Gtk.ResponseType.YES:
try: global apple_id
with open(f"{altheapath}/saved.txt", "r") as f: global password
for line in f: f = open(f"{(altheapath)}/saved.txt", "r")
if 'ł' in line: for line in f:
global apple_id, password, savedcheck apple_id, password = line.split("ł") # unacceptable char both in e-mail and apple id
apple_id, password = line.split("ł") f.close()
savedcheck = True print(apple_id, password)
Login().on_click_me_clicked1() global savedcheck
break savedcheck = True
except (ValueError, FileNotFoundError) as e: Login().on_click_me_clicked1()
print(f"Error: {e}")
else: else:
silent_remove(f"{altheapath}/saved.txt") silent_remove(f"{(altheapath)}/saved.txt")
Login().show_all() win3 = Login()
win3.show_all()
dialog.destroy() dialog.destroy()
def win1(): def win1():
winerm() if os.path.isfile(f"{altheapath}/saved.txt") else openwindow(Login) if os.path.isfile(f"{(altheapath)}/saved.txt"):
winerm()
else:
openwindow(Login)
def win2(_): def win2(_):
win1() if os.path.isfile(f"{(altheapath)}/saved.txt"):
winerm()
else:
openwindow(Login)
def actionCallback(notification, action, user_data=None): def actionCallback(notification, action, user_data=None):
Gtk.show_uri_on_window(None, "https://github.com/vyvir/althea/releases", Gdk.CURRENT_TIME) Gtk.show_uri_on_window(
None, "https://github.com/vyvir/althea/releases", Gdk.CURRENT_TIME
)
quitit() quitit()
def launchatlogin1(_): def launchatlogin1(_):
global command_six
if command_six.get_active(): if command_six.get_active():
global AutoStart
os.popen(AutoStart).read() os.popen(AutoStart).read()
return True return True
silent_remove("$HOME/.config/autostart/althea.desktop") else:
return False silent_remove("$HOME/.config/autostart/althea.desktop")
return False
def silent_remove(filename): def silent_remove(filename):
try: try:
os.remove(filename) os.remove(filename)
except OSError as e: except OSError as e:
if e.errno != errno.ENOENT: if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
raise raise # re-raise exception if a different error occurred
def altstore_download(value): def altstore_download(value):
# setting the base URL value
baseUrl = "https://cdn.altstore.io/file/altstore/apps.json" baseUrl = "https://cdn.altstore.io/file/altstore/apps.json"
response = requests.get(baseUrl)
if response.status_code == 200: # retrieving data from JSON Data
data = response.json() json_data = requests.get(baseUrl)
if json_data.status_code == 200:
data = json_data.json()
for app in data['apps']: for app in data['apps']:
if app['name'] == "AltStore": if app['name'] == "AltStore":
if value == "Check": if value == "Check":
size = app['versions'][0]['size'] size = app['versions'][0]['size']
return size == os.path.getsize(f'{altheapath}/AltStore.ipa') return size == os.path.getsize(f'{(altheapath)}/AltStore.ipa')
elif value == "Download": break
if value == "Download":
latest = app['versions'][0]['downloadURL'] latest = app['versions'][0]['downloadURL']
r = requests.get(latest, allow_redirects=True) r = requests.get(
latest,
allow_redirects=True,
)
latest_filename = latest.split('/')[-1] latest_filename = latest.split('/')[-1]
with open(f"{altheapath}/{latest_filename}", "wb") as f: open(f"{(altheapath)}/{(latest_filename)}", "wb").write(r.content)
f.write(r.content) os.rename(f"{(altheapath)}/{(latest_filename)}", f"{(altheapath)}/AltStore.ipa")
os.rename(f"{altheapath}/{latest_filename}", f"{altheapath}/AltStore.ipa") subprocess.run(f"chmod 755 {(altheapath)}/AltStore.ipa", shell=True)
subprocess.run(["chmod", "755", f"{altheapath}/AltStore.ipa"]) break
return True return True
return False else:
return False
def ios_version(): def ios_version():
silent_remove(f"{(altheapath)}/ideviceinfo.txt") silent_remove(f"{(altheapath)}/ideviceinfo.txt")
@@ -324,221 +358,227 @@ def ios_version():
class SplashScreen(Handy.Window): class SplashScreen(Handy.Window):
def __init__(self): def __init__(self):
super().__init__(title="Loading") super().__init__(title="Loading")
self.setup_window()
self.create_ui()
self.start_startup_process()
def setup_window(self):
self.set_resizable(False) self.set_resizable(False)
self.set_default_size(512, 288) self.set_default_size(512, 288)
self.present() self.present()
self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
self.set_keep_above(True) self.set_keep_above(True)
def create_ui(self): self.mainBox = Gtk.Box(
self.mainBox = Gtk.Box(spacing=6, orientation=Gtk.Orientation.VERTICAL) spacing=6,
orientation=Gtk.Orientation.VERTICAL,
halign=Gtk.Align.START,
valign=Gtk.Align.START,
)
self.add(self.mainBox) self.add(self.mainBox)
image = self.create_image() pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename=os.path.join("resources/4.png"),
width=512,
height=288,
preserve_aspect_ratio=False,
)
image = Gtk.Image.new_from_pixbuf(pixbuf)
image.show()
self.mainBox.pack_start(image, False, True, 0) self.mainBox.pack_start(image, False, True, 0)
self.lbl1 = Gtk.Label(label="Starting althea...") self.lbl1 = Gtk.Label(label="Starting althea...")
self.mainBox.pack_start(self.lbl1, False, False, 6) self.mainBox.pack_start(self.lbl1, False, False, 6)
self.loadalthea = Gtk.ProgressBar() self.loadalthea = Gtk.ProgressBar()
self.mainBox.pack_start(self.loadalthea, True, True, 0) self.mainBox.pack_start(self.loadalthea, True, True, 0)
def create_image(self):
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename=os.path.join("resources/4.png"),
width=512, height=288, preserve_aspect_ratio=False
)
image = Gtk.Image.new_from_pixbuf(pixbuf)
image.show()
return image
def start_startup_process(self):
self.t = threading.Thread(target=self.startup_process) self.t = threading.Thread(target=self.startup_process)
self.t.start() self.t.start()
GLib.timeout_add(200, self.check_thread) self.wait_for_t(self.t)
def check_thread(self): def wait_for_t(self, t):
if not self.t.is_alive(): if not self.t.is_alive():
global indicator global indicator
indicator.set_status(appindicator.IndicatorStatus.ACTIVE) indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
self.t.join() self.t.join()
self.destroy() self.destroy()
return False else:
return True GLib.timeout_add(200, self.wait_for_t, self.t)
def startup_process(self): def startup_process(self):
steps = [ self.lbl1.set_text("Checking if anisette-server is already running...")
(self.check_anisette_server, "Checking if anisette-server is already running...", 0.1), self.loadalthea.set_fraction(0.1)
(self.setup_anisette_server, "Setting up anisette-server if not installed...", 0.3), command = 'curl 127.0.0.1:6969 | grep -q "{"'
(self.download_apple_music_apk, "Downloading Apple Music APK if necessary...", 0.4), CheckRun = subprocess.run(command, shell=True)
(self.extract_libraries, "Extracting necessary libraries if needed...", 0.5), if not os.path.isfile(f"{(altheapath)}/anisette-server"):
(self.start_anisette_server, "Starting anisette-server...", 0.6), self.lbl1.set_text("Downloading anisette-server...")
(self.setup_altserver, "Setting up AltServer if not installed...", 0.8), if computer_cpu_platform == 'x86_64':
(self.start_altserver, "Starting AltServer...", 1.0) r = requests.get(
] "https://github.com/vyvir/althea/releases/download/v0.5.0/anisette-server-x86_64",
allow_redirects=True,
)
elif computer_cpu_platform == "aarch64":
#Thanks, Dadoum for the anisette server!
#or vyvir, do not forget to upload ur version of server.
r = requests.get(
"https://github.com/vyvir/althea/releases/download/v0.5.0/anisette-server-aarch64",
allow_redirects=True
)
#sorry i dont know what will arm32 output
elif computer_cpu_platform.find('v7') != -1 or computer_cpu_platform.find('ARM') != -1 or computer_cpu_platform.find('hf') != -1:
r = requests.get(
"https://github.com/vyvir/althea/releases/download/v0.5.0/anisette-server-armv7",
allow_redirects=True
)
else:
print('WARNING: YOUR CPU IS NOT SUPPORTED, THE PROGRAM MAY NOT WORK!')
#ooops, just download x86-64 ver
r = requests.get(
"https://github.com/vyvir/althea/releases/download/v0.5.0/anisette-server-x86_64",
allow_redirects=True,
)
open(f"{(altheapath)}/anisette-server", "wb").write(r.content)
subprocess.run(f"chmod +x {(altheapath)}/anisette-server", shell=True)
subprocess.run(f"chmod 755 {(altheapath)}/anisette-server", shell=True)
self.loadalthea.set_fraction(0.2)
self.lbl1.set_text("Downloading Apple Music APK...")
r = requests.get(
"https://apps.mzstatic.com/content/android-apple-music-apk/applemusic.apk",
allow_redirects=True,
)
open(f"{(altheapath)}/am.apk", "wb").write(r.content)
os.makedirs(f"{(altheapath)}/lib/x86_64")
self.loadalthea.set_fraction(0.3)
self.lbl1.set_text("Extracting necessary libraries...")
CheckRunB = subprocess.run(
f'unzip -j "{(altheapath)}/am.apk" "lib/x86_64/libstoreservicescore.so" -d "{(altheapath)}/lib/x86_64"',
shell=True,
)
CheckRunC = subprocess.run(
f'unzip -j "{(altheapath)}/am.apk" "lib/x86_64/libCoreADI.so" -d "{(altheapath)}/lib/x86_64"',
shell=True,
)
silent_remove(f"{(altheapath)}/am.apk")
self.loadalthea.set_fraction(0.4)
self.lbl1.set_text("Starting anisette-server...")
subprocess.run(f"cd {(altheapath)} && ./anisette-server &", shell=True)#-n 127.0.0.1 -p 6969 &", shell=True
self.loadalthea.set_fraction(0.5)
finished = False
while not finished:
CheckRun5 = subprocess.run(command, shell=True)
if CheckRun5.returncode == 0:
finished = True
else:
sleep(1)
if not os.path.isfile(f"{(altheapath)}/AltServer"):
self.lbl1.set_text("Downloading AltServer...")
self.loadalthea.set_fraction(0.6)
for step, message, progress in steps: """
GLib.idle_add(self.lbl1.set_text, message) r = requests.get(
GLib.idle_add(self.loadalthea.set_fraction, progress) "https://github.com/NyaMisty/AltServer-Linux/releases/download/v0.0.5/AltServer-x86_64",
step() allow_redirects=True,
)
def check_anisette_server(self): """
command = 'curl -s 127.0.0.1:6969 | grep -q "{"' if computer_cpu_platform == 'AMD64':
result = subprocess.run(command, shell=True) r = requests.get(
return result.returncode == 0 "https://github.com/NyaMisty/AltServer-Linux/releases/download/v0.0.5/AltServer-x86_64",
allow_redirects=True,
def setup_anisette_server(self): )
anisette_path = f"{altheapath}/anisette-server" elif computer_cpu_platform == 'aarch64':
if os.path.isfile(anisette_path): r = requests.get(
print("Anisette server already installed.") "https://github.com/NyaMisty/AltServer-Linux/releases/download/v0.0.5/AltServer-aarch64",
return allow_redirects=True
print("Installing Anisette server...") )
urls = { elif computer_cpu_platform.find('v7') != -1 or computer_cpu_platform.find('ARM') != -1 or computer_cpu_platform.find('hf') != -1:
'x86_64': "https://github.com/vyvir/althea/releases/download/v0.5.0/anisette-server-x86_64", r = requests.get(
'aarch64': "https://github.com/vyvir/althea/releases/download/v0.5.0/anisette-server-aarch64", "https://github.com/NyaMisty/AltServer-Linux/releases/download/v0.0.5/AltServer-armv7",
'armv7': "https://github.com/vyvir/althea/releases/download/v0.5.0/anisette-server-armv7", allow_redirects=True
} )
cpu_url = urls.get(computer_cpu_platform, urls['x86_64']) else:
self.download_file(cpu_url, anisette_path) print('WARNING: YOUR CPU IS NOT SUPPORTED, AltServer MAY NOT WORK!')
self.run_command(f"chmod +x {anisette_path}") #ooops, just download x86-64 ver
self.run_command(f"chmod 755 {anisette_path}") r = requests.get(
"https://github.com/NyaMisty/AltServer-Linux/releases/download/v0.0.5/AltServer-x86_64",
def download_apple_music_apk(self): allow_redirects=True,
apk_path = f"{altheapath}/am.apk" )
if os.path.isfile(apk_path): open(f"{(altheapath)}/AltServer", "wb").write(r.content)
print("Apple Music APK already downloaded.") subprocess.run(f"chmod +x {(altheapath)}/AltServer", shell=True)
return subprocess.run(f"chmod 755 {(altheapath)}/AltServer", shell=True)
print("Downloading Apple Music APK...") self.loadalthea.set_fraction(0.8)
url = "https://apps.mzstatic.com/content/android-apple-music-apk/applemusic.apk" if not os.path.isfile(f"{(altheapath)}/AltStore.ipa"):
self.download_file(url, apk_path) self.lbl1.set_text("Downloading AltStore...")
altstore_download("Download")
def extract_libraries(self):
lib_path = f"{altheapath}/lib/x86_64/libstoreservicescore.so"
if os.path.isfile(lib_path):
print("Libraries already extracted.")
return
print("Extracting libraries...")
os.makedirs(f"{altheapath}/lib/x86_64", exist_ok=True)
self.run_command(f'unzip -j "{altheapath}/am.apk" "lib/x86_64/libstoreservicescore.so" -d "{altheapath}/lib/x86_64"')
self.run_command(f'unzip -j "{altheapath}/am.apk" "lib/x86_64/libCoreADI.so" -d "{altheapath}/lib/x86_64"')
os.remove(f"{altheapath}/am.apk")
def start_anisette_server(self):
print("Starting Anisette server...")
self.run_command(f"cd {altheapath} && ./anisette-server &")
for _ in range(30):
if self.check_anisette_server():
break
sleep(1)
else: else:
print("Failed to start anisette-server") self.lbl1.set_text("Checking latest AltStore version...")
if not altstore_download("Check"):
def setup_altserver(self): self.lbl1.set_text("Downloading new version of AltStore...")
altserver_path = f"{altheapath}/AltServer" altstore_download("Download")
if os.path.isfile(altserver_path): self.lbl1.set_text("Starting AltServer...")
print("AltServer already installed.") self.loadalthea.set_fraction(1.0)
return subprocess.run(f"{(altheapath)}/AltServer &", shell=True)
print("Installing AltServer...") return 0
altserver_urls = {
'AMD64': "https://github.com/NyaMisty/AltServer-Linux/releases/download/v0.0.5/AltServer-x86_64",
'aarch64': "https://github.com/NyaMisty/AltServer-Linux/releases/download/v0.0.5/AltServer-aarch64",
'armv7': "https://github.com/NyaMisty/AltServer-Linux/releases/download/v0.0.5/AltServer-armv7",
}
altserver_url = altserver_urls.get(computer_cpu_platform, altserver_urls['AMD64'])
self.download_file(altserver_url, altserver_path)
self.run_command(f"chmod +x {altserver_path}")
self.run_command(f"chmod 755 {altserver_path}")
def start_altserver(self):
print("Starting AltServer...")
self.run_command(f"{altheapath}/AltServer &")
def download_file(self, url, destination):
if os.path.isfile(destination):
print(f"File {destination} already exists.")
return
try:
r = requests.get(url, allow_redirects=True)
r.raise_for_status()
with open(destination, "wb") as f:
f.write(r.content)
except requests.RequestException as e:
print(f"Error downloading file: {e}")
def run_command(self, command):
subprocess.run(command, shell=True)
class Login(Gtk.Window): class Login(Gtk.Window):#
def __init__(self): def __init__(self):
super().__init__(title="Login") super().__init__(title="Login")
self.setup_window()
self.create_ui()
def setup_window(self):
self.present() self.present()
self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
self.set_resizable(False) self.set_resizable(False)
self.set_border_width(10) self.set_border_width(10)
def create_ui(self):
grid = Gtk.Grid() grid = Gtk.Grid()
self.add(grid) self.add(grid)
self.entry1 = self.create_entry("Apple ID: ", grid, 0) label = Gtk.Label(label="Apple ID: ")
self.entry = self.create_password_entry("Password: ", grid, 2) label.set_justify(Gtk.Justification.LEFT)
self.entry1 = Gtk.Entry()
label1 = Gtk.Label(label="Password: ")
label1.set_justify(Gtk.Justification.LEFT)
self.entry = Gtk.Entry()
self.entry.set_visibility(False)
global icon_name
self.entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, icon_name)
self.entry.connect("icon-press", self.on_icon_toggled)
self.button = Gtk.Button.new_with_label("Login") self.button = Gtk.Button.new_with_label("Login")
self.button.connect("clicked", self.on_click_me_clicked) self.button.connect("clicked", self.on_click_me_clicked)
grid.add(label)
grid.attach(self.entry1, 1, 0, 2, 1)
grid.attach_next_to(label1, label, Gtk.PositionType.BOTTOM, 1, 2)
grid.attach(self.entry, 1, 2, 1, 1)
grid.attach_next_to(self.button, self.entry, Gtk.PositionType.RIGHT, 1, 1) grid.attach_next_to(self.button, self.entry, Gtk.PositionType.RIGHT, 1, 1)
def create_entry(self, label_text, grid, row): silent_remove(f"{(altheapath)}/log.txt")
label = Gtk.Label(label=label_text)
label.set_justify(Gtk.Justification.LEFT)
entry = Gtk.Entry()
grid.add(label)
grid.attach(entry, 1, row, 2, 1)
return entry
def create_password_entry(self, label_text, grid, row): def on_click_me_clicked1(self):
entry = self.create_entry(label_text, grid, row) self.realthread1 = threading.Thread(target=self.onclickmethread)
entry.set_visibility(False) self.realthread1.start()
entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "changes-prevent-symbolic") GLib.idle_add(self.install_process)
entry.connect("icon-press", self.on_icon_toggled)
return entry
def on_click_me_clicked(self, button): def on_click_me_clicked(self, button):
self.save_credentials_dialog() silent_remove(f"{(altheapath)}/log.txt")
self.start_login_process() if not os.path.isfile(f"{(altheapath)}/saved.txt"):
self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
def save_credentials_dialog(self):
if not os.path.isfile(f"{altheapath}/saved.txt"):
dialog = Gtk.MessageDialog( dialog = Gtk.MessageDialog(
transient_for=self, transient_for=self,
flags=0, flags=0,
message_type=Gtk.MessageType.QUESTION, message_type=Gtk.MessageType.QUESTION,
buttons=Gtk.ButtonsType.YES_NO, buttons=Gtk.ButtonsType.YES_NO,
text="Do you want to save your login and password?" text="Do you want to save your login and password?",
) )
dialog.format_secondary_text("This will allow you to log in automatically.") dialog.format_secondary_text("This will allow you to login automatically.")
response = dialog.run() response = dialog.run()
if response == Gtk.ResponseType.YES: if response == Gtk.ResponseType.YES:
self.save_credentials() apple_id = self.entry1.get_text().lower()
password = self.entry.get_text()
f = open(f"{(altheapath)}/saved.txt", "x")
f.write(apple_id)
f.write(":")
f.write(password)
f.close()
dialog.destroy() dialog.destroy()
def save_credentials(self):
apple_id = self.entry1.get_text().lower()
password = self.entry.get_text()
with open(f"{altheapath}/saved.txt", "w") as f:
f.write(f"{apple_id}:{password}")
def start_login_process(self):
self.entry.set_progress_pulse_step(0.2) self.entry.set_progress_pulse_step(0.2)
# Call self.do_pulse every 100 ms
self.timeout_id = GLib.timeout_add(100, self.do_pulse, None) self.timeout_id = GLib.timeout_add(100, self.do_pulse, None)
self.entry.set_editable(False) self.entry.set_editable(False)
self.entry1.set_editable(False) self.entry1.set_editable(False)
@@ -547,46 +587,30 @@ class Login(Gtk.Window):
self.realthread1.start() self.realthread1.start()
GLib.idle_add(self.install_process) GLib.idle_add(self.install_process)
def onclickmethread(self): def onclickmethread(self):
global apple_id, password
if not savedcheck:
apple_id = self.entry1.get_text().lower()
password = self.entry.get_text()
else:
with open(f"{altheapath}/saved.txt", "r") as f:
saved_data = f.read().strip()
if ":" in saved_data:
apple_id, password = saved_data.split(":", 1)
else:
print("Invalid saved credentials format.")
return
if ios_version() >= "15.0": if ios_version() >= "15.0":
try: global savedcheck
UDID = subprocess.check_output("idevice_id -l", shell=True).decode().strip() global apple_id
except subprocess.CalledProcessError as e: global password
print(f"Error obtaining UDID: {e}") if not savedcheck:
return apple_id = self.entry1.get_text().lower()
password = self.entry.get_text()
silent_remove(f"{altheapath}/log.txt") UDID = subprocess.check_output("idevice_id -l", shell=True).decode().strip()
global InsAltStore
if os.path.isdir(f'{os.environ["HOME"]}/.adi'): print(PATH)
rmtree(f'{os.environ["HOME"]}/.adi') silent_remove(f"{(altheapath)}/log.txt")
#f = open(f"{(altheapath)}/log.txt", "w")
InsAltStoreCMD = f"""export ALTSERVER_ANISETTE_SERVER='http://127.0.0.1:6969' ; {AltServer} -u {UDID} -a {apple_id} -p {password} {PATH} > {os.environ["HOME"]}/.local/share/althea/log.txt""" #f.close()
try: if os.path.isdir(f'{ os.environ["HOME"] }/.adi'):
global InsAltStore rmtree(f'{ os.environ["HOME"] }/.adi')
InsAltStore = subprocess.Popen( InsAltStoreCMD = f"""export ALTSERVER_ANISETTE_SERVER='http://127.0.0.1:6969' ; {(AltServer)} -u {UDID} -a {apple_id} -p {password} {PATH} > {("$HOME/.local/share/althea/log.txt")}"""
InsAltStoreCMD, InsAltStore = subprocess.Popen(
stdin=subprocess.PIPE, InsAltStoreCMD,
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
shell=True, stdout=subprocess.PIPE,
) shell=True,
except Exception as e: )
print(f"Error starting subprocess: {e}") else: # If the iOS version is lower than 15.0, AltServer-Linux won't run
else:
global Failmsg global Failmsg
Failmsg = "iOS 15.0 or later is required." Failmsg = "iOS 15.0 or later is required."
dialog2 = DialogExample3(self) dialog2 = DialogExample3(self)
@@ -599,39 +623,46 @@ class Login(Gtk.Window):
WarnTime = 0 WarnTime = 0
TwoFactorTime = 0 TwoFactorTime = 0
global InsAltStore global InsAltStore
while Installing: while Installing:
CheckIns = subprocess.run( CheckIns = subprocess.run(
f'grep -F "Could not" {altheapath}/log.txt', shell=True f'grep -F "Could not" {(altheapath)}/log.txt', shell=True
) )
CheckWarn = subprocess.run( CheckWarn = subprocess.run(
f'grep -F "Are you sure you want to continue?" {altheapath}/log.txt', shell=True f'grep -F "Are you sure you want to continue?" {(altheapath)}/log.txt',
shell=True,
) )
CheckSuccess = subprocess.run( CheckSuccess = subprocess.run(
f'grep -F "Notify: Installation Succeeded" {altheapath}/log.txt', shell=True f'grep -F "Notify: Installation Succeeded" {(altheapath)}/log.txt',
shell=True,
) )
Check2fa = subprocess.run( Check2fa = subprocess.run(
f'grep -F "Enter two factor code" {altheapath}/log.txt', shell=True f'grep -F "Enter two factor code" {(altheapath)}/log.txt', shell=True
) )
if CheckIns.returncode == 0: if CheckIns.returncode == 0:
InsAltStore.terminate() InsAltStore.terminate()
Installing = False Installing = False
global Failmsg global Failmsg
Failmsg = subprocess.check_output(f"tail -6 {altheapath}/log.txt", shell=True).decode() Failmsg = subprocess.check_output(
f"tail -6 {(altheapath)}/log.txt", shell=True
).decode()
dialog2 = DialogExample3(self) dialog2 = DialogExample3(self)
dialog2.run() dialog2.run()
dialog2.destroy() dialog2.destroy()
self.destroy() self.destroy()
elif CheckWarn.returncode == 0 and WarnTime == 0: elif CheckWarn.returncode == 0 and WarnTime == 0:
Installing = False Installing = False
word = "Are you sure you want to continue?" word = "Are you sure you want to continue?"
with open(f"{altheapath}/log.txt", "r") as file: # This fixes an issue where the warn window appears when it shouldn't
with open(f"{(altheapath)}/log.txt", "r") as file:
# Read all content of the file
content = file.read() content = file.read()
# Check if a string present in the file
if word in content: if word in content:
global Warnmsg global Warnmsg
Warnmsg = subprocess.check_output(f"tail -8 {os.environ['HOME']}/.local/share/althea/log.txt", shell=True).decode() Warnmsg = subprocess.check_output(
f"tail -8 {('$HOME/.local/share/althea/log.txt')}",
shell=True,
).decode()
dialog1 = DialogExample2(self) dialog1 = DialogExample2(self)
response1 = dialog1.run() response1 = dialog1.run()
if response1 == Gtk.ResponseType.OK: if response1 == Gtk.ResponseType.OK:
@@ -646,14 +677,13 @@ class Login(Gtk.Window):
else: else:
WarnTime = 1 WarnTime = 1
Installing = True Installing = True
elif Check2fa.returncode == 0 and TwoFactorTime == 0: elif Check2fa.returncode == 0 and TwoFactorTime == 0:
Installing = False Installing = False
dialog = DialogExample(self) dialog = DialogExample(self)
response = dialog.run() response = dialog.run()
if response == Gtk.ResponseType.OK: if response == Gtk.ResponseType.OK:
vercode = dialog.entry2.get_text().strip() + "\n" vercode = dialog.entry2.get_text()
print(f"2FA Code: {vercode}") vercode = vercode + "\n"
vercodebytes = bytes(vercode.encode()) vercodebytes = bytes(vercode.encode())
InsAltStore.communicate(input=vercodebytes) InsAltStore.communicate(input=vercodebytes)
TwoFactorTime = 1 TwoFactorTime = 1
@@ -665,7 +695,6 @@ class Login(Gtk.Window):
self.cancel() self.cancel()
dialog.destroy() dialog.destroy()
self.destroy() self.destroy()
elif CheckSuccess.returncode == 0: elif CheckSuccess.returncode == 0:
Installing = False Installing = False
self.success() self.success()
@@ -704,12 +733,10 @@ class Login(Gtk.Window):
global icon_name global icon_name
if icon_name == "changes-prevent-symbolic": if icon_name == "changes-prevent-symbolic":
icon_name = "changes-allow-symbolic" icon_name = "changes-allow-symbolic"
visibility = True self.entry.set_visibility(True)
else: elif icon_name == "changes-allow-symbolic":
icon_name = "changes-prevent-symbolic" icon_name = "changes-prevent-symbolic"
visibility = False self.entry.set_visibility(False)
self.entry.set_visibility(visibility)
self.entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, icon_name) self.entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, icon_name)
# #
@@ -840,16 +867,16 @@ class FileChooserWindow(Gtk.Window):
dialog.destroy() dialog.destroy()
def add_filters(self, dialog): def add_filters(self, dialog):
filters = [ filter_ipa = Gtk.FileFilter()
("IPA files", "*.ipa"), filter_ipa.set_name("IPA files")
("Any files", "*") filter_ipa.add_pattern("*.ipa")
] dialog.add_filter(filter_ipa)
filter_any = Gtk.FileFilter()
filter_any.set_name("Any files")
filter_any.add_pattern("*")
dialog.add_filter(filter_any)
for name, pattern in filters:
filter = Gtk.FileFilter()
filter.set_name(name)
filter.add_pattern(pattern)
dialog.add_filter(filter)
class DialogExample(Gtk.Dialog): class DialogExample(Gtk.Dialog):
def __init__(self, parent): def __init__(self, parent):
@@ -857,27 +884,27 @@ class DialogExample(Gtk.Dialog):
super().__init__(title="Verification code", transient_for=parent, flags=0) super().__init__(title="Verification code", transient_for=parent, flags=0)
else: else:
super().__init__(title="Verification code", flags=0) super().__init__(title="Verification code", flags=0)
self.present()
self.add_buttons(
Gtk.STOCK_CANCEL,
Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK,
Gtk.ResponseType.OK,
)
self.set_resizable(False)
self.set_border_width(10)
self.set_resizable(False) labelhelp = Gtk.Label(
self.set_border_width(10) label="Enter the verification \ncode on your device: "
)
labelhelp.set_justify(Gtk.Justification.CENTER)
self.add_buttons( self.entry2 = Gtk.Entry()
Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK, Gtk.ResponseType.OK,
)
labelhelp = Gtk.Label(label="Enter the verification \ncode on your device:") box = self.get_content_area()
labelhelp.set_justify(Gtk.Justification.CENTER) box.add(labelhelp)
box.add(self.entry2)
self.entry2 = Gtk.Entry() self.show_all()
box = self.get_content_area()
box.add(labelhelp)
box.add(self.entry2)
self.show_all()
self.present()
self.entry2.grab_focus()
class DialogExample2(Gtk.Dialog): class DialogExample2(Gtk.Dialog):
@@ -1038,21 +1065,13 @@ class OopsInternet(Handy.Window):
def on_info_clicked2(self, widget): def on_info_clicked2(self, widget):
quitit() quitit()
# Main function
def main(): def main():
GLib.set_prgname("althea") GLib.set_prgname("althea") # Sets the global program name
global altheapath global altheapath
#global file_name #global file_name
altheapath = os.path.expanduser("~/.local/share/althea") if not os.path.exists(altheapath): # Creates $HOME/.local/share/althea
os.mkdir(altheapath)
if not os.path.exists(altheapath):
os.makedirs(altheapath)
log_file_path = os.path.join(altheapath, "log.txt")
if not os.path.isfile(log_file_path):
with open(log_file_path, 'w') as f:
f.write("")
if Gtk.StatusIcon.is_embedded: if Gtk.StatusIcon.is_embedded:
if connectioncheck(): if connectioncheck():
global indicator global indicator
@@ -1066,10 +1085,9 @@ def main():
indicator.set_status(appindicator.IndicatorStatus.PASSIVE) indicator.set_status(appindicator.IndicatorStatus.PASSIVE)
openwindow(SplashScreen) openwindow(SplashScreen)
else: else:
openwindow(OopsInternet) openwindow(OopsInternet) # Notify the user there is no Internet connection
else: else:
openwindow(Oops) openwindow(Oops) # Notify the user the tray icons aren't installed
Handy.init() Handy.init()
Gtk.main() Gtk.main()