OSDN Git Service

5088c9ab3bf80a462f5b88371f2d40b01b440eea
[delesterandomselector/DelesteRandomSelector.git] / src / com / ranfa / lib / songinfo / FetchFromAPI.java
1 package com.ranfa.lib.songinfo;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.Collections;
7 import java.util.HashMap;
8 import java.util.LinkedHashMap;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.concurrent.CompletableFuture;
12 import java.util.concurrent.ExecutorService;
13 import java.util.concurrent.Executors;
14 import java.util.concurrent.TimeUnit;
15
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 import com.fasterxml.jackson.core.type.TypeReference;
20 import com.fasterxml.jackson.databind.JsonNode;
21 import com.fasterxml.jackson.databind.ObjectMapper;
22 import com.ranfa.lib.concurrent.CountedThreadFactory;
23
24 import HajimeAPI4J.api.HajimeAPI4J.List_Params;
25 import HajimeAPI4J.api.HajimeAPI4J.List_Type;
26 import HajimeAPI4J.api.HajimeAPI4J.Music_Params;
27 import HajimeAPI4J.api.HajimeAPI4J.Token;
28 import HajimeAPI4J.api.HajimeAPIBuilder;
29 import HajimeAPI4J.api.util.HajimeAPI4JImpl;
30 import HajimeAPI4J.api.util.datatype.Member;
31
32 public class FetchFromAPI {
33         
34         private Logger logger = LoggerFactory.getLogger(FetchFromAPI.class);
35         
36         
37         private ExecutorService apiExecutor = Executors.newCachedThreadPool(new CountedThreadFactory(() -> "DRS", "HajimeAPIInquerier"));
38         private List<JsonNode> nodes;
39         
40         // constructor
41         
42         public FetchFromAPI(String... songnames) {
43                 List<CompletableFuture<JsonNode>> listFutures = new ArrayList<>();
44                 for(String songname : Arrays.asList(songnames)) {
45                         Map<String, Object> data = fetchList(songname);
46                         if(data.getOrDefault("error", "false").equals("true")) {
47                                 JsonNode errorNode = new ObjectMapper().valueToTree(data);
48                                 CompletableFuture<JsonNode> error = CompletableFuture.supplyAsync(() -> errorNode, apiExecutor);
49                                 listFutures.add(error);
50                                 continue;
51                         }
52                         int taxId = Integer.parseInt(data.get("song_id").toString());
53                         HajimeAPI4JImpl impl = HajimeAPIBuilder.createDefault(Token.MUSIC)
54                                         .addParameter(Music_Params.ID   , String.valueOf(taxId))
55                                         .build();
56                         logger.info("fetch data : {}", taxId);
57                         listFutures.add(impl.getAsync(apiExecutor));
58                 }
59                 CompletableFuture.allOf(listFutures.toArray(new CompletableFuture[listFutures.size()])).join();
60                 nodes = new ArrayList<>();
61                 listFutures.stream().forEach(cf -> {
62                         nodes.add(cf.join());
63                 });
64         }
65         
66         private Map<String, Object> fetchList(String songname) {
67                 HajimeAPI4JImpl api = HajimeAPIBuilder.createDefault(Token.LIST)
68                                 .addParameter(List_Params.TYPE, List_Type.MUSIC.toString())
69                                 .addParameter(List_Params.SEARCH, songname)
70                                 .build();
71                 List<Map<String, Object>> parse = Collections.emptyList();
72                 try {
73                         parse = new ObjectMapper().readValue( api.getAsync(apiExecutor).join().traverse(), new TypeReference<List<Map<String, Object>>>() {});
74                         TimeUnit.SECONDS.sleep(1);
75                 } catch (IOException | InterruptedException e) {
76                         logger.error("Exception while processing json map");
77                 }
78                 for(Map<String, Object> tmp : parse ) {
79                         if(tmp.get("name").toString().equals(songname))
80                                 return tmp;
81                 }
82                 HashMap<String, Object> altRes = new HashMap<>();
83                 altRes.put("error", "true");
84                 return altRes;
85         }
86         
87         public List<Map<String, String>> getInformation() {
88                 List<Map<String, String>> resultList = new ArrayList<>();
89                 int nodeSize = nodes.size();
90                 try {
91                         for(JsonNode node : nodes) {
92                                 LinkedHashMap<String, String> result = new LinkedHashMap<>();
93                                 result.put("songname", node.get("name").asText());
94                                 result.put("link", node.get("link").asText());
95                                 String lyric = "",
96                                                 composer = "",
97                                                 arrange = "";
98                                 TypeReference<List<Map<String, Object>>> typeRef = new TypeReference<List<Map<String,Object>>>() {};
99                                 ObjectMapper mapper = new ObjectMapper();
100                                 List<Map<String, Object>> lyricList = mapper.readValue(node.get("lyrics").traverse(), typeRef),
101                                                 composerList = mapper.readValue(node.get("composer").traverse(), typeRef),
102                                                 arrangeList = mapper.readValue(node.get("arrange").traverse(), typeRef);
103                                 lyric = CompletableFuture.supplyAsync(() -> getArrayedNames(lyricList), apiExecutor).join();
104                                 composer = CompletableFuture.supplyAsync(() -> getArrayedNames(composerList), apiExecutor).join();
105                                 arrange = CompletableFuture.supplyAsync(() -> getArrayedNames(arrangeList), apiExecutor).join();
106                                 result.put("lyric", lyric);
107                                 result.put("composer", composer);
108                                 result.put("arrange", arrange);
109                                 StringBuilder memberBuilder = new StringBuilder();
110                                 for(Member tmpMember : mapper.readValue(node.get("member").traverse(), new TypeReference<List<Member>>() {})) {
111                                         memberBuilder.append(tmpMember.getName()).append(",");
112                                 }
113                                 memberBuilder.deleteCharAt(memberBuilder.length() - 1);
114                                 result.put("member", memberBuilder.toString());
115                                 logger.info("data fetch complete. : {}", result);
116                                 resultList.add(result);
117                         }
118                 } catch(IOException e) {
119                         logger.warn("Exception while processing json", e);
120                         String errorStr = "No data";
121                         for(int i = 0; i < nodeSize; i++) {
122                                 Map<String, String> tmp = new HashMap<>();
123                                 JsonNode tmpNode = nodes.get(i);
124                                 tmp.put("songname", tmpNode.get("name").asText());
125                                 tmp.put("link", tmpNode.get("link").asText());
126                                 tmp.put("lyric", errorStr);
127                                 tmp.put("composer", errorStr);
128                                 tmp.put("arrange", errorStr);
129                                 tmp.put("member", errorStr);
130                                 resultList.add(tmp);
131                         }
132                 }
133                 
134                 return resultList;
135         }
136         
137         
138         private String getArrayedNames(List<Map<String, Object>> data) {
139                 if(data == null) {
140                         return "No Data";
141                 }
142                 StringBuilder builder = new StringBuilder();
143                 for(Map<String, Object> tmp : data) {
144                         builder.append(tmp.get("name").toString()).append(",");
145                 }
146                 builder.deleteCharAt(builder.length() - 1);
147                 return builder.toString();
148         }
149
150 }