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