OSDN Git Service

e9d434d0c35fe01092de8286c2fe3d9206dc3479
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / threads / ENThumbnailRunner.java
1 /*
2  * This file is part of NeighborNote
3  * Copyright 2013 Yuki Takahashi
4  * 
5  * This file may be licensed under the terms of of the
6  * GNU General Public License Version 2 (the ``GPL'').
7  *
8  * Software distributed under the License is distributed
9  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
10  * express or implied. See the GPL for the specific language
11  * governing rights and limitations.
12  *
13  * You should have received a copy of the GPL along with this
14  * program. If not, go to http://www.gnu.org/licenses/gpl.html
15  * or write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18 */
19
20 package cx.fbn.nevernote.threads;
21
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25 import java.io.UnsupportedEncodingException;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.concurrent.LinkedBlockingQueue;
29
30 import org.apache.http.HttpResponse;
31 import org.apache.http.NameValuePair;
32 import org.apache.http.client.ClientProtocolException;
33 import org.apache.http.client.HttpClient;
34 import org.apache.http.client.entity.UrlEncodedFormEntity;
35 import org.apache.http.client.methods.HttpPost;
36 import org.apache.http.impl.client.DefaultHttpClient;
37 import org.apache.http.message.BasicNameValuePair;
38 import org.apache.http.util.EntityUtils;
39
40 import com.evernote.edam.type.User;
41 import com.trolltech.qt.core.QByteArray;
42 import com.trolltech.qt.core.QMutex;
43 import com.trolltech.qt.core.QObject;
44 import com.trolltech.qt.gui.QPixmap;
45
46 import cx.fbn.nevernote.Global;
47 import cx.fbn.nevernote.oauth.OAuthTokenizer;
48 import cx.fbn.nevernote.signals.ENThumbnailSignal;
49 import cx.fbn.nevernote.signals.LimitSignal;
50 import cx.fbn.nevernote.sql.DatabaseConnection;
51 import cx.fbn.nevernote.utilities.AESEncrypter;
52 import cx.fbn.nevernote.utilities.ApplicationLogger;
53
54 public class ENThumbnailRunner extends QObject implements Runnable{
55         
56         private final ApplicationLogger                                 logger;
57         private final DatabaseConnection                                conn;
58         public volatile ENThumbnailSignal                               enThumbnailSignal;
59         public QMutex                                                                   mutex;
60         private volatile boolean                                                keepRunning;
61         private volatile LinkedBlockingQueue<String>    workQueue;
62         public volatile LimitSignal                                     limitSignal;
63         private volatile User                                                   user;
64         private volatile String                                                 serverUrl;
65         
66         public ENThumbnailRunner(ApplicationLogger logger, DatabaseConnection conn) {
67                 this.logger = logger;
68                 this.conn = conn;
69                 this.enThumbnailSignal = new ENThumbnailSignal();
70                 this.mutex = new QMutex();
71                 this.keepRunning = true;
72                 this.workQueue = new LinkedBlockingQueue<String>();
73                 this.limitSignal = new LimitSignal();
74                 this.user = new User();
75                 this.serverUrl = "";
76         }
77
78         @Override
79         public void run() {
80                 thread().setPriority(Thread.MIN_PRIORITY);
81                 
82                 logger.log(logger.MEDIUM, "ENThumbnailスレッド開始");
83                 while (keepRunning) {
84                         try {
85                                 String work = workQueue.take();
86                                 mutex.lock();
87                                 if (work.startsWith("GET")) {
88                                         String guid = work.replace("GET ", "");
89                                         logger.log(logger.EXTREME, "Evernoteサムネイル取得開始 guid = " + guid);
90                                         
91                                         QByteArray thumbnailData = getENThumbnailData(guid);
92                                         if (thumbnailData == null) {                            // 取得に失敗
93                                                 logger.log(logger.EXTREME, "Evernoteサムネイルの取得に失敗");
94                                         } else {
95                                                 QPixmap thumbnail_p = new QPixmap();
96                                                 thumbnail_p.loadFromData(thumbnailData);
97                                                 logger.log(logger.EXTREME, "Evernoteサムネイルの取得に成功");
98                                                 saveImage(thumbnail_p, guid);
99                                                 registImage(thumbnailData, guid);
100                                         }
101                                         
102                                         enThumbnailSignal.getENThumbnailFinished.emit(guid);
103                                         logger.log(logger.EXTREME, "Evernoteサムネイル取得完了 guid = " + guid);
104                                 } else if (work.startsWith("STOP")) {
105                                         logger.log(logger.MEDIUM, "ENThumbnailスレッド停止");
106                                         keepRunning = false;
107                                 }
108                                 mutex.unlock();
109                         } catch (InterruptedException e) {
110                                 // TODO 自動生成された catch ブロック
111                                 e.printStackTrace();
112                         }
113                 }
114         }
115         
116         // Evernoteサーバからサムネイルを取得
117         private synchronized QByteArray getENThumbnailData(String guid) {
118                 // サムネイルをEvernoteサーバから取得
119                 String shardId = user.getShardId();
120                 if (shardId == null || shardId.equals("")) {
121                         return null;
122                 }
123                 
124                 OAuthTokenizer tokenizer = new OAuthTokenizer();
125         AESEncrypter aes = new AESEncrypter();
126         try {
127                         aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
128                 } catch (FileNotFoundException e) {
129                         e.printStackTrace();
130                 }
131                 String authString = aes.getString();
132                 String oauthToken = new String();
133                 if (!authString.equals("")) {
134                         tokenizer.tokenize(authString);
135                         oauthToken = tokenizer.oauth_token;
136                 }
137                 
138                 HttpClient httpClient = new DefaultHttpClient();
139
140                 HttpPost httpPost = new HttpPost("https://" + serverUrl + "/shard/" + user.getShardId() + "/thm/note/" + guid + ".png");
141                 httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
142                 httpPost.setHeader("Host", getServerUrl());
143
144                 List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
145                 nameValuePairs.add(new BasicNameValuePair("auth", oauthToken));
146                 nameValuePairs.add(new BasicNameValuePair("size", "80"));
147                 
148                 QByteArray data = new QByteArray();
149                 try {
150                         httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
151                         // Webサーバからのレスポンスを処理
152                         HttpResponse response = null;
153                         response = httpClient.execute(httpPost);
154                         byte[] bytes = EntityUtils.toByteArray(response.getEntity());
155                         data = new QByteArray(bytes);
156                 } catch (UnsupportedEncodingException e) {
157                         e.printStackTrace();
158                         return null;
159                 } catch (ClientProtocolException e) {
160                         e.printStackTrace();
161                         return null;
162                 } catch (IOException e) {
163                         e.printStackTrace();
164                         return null;
165                 } finally {
166                         httpClient.getConnectionManager().shutdown();
167                 }
168
169                 return data;
170         }
171         
172         // サムネイルをpng形式のファイルとしてresディレクトリに保存
173         private synchronized void saveImage(QPixmap thumbnail, String guid) {
174                 String thumbnailName = Global.getFileManager().getResDirPath("enThumbnail-" + guid + ".png");
175                 thumbnail.save(thumbnailName, "PNG");
176         }
177         
178         // サムネイルのバイナリデータをデータベースに登録
179         private synchronized void registImage(QByteArray data, String guid) {
180                 conn.getNoteTable().setENThumbnail(guid, data);
181         }
182
183         public boolean isKeepRunning() {
184                 return keepRunning;
185         }
186
187         public void setKeepRunning(boolean keepRunning) {
188                 this.keepRunning = keepRunning;
189         }
190         
191         public boolean addGuid(String guid) {
192                 if (workQueue.offer("GET " + guid)) {
193                         return true;
194                 }
195                 
196                 return false;
197         }
198         
199         public boolean addStop() {
200                 if (workQueue.offer("STOP")) {
201                         return true;
202                 }
203                 return false;
204         }
205
206         public User getUser() {
207                 return user;
208         }
209
210         public void setUser(User user) {
211                 this.user = user;
212         }
213
214         public String getServerUrl() {
215                 return serverUrl;
216         }
217
218         public void setServerUrl(String serverUrl) {
219                 this.serverUrl = serverUrl;
220         }
221 }