OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 import multiprocessing | 4 import multiprocessing |
5 import os | 5 import os |
6 import sqlite3 | 6 import sqlite3 |
7 | 7 |
| 8 import page_sets |
| 9 |
8 from profile_creators import fast_navigation_profile_extender | 10 from profile_creators import fast_navigation_profile_extender |
9 from profile_creators import profile_safe_url_list | 11 from profile_creators import profile_safe_url_list |
10 | 12 |
11 class CookieProfileExtender( | 13 class CookieProfileExtender( |
12 fast_navigation_profile_extender.FastNavigationProfileExtender): | 14 fast_navigation_profile_extender.FastNavigationProfileExtender): |
13 """This extender performs a large number of navigations (up to 500), with the | 15 """This extender fills in the cookie database. |
14 goal of filling out the cookie database. | |
15 | 16 |
16 By default, Chrome purges the cookie DB down to 3300 cookies. However, it | 17 By default, Chrome purges the cookie DB down to 3300 cookies. However, it |
17 won't purge cookies accessed in the last month. This means the extender needs | 18 won't purge cookies accessed in the last month. This means the extender needs |
18 to be careful not to create an artificially high number of cookies. | 19 to be careful not to create an artificially high number of cookies. |
19 """ | 20 """ |
20 _COOKIE_DB_EXPECTED_SIZE = 3300 | 21 _COOKIE_DB_EXPECTED_SIZE = 3300 |
21 | 22 |
22 def __init__(self): | 23 def __init__(self): |
23 # The rate limiting factors are fetching network resources and executing | 24 # The rate limiting factors are fetching network resources and executing |
24 # javascript. There's not much to be done about the former, and having one | 25 # javascript. There's not much to be done about the former, and having one |
25 # tab per logical core appears close to optimum for the latter. | 26 # tab per logical core appears close to optimum for the latter. |
26 maximum_batch_size = multiprocessing.cpu_count() | 27 maximum_batch_size = multiprocessing.cpu_count() |
27 super(CookieProfileExtender, self).__init__(maximum_batch_size) | 28 super(CookieProfileExtender, self).__init__(maximum_batch_size) |
28 | 29 |
29 # A list of urls that have not yet been navigated to. This list will shrink | 30 # A list of urls that have not yet been navigated to. This list will shrink |
30 # over time. Each navigation will add a diminishing number of new cookies, | 31 # over time. Each navigation will add a diminishing number of new cookies, |
31 # since there's a high probability that the cookie is already present. If | 32 # since there's a high probability that the cookie is already present. |
32 # the cookie DB isn't full by 500 navigations, just give up. | 33 self._page_set = page_sets.ProfileSafeUrlsPageSet() |
33 self._navigation_urls = profile_safe_url_list.GetShuffledSafeUrls()[0:500] | 34 urls = [] |
| 35 for user_story in self._page_set.user_stories: |
| 36 urls.append(user_story.url) |
| 37 self._navigation_urls = urls |
34 | 38 |
35 def GetUrlIterator(self): | 39 def GetUrlIterator(self): |
36 """Superclass override.""" | 40 """Superclass override.""" |
37 return iter(self._navigation_urls) | 41 return iter(self._navigation_urls) |
38 | 42 |
39 def ShouldExitAfterBatchNavigation(self): | 43 def ShouldExitAfterBatchNavigation(self): |
40 """Superclass override.""" | 44 """Superclass override.""" |
41 return self._IsCookieDBFull() | 45 return self._IsCookieDBFull() |
42 | 46 |
| 47 def WebPageReplayArchivePath(self): |
| 48 return self._page_set.WprFilePathForUserStory( |
| 49 self._page_set.user_stories[0]) |
| 50 |
| 51 def FetchWebPageReplayArchives(self): |
| 52 """Superclass override.""" |
| 53 self._page_set.wpr_archive_info.DownloadArchivesIfNeeded() |
| 54 |
43 @staticmethod | 55 @staticmethod |
44 def _CookieCountInDB(db_path): | 56 def _CookieCountInDB(db_path): |
45 """The number of cookies in the db at |db_path|.""" | 57 """The number of cookies in the db at |db_path|.""" |
46 connection = sqlite3.connect(db_path) | 58 connection = sqlite3.connect(db_path) |
47 try: | 59 try: |
48 cursor = connection.cursor() | 60 cursor = connection.cursor() |
49 cursor.execute("select count(*) from cookies") | 61 cursor.execute("select count(*) from cookies") |
50 cookie_count = cursor.fetchone()[0] | 62 cookie_count = cursor.fetchone()[0] |
51 except: | 63 except: |
52 raise | 64 raise |
53 finally: | 65 finally: |
54 connection.close() | 66 connection.close() |
55 return cookie_count | 67 return cookie_count |
56 | 68 |
57 def _IsCookieDBFull(self): | 69 def _IsCookieDBFull(self): |
58 """Chrome does not immediately flush cookies to its database. It's possible | 70 """Chrome does not immediately flush cookies to its database. It's possible |
59 that this method will return a false negative.""" | 71 that this method will return a false negative.""" |
60 cookie_db_path = os.path.join(self.profile_path, "Default", "Cookies") | 72 cookie_db_path = os.path.join(self.profile_path, "Default", "Cookies") |
61 try: | 73 try: |
62 cookie_count = CookieProfileExtender._CookieCountInDB(cookie_db_path) | 74 cookie_count = CookieProfileExtender._CookieCountInDB(cookie_db_path) |
63 except sqlite3.OperationalError: | 75 except sqlite3.OperationalError: |
64 # There will occasionally be contention for the SQLite database. This | 76 # There will occasionally be contention for the SQLite database. This |
65 # shouldn't happen often, so ignore the errors. | 77 # shouldn't happen often, so ignore the errors. |
66 return False | 78 return False |
67 | 79 |
68 return cookie_count > CookieProfileExtender._COOKIE_DB_EXPECTED_SIZE | 80 return cookie_count > CookieProfileExtender._COOKIE_DB_EXPECTED_SIZE |
OLD | NEW |