OSDN Git Service

Refreshing widget list when a package containing a widget changes
[android-x86/packages-apps-Launcher3.git] / print_db.py
1 #!/usr/bin/env python2.5
2
3 import cgi
4 import codecs
5 import os
6 import pprint
7 import shutil
8 import sys
9 import sqlite3
10
11 SCREENS = 0
12 COLUMNS = 4
13 ROWS = 4
14 HOTSEAT_SIZE = 4
15 CELL_SIZE = 110
16
17 CONTAINER_DESKTOP = -100
18 CONTAINER_HOTSEAT = -101
19
20 DIR = "db_files"
21 AUTO_FILE = DIR + "/launcher.db"
22 INDEX_FILE = DIR + "/index.html"
23
24 def usage():
25   print "usage: print_db.py launcher.db <sw600|sw720> -- prints a launcher.db"
26   print "usage: print_db.py <sw600|sw720> -- adb pulls a launcher.db from a device"
27   print "       and prints it"
28   print
29   print "The dump will be created in a directory called db_files in cwd."
30   print "This script will delete any db_files directory you have now"
31
32
33 def make_dir():
34   shutil.rmtree(DIR, True)
35   os.makedirs(DIR)
36
37 def adb_root_remount():
38   os.system("adb root")
39   os.system("adb remount")
40
41 def pull_file(fn):
42   print "pull_file: " + fn
43   rv = os.system("adb pull"
44     + " /data/data/com.google.android.googlequicksearchbox/databases/launcher.db"
45     + " " + fn);
46   if rv != 0:
47     print "adb pull failed"
48     sys.exit(1)
49
50 def get_favorites(conn):
51   c = conn.cursor()
52   c.execute("SELECT * FROM favorites")
53   columns = [d[0] for d in c.description]
54   rows = []
55   for row in c:
56     rows.append(row)
57   return columns,rows
58
59 def get_screens(conn):
60   c = conn.cursor()
61   c.execute("SELECT * FROM workspaceScreens")
62   columns = [d[0] for d in c.description]
63   rows = []
64   for row in c:
65     rows.append(row)
66   return columns,rows
67
68 def print_intent(out, id, i, cell):
69   if cell:
70     out.write("""<span class="intent" title="%s">shortcut</span>""" % (
71         cgi.escape(cell, True)
72       ))
73
74
75 def print_icon(out, id, i, cell):
76   if cell:
77     icon_fn = "icon_%d.png" % id
78     out.write("""<img style="width: 3em; height: 3em;" src="%s">""" % ( icon_fn ))
79     f = file(DIR + "/" + icon_fn, "w")
80     f.write(cell)
81     f.close()
82
83 def print_icon_type(out, id, i, cell):
84   if cell == 0:
85     out.write("Application (%d)" % cell)
86   elif cell == 1:
87     out.write("Shortcut (%d)" % cell)
88   elif cell == 2:
89     out.write("Folder (%d)" % cell)
90   elif cell == 4:
91     out.write("Widget (%d)" % cell)
92   elif cell:
93     out.write("%d" % cell)
94
95 def print_cell(out, id, i, cell):
96   if not cell is None:
97     out.write(cgi.escape(unicode(cell)))
98
99 FUNCTIONS = {
100   "intent": print_intent,
101   "icon": print_icon,
102   "iconType": print_icon_type
103 }
104
105 def render_cell_info(out, cell, occupied):
106   if cell is None:
107     out.write("    <td width=%d height=%d></td>\n" %
108         (CELL_SIZE, CELL_SIZE))
109   elif cell == occupied:
110     pass
111   else:
112     cellX = cell["cellX"]
113     cellY = cell["cellY"]
114     spanX = cell["spanX"]
115     spanY = cell["spanY"]
116     intent = cell["intent"]
117     if intent:
118       title = "title=\"%s\"" % cgi.escape(cell["intent"], True)
119     else:
120       title = ""
121     out.write(("    <td colspan=%d rowspan=%d width=%d height=%d"
122         + " bgcolor=#dddddd align=center valign=middle %s>") % (
123           spanX, spanY,
124           (CELL_SIZE*spanX), (CELL_SIZE*spanY),
125           title))
126     itemType = cell["itemType"]
127     if itemType == 0:
128       out.write("""<img style="width: 4em; height: 4em;" src="icon_%d.png">\n""" % ( cell["_id"] ))
129       out.write("<br/>\n")
130       out.write(cgi.escape(cell["title"]) + " <br/><i>(app)</i>")
131     elif itemType == 1:
132       out.write("""<img style="width: 4em; height: 4em;" src="icon_%d.png">\n""" % ( cell["_id"] ))
133       out.write("<br/>\n")
134       out.write(cgi.escape(cell["title"]) + " <br/><i>(shortcut)</i>")
135     elif itemType == 2:
136       out.write("""<i>folder</i>""")
137     elif itemType == 4:
138       out.write("<i>widget %d</i><br/>\n" % cell["appWidgetId"])
139     else:
140       out.write("<b>unknown type: %d</b>" % itemType)
141     out.write("</td>\n")
142
143 def render_screen_info(out, screen):
144   out.write("<tr>")
145   out.write("<td>%s</td>" % (screen["_id"]))
146   out.write("<td>%s</td>" % (screen["screenRank"]))
147   out.write("</tr>")
148
149 def process_file(fn):
150   global SCREENS, COLUMNS, ROWS, HOTSEAT_SIZE
151   print "process_file: " + fn
152   conn = sqlite3.connect(fn)
153   columns,rows = get_favorites(conn)
154   screenCols, screenRows = get_screens(conn)
155
156   data = [dict(zip(columns,row)) for row in rows]
157   screenData = [dict(zip(screenCols, screenRow)) for screenRow in screenRows]
158
159   # Calculate the proper number of screens, columns, and rows in this db
160   screensIdMap = []
161   hotseatIdMap = []
162   HOTSEAT_SIZE = 0
163   for d in data:
164     if d["spanX"] is None:
165       d["spanX"] = 1
166     if d["spanY"] is None:
167       d["spanY"] = 1
168     if d["container"] == CONTAINER_DESKTOP:
169       if d["screen"] not in screensIdMap:
170         screensIdMap.append(d["screen"])
171       COLUMNS = max(COLUMNS, d["cellX"] + d["spanX"])
172       ROWS = max(ROWS, d["cellX"] + d["spanX"])
173     elif d["container"] == CONTAINER_HOTSEAT:
174       hotseatIdMap.append(d["screen"])
175       HOTSEAT_SIZE = max(HOTSEAT_SIZE, d["screen"] + 1)
176   SCREENS = len(screensIdMap)
177
178   out = codecs.open(INDEX_FILE, encoding="utf-8", mode="w")
179   out.write("""<html>
180 <head>
181 <style type="text/css">
182 .intent {
183   font-style: italic;
184 }
185 </style>
186 </head>
187 <body>
188 """)
189
190   # Data table
191   out.write("<b>Favorites table</b><br/>\n")
192   out.write("""<html>
193 <table border=1 cellspacing=0 cellpadding=4>
194 <tr>
195 """)
196   print_functions = []
197   for col in columns:
198     print_functions.append(FUNCTIONS.get(col, print_cell))
199   for i in range(0,len(columns)):
200     col = columns[i]
201     out.write("""  <th>%s</th>
202 """ % ( col ))
203   out.write("""
204 </tr>
205 """)
206
207   for row in rows:
208     out.write("""<tr>
209 """)
210     for i in range(0,len(row)):
211       cell = row[i]
212       # row[0] is always _id
213       out.write("""  <td>""")
214       print_functions[i](out, row[0], row, cell)
215       out.write("""</td>
216 """)
217     out.write("""</tr>
218 """)
219   out.write("""</table>
220 """)
221
222   # Screens
223   out.write("<br/><b>Screens</b><br/>\n")
224   out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
225   out.write("<tr><td>Screen ID</td><td>Rank</td></tr>\n")
226   for screen in screenData:
227     render_screen_info(out, screen)
228   out.write("</table>\n")
229
230   # Hotseat
231   hotseat = []
232   for i in range(0, HOTSEAT_SIZE):
233     hotseat.append(None)
234   for row in data:
235     if row["container"] != CONTAINER_HOTSEAT:
236       continue
237     screen = row["screen"]
238     hotseat[screen] = row
239   out.write("<br/><b>Hotseat</b><br/>\n")
240   out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
241   for cell in hotseat:
242     render_cell_info(out, cell, None)
243   out.write("</table>\n")
244
245   # Pages
246   screens = []
247   for i in range(0,SCREENS):
248     screen = []
249     for j in range(0,ROWS):
250       m = []
251       for k in range(0,COLUMNS):
252         m.append(None)
253       screen.append(m)
254     screens.append(screen)
255   occupied = "occupied"
256   for row in data:
257     # desktop
258     if row["container"] != CONTAINER_DESKTOP:
259       continue
260     screen = screens[screensIdMap.index(row["screen"])]
261     cellX = row["cellX"]
262     cellY = row["cellY"]
263     spanX = row["spanX"]
264     spanY = row["spanY"]
265     for j in range(cellY, cellY+spanY):
266       for k in range(cellX, cellX+spanX):
267         screen[j][k] = occupied
268     screen[cellY][cellX] = row
269   i=0
270   for screen in screens:
271     out.write("<br/><b>Screen %d</b><br/>\n" % i)
272     out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
273     for m in screen:
274       out.write("  <tr>\n")
275       for cell in m:
276         render_cell_info(out, cell, occupied)
277       out.write("</tr>\n")
278     out.write("</table>\n")
279     i=i+1
280
281   out.write("""
282 </body>
283 </html>
284 """)
285
286   out.close()
287
288 def updateDeviceClassConstants(str):
289   global SCREENS, COLUMNS, ROWS, HOTSEAT_SIZE
290   devClass = str.lower()
291   if devClass == "sw600":
292     COLUMNS = 6
293     ROWS = 6
294     HOTSEAT_SIZE = 6
295     return True
296   elif devClass == "sw720":
297     COLUMNS = 8
298     ROWS = 6
299     HOTSEAT_SIZE = 8
300     return True
301   return False
302
303 def main(argv):
304   if len(argv) == 1 or (len(argv) == 2 and updateDeviceClassConstants(argv[1])):
305     make_dir()
306     adb_root_remount()
307     pull_file(AUTO_FILE)
308     process_file(AUTO_FILE)
309   elif len(argv) == 2 or (len(argv) == 3 and updateDeviceClassConstants(argv[2])):
310     make_dir()
311     process_file(argv[1])
312   else:
313     usage()
314
315 if __name__=="__main__":
316   main(sys.argv)