Merge branch 'subtree'
[fanfix.git] / src / be / nikiroo / fanfix / VersionCheck.java
1 package be.nikiroo.fanfix;
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 import be.nikiroo.utils.Version;
15
16 /**
17 * Version checker: can check the current version of the program against a
18 * remote changelog, and list the missed updates and their description.
19 *
20 * @author niki
21 */
22 public class VersionCheck {
23 private static final String base = "https://github.com/${PROJECT}/raw/master/changelog${LANG}.md";
24
25 private Version current;
26 private List<Version> newer;
27 private Map<Version, List<String>> changes;
28
29 /**
30 * Create a new {@link VersionCheck}.
31 *
32 * @param current
33 * the current version of the program
34 * @param newer
35 * the list of available {@link Version}s newer the current one
36 * @param changes
37 * the list of changes
38 */
39 private VersionCheck(Version current, List<Version> newer,
40 Map<Version, List<String>> changes) {
41 this.current = current;
42 this.newer = newer;
43 this.changes = changes;
44 }
45
46 /**
47 * Check if there are more recent {@link Version}s of this program
48 * available.
49 *
50 * @return TRUE if there is at least one
51 */
52 public boolean isNewVersionAvailable() {
53 return !newer.isEmpty();
54 }
55
56 /**
57 * The current {@link Version} of the program.
58 *
59 * @return the current {@link Version}
60 */
61 public Version getCurrentVersion() {
62 return current;
63 }
64
65 /**
66 * The list of available {@link Version}s newer than the current one.
67 *
68 * @return the newer {@link Version}s
69 */
70 public List<Version> getNewer() {
71 return newer;
72 }
73
74 /**
75 * The list of changes for each available {@link Version} newer than the
76 * current one.
77 *
78 * @return the list of changes
79 */
80 public Map<Version, List<String>> getChanges() {
81 return changes;
82 }
83
84 /**
85 * Ignore the check result.
86 */
87 public void ignore() {
88
89 }
90
91 /**
92 * Accept the information, and do not check again until the minimum wait
93 * time has elapsed.
94 */
95 public void ok() {
96 Instance.getInstance().setVersionChecked();
97 }
98
99 /**
100 * Check if there are available {@link Version}s of this program more recent
101 * than the current one.
102 *
103 * @param githubProject
104 * the GitHub project to check on, for instance "nikiroo/fanfix"
105 *
106 * @return a {@link VersionCheck}
107 */
108 public static VersionCheck check(String githubProject) {
109 Version current = Version.getCurrentVersion();
110 List<Version> newer = new ArrayList<Version>();
111 Map<Version, List<String>> changes = new HashMap<Version, List<String>>();
112
113 if (Instance.getInstance().isVersionCheckNeeded()) {
114 try {
115 // Use the right project:
116 String base = VersionCheck.base.replace("${PROJECT}",
117 githubProject);
118
119 // Prepare the URLs according to the user's language:
120 Locale lang = Instance.getInstance().getTrans().getLocale();
121 String fr = lang.getLanguage();
122 String BE = lang.getCountry().replace(".UTF8", "");
123 String urlFrBE = base.replace("${LANG}", "-" + fr + "_" + BE);
124 String urlFr = base.replace("${LANG}", "-" + fr);
125 String urlDefault = base.replace("${LANG}", "");
126
127 InputStream in = null;
128 for (String url : new String[] { urlFrBE, urlFr, urlDefault }) {
129 try {
130 in = Instance.getInstance().getCache().openNoCache(
131 new URL(url), null, null, null, null);
132 break;
133 } catch (IOException e) {
134 }
135 }
136
137 if (in == null) {
138 throw new IOException("No changelog found");
139 }
140
141 BufferedReader reader = new BufferedReader(
142 new InputStreamReader(in, "UTF-8"));
143 try {
144 Version version = new Version();
145 for (String line = reader.readLine(); line != null; line = reader
146 .readLine()) {
147 if (line.startsWith("## Version ")) {
148 version = new Version(line.substring("## Version "
149 .length()));
150 if (version.isNewerThan(current)) {
151 newer.add(version);
152 changes.put(version, new ArrayList<String>());
153 } else {
154 version = new Version();
155 }
156 } else if (!version.isEmpty() && !newer.isEmpty()
157 && !line.isEmpty()) {
158 List<String> ch = changes.get(newer.get(newer
159 .size() - 1));
160 if (!ch.isEmpty() && !line.startsWith("- ")) {
161 int i = ch.size() - 1;
162 ch.set(i, ch.get(i) + " " + line.trim());
163 } else {
164 ch.add(line.substring("- ".length()).trim());
165 }
166 }
167 }
168 } finally {
169 reader.close();
170 }
171 } catch (IOException e) {
172 Instance.getInstance().getTraceHandler()
173 .error(new IOException("Cannot download latest changelist on github.com", e));
174 }
175 }
176
177 return new VersionCheck(current, newer, changes);
178 }
179 }