Package org.mage.plugins.card.images

Source Code of org.mage.plugins.card.images.DownloadPictures$ProxyHandler

package org.mage.plugins.card.images;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import mage.cards.Card;

import org.apache.log4j.Logger;
import org.mage.plugins.card.CardUrl;
import org.mage.plugins.card.constants.Constants;
import org.mage.plugins.card.properties.SettingsManager;
import org.mage.plugins.card.utils.CardImageUtils;

public class DownloadPictures extends DefaultBoundedRangeModel implements Runnable {

  private int type;
  private JTextField addr, port;
  private JProgressBar bar;
  private JOptionPane dlg;
  private boolean cancel;
  private JButton close;
  private int cardIndex;
  private ArrayList<CardUrl> cards;
  private ArrayList<CardUrl> cardsInGame;
  private JComboBox jComboBox1;
  private JLabel jLabel1;
  private static boolean offlineMode = false;
  private JCheckBox checkBox;

  public static final Proxy.Type[] types = Proxy.Type.values();

  public static void main(String[] args) {
    startDownload(null, null);
  }

  public static void startDownload(JFrame frame, Set<Card> allCards) {
    ArrayList<CardUrl> cards = getNeededCards(allCards);

    /*
     * if (cards == null || cards.size() == 0) {
     * JOptionPane.showMessageDialog(null,
     * "All card pictures have been downloaded."); return; }
     */

    DownloadPictures download = new DownloadPictures(cards);
    JDialog dlg = download.getDlg(frame);
    dlg.setVisible(true);
    dlg.dispose();
    download.setCancel(true);
  }

