Add support for lwn.net (WIP)
[gofetch.git] / src / be / nikiroo / gofetch / support / LWN.java
CommitLineData
eaaeae39
NR
1package be.nikiroo.gofetch.support;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.net.URL;
6import java.util.ArrayList;
7import java.util.List;
8
9import org.jsoup.helper.DataUtil;
10import org.jsoup.nodes.Document;
11import org.jsoup.nodes.Element;
12import org.jsoup.select.Elements;
13
14import be.nikiroo.gofetch.data.Comment;
15import be.nikiroo.gofetch.data.Story;
16
17/**
18 * Support <a href='https://lwn.net/'>https://lwn.net/</a>.
19 *
20 * @author niki
21 */
22public class LWN extends BasicSupport {
23 @Override
24 public String getDescription() {
25 return "LWN: Linux Weekly Newsletter";
26 }
27
28 @Override
29 public List<Story> list() throws IOException {
30 // TODO: comments + do not get comment for [$] stories
31 // + update body on getComment (global change, also LinuxToday)
32
33 List<Story> list = new ArrayList<Story>();
34
35 URL url = new URL("https://lwn.net/");
36 InputStream in = open(url);
37 Document doc = DataUtil.load(in, "UTF-8", url.toString());
38 Elements stories = doc.getElementsByClass("pure-u-1");
39 for (Element story : stories) {
40 Elements titles = story.getElementsByClass("Headline");
41 Elements listings = story.getElementsByClass("BlurbListing");
42 if (titles.size() == 0) {
43 continue;
44 }
45 if (listings.size() == 0) {
46 continue;
47 }
48
49 Element listing = listings.get(0);
50 if (listing.children().size() < 2) {
51 continue;
52 }
53
54
55 String title = titles.get(0).text();
56 String details = listing.children().get(0).text();
57 String body = listing.children().get(1).text();
58
59 String author = "";
60 int pos = details.indexOf(" by ");
61 if (pos >= 0) {
62 author = details.substring(pos + " by ".length()).trim();
63 }
64
65 String date = "";
66 pos = details.indexOf(" Posted ");
67 if (pos >= 0) {
68 date = details.substring(pos + " Posted ".length()).trim();
69 }
70
71
72 String id = "";
73 String intUrl = "";
74 String extUrl = "";
75 for (Element idElem : story.getElementsByTag("a")) {
76 // Last link is the story link
77 intUrl = idElem.absUrl("href");
78 pos = intUrl.indexOf("#Comments");
79 if (pos >= 0) {
80 intUrl = intUrl.substring(0, pos -1);
81 }
82 id = intUrl.replaceAll("[^0-9]", "");
83 }
84
85 list.add(new Story(getType(), id, title, details, intUrl, extUrl, body));
86 }
87
88 return list;
89 }
90
91 @Override
92 public List<Comment> getComments(Story story) throws IOException {
93 List<Comment> comments = new ArrayList<Comment>();
94
95 /*
96 URL url = new URL(story.getUrlInternal());
97 InputStream in = open(url);
98 Document doc = DataUtil.load(in, "UTF-8", url.toString());
99 Elements listing = doc.getElementsByTag("main");
100 if (listing.size() > 0) {
101 comments.addAll(getComments(listing.get(0)));
102 }
103 */
104
105 return comments;
106 }
107
108 private List<Comment> getComments(Element listing) {
109 List<Comment> comments = new ArrayList<Comment>();
110 for (Element commentElement : listing.children()) {
111 if (commentElement.hasClass("comment")) {
112 Comment comment = getComment(commentElement);
113 if (!comment.isEmpty()) {
114 comments.add(comment);
115 }
116 }
117 }
118 return comments;
119 }
120
121 private Comment getComment(Element commentElement) {
122 String title = firstOrEmptyTag(commentElement, "h3");
123 String author = firstOrEmpty(commentElement, "h4");
124 String content = firstOrEmpty(commentElement, "comment-body");
125
126 String date = "";
127 int pos = author.lastIndexOf(" on ");
128 if (pos >= 0) {
129 date = author.substring(pos + " on ".length()).trim();
130 author = author.substring(0, pos).trim();
131 }
132
133 Comment comment = new Comment(commentElement.id(), author, title, date,
134 content);
135
136 Elements commentOutline = commentElement
137 .getElementsByClass("comment-outline");
138 if (commentOutline.size() > 0) {
139 comment.addAll(getComments(commentOutline.get(0)));
140 }
141
142 return comment;
143 }
144
145 /**
146 * Get the first element of the given class, or an empty {@link String} if
147 * none found.
148 *
149 * @param element
150 * the element to look in
151 * @param className
152 * the class to look for
153 *
154 * @return the value or an empty {@link String}
155 */
156 private String firstOrEmpty(Element element, String className) {
157 Elements subElements = element.getElementsByClass(className);
158 if (subElements.size() > 0) {
159 return subElements.get(0).text();
160 }
161
162 return "";
163 }
164
165 /**
166 * Get the first element of the given tag, or an empty {@link String} if
167 * none found.
168 *
169 * @param element
170 * the element to look in
171 * @param tagName
172 * the tag to look for
173 *
174 * @return the value or an empty {@link String}
175 */
176 private String firstOrEmptyTag(Element element, String tagName) {
177 Elements subElements = element.getElementsByTag(tagName);
178 if (subElements.size() > 0) {
179 return subElements.get(0).text();
180 }
181
182 return "";
183 }
184}