Re: PSA: How to archive your EXACT homescreen(s) apps to Windows for perfect cross-platform backup/restore sans the net
Maria Sophia <[email protected]>
| Newsgroups | comp.mobile.android,alt.comp.microsoft.windows,alt.comp.os.windows-10 |
|---|---|
| Organization | BWH Usenet Archive (https://usenet.blueworldhosting.com) |
| Message-ID | <[email protected]> |
Maria Sophia wrote:
> This makes a skeleton on the desktop of the homescreen hierarchy.
> But, there are two python scripts which need to be merged into one.
>
> 1. First, novasql.py creates a file containing panels, folders & apps
> 2. Then, novadir.py creates a physical folder hierarchy for each panel
This novabuild.py script combines the two scripts above into a single script which only needs for input the nova database and the output is a complete folder hierarchy for each homescreen panel.
# -------------------------------------------------------------------
# novabuild.py
# Parse nova.db and build physical folder/APK directory skeleton
# python novabuild.py
# -------------------------------------------------------------------
# The "favorites" table stores app shortcuts and folder containers.
# -------------------------------------------------------------------
# v1p0 20260819 Combined SQL parsing and direct directory tree generation
# -------------------------------------------------------------------
import os
import re
import sqlite3
db_file = "nova.db"
base_dir = "./android_archive"
if not os.path.exists(db_file):
print(f"Error: {db_file} not found. Please place it in the working directory.")
exit(1)
print(f"Connecting to {db_file} and building directory skeleton...")
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
# 1. Fetch distinct screen indices associated with desktop items
cursor.execute(
"SELECT DISTINCT screen FROM favorites WHERE container = -100 ORDER BY screen ASC;"
)
screens = cursor.fetchall()
for (screen_num,) in screens:
current_panel = f"panel_{screen_num}"
print(f"\n--- Processing: {current_panel} ---")
# 2. Find folders located directly on this specific screen (ignoring blank titles)
cursor.execute(
"SELECT _id, title FROM favorites WHERE container = -100 AND screen = ?"
" AND intent IS NULL AND title IS NOT NULL AND TRIM(title) != '';",
(screen_num,),
)
folders = cursor.fetchall()
for folder_id, folder_name in folders:
# Clean folder name for safe filesystem usage
clean_folder_name = re.sub(r'[\\/*?:"<>|]', "", folder_name).strip()
if not clean_folder_name:
clean_folder_name = "unnamed_folder"
# Get apps inside this folder
cursor.execute(
"SELECT title, intent FROM favorites WHERE container = ?;",
(folder_id,),
)
items = cursor.fetchall()
if items:
for app_title, intent in items:
pkg = "Unknown"
if intent and "component=" in intent:
try:
part = intent.split("component=")[1]
pkg = part.split("/")[0]
except IndexError:
pkg = intent
target_path = os.path.join(
base_dir, current_panel, clean_folder_name, pkg
)
os.makedirs(target_path, exist_ok=True)
print(f"Created: {target_path}")
else:
# Handle empty folders by creating the base folder path anyway
target_path = os.path.join(base_dir, current_panel, clean_folder_name)
os.makedirs(target_path, exist_ok=True)
print(f"Created (Empty Folder): {target_path}")
# 3. Find loose/top-level apps sitting directly on this screen (not in folders)
cursor.execute(
"SELECT title, intent FROM favorites WHERE container = -100 AND screen = ?"
" AND intent IS NOT NULL;",
(screen_num,),
)
loose_apps = cursor.fetchall()
if loose_apps:
for app_title, intent in loose_apps:
pkg = "Unknown"
if intent and "component=" in intent:
try:
part = intent.split("component=")[1]
pkg = part.split("/")[0]
except IndexError:
pkg = intent
target_path = os.path.join(
base_dir, current_panel, "loose_apps", pkg
)
os.makedirs(target_path, exist_ok=True)
print(f"Created: {target_path}")
conn.close()
print("\nSkeleton folder hierarchy successfully built directly from nova.db!")
# end of novabuild.py