OSDN Git Service

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