update:2021.03.19
fix:重新提交 add:
This commit is contained in:
313
print_db.py
Normal file
313
print_db.py
Normal file
@@ -0,0 +1,313 @@
|
||||
#!/usr/bin/env python2.5
|
||||
|
||||
import cgi
|
||||
import codecs
|
||||
import os
|
||||
import pprint
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import sqlite3
|
||||
|
||||
SCREENS = 0
|
||||
COLUMNS = 4
|
||||
ROWS = 4
|
||||
HOTSEAT_SIZE = 4
|
||||
CELL_SIZE = 110
|
||||
|
||||
CONTAINER_DESKTOP = -100
|
||||
CONTAINER_HOTSEAT = -101
|
||||
|
||||
DIR = "db_files"
|
||||
AUTO_FILE = DIR + "/launcher.db"
|
||||
INDEX_FILE = DIR + "/index.html"
|
||||
|
||||
def usage():
|
||||
print "usage: print_db.py launcher.db <4x4|5x5|5x6|...> -- prints a launcher.db with"
|
||||
print " the specified grid size (rows x cols)"
|
||||
print "usage: print_db.py <4x4|5x5|5x6|...> -- adb pulls a launcher.db from a device"
|
||||
print " and prints it with the specified grid size (rows x cols)"
|
||||
print
|
||||
print "The dump will be created in a directory called db_files in cwd."
|
||||
print "This script will delete any db_files directory you have now"
|
||||
|
||||
|
||||
def make_dir():
|
||||
shutil.rmtree(DIR, True)
|
||||
os.makedirs(DIR)
|
||||
|
||||
def adb_root_remount():
|
||||
os.system("adb root")
|
||||
os.system("adb remount")
|
||||
|
||||
def pull_file(fn):
|
||||
print "pull_file: " + fn
|
||||
rv = os.system("adb pull"
|
||||
+ " /data/data/com.android.uiuios/databases/launcher.db"
|
||||
+ " " + fn);
|
||||
if rv != 0:
|
||||
print "adb pull failed"
|
||||
sys.exit(1)
|
||||
|
||||
def get_favorites(conn):
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM favorites")
|
||||
columns = [d[0] for d in c.description]
|
||||
rows = []
|
||||
for row in c:
|
||||
rows.append(row)
|
||||
return columns,rows
|
||||
|
||||
def get_screens(conn):
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM workspaceScreens")
|
||||
columns = [d[0] for d in c.description]
|
||||
rows = []
|
||||
for row in c:
|
||||
rows.append(row)
|
||||
return columns,rows
|
||||
|
||||
def print_intent(out, id, i, cell):
|
||||
if cell:
|
||||
out.write("""<span class="intent" title="%s">shortcut</span>""" % (
|
||||
cgi.escape(cell, True)
|
||||
))
|
||||
|
||||
|
||||
def print_icon(out, id, i, cell):
|
||||
if cell:
|
||||
icon_fn = "icon_%d.png" % id
|
||||
out.write("""<img style="width: 3em; height: 3em;" src="%s">""" % ( icon_fn ))
|
||||
f = file(DIR + "/" + icon_fn, "w")
|
||||
f.write(cell)
|
||||
f.close()
|
||||
|
||||
def print_icon_type(out, id, i, cell):
|
||||
if cell == 0:
|
||||
out.write("Application (%d)" % cell)
|
||||
elif cell == 1:
|
||||
out.write("Shortcut (%d)" % cell)
|
||||
elif cell == 2:
|
||||
out.write("Folder (%d)" % cell)
|
||||
elif cell == 4:
|
||||
out.write("Widget (%d)" % cell)
|
||||
elif cell:
|
||||
out.write("%d" % cell)
|
||||
|
||||
def print_cell(out, id, i, cell):
|
||||
if not cell is None:
|
||||
out.write(cgi.escape(unicode(cell)))
|
||||
|
||||
FUNCTIONS = {
|
||||
"intent": print_intent,
|
||||
"icon": print_icon,
|
||||
"iconType": print_icon_type
|
||||
}
|
||||
|
||||
def render_cell_info(out, cell, occupied):
|
||||
if cell is None:
|
||||
out.write(" <td width=%d height=%d></td>\n" %
|
||||
(CELL_SIZE, CELL_SIZE))
|
||||
elif cell == occupied:
|
||||
pass
|
||||
else:
|
||||
cellX = cell["cellX"]
|
||||
cellY = cell["cellY"]
|
||||
spanX = cell["spanX"]
|
||||
spanY = cell["spanY"]
|
||||
intent = cell["intent"]
|
||||
if intent:
|
||||
title = "title=\"%s\"" % cgi.escape(cell["intent"], True)
|
||||
else:
|
||||
title = ""
|
||||
out.write((" <td colspan=%d rowspan=%d width=%d height=%d"
|
||||
+ " bgcolor=#dddddd align=center valign=middle %s>") % (
|
||||
spanX, spanY,
|
||||
(CELL_SIZE*spanX), (CELL_SIZE*spanY),
|
||||
title))
|
||||
itemType = cell["itemType"]
|
||||
if itemType == 0:
|
||||
out.write("""<img style="width: 4em; height: 4em;" src="icon_%d.png">\n""" % ( cell["_id"] ))
|
||||
out.write("<br/>\n")
|
||||
out.write(cgi.escape(cell["title"]) + " <br/><i>(app)</i>")
|
||||
elif itemType == 1:
|
||||
out.write("""<img style="width: 4em; height: 4em;" src="icon_%d.png">\n""" % ( cell["_id"] ))
|
||||
out.write("<br/>\n")
|
||||
out.write(cgi.escape(cell["title"]) + " <br/><i>(shortcut)</i>")
|
||||
elif itemType == 2:
|
||||
out.write("""<i>folder</i>""")
|
||||
elif itemType == 4:
|
||||
out.write("<i>widget %d</i><br/>\n" % cell["appWidgetId"])
|
||||
else:
|
||||
out.write("<b>unknown type: %d</b>" % itemType)
|
||||
out.write("</td>\n")
|
||||
|
||||
def render_screen_info(out, screen):
|
||||
out.write("<tr>")
|
||||
out.write("<td>%s</td>" % (screen["_id"]))
|
||||
out.write("<td>%s</td>" % (screen["screenRank"]))
|
||||
out.write("</tr>")
|
||||
|
||||
def process_file(fn):
|
||||
global SCREENS, COLUMNS, ROWS, HOTSEAT_SIZE
|
||||
print "process_file: " + fn
|
||||
conn = sqlite3.connect(fn)
|
||||
columns,rows = get_favorites(conn)
|
||||
screenCols, screenRows = get_screens(conn)
|
||||
|
||||
data = [dict(zip(columns,row)) for row in rows]
|
||||
screenData = [dict(zip(screenCols, screenRow)) for screenRow in screenRows]
|
||||
|
||||
# Calculate the proper number of screens, columns, and rows in this db
|
||||
screensIdMap = []
|
||||
hotseatIdMap = []
|
||||
HOTSEAT_SIZE = 0
|
||||
for d in data:
|
||||
if d["spanX"] is None:
|
||||
d["spanX"] = 1
|
||||
if d["spanY"] is None:
|
||||
d["spanY"] = 1
|
||||
if d["container"] == CONTAINER_DESKTOP:
|
||||
if d["screen"] not in screensIdMap:
|
||||
screensIdMap.append(d["screen"])
|
||||
COLUMNS = max(COLUMNS, d["cellX"] + d["spanX"])
|
||||
ROWS = max(ROWS, d["cellX"] + d["spanX"])
|
||||
elif d["container"] == CONTAINER_HOTSEAT:
|
||||
hotseatIdMap.append(d["screen"])
|
||||
HOTSEAT_SIZE = max(HOTSEAT_SIZE, d["screen"] + 1)
|
||||
SCREENS = len(screensIdMap)
|
||||
|
||||
out = codecs.open(INDEX_FILE, encoding="utf-8", mode="w")
|
||||
out.write("""<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
.intent {
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
""")
|
||||
|
||||
# Data table
|
||||
out.write("<b>Favorites table</b><br/>\n")
|
||||
out.write("""<html>
|
||||
<table border=1 cellspacing=0 cellpadding=4>
|
||||
<tr>
|
||||
""")
|
||||
print_functions = []
|
||||
for col in columns:
|
||||
print_functions.append(FUNCTIONS.get(col, print_cell))
|
||||
for i in range(0,len(columns)):
|
||||
col = columns[i]
|
||||
out.write(""" <th>%s</th>
|
||||
""" % ( col ))
|
||||
out.write("""
|
||||
</tr>
|
||||
""")
|
||||
|
||||
for row in rows:
|
||||
out.write("""<tr>
|
||||
""")
|
||||
for i in range(0,len(row)):
|
||||
cell = row[i]
|
||||
# row[0] is always _id
|
||||
out.write(""" <td>""")
|
||||
print_functions[i](out, row[0], row, cell)
|
||||
out.write("""</td>
|
||||
""")
|
||||
out.write("""</tr>
|
||||
""")
|
||||
out.write("""</table>
|
||||
""")
|
||||
|
||||
# Screens
|
||||
out.write("<br/><b>Screens</b><br/>\n")
|
||||
out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
|
||||
out.write("<tr><td>Screen ID</td><td>Rank</td></tr>\n")
|
||||
for screen in screenData:
|
||||
render_screen_info(out, screen)
|
||||
out.write("</table>\n")
|
||||
|
||||
# Hotseat
|
||||
hotseat = []
|
||||
for i in range(0, HOTSEAT_SIZE):
|
||||
hotseat.append(None)
|
||||
for row in data:
|
||||
if row["container"] != CONTAINER_HOTSEAT:
|
||||
continue
|
||||
screen = row["screen"]
|
||||
hotseat[screen] = row
|
||||
out.write("<br/><b>Hotseat</b><br/>\n")
|
||||
out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
|
||||
for cell in hotseat:
|
||||
render_cell_info(out, cell, None)
|
||||
out.write("</table>\n")
|
||||
|
||||
# Pages
|
||||
screens = []
|
||||
for i in range(0,SCREENS):
|
||||
screen = []
|
||||
for j in range(0,ROWS):
|
||||
m = []
|
||||
for k in range(0,COLUMNS):
|
||||
m.append(None)
|
||||
screen.append(m)
|
||||
screens.append(screen)
|
||||
occupied = "occupied"
|
||||
for row in data:
|
||||
# desktop
|
||||
if row["container"] != CONTAINER_DESKTOP:
|
||||
continue
|
||||
screen = screens[screensIdMap.index(row["screen"])]
|
||||
cellX = row["cellX"]
|
||||
cellY = row["cellY"]
|
||||
spanX = row["spanX"]
|
||||
spanY = row["spanY"]
|
||||
for j in range(cellY, cellY+spanY):
|
||||
for k in range(cellX, cellX+spanX):
|
||||
screen[j][k] = occupied
|
||||
screen[cellY][cellX] = row
|
||||
i=0
|
||||
for screen in screens:
|
||||
out.write("<br/><b>Screen %d</b><br/>\n" % i)
|
||||
out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
|
||||
for m in screen:
|
||||
out.write(" <tr>\n")
|
||||
for cell in m:
|
||||
render_cell_info(out, cell, occupied)
|
||||
out.write("</tr>\n")
|
||||
out.write("</table>\n")
|
||||
i=i+1
|
||||
|
||||
out.write("""
|
||||
</body>
|
||||
</html>
|
||||
""")
|
||||
|
||||
out.close()
|
||||
|
||||
def updateDeviceClassConstants(str):
|
||||
global SCREENS, COLUMNS, ROWS, HOTSEAT_SIZE
|
||||
match = re.search(r"(\d+)x(\d+)", str)
|
||||
if match:
|
||||
COLUMNS = int(match.group(1))
|
||||
ROWS = int(match.group(2))
|
||||
HOTSEAT_SIZE = 2 * int(COLUMNS / 2)
|
||||
return True
|
||||
return False
|
||||
|
||||
def main(argv):
|
||||
if len(argv) == 1 or (len(argv) == 2 and updateDeviceClassConstants(argv[1])):
|
||||
make_dir()
|
||||
adb_root_remount()
|
||||
pull_file(AUTO_FILE)
|
||||
process_file(AUTO_FILE)
|
||||
elif len(argv) == 2 or (len(argv) == 3 and updateDeviceClassConstants(argv[2])):
|
||||
make_dir()
|
||||
process_file(argv[1])
|
||||
else:
|
||||
usage()
|
||||
|
||||
if __name__=="__main__":
|
||||
main(sys.argv)
|
||||
Reference in New Issue
Block a user