Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(385)

Side by Side Diff: ios/chrome/browser/reading_list/url_downloader.cc

Issue 2506993002: Create offline_url_utils (Closed)
Patch Set: feedback Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 4
5 #include "ios/chrome/browser/reading_list/url_downloader.h" 5 #include "ios/chrome/browser/reading_list/url_downloader.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/md5.h"
13 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
14 #include "base/path_service.h" 13 #include "base/path_service.h"
15 #include "ios/chrome/browser/chrome_paths.h" 14 #include "ios/chrome/browser/chrome_paths.h"
16 #include "ios/chrome/browser/dom_distiller/distiller_viewer.h" 15 #include "ios/chrome/browser/dom_distiller/distiller_viewer.h"
16 #include "ios/chrome/browser/reading_list/offline_url_utils.h"
17 #include "ios/web/public/web_thread.h" 17 #include "ios/web/public/web_thread.h"
18 #include "net/base/escape.h" 18 #include "net/base/escape.h"
19 #include "url/gurl.h" 19 #include "url/gurl.h"
20 20
21 const char kReadingListOfflineDirectory[] = "Offline";
22
23 // URLDownloader 21 // URLDownloader
24 22
25 URLDownloader::URLDownloader( 23 URLDownloader::URLDownloader(
26 dom_distiller::DomDistillerService* distiller_service, 24 dom_distiller::DomDistillerService* distiller_service,
27 PrefService* prefs, 25 PrefService* prefs,
28 base::FilePath chrome_profile_path, 26 base::FilePath chrome_profile_path,
29 const DownloadCompletion& download_completion, 27 const DownloadCompletion& download_completion,
30 const SuccessCompletion& delete_completion) 28 const SuccessCompletion& delete_completion)
31 : distiller_service_(distiller_service), 29 : distiller_service_(distiller_service),
32 pref_service_(prefs), 30 pref_service_(prefs),
33 download_completion_(download_completion), 31 download_completion_(download_completion),
34 delete_completion_(delete_completion), 32 delete_completion_(delete_completion),
35 working_(false), 33 working_(false),
36 base_directory_(chrome_profile_path), 34 base_directory_(chrome_profile_path),
37 task_tracker_() {} 35 task_tracker_() {}
38 36
39 URLDownloader::~URLDownloader() { 37 URLDownloader::~URLDownloader() {
40 task_tracker_.TryCancelAll(); 38 task_tracker_.TryCancelAll();
41 } 39 }
42 40
43 void URLDownloader::OfflineURLExists(const GURL& url, 41 void URLDownloader::OfflineURLExists(const GURL& url,
44 base::Callback<void(bool)> callback) { 42 base::Callback<void(bool)> callback) {
45 task_tracker_.PostTaskAndReplyWithResult( 43 task_tracker_.PostTaskAndReplyWithResult(
46 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(), 44 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(),
47 FROM_HERE, base::Bind(&base::PathExists, OfflinePageAbsolutePath(url)), 45 FROM_HERE,
46 base::Bind(&base::PathExists,
47 reading_list::OfflinePageAbsolutePath(base_directory_, url)),
48 callback); 48 callback);
49 } 49 }
50 50
51 void URLDownloader::RemoveOfflineURL(const GURL& url) { 51 void URLDownloader::RemoveOfflineURL(const GURL& url) {
52 // Remove all download tasks for this url as it would be pointless work. 52 // Remove all download tasks for this url as it would be pointless work.
53 tasks_.erase( 53 tasks_.erase(
54 std::remove(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)), 54 std::remove(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)),
55 tasks_.end()); 55 tasks_.end());
56 tasks_.push_back(std::make_pair(DELETE, url)); 56 tasks_.push_back(std::make_pair(DELETE, url));
57 HandleNextTask(); 57 HandleNextTask();
58 } 58 }
59 59
60 void URLDownloader::DownloadOfflineURL(const GURL& url) { 60 void URLDownloader::DownloadOfflineURL(const GURL& url) {
61 if (std::find(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)) == 61 if (std::find(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)) ==
62 tasks_.end()) { 62 tasks_.end()) {
63 tasks_.push_back(std::make_pair(DOWNLOAD, url)); 63 tasks_.push_back(std::make_pair(DOWNLOAD, url));
64 HandleNextTask(); 64 HandleNextTask();
65 } 65 }
66 } 66 }
67 67
68 void URLDownloader::DownloadCompletionHandler(const GURL& url, 68 void URLDownloader::DownloadCompletionHandler(const GURL& url,
69 const std::string& title, 69 const std::string& title,
70 SuccessState success) { 70 SuccessState success) {
71 DCHECK(working_); 71 DCHECK(working_);
72 72
73 auto post_delete = base::Bind( 73 auto post_delete = base::Bind(
74 [](URLDownloader* _this, const GURL& url, const std::string& title, 74 [](URLDownloader* _this, const GURL& url, const std::string& title,
75 SuccessState success) { 75 SuccessState success) {
76 _this->download_completion_.Run(url, success, 76 _this->download_completion_.Run(
77 _this->OfflinePagePath(url), title); 77 url, success, reading_list::OfflinePagePath(url), title);
78 _this->distiller_.reset(); 78 _this->distiller_.reset();
79 _this->working_ = false; 79 _this->working_ = false;
80 _this->HandleNextTask(); 80 _this->HandleNextTask();
81 }, 81 },
82 base::Unretained(this), url, title, success); 82 base::Unretained(this), url, title, success);
83 83
84 // If downloading failed, clean up any partial download. 84 // If downloading failed, clean up any partial download.
85 if (success == ERROR_RETRY || success == ERROR_PERMANENT) { 85 if (success == ERROR_RETRY || success == ERROR_PERMANENT) {
86 task_tracker_.PostTaskAndReply( 86 task_tracker_.PostTaskAndReply(
87 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(), 87 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(),
88 FROM_HERE, base::Bind( 88 FROM_HERE, base::Bind(
89 [](const base::FilePath& offline_directory_path) { 89 [](const base::FilePath& offline_directory_path) {
90 base::DeleteFile(offline_directory_path, true); 90 base::DeleteFile(offline_directory_path, true);
91 }, 91 },
92 OfflineURLDirectoryAbsolutePath(url)), 92 reading_list::OfflineURLDirectoryAbsolutePath(
93 base_directory_, url)),
93 post_delete); 94 post_delete);
94 } else { 95 } else {
95 post_delete.Run(); 96 post_delete.Run();
96 } 97 }
97 } 98 }
98 99
99 void URLDownloader::DeleteCompletionHandler(const GURL& url, bool success) { 100 void URLDownloader::DeleteCompletionHandler(const GURL& url, bool success) {
100 DCHECK(working_); 101 DCHECK(working_);
101 delete_completion_.Run(url, success); 102 delete_completion_.Run(url, success);
102 working_ = false; 103 working_ = false;
103 HandleNextTask(); 104 HandleNextTask();
104 } 105 }
105 106
106 void URLDownloader::HandleNextTask() { 107 void URLDownloader::HandleNextTask() {
107 if (working_ || tasks_.empty()) { 108 if (working_ || tasks_.empty()) {
108 return; 109 return;
109 } 110 }
110 working_ = true; 111 working_ = true;
111 112
112 Task task = tasks_.front(); 113 Task task = tasks_.front();
113 tasks_.pop_front(); 114 tasks_.pop_front();
114 GURL url = task.second; 115 GURL url = task.second;
115 116
116 if (task.first == DELETE) { 117 if (task.first == DELETE) {
117 task_tracker_.PostTaskAndReplyWithResult( 118 task_tracker_.PostTaskAndReplyWithResult(
118 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(), 119 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(),
119 FROM_HERE, base::Bind(&base::DeleteFile, 120 FROM_HERE, base::Bind(&base::DeleteFile,
120 OfflineURLDirectoryAbsolutePath(url), true), 121 reading_list::OfflineURLDirectoryAbsolutePath(
122 base_directory_, url),
123 true),
121 base::Bind(&URLDownloader::DeleteCompletionHandler, 124 base::Bind(&URLDownloader::DeleteCompletionHandler,
122 base::Unretained(this), url)); 125 base::Unretained(this), url));
123 } else if (task.first == DOWNLOAD) { 126 } else if (task.first == DOWNLOAD) {
124 DCHECK(!distiller_); 127 DCHECK(!distiller_);
125 OfflineURLExists(url, base::Bind(&URLDownloader::DownloadURL, 128 OfflineURLExists(url, base::Bind(&URLDownloader::DownloadURL,
126 base::Unretained(this), url)); 129 base::Unretained(this), url));
127 } 130 }
128 } 131 }
129 132
130 void URLDownloader::DownloadURL(GURL url, bool offline_url_exists) { 133 void URLDownloader::DownloadURL(GURL url, bool offline_url_exists) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 images, 169 images,
167 const std::string& html) { 170 const std::string& html) {
168 if (CreateOfflineURLDirectory(url)) { 171 if (CreateOfflineURLDirectory(url)) {
169 return SaveHTMLForURL(SaveAndReplaceImagesInHTML(url, html, images), url) 172 return SaveHTMLForURL(SaveAndReplaceImagesInHTML(url, html, images), url)
170 ? DOWNLOAD_SUCCESS 173 ? DOWNLOAD_SUCCESS
171 : ERROR_PERMANENT; 174 : ERROR_PERMANENT;
172 } 175 }
173 return ERROR_PERMANENT; 176 return ERROR_PERMANENT;
174 } 177 }
175 178
176 base::FilePath URLDownloader::OfflineRootDirectoryPath() {
177 return base_directory_.Append(
178 FILE_PATH_LITERAL(kReadingListOfflineDirectory));
179 }
180
181 std::string URLDownloader::OfflineURLDirectoryID(const GURL& url) {
182 return base::MD5String(url.spec());
183 }
184
185 base::FilePath URLDownloader::OfflinePagePath(const GURL& url) {
186 base::FilePath directory(OfflineURLDirectoryID(url));
187 return directory.Append(FILE_PATH_LITERAL("page.html"));
188 }
189
190 base::FilePath URLDownloader::OfflineURLDirectoryAbsolutePath(const GURL& url) {
191 return OfflineRootDirectoryPath().Append(OfflineURLDirectoryID(url));
192 }
193
194 base::FilePath URLDownloader::OfflinePageAbsolutePath(const GURL& url) {
195 return OfflineRootDirectoryPath().Append(OfflinePagePath(url));
196 }
197
198 bool URLDownloader::CreateOfflineURLDirectory(const GURL& url) { 179 bool URLDownloader::CreateOfflineURLDirectory(const GURL& url) {
199 base::FilePath path = OfflineURLDirectoryAbsolutePath(url); 180 base::FilePath path =
181 reading_list::OfflineURLDirectoryAbsolutePath(base_directory_, url);
200 if (!DirectoryExists(path)) { 182 if (!DirectoryExists(path)) {
201 return CreateDirectoryAndGetError(path, nil); 183 return CreateDirectoryAndGetError(path, nil);
202 } 184 }
203 return true; 185 return true;
204 } 186 }
205 187
206 bool URLDownloader::SaveImage(const GURL& url, 188 bool URLDownloader::SaveImage(const GURL& url,
207 const GURL& image_url, 189 const GURL& image_url,
208 const std::string& data, 190 const std::string& data,
209 std::string* image_name) { 191 std::string* image_name) {
210 std::string image_hash = base::MD5String(image_url.spec()); 192 std::string image_hash = base::MD5String(image_url.spec());
211 *image_name = image_hash; 193 *image_name = image_hash;
212 base::FilePath path = OfflineURLDirectoryAbsolutePath(url).Append(image_hash); 194 base::FilePath path =
195 reading_list::OfflineURLDirectoryAbsolutePath(base_directory_, url)
196 .Append(image_hash);
213 if (!base::PathExists(path)) { 197 if (!base::PathExists(path)) {
214 return base::WriteFile(path, data.c_str(), data.length()) > 0; 198 return base::WriteFile(path, data.c_str(), data.length()) > 0;
215 } 199 }
216 return true; 200 return true;
217 } 201 }
218 202
219 std::string URLDownloader::SaveAndReplaceImagesInHTML( 203 std::string URLDownloader::SaveAndReplaceImagesInHTML(
220 const GURL& url, 204 const GURL& url,
221 const std::string& html, 205 const std::string& html,
222 const std::vector<dom_distiller::DistillerViewerInterface::ImageInfo>& 206 const std::vector<dom_distiller::DistillerViewerInterface::ImageInfo>&
(...skipping 13 matching lines...) Expand all
236 pos = mutable_html.find(image_url, pos + local_image_name.size()); 220 pos = mutable_html.find(image_url, pos + local_image_name.size());
237 } 221 }
238 } 222 }
239 return mutable_html; 223 return mutable_html;
240 } 224 }
241 225
242 bool URLDownloader::SaveHTMLForURL(std::string html, const GURL& url) { 226 bool URLDownloader::SaveHTMLForURL(std::string html, const GURL& url) {
243 if (html.empty()) { 227 if (html.empty()) {
244 return false; 228 return false;
245 } 229 }
246 base::FilePath path = OfflinePageAbsolutePath(url); 230 base::FilePath path =
231 reading_list::OfflinePageAbsolutePath(base_directory_, url);
247 return base::WriteFile(path, html.c_str(), html.length()) > 0; 232 return base::WriteFile(path, html.c_str(), html.length()) > 0;
248 } 233 }
OLDNEW
« no previous file with comments | « ios/chrome/browser/reading_list/url_downloader.h ('k') | ios/chrome/browser/reading_list/url_downloader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698