Reddit: fix problem with new kind of html (wip)
[gofetch.git] / src / be / nikiroo / gofetch / Fetcher.java
index 725355c2a1c173deba5c54f85edf08967076d2cd..bb4cf4d31f32a7266550cb9c46672368dd7a905e 100644 (file)
@@ -4,7 +4,9 @@ import java.io.File;
 import java.io.FileWriter;
 import java.io.FilenameFilter;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 import be.nikiroo.gofetch.data.Story;
@@ -12,7 +14,7 @@ import be.nikiroo.gofetch.output.Gopher;
 import be.nikiroo.gofetch.output.Html;
 import be.nikiroo.gofetch.output.Output;
 import be.nikiroo.gofetch.support.BasicSupport;
-import be.nikiroo.gofetch.support.BasicSupport.Type;
+import be.nikiroo.gofetch.support.Type;
 import be.nikiroo.utils.IOUtils;
 
 /**
@@ -40,8 +42,8 @@ public class Fetcher {
         *            the sub directory and (pre-)selector to use for the resources
         *            (<b>will</b> have an impact on the files' content)
         * @param type
-        *            the type of news to get (or the special keyword ALL to get all
-        *            of the supported sources)
+        *            the type of news to get (or NULL to get all of the supported
+        *            sources)
         * @param maxStories
         *            the maximum number of stories to show on the resume page
         * @param hostname
@@ -79,45 +81,49 @@ public class Fetcher {
                        BasicSupport support = BasicSupport.getSupport(type);
 
                        if (type == this.type || this.type == null) {
-                               list(support);
+                               try {
+                                       list(support);
+                               } catch (Exception e) {
+                                       new Exception("Failed to process support: " + type, e)
+                                                       .printStackTrace();
+                               }
                        }
 
-                       gopherBuilder.append("1" + support.getDescription()).append("\t")
-                                       .append("1" + support.getSelector()) //
-                                       .append("\t").append(hostname) //
-                                       .append("\t").append(Integer.toString(port)) //
-                                       .append("\r\n");
+                       gopherBuilder.append(getLink(support.getDescription(),
+                                       support.getSelector(), true, false));
 
                        String ref = support.getSelector();
                        while (ref.startsWith("/")) {
                                ref = ref.substring(1);
                        }
-                       htmlBuilder.append("<div class='site'><a href='../" + ref + "'>"
-                                       + support.getDescription() + "</a></div>\n");
+                       ref = "../" + ref + "/index.html";
+
+                       htmlBuilder.append(getLink(support.getDescription(), ref, true,
+                                       true));
                }
 
                File gopherCache = new File(dir, preselector);
                gopherCache.mkdirs();
                File htmlIndex = new File(gopherCache, "index.html");
-               gopherCache = new File(gopherCache, ".cache");
+               gopherCache = new File(gopherCache, "gophermap");
 
                Output gopher = new Gopher(null, hostname, preselector, port);
                Output html = new Html(null, hostname, preselector, port);
 
                FileWriter writer = new FileWriter(gopherCache);
                try {
-                       writer.append(gopher.getIndexHeader());
+                       writer.append(gopher.getMainIndexHeader());
                        writer.append(gopherBuilder.toString());
-                       writer.append(gopher.getIndexFooter());
+                       writer.append(gopher.getMainIndexFooter());
                } finally {
                        writer.close();
                }
 
                try {
                        writer = new FileWriter(htmlIndex);
-                       writer.append(html.getIndexHeader());
+                       writer.append(html.getMainIndexHeader());
                        writer.append(htmlBuilder.toString());
-                       writer.append(html.getIndexFooter());
+                       writer.append(html.getMainIndexFooter());
                } finally {
                        writer.close();
                }
@@ -141,12 +147,21 @@ public class Fetcher {
 
                // Get comments (and update stories if needed):
                int i = 1;
+               List<Story> fetchedStories = new ArrayList<Story>(stories.size());
                for (Story story : stories) {
-                       System.err.println(String.format("%02d/%02d", i, stories.size())
+                       System.err.print(String.format("%02d/%02d", i, stories.size())
                                        + " Fetching full story " + story.getId() + "...");
-                       support.fetch(story);
+                       try {
+                               support.fetch(story);
+                               fetchedStories.add(story);
+                               System.err.println();
+                       } catch (IOException e) {
+e.printStackTrace();
+                               System.err.println(" Failed to get story!");
+                       }
                        i++;
                }
+               stories = fetchedStories;
 
                Output gopher = new Gopher(support.getType(), hostname, preselector,
                                port);
@@ -175,39 +190,108 @@ public class Fetcher {
                        }
                });
 
-               // Finding which ones to show:
-               int from = 0;
-               int to = 0;
-               if (headers.length > 0) {
-                       Arrays.sort(headers);
-                       from = headers.length - 1;
-                       to = headers.length - maxStories;
-                       if (to < 0) {
-                               to = 0;
+               // Reverse sort:
+               Arrays.sort(headers);
+               List<String> tmp = Arrays.asList(headers);
+               Collections.reverse(tmp);
+               headers = tmp.toArray(new String[] {});
+               //
+
+               // Write the main index (with "MORE" links if needed)
+               int page = 0;
+               List<String> gopherLines = new ArrayList<String>();
+               List<String> htmlLines = new ArrayList<String>();
+               gopherLines.add(gopher.getIndexHeader(support));
+               htmlLines.add(html.getIndexHeader(support));
+               for (i = 0; i < headers.length; i++) {
+                       File gopherFile = new File(varDir, headers[i]);
+                       File htmlFile = new File(varDir, headers[i] + ".html");
+
+                       if (gopherFile.exists())
+                               gopherLines.add(IOUtils.readSmallFile(gopherFile));
+                       if (htmlFile.exists())
+                               htmlLines.add(IOUtils.readSmallFile(htmlFile));
+
+                       boolean enoughStories = (i > 0 && i % maxStories == 0);
+                       boolean last = i == headers.length - 1;
+                       if (enoughStories || last) {
+                               if (!last) {
+                                       gopherLines.add(getLink("More", support.getSelector()
+                                                       + "gophermap_" + (page + 1), true, false));
+
+                                       htmlLines.add(getLink("More", "index_" + (page + 1)
+                                                       + ".html", true, true));
+                               }
+
+                               gopherLines.add(gopher.getIndexFooter(support));
+                               htmlLines.add(html.getIndexFooter(support));
+                               write(gopherLines, varDir, "gophermap", "", page);
+                               write(htmlLines, varDir, "index", ".html", page);
+                               gopherLines = new ArrayList<String>();
+                               htmlLines = new ArrayList<String>();
+                               page++;
                        }
                }
+       }
 
-               // Writing the cache/index files with the stories:
-               File gopherCache = new File(varDir, ".cache");
-               FileWriter writer = new FileWriter(gopherCache);
+       /**
+        * Write an index/gophermap file with the given link content for the
+        * selected supported web site.
+        * 
+        * @param lines
+        *            the link content (the stories and a short description)
+        * @param varDir
+        *            the base directory to write into
+        * @param basename
+        *            the base file name
+        * @param ext
+        *            the file extension (for instance, ".html")
+        * @param page
+        *            the page number (0 = main index)
+        * 
+        * @throws IOException
+        *             in case of I/O errors
+        */
+       private void write(List<String> lines, File varDir, String basename,
+                       String ext, int page) throws IOException {
+               File file = new File(varDir, basename + (page > 0 ? "_" + page : "")
+                               + ext);
+
+               FileWriter writer = new FileWriter(file);
                try {
-                       for (i = from; i >= to; i--) {
-                               writer.append(IOUtils
-                                               .readSmallFile(new File(varDir, headers[i])));
+                       for (String line : lines) {
+                               writer.append(line).append("\r\n");
                        }
                } finally {
                        writer.close();
                }
+       }
 
-               File htmlIndex = new File(varDir, "index.html");
-               writer = new FileWriter(htmlIndex);
-               try {
-                       for (i = from; i >= to; i--) {
-                               writer.append(IOUtils.readSmallFile(new File(varDir, headers[i]
-                                               + ".html")));
-                       }
-               } finally {
-                       writer.close();
+       /**
+        * Create a link.
+        * 
+        * @param name
+        *            the link name (what the user will see)
+        * @param ref
+        *            the actual link reference (the target)
+        * @param menu
+        *            menu (gophermap, i) mode -- not used in html mode
+        * @param html
+        *            TRUE for html mode, FALSE for gopher mode
+        * 
+        * @return the ready-to-use link in a {@link String}
+        */
+       private String getLink(String name, String ref, boolean menu, boolean html) {
+               if (!html) {
+                       return new StringBuilder().append((menu ? "1" : "0") + name)
+                                       .append("\t").append(ref) //
+                                       .append("\t").append(hostname) //
+                                       .append("\t").append(Integer.toString(port)) //
+                                       .append("\r\n").toString();
                }
+
+               return new StringBuilder().append(
+                               "<div class='site'><a href='" + ref + "'>" + name
+                                               + "</a></div>\n").toString();
        }
 }