Commit | Line | Data |
---|---|---|
1fdc7577 NR |
1 | package be.nikiroo.utils; |
2 | ||
3 | import java.io.BufferedReader; | |
4 | import java.io.IOException; | |
5 | import java.io.InputStream; | |
6 | import java.io.InputStreamReader; | |
7 | import java.net.URL; | |
8 | import java.util.ArrayList; | |
9 | import java.util.HashMap; | |
10 | import java.util.List; | |
11 | import java.util.Locale; | |
12 | import java.util.Map; | |
13 | ||
14 | /** | |
15 | * Version checker: can check the current version of the program against a | |
16 | * remote changelog, and list the missed updates and their description. | |
17 | * | |
18 | * @author niki | |
19 | */ | |
20 | public class VersionCheck { | |
21 | private static final String base = "https://github.com/${PROJECT}/raw/master/changelog${LANG}.md"; | |
22 | private static Downloader downloader = new Downloader(null); | |
23 | ||
24 | private Version current; | |
25 | private List<Version> newer; | |
26 | private Map<Version, List<String>> changes; | |
27 | ||
28 | /** | |
29 | * Create a new {@link VersionCheck}. | |
30 | * | |
31 | * @param current | |
32 | * the current version of the program | |
33 | * @param newer | |
34 | * the list of available {@link Version}s newer the current one | |
35 | * @param changes | |
36 | * the list of changes | |
37 | */ | |
38 | private VersionCheck(Version current, List<Version> newer, | |
39 | Map<Version, List<String>> changes) { | |
40 | this.current = current; | |
41 | this.newer = newer; | |
42 | this.changes = changes; | |
43 | } | |
44 | ||
45 | /** | |
46 | * Check if there are more recent {@link Version}s of this program | |
47 | * available. | |
48 | * | |
49 | * @return TRUE if there is at least one | |
50 | */ | |
51 | public boolean isNewVersionAvailable() { | |
52 | return !newer.isEmpty(); | |
53 | } | |
54 | ||
55 | /** | |
56 | * The current {@link Version} of the program. | |
57 | * | |
58 | * @return the current {@link Version} | |
59 | */ | |
60 | public Version getCurrentVersion() { | |
61 | return current; | |
62 | } | |
63 | ||
64 | /** | |
65 | * The list of available {@link Version}s newer than the current one. | |
66 | * | |
67 | * @return the newer {@link Version}s | |
68 | */ | |
69 | public List<Version> getNewer() { | |
70 | return newer; | |
71 | } | |
72 | ||
73 | /** | |
74 | * The list of changes for each available {@link Version} newer than the | |
75 | * current one. | |
76 | * | |
77 | * @return the list of changes | |
78 | */ | |
79 | public Map<Version, List<String>> getChanges() { | |
80 | return changes; | |
81 | } | |
82 | ||
83 | /** | |
84 | * Check if there are available {@link Version}s of this program more recent | |
85 | * than the current one. | |
86 | * | |
87 | * @param githubProject | |
88 | * the GitHub project to check on, for instance "nikiroo/fanfix" | |
89 | * @param lang | |
90 | * the current locale, so we can try to get the changelog in the | |
91 | * correct language (can be NULL, will fetch the default | |
92 | * changelog) | |
93 | * | |
94 | * @return a {@link VersionCheck} | |
95 | * | |
96 | * @throws IOException | |
97 | * in case of I/O error | |
98 | */ | |
99 | public static VersionCheck check(String githubProject, Locale lang) | |
100 | throws IOException { | |
101 | Version current = Version.getCurrentVersion(); | |
102 | List<Version> newer = new ArrayList<Version>(); | |
103 | Map<Version, List<String>> changes = new HashMap<Version, List<String>>(); | |
104 | ||
105 | // Use the right project: | |
106 | String base = VersionCheck.base.replace("${PROJECT}", githubProject); | |
107 | ||
108 | // Prepare the URLs according to the user's language (we take here | |
109 | // "-fr_BE" as an example): | |
110 | String fr = lang == null ? "" : "-" + lang.getLanguage(); | |
111 | String BE = lang == null ? "" | |
112 | : "_" + lang.getCountry().replace(".UTF8", ""); | |
113 | String urlFrBE = base.replace("${LANG}", fr + BE); | |
114 | String urlFr = base.replace("${LANG}", "-" + fr); | |
115 | String urlDefault = base.replace("${LANG}", ""); | |
116 | ||
117 | InputStream in = null; | |
118 | for (String url : new String[] { urlFrBE, urlFr, urlDefault }) { | |
119 | try { | |
120 | in = downloader.open(new URL(url), false); | |
121 | break; | |
122 | } catch (IOException e) { | |
123 | } | |
124 | } | |
125 | ||
126 | if (in == null) { | |
127 | throw new IOException("No changelog found"); | |
128 | } | |
129 | ||
130 | BufferedReader reader = new BufferedReader( | |
131 | new InputStreamReader(in, "UTF-8")); | |
132 | try { | |
133 | Version version = new Version(); | |
134 | for (String line = reader.readLine(); line != null; line = reader | |
135 | .readLine()) { | |
136 | if (line.startsWith("## Version ")) { | |
137 | version = new Version( | |
138 | line.substring("## Version ".length())); | |
139 | if (version.isNewerThan(current)) { | |
140 | newer.add(version); | |
141 | changes.put(version, new ArrayList<String>()); | |
142 | } else { | |
143 | version = new Version(); | |
144 | } | |
145 | } else if (!version.isEmpty() && !newer.isEmpty() | |
146 | && !line.isEmpty()) { | |
147 | List<String> ch = changes.get(newer.get(newer.size() - 1)); | |
148 | if (!ch.isEmpty() && !line.startsWith("- ")) { | |
149 | int i = ch.size() - 1; | |
150 | ch.set(i, ch.get(i) + " " + line.trim()); | |
151 | } else { | |
152 | ch.add(line.substring("- ".length()).trim()); | |
153 | } | |
154 | } | |
155 | } | |
156 | } finally { | |
157 | reader.close(); | |
158 | } | |
159 | ||
160 | return new VersionCheck(current, newer, changes); | |
161 | } | |
162 | ||
163 | @Override | |
164 | public String toString() { | |
165 | return String.format( | |
166 | "Version checker: version [%s], %d releases behind latest version [%s]", // | |
167 | current, // | |
168 | newer.size(), // | |
169 | newer.isEmpty() ? current : newer.get(newer.size() - 1)// | |
170 | ); | |
171 | } | |
172 | } |