  public JDialog getDlg(JFrame frame) {
    String title = "Downloading";
    if (offlineMode) {
      title += " (using local card db)";
    }
    final JDialog dlg = this.dlg.createDialog(frame, title);
    close.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        dlg.setVisible(false);
      }
    });
    return dlg;
  }

  public void setCancel(boolean cancel) {
    this.cancel = cancel;
  }

  public DownloadPictures(ArrayList<CardUrl> cards) {
    this.cards = cards;

    this.cardsInGame = new ArrayList<CardUrl>();
    for (CardUrl url : cards) {
      if (url.isExistsInTheGame())
        cardsInGame.add(url);
    }

    addr = new JTextField("Proxy Address");
    port = new JTextField("Proxy Port");
    bar = new JProgressBar(this);

    JPanel p0 = new JPanel();
    p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS));

    // Proxy Choice
    ButtonGroup bg = new ButtonGroup();
    String[] labels = { "No Proxy", "HTTP Proxy", "SOCKS Proxy" };
    for (int i = 0; i < types.length; i++) {
      JRadioButton rb = new JRadioButton(labels[i]);
      rb.addChangeListener(new ProxyHandler(i));
      bg.add(rb);
      p0.add(rb);
      if (i == 0)
        rb.setSelected(true);
    }

    // Proxy config
    p0.add(addr);
    p0.add(port);

    p0.add(Box.createVerticalStrut(5));
    jLabel1 = new JLabel();
    jLabel1.setText("Please select server:");

    jLabel1.setAlignmentX(Component.LEFT_ALIGNMENT);

    p0.add(jLabel1);
    p0.add(Box.createVerticalStrut(5));
    ComboBoxModel jComboBox1Model = new DefaultComboBoxModel(new String[] { "magiccards.info" });
    jComboBox1 = new JComboBox();

    jComboBox1.setModel(jComboBox1Model);
    jComboBox1.setAlignmentX(Component.LEFT_ALIGNMENT);
    p0.add(jComboBox1);
    p0.add(Box.createVerticalStrut(5));

    // Start
    final JButton b = new JButton("Start download");
    b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        new Thread(DownloadPictures.this).start();
        b.setEnabled(false);
        checkBox.setEnabled(false);
      }
    });
    p0.add(Box.createVerticalStrut(5));

    // Progress
    p0.add(bar);
    bar.setStringPainted(true);
    int count = cards.size();
    float mb = (count * 70.0f) / 1024;
    bar.setString(String.format(cardIndex == cards.size() ? "%d of %d cards finished! Please close!"
        : "%d of %d cards finished! Please wait! [%.1f Mb]", 0, cards.size(), mb));
    Dimension d = bar.getPreferredSize();
    d.width = 300;
    bar.setPreferredSize(d);

    p0.add(Box.createVerticalStrut(5));
    checkBox = new JCheckBox("Download for current game only.");
    p0.add(checkBox);
    p0.add(Box.createVerticalStrut(5));
    checkBox.setEnabled(!offlineMode);

    checkBox.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        if (checkBox.isSelected()) {
          int count = DownloadPictures.this.cardsInGame.size();
          float mb = (count * 70.0f) / 1024;
          bar.setString(String.format(count == 0 ? "No images to download!" : "%d of %d cards finished! Please wait! [%.1f Mb]",
              0, DownloadPictures.this.cardsInGame.size(), mb));
        } else {
          int count = DownloadPictures.this.cards.size();
          float mb = (count * 70.0f) / 1024;
          bar.setString(String.format(cardIndex == count ? "%d of %d cards finished! Please close!"
              : "%d of %d cards finished! Please wait! [%.1f Mb]", 0, count, mb));
        }
      }
    });

    // JOptionPane
    Object[] options = { b, close = new JButton("Cancel") };
    dlg = new JOptionPane(p0, JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[1]);
  }

  private static ArrayList<CardUrl> getNeededCards(Set<Card> allCards) {

    ArrayList<CardUrl> cardsToDownload = new ArrayList<CardUrl>();

    /**
     * read all card names and urls
     */
    ArrayList<CardUrl> allCardsUrls = new ArrayList<CardUrl>();

    try {
      offlineMode = true;

      for (Card card : allCards) {
        if (card.getCardNumber() > 0 && !card.getExpansionSetCode().isEmpty()) {
          CardUrl url = new CardUrl(card.getName(), card.getExpansionSetCode(), card.getCardNumber(), false);
          allCardsUrls.add(url);
        } else {
          if (card.getCardNumber() < 1) {
            System.err.println("There was a critical error!");
            log.error("Card has no collector ID and won't be sent to client: " + card);
          } else if (card.getExpansionSetCode().isEmpty()) {
            System.err.println("There was a critical error!");
            log.error("Card has no set name and won't be sent to client:" + card);
          }
        }
      }

      allCardsUrls.addAll(getTokenCardUrls());
    } catch (Exception e) {
      log.error(e);
    }

    File file;

    /**
     * check to see which cards we already have
     */
    for (CardUrl card : allCardsUrls) {
      boolean withCollectorId = false;
      if (card.name.equals("Forest") || card.name.equals("Mountain") || card.name.equals("Swamp") || card.name.equals("Island")
          || card.name.equals("Plains")) {
        withCollectorId = true;
      }
      file = new File(CardImageUtils.getImagePath(card, withCollectorId));
      if (!file.exists()) {
        cardsToDownload.add(card);
      }
    }

    for (CardUrl card : cardsToDownload) {
      if (card.token) {
        log.info("Card to download: " + card.name + " (Token) " + card.url);
      } else {
        try {
          log.info("Card to download: " + card.name + " (" + card.set + ") "
              + CardImageUtils.generateURL(card.collector, card.set));
        } catch (Exception e) {
          log.error(e);
        }
      }
    }

    return cardsToDownload;
  }

  private static ArrayList<CardUrl> getTokenCardUrls() throws RuntimeException {
    ArrayList<CardUrl> list = new ArrayList<CardUrl>();
    HashSet<String> filter = new HashSet<String>();
    InputStream in = DownloadPictures.class.getClassLoader().getResourceAsStream("card-pictures-tok.txt");
    readImageURLsFromFile(in, list, filter);
    return list;
  }

  private static void readImageURLsFromFile(InputStream in, ArrayList<CardUrl> list, Set<String> filter) throws RuntimeException {
    if (in == null) {
      log.error("resources input stream is null");
      return;
    }

    BufferedReader reader = null;
    InputStreamReader input = null;
    try {
      input = new InputStreamReader(in);
      reader = new BufferedReader(input);
      String line;

      line = reader.readLine();
      while (line != null) {
        line = line.trim();
        if (line.startsWith("|")) { // new format
          String[] params = line.split("\\|");
          if (params.length >= 4) {
            if (params[1].toLowerCase().equals("generate") && params[2].startsWith("TOK:")) {
              String set = params[2].substring(4);
              CardUrl cardUrl = new CardUrl(params[3], set, 0, true);
              cardUrl.token = true;
              cardUrl.url = generateTokenUrl(params[3], set);
              list.add(cardUrl);
            } else {
              CardUrl cardUrl = new CardUrl(params[2], params[1].toUpperCase(), 0, false);
              cardUrl.url = params[3];
              if (cardUrl.set.startsWith("TOK:")) {
                cardUrl.token = true;
                cardUrl.set = cardUrl.set.substring(4);
              }
              list.add(cardUrl);
            }
          } else {
            log.error("wrong format for image urls: " + line);
          }
        }
        line = reader.readLine();
      }

    } catch (Exception ex) {
      log.error(ex);
      throw new RuntimeException("DownloadPictures : readFile() error");
    } finally {
      if (input != null) {
        try {
          input.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      if (reader != null) {
        try {
          reader.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }

    }
  }

  final static Map<String, String> setNameReplacement = new HashMap<String, String>() {
    {
      put("SOM", "scars-of-mirrodin");
      put("M11", "magic-2011");
      put("ROE", "rise-of-the-eldrazi");
      put("PVC", "duel-decks-phyrexia-vs-the-coalition");
      put("WWK", "worldwake");
      put("ZEN", "zendikar");
      put("HOP", "planechase");
      put("M10", "magic-2010");
      put("GVL", "duel-decks-garruk-vs-liliana");
      put("ARB", "alara-reborn");
      put("DVD", "duel-decks-divine-vs-demonic");
      put("CON", "conflux");
      put("JVC", "duel-decks-jace-vs-chandra");
      put("ALA", "shards-of-alara");
      put("EVE", "eventide");
      put("SHM", "shadowmoor");
      put("EVG", "duel-decks-elves-vs-goblins");
      put("MOR", "morningtide");
      put("LRW", "lorwyn");
      put("10E", "tenth-edition");
      put("CSP", "coldsnap");
    }
    private static final long serialVersionUID = 1L;
  };

  private static String generateTokenUrl(String name, String set) {
    String _name = name.replaceAll(" ", "-").toLowerCase();
    String _set = "not-supported-set";
    if (setNameReplacement.containsKey(set)) {
      _set = setNameReplacement.get(set);
    } else {
      _set += "-" + set;
    }
    String url = "http://magiccards.info/extras/token/" + _set + "/" + _name + ".jpg";
    return url;
  }

  private class ProxyHandler implements ChangeListener {
    private int type;

    public ProxyHandler(int type) {
      this.type = type;
    }

    public void stateChanged(ChangeEvent e) {
      if (((AbstractButton) e.getSource()).isSelected()) {
        DownloadPictures.this.type = type;
        addr.setEnabled(type != 0);
        port.setEnabled(type != 0);
      }
    }
  }

  public void run() {
    BufferedInputStream in;
    BufferedOutputStream out;

    File base = new File(Constants.IO.imageBaseDir);
    if (!base.exists()) {
      base.mkdir();
    }

    Proxy p = null;
    if (type == 0)
      p = Proxy.NO_PROXY;
    else
      try {
        p = new Proxy(types[type], new InetSocketAddress(addr.getText(), Integer.parseInt(port.getText())));
      } catch (Exception ex) {
        throw new RuntimeException("Gui_DownloadPictures : error 1 - " + ex);
      }

    if (p != null) {
      byte[] buf = new byte[1024];
      int len;
      HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls();

      for (update(0); (checkBox.isSelected() ? cardIndex < cardsInGame.size() : cardIndex < cards.size()) && !cancel; update(cardIndex + 1)) {
        try {

          CardUrl card = checkBox.isSelected() ? cardsInGame.get(cardIndex) : cards.get(cardIndex);

          log.info("Downloading card: " + card.name + " (" + card.set + ")");

          URL url = new URL(CardImageUtils.generateURL(card.collector, card.set));
          if (ignoreUrls.contains(card.set) || card.token) {
            // we have card in scripts, but we should ignore
            // downloading image for it
            // (e.g. for cards from custom or not released yet sets
            // such urls should come from card-pictures files
            // instead
            if (card.collector != 0) {
              continue;
            }
            url = new URL(card.url);
          }
          in = new BufferedInputStream(url.openConnection(p).getInputStream());

          createDirForCard(card);

          boolean withCollectorId = false;
          if (card.name.equals("Forest") || card.name.equals("Mountain") || card.name.equals("Swamp")
              || card.name.equals("Island") || card.name.equals("Plains")) {
            withCollectorId = true;
          }
          File fileOut = new File(CardImageUtils.getImagePath(card, withCollectorId));

          out = new BufferedOutputStream(new FileOutputStream(fileOut));

          while ((len = in.read(buf)) != -1) {
            // user cancelled
            if (cancel) {
              in.close();
              out.flush();
              out.close();

              // delete what was written so far
              fileOut.delete();

              return;
            }

            out.write(buf, 0, len);
          }

          in.close();
          out.flush();
          out.close();
        } catch (Exception ex) {
          log.error(ex, ex);
          /*
           * int more = JOptionPane.showConfirmDialog(null,
           * "Some error occured. Continue downloading pictures?",
           * "Error", JOptionPane.YES_NO_OPTION); if (more ==
           * JOptionPane.NO_OPTION) { break; }
           */
        }
      }
    }
    close.setText("Close");
  }

  private static File createDirForCard(CardUrl card) throws Exception {
    File setDir = new File(CardImageUtils.getImageDir(card));
    if (!setDir.exists()) {
      setDir.mkdirs();
    }
    return setDir;
  }

  private void update(int card) {
    this.cardIndex = card;
    final class Worker implements Runnable {
      private int card;

      Worker(int card) {
        this.card = card;
      }

      public void run() {
        fireStateChanged();
        if (checkBox.isSelected()) {
          int count = DownloadPictures.this.cardsInGame.size();
          int countLeft = count - card;
          float mb = (countLeft * 70.0f) / 1024;
          bar.setString(String.format(this.card == count ? "%d of %d cards finished! Please close!"
              : "%d of %d cards finished! Please wait!  [%.1f Mb]", this.card, count, mb));
        } else {
          int count = DownloadPictures.this.cards.size();
          int countLeft = count - card;
          float mb = (countLeft * 70.0f) / 1024;
          bar.setString(String.format(cardIndex == count ? "%d of %d cards finished! Please close!"
              : "%d of %d cards finished! Please wait! [%.1f Mb]", this.card, count, mb));
        }
      }
    }

    EventQueue.invokeLater(new Worker(card));
  }

  private static final Logger log = Logger.getLogger(DownloadPictures.class);

  private static final long serialVersionUID = 1L;
}
TOP

Related Classes of org.mage.plugins.card.images.DownloadPictures$ProxyHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.