1 package com.foxinmy.weixin4j.qy.api;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.StringWriter;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.Date;
10 import java.util.LinkedHashMap;
11 import java.util.List;
12 import java.util.Map;
13
14 import com.alibaba.fastjson.JSON;
15 import com.alibaba.fastjson.JSONArray;
16 import com.alibaba.fastjson.JSONObject;
17 import com.alibaba.fastjson.serializer.PropertyFilter;
18 import com.foxinmy.weixin4j.exception.WeixinException;
19 import com.foxinmy.weixin4j.http.ContentType;
20 import com.foxinmy.weixin4j.http.HttpHeaders;
21 import com.foxinmy.weixin4j.http.HttpMethod;
22 import com.foxinmy.weixin4j.http.HttpRequest;
23 import com.foxinmy.weixin4j.http.HttpResponse;
24 import com.foxinmy.weixin4j.http.MimeType;
25 import com.foxinmy.weixin4j.http.apache.content.ByteArrayBody;
26 import com.foxinmy.weixin4j.http.apache.content.InputStreamBody;
27 import com.foxinmy.weixin4j.http.apache.mime.FormBodyPart;
28 import com.foxinmy.weixin4j.http.weixin.ApiResult;
29 import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
30 import com.foxinmy.weixin4j.model.Token;
31 import com.foxinmy.weixin4j.model.media.MediaCounter;
32 import com.foxinmy.weixin4j.model.media.MediaDownloadResult;
33 import com.foxinmy.weixin4j.model.media.MediaItem;
34 import com.foxinmy.weixin4j.model.media.MediaRecord;
35 import com.foxinmy.weixin4j.model.media.MediaUploadResult;
36 import com.foxinmy.weixin4j.model.paging.Pageable;
37 import com.foxinmy.weixin4j.qy.model.Callback;
38 import com.foxinmy.weixin4j.qy.model.Party;
39 import com.foxinmy.weixin4j.qy.model.User;
40 import com.foxinmy.weixin4j.token.TokenManager;
41 import com.foxinmy.weixin4j.tuple.MpArticle;
42 import com.foxinmy.weixin4j.type.MediaType;
43 import com.foxinmy.weixin4j.util.Consts;
44 import com.foxinmy.weixin4j.util.FileUtil;
45 import com.foxinmy.weixin4j.util.IOUtil;
46 import com.foxinmy.weixin4j.util.ObjectId;
47 import com.foxinmy.weixin4j.util.RegexUtil;
48 import com.foxinmy.weixin4j.util.StringUtil;
49
50
51
52
53
54
55
56
57
58
59 public class MediaApi extends QyApi {
60
61 private final TokenManager tokenManager;
62
63 public MediaApi(TokenManager tokenManager) {
64 this.tokenManager = tokenManager;
65 }
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public String uploadImage(InputStream is, String fileName)
81 throws WeixinException {
82 if (StringUtil.isBlank(fileName)) {
83 fileName = ObjectId.get().toHexString();
84 }
85 if (StringUtil.isBlank(FileUtil.getFileExtension(fileName))) {
86 fileName = String.format("%s.jpg", fileName);
87 }
88 String media_uploadimg_uri = getRequestUri("media_uploadimg_uri");
89 MimeType mimeType = new MimeType("image",
90 FileUtil.getFileExtension(fileName));
91 Token token = tokenManager.getCache();
92 WeixinResponse response = weixinExecutor.post(
93 String.format(media_uploadimg_uri, token.getAccessToken()),
94 new FormBodyPart("media", new InputStreamBody(is, mimeType
95 .toString(), fileName)));
96 return response.getAsJson().getString("url");
97 }
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 public MediaUploadResult uploadMedia(int agentid, InputStream is,
120 String fileName) throws WeixinException {
121 byte[] content;
122 try {
123 content = IOUtil.toByteArray(is);
124 } catch (IOException e) {
125 throw new WeixinException(e);
126 }
127 if (StringUtil.isBlank(fileName)) {
128 fileName = ObjectId.get().toHexString();
129 }
130 String suffixName = FileUtil.getFileExtension(fileName);
131 if (StringUtil.isBlank(suffixName)) {
132 suffixName = FileUtil
133 .getFileType(new ByteArrayInputStream(content));
134 fileName = String.format("%s.%s", fileName, suffixName);
135 }
136 MediaType mediaType = MediaType.file;
137 if (",bmp,png,jpeg,jpg,gif,"
138 .contains(String.format(",%s,", suffixName))) {
139 mediaType = MediaType.image;
140 } else if (",mp3,wma,wav,amr,".contains(String.format(",%s,",
141 suffixName))) {
142 mediaType = MediaType.voice;
143 } else if (",rm,rmvb,wmv,avi,mpg,mpeg,mp4,".contains(String.format(
144 ",%s,", suffixName))) {
145 mediaType = MediaType.video;
146 }
147 Token token = tokenManager.getCache();
148 try {
149 WeixinResponse response = null;
150 if (agentid > 0) {
151 String material_media_upload_uri = getRequestUri("material_media_upload_uri");
152 response = weixinExecutor.post(String.format(
153 material_media_upload_uri, token.getAccessToken(),
154 mediaType.name(), agentid), new FormBodyPart("media",
155 new ByteArrayBody(content, mediaType.getMimeType()
156 .toString(), fileName)));
157 JSONObject obj = response.getAsJson();
158 return new MediaUploadResult(obj.getString("media_id"),
159 mediaType, new Date(), obj.getString("url"));
160 } else {
161 String media_upload_uri = getRequestUri("media_upload_uri");
162 response = weixinExecutor.post(String.format(media_upload_uri,
163 token.getAccessToken(), mediaType.name()),
164 new FormBodyPart("media", new ByteArrayBody(content,
165 mediaType.getMimeType().toString(), fileName)));
166 JSONObject obj = response.getAsJson();
167 return new MediaUploadResult(obj.getString("media_id"),
168 obj.getObject("type", MediaType.class), new Date(
169 obj.getLong("created_at") * 1000l),
170 obj.getString("url"));
171 }
172 } finally {
173 if (is != null) {
174 try {
175 is.close();
176 } catch (IOException e) {
177 ;
178 }
179 }
180 }
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197 public MediaDownloadResult downloadMedia(int agentid, String mediaId)
198 throws WeixinException {
199 Token token = tokenManager.getCache();
200 HttpRequest request = null;
201 if (agentid > 0) {
202 String material_media_download_uri = getRequestUri("material_media_download_uri");
203 request = new HttpRequest(HttpMethod.GET, String.format(
204 material_media_download_uri, token.getAccessToken(),
205 mediaId, agentid));
206 } else {
207 String media_download_uri = getRequestUri("media_download_uri");
208 request = new HttpRequest(HttpMethod.GET, String.format(
209 media_download_uri, token.getAccessToken(), mediaId));
210 }
211 HttpResponse response = weixinExecutor.doRequest(request);
212 HttpHeaders headers = response.getHeaders();
213 String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
214 String disposition = headers.getFirst(HttpHeaders.CONTENT_DISPOSITION);
215 String fileName = RegexUtil
216 .regexFileNameFromContentDispositionHeader(disposition);
217 if (StringUtil.isBlank(fileName)) {
218 fileName = String.format("%s.%s", mediaId,
219 contentType.split("/")[1]);
220 }
221 return new MediaDownloadResult(response.getContent(),
222 ContentType.create(contentType), fileName);
223 }
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242 public String uploadMaterialArticle(int agentid, List<MpArticle> articles)
243 throws WeixinException {
244 Token token = tokenManager.getCache();
245 String material_article_upload_uri = getRequestUri("material_article_upload_uri");
246 JSONObject obj = new JSONObject();
247 obj.put("agentid", agentid);
248 JSONObject news = new JSONObject();
249 news.put("articles", articles);
250 obj.put("mpnews", news);
251 WeixinResponse response = weixinExecutor.post(
252 String.format(material_article_upload_uri,
253 token.getAccessToken()), obj.toJSONString());
254
255 return response.getAsJson().getString("media_id");
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270 public ApiResult deleteMaterialMedia(int agentid, String mediaId)
271 throws WeixinException {
272 Token token = tokenManager.getCache();
273 String material_media_del_uri = getRequestUri("material_media_del_uri");
274 WeixinResponse response = weixinExecutor.get(String.format(
275 material_media_del_uri, token.getAccessToken(), mediaId,
276 agentid));
277 return response.getAsResult();
278 }
279
280
281
282
283
284
285
286
287
288
289
290
291
292 public List<MpArticle> downloadArticle(int agentid, String mediaId)
293 throws WeixinException {
294 MediaDownloadResult result = downloadMedia(agentid, mediaId);
295 byte[] content = result.getContent();
296 JSONObject obj = JSON.parseObject(content, 0, content.length,
297 Consts.UTF_8.newDecoder(), JSONObject.class);
298 return JSON.parseArray(obj.getJSONObject("mpnews")
299 .getString("articles"), MpArticle.class);
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317 public String updateMaterialArticle(int agentid, String mediaId,
318 List<MpArticle> articles) throws WeixinException {
319 Token token = tokenManager.getCache();
320 String material_article_update_uri = getRequestUri("material_article_update_uri");
321 JSONObject obj = new JSONObject();
322 obj.put("agentid", agentid);
323 JSONObject news = new JSONObject();
324 news.put("articles", articles);
325 obj.put("mpnews", news);
326 obj.put("media_id", mediaId);
327 WeixinResponse response = weixinExecutor.post(
328 String.format(material_article_update_uri,
329 token.getAccessToken()), obj.toJSONString());
330
331 return response.getAsJson().getString("media_id");
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345 public MediaCounter countMaterialMedia(int agentid) throws WeixinException {
346 Token token = tokenManager.getCache();
347 String material_media_count_uri = getRequestUri("material_media_count_uri");
348 WeixinResponse response = weixinExecutor.get(String.format(
349 material_media_count_uri, token.getAccessToken(), agentid));
350 JSONObject result = response.getAsJson();
351 MediaCounter counter = JSON.toJavaObject(result, MediaCounter.class);
352 counter.setNewsCount(result.getIntValue("mpnews_count"));
353 return counter;
354 }
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375 public MediaRecord listMaterialMedia(int agentid, MediaType mediaType,
376 Pageable pageable) throws WeixinException {
377 Token token = tokenManager.getCache();
378 String material_media_list_uri = getRequestUri("material_media_list_uri");
379 JSONObject obj = new JSONObject();
380 obj.put("agentid", agentid);
381 obj.put("type",
382 mediaType == MediaType.news ? "mpnews" : mediaType.name());
383 obj.put("offset", pageable.getOffset());
384 obj.put("count", pageable.getPageSize());
385 WeixinResponse response = weixinExecutor.post(
386 String.format(material_media_list_uri, token.getAccessToken()),
387 obj.toJSONString());
388 obj = response.getAsJson();
389
390 obj.put("items", obj.remove("itemlist"));
391 MediaRecord mediaRecord = JSON.toJavaObject(obj, MediaRecord.class);
392 mediaRecord.setMediaType(mediaType);
393 mediaRecord.setPageable(pageable);
394 return mediaRecord;
395 }
396
397
398
399
400
401
402
403
404
405
406
407
408 public List<MediaItem> listAllMaterialMedia(int agentid, MediaType mediaType)
409 throws WeixinException {
410 Pageable pageable = new Pageable(1, 20);
411 List<MediaItem> mediaList = new ArrayList<MediaItem>();
412 MediaRecord mediaRecord = null;
413 for (;;) {
414 mediaRecord = listMaterialMedia(agentid, mediaType, pageable);
415 if (mediaRecord.getItems() == null
416 || mediaRecord.getItems().isEmpty()) {
417 break;
418 }
419 mediaList.addAll(mediaRecord.getItems());
420 if (!mediaRecord.getPagedata().hasNext()) {
421 break;
422 }
423 pageable = pageable.next();
424 }
425 return mediaList;
426 }
427
428
429
430
431
432
433
434
435
436
437
438
439 public String batchUploadUsers(List<User> users) throws WeixinException {
440 return batchUpload("batch_syncuser.cvs", users);
441 }
442
443
444
445
446
447
448
449
450
451
452
453 public String batchUploadParties(List<Party> parties)
454 throws WeixinException {
455 return batchUpload("batch_replaceparty.cvs", parties);
456 }
457
458 private <T> String batchUpload(String batchName, List<T> models)
459 throws WeixinException {
460 StringWriter writer = new StringWriter();
461 try {
462 JSONObject csvObj = JSON.parseObject(weixinBundle().getString(
463 batchName));
464 JSONArray columns = csvObj.getJSONArray("column");
465 writer.write(csvObj.getString("header"));
466 final Map<String, Object> column = new LinkedHashMap<String, Object>();
467 for (Object col : columns) {
468 column.put(col.toString(), "");
469 }
470 writer.write("\r\n");
471 for (T model : models) {
472 JSON.toJSONString(model, new PropertyFilter() {
473 @Override
474 public boolean apply(Object object, String name,
475 Object value) {
476 if (column.containsKey(name)) {
477 if (value instanceof Collection) {
478 column.put(name,
479 StringUtil.join(((Collection<?>) value)
480 .iterator(), ';'));
481 } else {
482 column.put(name, value);
483 }
484 }
485 return true;
486 }
487 });
488 writer.write(StringUtil.join(column.values(), ','));
489 writer.write("\r\n");
490 }
491 return uploadMedia(
492 0,
493 new ByteArrayInputStream(writer.getBuffer().toString()
494 .getBytes(Consts.UTF_8)), batchName).getMediaId();
495 } finally {
496 try {
497 writer.close();
498 } catch (IOException e) {
499 ;
500 }
501 }
502 }
503 }