프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / DownloadManager / PageStorage.cs @ master

이력 | 보기 | 이력해설 | 다운로드 (10.8 KB)

1 2007ecaa taeseongkim
using System;
2
using System.Collections.Concurrent;
3
using System.Collections.Generic;
4
using System.ComponentModel;
5
using System.Linq;
6 2b1f30fe taeseongkim
using System.Net;
7 2007ecaa taeseongkim
using System.Text;
8
using System.Threading.Tasks;
9
10
namespace KCOM.PageManager
11
{
12
    public class PageStorage
13
    {
14
        public event EventHandler<PageLoadCompletedEventArgs> PageLoadCompleted;
15
16
        private const int DEFUALT_TALK_PAGE_COUNT = 10;
17
18
        List<int> WorkItems = new List<int>();
19
        ConcurrentBag<PageItem> fileItems = new ConcurrentBag<PageItem>();
20
        BackgroundWorker backgroundWorker;
21
        
22
        string _localStorage;
23
        string _fileExt;
24
        string _BaseUri;
25
        int _TotalPages;
26
        int _TakeCount;
27 2b1f30fe taeseongkim
        string _token;
28 2007ecaa taeseongkim
        bool IsWork = false;
29
        bool IsDownload = false;
30
31
        public PageStorage(string BaseUri, string localStoragePath, string fileExt, int totalPages, int takeCount = 5)
32
        {
33
            try
34
            {
35
                backgroundWorker = new BackgroundWorker { WorkerSupportsCancellation = true, WorkerReportsProgress = true };
36
                backgroundWorker.DoWork += BackgroundWorker_DoWork;
37
                backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
38
                _fileExt = fileExt;
39
                _BaseUri = BaseUri;
40
                _localStorage = localStoragePath;
41
                _TotalPages = totalPages;
42
                _TakeCount = takeCount;
43
44 66bd3240 taeseongkim
                //_token = Authenticate(_BaseUri);
45 2b1f30fe taeseongkim
46 2007ecaa taeseongkim
                System.IO.Directory.CreateDirectory(_localStorage);
47
48
                //backgroundWorker.RunWorkerAsync(new int[] { 1, 10 });
49
            }
50
            catch (Exception ex)
51
            {
52
                throw new Exception("PageStorage", ex);
53
            }
54
        }
55
56
        private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
57
        {
58
            System.Diagnostics.Debug.WriteLine(_fileExt + ":" + e.ProgressPercentage.ToString() + "%");
59
        }
60
61
        private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
62
        {
63
             DownloadWork();
64
        }
65
66
        private void DownloadWork()
67
        { 
68
            while (WorkItems.Count > 0)
69
            {
70
                if (!IsDownload)
71
                {
72
                    int item = -1;
73
                    try
74
                    {
75
76
                        if (WorkItems.TryFrist(true, out item))
77
                        {
78
                            var result = DownloadPageAsync(item, null);
79
                        }
80
                    }
81
                    catch (Exception ex)
82
                    {
83
                        System.Diagnostics.Debug.WriteLine(ex.ToString());
84
                    }
85
                }
86
87 1edefbdf taeseongkim
                System.Threading.Thread.Sleep(100);
88 2007ecaa taeseongkim
89
            }
90
91
            IsWork = false;
92
        }
93
94
        public async void DownloadWorkAsync(int startPage, int TakeCount)
95
        {
96
            if (0 < _TakeCount && startPage < _TotalPages)
97
            {
98
                int takecount = _TakeCount;
99
100
                if (_TotalPages < startPage + takecount)
101
                {
102
                    takecount = _TotalPages - startPage;
103
                    _TakeCount = 0;
104
                }
105
106
                WorkItems.AddRange(Enumerable.Range(startPage, TakeCount - 1));
107
            }
108
109
            if (!IsWork && WorkItems.Count() > 0)
110
            {
111
                IsWork = true;
112
                await Task.Run(() => DownloadWork());
113
            }
114
            //if (!backgroundWorker.IsBusy && WorkItems.Count() > 0)
115
            //{
116
            //    backgroundWorker.RunWorkerAsync();
117
            //}
118
        }
119
120
        public  void DownloadWork(int startPage, int TakeCount)
121
        {
122 664ea2e1 taeseongkim
            if (0 < _TakeCount && startPage <= _TotalPages)
123 2007ecaa taeseongkim
            {
124
                WorkItems.AddRange(Enumerable.Range(startPage, _TotalPages));
125
            }
126
127
            if (!IsWork && WorkItems.Count() > 0)
128
            {
129
                IsWork = true;
130
                DownloadWork();
131
            }
132
        }
133
134
        public async Task<Uri> GetPageUriAsync(System.Threading.CancellationToken? cts, int PageNo, bool IsRestart = false)
135
        {
136
            IsDownload = true;
137
138
            Uri result = null;
139
140
            try
141
            {
142
                System.Diagnostics.Debug.WriteLine("GetPageAsync");
143
144
                var pageItem = await DownloadPageAsync(PageNo, cts);
145
146
                // 다음 페이지가 미리 다운로드 되도록 추가
147
                if (pageItem != null && 0 < _TakeCount && PageNo + 1 < _TotalPages)
148
                {
149
                    int takecount = _TakeCount;
150
151
                    if (_TotalPages < PageNo + 1 + takecount)
152
                    {
153
                        takecount = _TotalPages - PageNo + 1;
154
                    }
155
156
                    DownloadWorkAsync(PageNo + 1, takecount);
157
                    //var takePageNoList = Enumerable.Range(PageNo + 1, _TakeCount);
158
                }
159
160
                result = pageItem.LocalUri;
161
            }
162
            catch (Exception ex)
163
            {
164
                if (cts != null)
165
                {
166
                    if (cts.Value.IsCancellationRequested)
167
                    {
168
                        return result;
169
                    }
170
                }
171
172
                if (!IsRestart)
173
                {
174
                    await Task.Delay(100);
175
176
                    result = await GetPageUriAsync(cts, PageNo, true);
177
                }
178
                //throw new Exception("GetPageAsync(string BasePageUri,int PageNo)", ex);
179
            }
180
            finally
181
            {
182
                IsDownload = false;
183
            }
184
185
            return result;
186
        }
187
188 2b1f30fe taeseongkim
        public string Authenticate(string baseUri)
189
        {
190
            string result = null;
191
192
            try
193
            {
194
                Uri uri = new Uri(baseUri);
195
                string baseUrl = uri.Scheme + "://" + uri.Host + (uri.IsDefaultPort ? "" : ":" + uri.Port);
196
197
                using (System.Net.WebClient client = new System.Net.WebClient())
198
                {
199
                    client.Headers.Add(HttpRequestHeader.Authorization, "!dsfadsfa@@~");
200
                    var response = client.DownloadString(baseUrl + "/Authenticate");
201
202
                    if (response != null)
203
                    {
204
                        result = response;
205
                    }
206
                }
207
            }
208
            catch (Exception)
209
            {
210
211
                throw;
212
            }
213
214
            return result;
215
        }
216
217 2007ecaa taeseongkim
        public async Task<PageItem> DownloadPageAsync(int PageNo, System.Threading.CancellationToken? cts)
218
        {
219
            IsDownload = true;
220
            PageItem result = new PageItem { PageNo = PageNo };
221
222
            try
223
            {
224
                var page = fileItems.Where(x => x.PageNo == PageNo).ToList();
225
226
                if (page.Count > 0)
227
                {
228
                    System.Diagnostics.Debug.WriteLine("DownloadPageAsync fileItems");
229
230
                    result = page.First();
231
232
                    /// 파일 체크 후 없으면 다시 다운로드
233
                    if (!System.IO.File.Exists(result.LocalFilePath))
234
                    {
235
                        //fileItems.(result);
236
237
                        result = await DownloadPageAsync(PageNo, cts);
238
                    }
239
                }
240
                else
241
                {
242
243
                    System.Diagnostics.Debug.WriteLine("DownloadPageAsync down");
244
245
                    string downloadFilePath = System.IO.Path.Combine(_localStorage, PageNo.ToString() + "." + _fileExt);
246
247
                    Uri originalUri = new Uri(_BaseUri.Replace("{PageNo}", PageNo.ToString()));
248
249
                    result = new PageItem
250
                    {
251
                        PageNo = PageNo,
252
                        OriginalUri = originalUri,
253
                        LocalUri = new Uri(downloadFilePath, UriKind.Absolute),
254
                        LocalFilePath = downloadFilePath
255
                    };
256
257
                    if (fileItems.Where(x => x.PageNo == PageNo).Count() == 0)
258
                    {
259
                        fileItems.Add(result);
260
                    }
261
262
                    using (System.Net.WebClient client = new System.Net.WebClient())
263
                    {
264 66bd3240 taeseongkim
                        //client.Headers.Add(HttpRequestHeader.Authorization, _token);
265 2007ecaa taeseongkim
                        client.UseDefaultCredentials = true;
266 77cdac33 taeseongkim
                        //client.Headers.Add("user-agent", "Your User-Agent");
267 2007ecaa taeseongkim
                        System.Net.IWebProxy webProxy = client.Proxy;
268
269
                        if (webProxy != null)
270
                        {
271
                            // Use the default credentials of the logged on user.
272
                            webProxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
273
                        }
274
275
                        if (cts != null)
276
                        {
277
                            client.DownloadProgressChanged += (snd, ect) =>
278
                            {
279
                                IsDownload = client.IsBusy;
280
281
                                if (cts.Value.IsCancellationRequested)
282
                                {
283
                                    client.CancelAsync();
284
                                }
285
                            };
286
                        }
287
288
                        client.DownloadFileCompleted += (snd, evt) =>
289
                        {
290
                            result.IsDownLoad = true;
291
292 6a19b48d taeseongkim
                            bool isLast = false;
293
                            
294
                            if(result.PageNo == _TotalPages)
295
                            {
296
                                isLast = true;
297
                            }
298
299
                            PageLoadCompleted?.Invoke(this, new PageLoadCompletedEventArgs(result, isLast));
300 2007ecaa taeseongkim
                            System.Diagnostics.Debug.WriteLine("Download : " + downloadFilePath);
301
                        };
302
303
                        await client.DownloadFileTaskAsync(originalUri, downloadFilePath);
304
305
                    }
306
307
                    //}
308
                    //System.Diagnostics.Debug.WriteLine("Download : " + result.LocalFilePath);
309
                }
310
            }
311
            catch (Exception ex)
312
            {
313
                throw new Exception("DownloadPageAsync : ", ex);
314
            }
315
            finally
316
            {
317
                IsDownload = false;
318
            }
319
320
            return result;
321
        }
322
323
        public void Clear()
324
        {
325
            try
326
            {
327
                backgroundWorker.CancelAsync();
328
                backgroundWorker.Dispose();
329
330
                foreach (var item in fileItems)
331
                {
332
                    System.IO.File.Delete(item.LocalFilePath);
333
                }
334
335
                System.IO.Directory.Delete(_localStorage, true);
336
            }
337
            catch (Exception ex)
338
            {
339
                System.Diagnostics.Debug.WriteLine(ex.ToString());
340
            }
341
        }
342
    }
343
}
클립보드 이미지 추가 (최대 크기: 500 MB)