Triad sou.

mixi 用ツールを作ってみた

mixi にログインして、html ファイルから一部を抜き出すソフトを作ってみた。
ほとんど書いたこと無かったけど Java ってラクだねw

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.net.MalformedURLException;

import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Mixi extends JApplet implements ActionListener  {

  private static final long serialVersionUID = 1L;

  private String cookie;
  private static final String ENCODING = "EUC-JP";
  private static final String MIXI_URL = "http://mixi.jp/";

  JPanel pMain = new JPanel();
  JTextField t1 = new JTextField("email@server.co.jp", 15);
  JTextField t2 = new JTextField("password", 15);
  // JTextField t3 = new JTextField("c:/", 15);
  JLabel l1 = new JLabel("Mail");
  JLabel l2 = new JLabel("Pass");
  // JLabel l3 = new JLabel("Path");
  JButton b1 = new JButton("execute");

  public void init() {
    System.setProperty("proxySet", "true");
    System.setProperty("proxyHost", "proxy.server.jp");
    System.setProperty("proxyPort", "80");

    Container contentPane = getContentPane();

    b1.addActionListener(this);
    b1.setActionCommand("execute");

    pMain.add(l1); pMain.add(t1);
    pMain.add(l2); pMain.add(t2);
    // pMain.add(l3); pMain.add(t3);
    pMain.add(b1);

    contentPane.add(pMain, BorderLayout.CENTER);
  }

  public void actionPerformed(ActionEvent e) {

    if (e.getSource() == b1) {
      try {
        Mixi mixi = new Mixi();
        mixi.login(t1.getText(), t2.getText());
        String[] footPrintList = mixi.getFootPrintList();
        System.out.printf("%d\n", Integer.parseInt(footPrintList[0]));

        java.util.Date date1 = new java.util.Date();
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyMMddHHmmss");
        // String filepath = t3.getText() + t1.getText() + sdf1.format(date1) + ".html";
        String filepath = t1.getText() + sdf1.format(date1) + ".html";
        File newfile = new File(filepath);

        if(newfile.exists()) {
          String msg = "ファイル " + filepath + " は既に存在します。";
          JOptionPane.showMessageDialog(null, msg);
        }
        else {
          newfile.createNewFile();
          if (newfile.isFile() && newfile.canWrite()){
            FileWriter filewriter = new FileWriter(newfile);
            BufferedWriter bw = new BufferedWriter(filewriter);
            PrintWriter pw = new PrintWriter(bw);
            pw.println("<?xml version='1.0' encoding='Shift_JIS'?>");
            pw.println("<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>");
            pw.println("<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='ja' lang='ja'>");
            pw.println("<head><meta http-equiv='Content-Type' content='text/html; charset=Shift_JIS' /><title>MixiTool</title></head><body>");
            pw.println("<form action='http://mixi.jp/login.pl' method='post' target='_blank'>");
            pw.println("<p><input type='hidden' name='next_url' value='/home.pl' />");
            pw.println("<input type='hidden' name='email' value='" + t1.getText() + "' />");
            pw.println("<input type='hidden' name='password' value='" + t2.getText() + "' />");
            pw.println("<input type='submit' value='login' accesskey='l' tabindex='1' /></p>");
            pw.println("</form><p>");
            for(int i = 1; i < Integer.parseInt(footPrintList[0]); i++){
              pw.println("<a href='http://mixi.jp/" +
                  (footPrintList[i].replaceAll(" ", "%20")).replaceAll("&", "&amp;") +
              "'>link</a>");
              if (i % 21 == 0) pw.println("<br />");
            }
            pw.println("</p></body></html>");
            pw.close();
            try {
              String cmd = newfile.getAbsolutePath();
              Runtime.getRuntime().exec("cmd /c start " + cmd);
            } catch (IOException e1) {
              e1.printStackTrace();
            }
            JOptionPane.showMessageDialog(null, "処理が完了しました、ブラウザ画面から操作してください。");
          } else {
            JOptionPane.showMessageDialog(null, "ファイルに書き込めません。");
          }
        }
      } catch(AuthenticateException e1) {
        JOptionPane.showMessageDialog(null, e1.getMessage());
      } catch(IOException e1) {
        JOptionPane.showMessageDialog(null, "通信中にエラーが起こりました: " + e1.getMessage());
      }
    }
  }

  public static void main(String[] args){
    class ClosingListener extends WindowAdapter {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    }

    Frame f = new Frame("MixiTool");

    Mixi w = new Mixi();
    w.init();
    w.start();
    f.add(w,"Center");
    f.pack();
    f.setSize(200, 200);

    ClosingListener CL = new ClosingListener();
    f.addWindowListener(CL);
    f.setVisible(true);
  }

  public Mixi() {
    cookie = "";
  }

  public void login(String email, String password) throws AuthenticateException, IOException {

    BufferedReader reader = null;
    BufferedWriter writer = null;

    try {
      StringBuilder parameter = new StringBuilder();
      parameter.append("email=").append(URLEncoder.encode(email, ENCODING)).append('&');
      parameter.append("password=").append(URLEncoder.encode(password, ENCODING)).append('&');
      parameter.append("next_url=").append(URLEncoder.encode("./home.pl", ENCODING));

      URL url = new URL(MIXI_URL + "login.pl");
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();
      connection.setRequestMethod("POST");
      connection.setDoOutput(true);

      writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
      writer.write(parameter.toString());
      writer.flush();

      Map<String, List<String>> headers = connection.getHeaderFields();
      List<String> values = headers.get("Set-Cookie");

      if(values != null)
        for(String value : values)
          cookie += value + ";";

      if(cookie.isEmpty())
        throw new AuthenticateException("ログインできませんでした");

      reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), ENCODING));
      String line;
      while((line = reader.readLine()) != null);

      reader.close();
      writer.close();

    } catch(UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    } catch(MalformedURLException e) {
      throw new RuntimeException(e);
    } catch(IOException e) {
      try {
        if(reader != null)
          reader.close();
        if(writer != null)
          writer.close();
      } catch(IOException ioe) {
        throw new RuntimeException(ioe);
      }
      throw e;
    }
  }

  public String[] getFootPrintList() throws AuthenticateException, IOException {

    if(cookie.isEmpty())
      throw new AuthenticateException("ログインしていません");

    String[] Lists = new String[1000];
    BufferedReader reader = null;
    int ct = 1, pg = 1, nc;
    Boolean cntflag = true;

    while(cntflag) {
      try {
        URL url = new URL(MIXI_URL + "list_appli_request.pl?page=" + pg + "&mode=all");
        URLConnection connection = url.openConnection();
        connection.setRequestProperty("Cookie", cookie);

        reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), ENCODING));
        String line;
        nc = 0;

        while((line = reader.readLine()) != null) {
          if (line.indexOf("list_appli_request.pl?mode=accept") >= 0) {
            // System.out.println("マッチしました。:" + line);
            String[] buff = line.split("\"");
            Lists[ct] = buff[1];
            ct++;
          }
          if (line.indexOf("次を表示") >= 0) {
            // System.out.println("次があります。" + line);
            nc++;
          }
        }
        if (nc > 0) {
          pg++;
          cntflag = true;
        }
        else cntflag = false;

      } catch(UnsupportedEncodingException e) {
        throw new RuntimeException(e);
      } catch(MalformedURLException e) {
        throw new RuntimeException(e);
      } catch(IOException e) {
        try {
          if(reader != null)
            reader.close();
        } catch(IOException ioe) {
          throw new RuntimeException(ioe);
        }
        throw e;
      }
    }

    Lists[0] = Integer.toString(ct);
    return Lists;

  }

  public class AuthenticateException extends IOException {

    private static final long serialVersionUID = 1L;

    public AuthenticateException() {
      super();
    }

    public AuthenticateException(String message) {
      super(message);
    }
  }

}

超参考にしたサイト

こちらのサイトのコードにプロキシ設定を足したぐらい。