1#!/usr/bin/env python2.5 2 3import cgi 4import os 5import shutil 6import sys 7import sqlite3 8 9SCREENS = 5 10COLUMNS = 4 11ROWS = 4 12HOTSEAT_SIZE = 5 13CELL_SIZE = 110 14 15DIR = "db_files" 16AUTO_FILE = DIR + "/launcher.db" 17INDEX_FILE = DIR + "/index.html" 18 19def usage(): 20 print "usage: print_db.py launcher.db -- prints a launcher.db" 21 print "usage: print_db.py -- adb pulls a launcher.db from a device" 22 print " and prints it" 23 print 24 print "The dump will be created in a directory called db_files in cwd." 25 print "This script will delete any db_files directory you have now" 26 27 28def make_dir(): 29 shutil.rmtree(DIR, True) 30 os.makedirs(DIR) 31 32def pull_file(fn): 33 print "pull_file: " + fn 34 rv = os.system("adb pull" 35 + " /data/data/com.android.launcher/databases/launcher.db" 36 + " " + fn); 37 if rv != 0: 38 print "adb pull failed" 39 sys.exit(1) 40 41def get_favorites(conn): 42 c = conn.cursor() 43 c.execute("SELECT * FROM favorites") 44 columns = [d[0] for d in c.description] 45 rows = [] 46 for row in c: 47 rows.append(row) 48 return columns,rows 49 50def print_intent(out, id, i, cell): 51 if cell: 52 out.write("""<span class="intent" title="%s">shortcut</span>""" % ( 53 cgi.escape(cell, True) 54 )) 55 56 57def print_icon(out, id, i, cell): 58 if cell: 59 icon_fn = "icon_%d.png" % id 60 out.write("""<img src="%s">""" % ( icon_fn )) 61 f = file(DIR + "/" + icon_fn, "w") 62 f.write(cell) 63 f.close() 64 65def print_cell(out, id, i, cell): 66 if not cell is None: 67 out.write(cgi.escape(str(cell))) 68 69FUNCTIONS = { 70 "intent": print_intent, 71 "icon": print_icon 72} 73 74def render_cell_info(out, cell, occupied): 75 if cell is None: 76 out.write(" <td width=%d height=%d></td>\n" % 77 (CELL_SIZE, CELL_SIZE)) 78 elif cell == occupied: 79 pass 80 else: 81 cellX = cell["cellX"] 82 cellY = cell["cellY"] 83 spanX = cell["spanX"] 84 spanY = cell["spanY"] 85 intent = cell["intent"] 86 if intent: 87 title = "title=\"%s\"" % cgi.escape(cell["intent"], True) 88 else: 89 title = "" 90 out.write((" <td colspan=%d rowspan=%d width=%d height=%d" 91 + " bgcolor=#dddddd align=center valign=middle %s>") % ( 92 spanX, spanY, 93 (CELL_SIZE*spanX), (CELL_SIZE*spanY), 94 title)) 95 itemType = cell["itemType"] 96 if itemType == 0: 97 out.write("""<img src="icon_%d.png">\n""" % ( cell["_id"] )) 98 out.write("<br/>\n") 99 out.write(cgi.escape(cell["title"]) + " <br/><i>(app)</i>") 100 elif itemType == 1: 101 out.write("""<img src="icon_%d.png">\n""" % ( cell["_id"] )) 102 out.write("<br/>\n") 103 out.write(cgi.escape(cell["title"]) + " <br/><i>(shortcut)</i>") 104 elif itemType == 2: 105 out.write("""<i>folder</i>""") 106 elif itemType == 3: 107 out.write("""<i>live folder</i>""") 108 elif itemType == 4: 109 out.write("<i>widget %d</i><br/>\n" % cell["appWidgetId"]) 110 elif itemType == 1000: 111 out.write("""<i>clock</i>""") 112 elif itemType == 1001: 113 out.write("""<i>search</i>""") 114 elif itemType == 1002: 115 out.write("""<i>photo frame</i>""") 116 else: 117 out.write("<b>unknown type: %d</b>" % itemType) 118 out.write("</td>\n") 119 120def process_file(fn): 121 print "process_file: " + fn 122 conn = sqlite3.connect(fn) 123 columns,rows = get_favorites(conn) 124 data = [dict(zip(columns,row)) for row in rows] 125 126 out = file(INDEX_FILE, "w") 127 out.write("""<html> 128<head> 129<style type="text/css"> 130.intent { 131 font-style: italic; 132} 133</style> 134</head> 135<body> 136""") 137 138 # Data table 139 out.write("<b>Favorites table</b><br/>\n") 140 out.write("""<html> 141<table border=1 cellspacing=0 cellpadding=4> 142<tr> 143""") 144 print_functions = [] 145 for col in columns: 146 print_functions.append(FUNCTIONS.get(col, print_cell)) 147 for i in range(0,len(columns)): 148 col = columns[i] 149 out.write(""" <th>%s</th> 150""" % ( col )) 151 out.write(""" 152</tr> 153""") 154 for row in rows: 155 out.write("""<tr> 156""") 157 for i in range(0,len(row)): 158 cell = row[i] 159 # row[0] is always _id 160 out.write(""" <td>""") 161 print_functions[i](out, row[0], row, cell) 162 out.write("""</td> 163""") 164 out.write("""</tr> 165""") 166 out.write("""</table> 167""") 168 169 # Hotseat 170 hotseat = [] 171 for i in range(0, HOTSEAT_SIZE): 172 hotseat.append(None) 173 for row in data: 174 if row["container"] != -101: 175 continue 176 screen = row["screen"] 177 hotseat[screen] = row 178 out.write("<br/><b>Hotseat</b><br/>\n") 179 out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n") 180 for cell in hotseat: 181 render_cell_info(out, cell, None) 182 out.write("</table>\n") 183 184 # Pages 185 screens = [] 186 for i in range(0,SCREENS): 187 screen = [] 188 for j in range(0,ROWS): 189 m = [] 190 for k in range(0,COLUMNS): 191 m.append(None) 192 screen.append(m) 193 screens.append(screen) 194 occupied = "occupied" 195 for row in data: 196 screen = screens[row["screen"]] 197 # desktop 198 if row["container"] != -100: 199 continue 200 cellX = row["cellX"] 201 cellY = row["cellY"] 202 spanX = row["spanX"] 203 spanY = row["spanY"] 204 for j in range(cellY, cellY+spanY): 205 for k in range(cellX, cellX+spanX): 206 screen[j][k] = occupied 207 screen[cellY][cellX] = row 208 i=0 209 for screen in screens: 210 out.write("<br/><b>Screen %d</b><br/>\n" % i) 211 out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n") 212 for m in screen: 213 out.write(" <tr>\n") 214 for cell in m: 215 render_cell_info(out, cell, occupied) 216 out.write("</tr>\n") 217 out.write("</table>\n") 218 i=i+1 219 220 out.write(""" 221</body> 222</html> 223""") 224 225 out.close() 226 227def main(argv): 228 if len(argv) == 1: 229 make_dir() 230 pull_file(AUTO_FILE) 231 process_file(AUTO_FILE) 232 elif len(argv) == 2: 233 make_dir() 234 process_file(argv[1]) 235 else: 236 usage() 237 238if __name__=="__main__": 239 main(sys.argv) 240