PageRenderTime 44ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/images/DownloadPictures.java

http://magic--another-game-engine.googlecode.com/
Java | 527 lines | 426 code | 72 blank | 29 comment | 72 complexity | 2bb6853d9b785e42a2e299cb36e31eb0 MD5 | raw file
  1. package org.mage.plugins.card.images;
  2. import java.awt.Component;
  3. import java.awt.Dimension;
  4. import java.awt.EventQueue;
  5. import java.awt.event.ActionEvent;
  6. import java.awt.event.ActionListener;
  7. import java.io.BufferedInputStream;
  8. import java.io.BufferedOutputStream;
  9. import java.io.BufferedReader;
  10. import java.io.File;
  11. import java.io.FileOutputStream;
  12. import java.io.InputStream;
  13. import java.io.InputStreamReader;
  14. import java.net.InetSocketAddress;
  15. import java.net.Proxy;
  16. import java.net.URL;
  17. import java.util.ArrayList;
  18. import java.util.HashMap;
  19. import java.util.HashSet;
  20. import java.util.Map;
  21. import java.util.Set;
  22. import javax.swing.AbstractButton;
  23. import javax.swing.Box;
  24. import javax.swing.BoxLayout;
  25. import javax.swing.ButtonGroup;
  26. import javax.swing.ComboBoxModel;
  27. import javax.swing.DefaultBoundedRangeModel;
  28. import javax.swing.DefaultComboBoxModel;
  29. import javax.swing.JButton;
  30. import javax.swing.JCheckBox;
  31. import javax.swing.JComboBox;
  32. import javax.swing.JDialog;
  33. import javax.swing.JFrame;
  34. import javax.swing.JLabel;
  35. import javax.swing.JOptionPane;
  36. import javax.swing.JPanel;
  37. import javax.swing.JProgressBar;
  38. import javax.swing.JRadioButton;
  39. import javax.swing.JTextField;
  40. import javax.swing.event.ChangeEvent;
  41. import javax.swing.event.ChangeListener;
  42. import mage.cards.Card;
  43. import org.apache.log4j.Logger;
  44. import org.mage.plugins.card.CardUrl;
  45. import org.mage.plugins.card.constants.Constants;
  46. import org.mage.plugins.card.properties.SettingsManager;
  47. import org.mage.plugins.card.utils.CardImageUtils;
  48. public class DownloadPictures extends DefaultBoundedRangeModel implements Runnable {
  49. private int type;
  50. private JTextField addr, port;
  51. private JProgressBar bar;
  52. private JOptionPane dlg;
  53. private boolean cancel;
  54. private JButton close;
  55. private int cardIndex;
  56. private ArrayList<CardUrl> cards;
  57. private ArrayList<CardUrl> cardsInGame;
  58. private JComboBox jComboBox1;
  59. private JLabel jLabel1;
  60. private static boolean offlineMode = false;
  61. private JCheckBox checkBox;
  62. public static final Proxy.Type[] types = Proxy.Type.values();
  63. public static void main(String[] args) {
  64. startDownload(null, null);
  65. }
  66. public static void startDownload(JFrame frame, Set<Card> allCards) {
  67. ArrayList<CardUrl> cards = getNeededCards(allCards);
  68. /*
  69. * if (cards == null || cards.size() == 0) {
  70. * JOptionPane.showMessageDialog(null,
  71. * "All card pictures have been downloaded."); return; }
  72. */
  73. DownloadPictures download = new DownloadPictures(cards);
  74. JDialog dlg = download.getDlg(frame);
  75. dlg.setVisible(true);
  76. dlg.dispose();
  77. download.setCancel(true);
  78. }
  79. public JDialog getDlg(JFrame frame) {
  80. String title = "Downloading";
  81. if (offlineMode) {
  82. title += " (using local card db)";
  83. }
  84. final JDialog dlg = this.dlg.createDialog(frame, title);
  85. close.addActionListener(new ActionListener() {
  86. public void actionPerformed(ActionEvent e) {
  87. dlg.setVisible(false);
  88. }
  89. });
  90. return dlg;
  91. }
  92. public void setCancel(boolean cancel) {
  93. this.cancel = cancel;
  94. }
  95. public DownloadPictures(ArrayList<CardUrl> cards) {
  96. this.cards = cards;
  97. this.cardsInGame = new ArrayList<CardUrl>();
  98. for (CardUrl url : cards) {
  99. if (url.isExistsInTheGame())
  100. cardsInGame.add(url);
  101. }
  102. addr = new JTextField("Proxy Address");
  103. port = new JTextField("Proxy Port");
  104. bar = new JProgressBar(this);
  105. JPanel p0 = new JPanel();
  106. p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS));
  107. // Proxy Choice
  108. ButtonGroup bg = new ButtonGroup();
  109. String[] labels = { "No Proxy", "HTTP Proxy", "SOCKS Proxy" };
  110. for (int i = 0; i < types.length; i++) {
  111. JRadioButton rb = new JRadioButton(labels[i]);
  112. rb.addChangeListener(new ProxyHandler(i));
  113. bg.add(rb);
  114. p0.add(rb);
  115. if (i == 0)
  116. rb.setSelected(true);
  117. }
  118. // Proxy config
  119. p0.add(addr);
  120. p0.add(port);
  121. p0.add(Box.createVerticalStrut(5));
  122. jLabel1 = new JLabel();
  123. jLabel1.setText("Please select server:");
  124. jLabel1.setAlignmentX(Component.LEFT_ALIGNMENT);
  125. p0.add(jLabel1);
  126. p0.add(Box.createVerticalStrut(5));
  127. ComboBoxModel jComboBox1Model = new DefaultComboBoxModel(new String[] { "magiccards.info" });
  128. jComboBox1 = new JComboBox();
  129. jComboBox1.setModel(jComboBox1Model);
  130. jComboBox1.setAlignmentX(Component.LEFT_ALIGNMENT);
  131. p0.add(jComboBox1);
  132. p0.add(Box.createVerticalStrut(5));
  133. // Start
  134. final JButton b = new JButton("Start download");
  135. b.addActionListener(new ActionListener() {
  136. public void actionPerformed(ActionEvent e) {
  137. new Thread(DownloadPictures.this).start();
  138. b.setEnabled(false);
  139. checkBox.setEnabled(false);
  140. }
  141. });
  142. p0.add(Box.createVerticalStrut(5));
  143. // Progress
  144. p0.add(bar);
  145. bar.setStringPainted(true);
  146. int count = cards.size();
  147. float mb = (count * 70.0f) / 1024;
  148. bar.setString(String.format(cardIndex == cards.size() ? "%d of %d cards finished! Please close!"
  149. : "%d of %d cards finished! Please wait! [%.1f Mb]", 0, cards.size(), mb));
  150. Dimension d = bar.getPreferredSize();
  151. d.width = 300;
  152. bar.setPreferredSize(d);
  153. p0.add(Box.createVerticalStrut(5));
  154. checkBox = new JCheckBox("Download for current game only.");
  155. p0.add(checkBox);
  156. p0.add(Box.createVerticalStrut(5));
  157. checkBox.setEnabled(!offlineMode);
  158. checkBox.addActionListener(new ActionListener() {
  159. public void actionPerformed(ActionEvent e) {
  160. if (checkBox.isSelected()) {
  161. int count = DownloadPictures.this.cardsInGame.size();
  162. float mb = (count * 70.0f) / 1024;
  163. bar.setString(String.format(count == 0 ? "No images to download!" : "%d of %d cards finished! Please wait! [%.1f Mb]",
  164. 0, DownloadPictures.this.cardsInGame.size(), mb));
  165. } else {
  166. int count = DownloadPictures.this.cards.size();
  167. float mb = (count * 70.0f) / 1024;
  168. bar.setString(String.format(cardIndex == count ? "%d of %d cards finished! Please close!"
  169. : "%d of %d cards finished! Please wait! [%.1f Mb]", 0, count, mb));
  170. }
  171. }
  172. });
  173. // JOptionPane
  174. Object[] options = { b, close = new JButton("Cancel") };
  175. dlg = new JOptionPane(p0, JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[1]);
  176. }
  177. private static ArrayList<CardUrl> getNeededCards(Set<Card> allCards) {
  178. ArrayList<CardUrl> cardsToDownload = new ArrayList<CardUrl>();
  179. /**
  180. * read all card names and urls
  181. */
  182. ArrayList<CardUrl> allCardsUrls = new ArrayList<CardUrl>();
  183. try {
  184. offlineMode = true;
  185. for (Card card : allCards) {
  186. if (card.getCardNumber() > 0 && !card.getExpansionSetCode().isEmpty()) {
  187. CardUrl url = new CardUrl(card.getName(), card.getExpansionSetCode(), card.getCardNumber(), false);
  188. allCardsUrls.add(url);
  189. } else {
  190. if (card.getCardNumber() < 1) {
  191. System.err.println("There was a critical error!");
  192. log.error("Card has no collector ID and won't be sent to client: " + card);
  193. } else if (card.getExpansionSetCode().isEmpty()) {
  194. System.err.println("There was a critical error!");
  195. log.error("Card has no set name and won't be sent to client:" + card);
  196. }
  197. }
  198. }
  199. allCardsUrls.addAll(getTokenCardUrls());
  200. } catch (Exception e) {
  201. log.error(e);
  202. }
  203. File file;
  204. /**
  205. * check to see which cards we already have
  206. */
  207. for (CardUrl card : allCardsUrls) {
  208. boolean withCollectorId = false;
  209. if (card.name.equals("Forest") || card.name.equals("Mountain") || card.name.equals("Swamp") || card.name.equals("Island")
  210. || card.name.equals("Plains")) {
  211. withCollectorId = true;
  212. }
  213. file = new File(CardImageUtils.getImagePath(card, withCollectorId));
  214. if (!file.exists()) {
  215. cardsToDownload.add(card);
  216. }
  217. }
  218. for (CardUrl card : cardsToDownload) {
  219. if (card.token) {
  220. log.info("Card to download: " + card.name + " (Token) " + card.url);
  221. } else {
  222. try {
  223. log.info("Card to download: " + card.name + " (" + card.set + ") "
  224. + CardImageUtils.generateURL(card.collector, card.set));
  225. } catch (Exception e) {
  226. log.error(e);
  227. }
  228. }
  229. }
  230. return cardsToDownload;
  231. }
  232. private static ArrayList<CardUrl> getTokenCardUrls() throws RuntimeException {
  233. ArrayList<CardUrl> list = new ArrayList<CardUrl>();
  234. HashSet<String> filter = new HashSet<String>();
  235. InputStream in = DownloadPictures.class.getClassLoader().getResourceAsStream("card-pictures-tok.txt");
  236. readImageURLsFromFile(in, list, filter);
  237. return list;
  238. }
  239. private static void readImageURLsFromFile(InputStream in, ArrayList<CardUrl> list, Set<String> filter) throws RuntimeException {
  240. if (in == null) {
  241. log.error("resources input stream is null");
  242. return;
  243. }
  244. BufferedReader reader = null;
  245. InputStreamReader input = null;
  246. try {
  247. input = new InputStreamReader(in);
  248. reader = new BufferedReader(input);
  249. String line;
  250. line = reader.readLine();
  251. while (line != null) {
  252. line = line.trim();
  253. if (line.startsWith("|")) { // new format
  254. String[] params = line.split("\\|");
  255. if (params.length >= 4) {
  256. if (params[1].toLowerCase().equals("generate") && params[2].startsWith("TOK:")) {
  257. String set = params[2].substring(4);
  258. CardUrl cardUrl = new CardUrl(params[3], set, 0, true);
  259. cardUrl.token = true;
  260. cardUrl.url = generateTokenUrl(params[3], set);
  261. list.add(cardUrl);
  262. } else {
  263. CardUrl cardUrl = new CardUrl(params[2], params[1].toUpperCase(), 0, false);
  264. cardUrl.url = params[3];
  265. if (cardUrl.set.startsWith("TOK:")) {
  266. cardUrl.token = true;
  267. cardUrl.set = cardUrl.set.substring(4);
  268. }
  269. list.add(cardUrl);
  270. }
  271. } else {
  272. log.error("wrong format for image urls: " + line);
  273. }
  274. }
  275. line = reader.readLine();
  276. }
  277. } catch (Exception ex) {
  278. log.error(ex);
  279. throw new RuntimeException("DownloadPictures : readFile() error");
  280. } finally {
  281. if (input != null) {
  282. try {
  283. input.close();
  284. } catch (Exception e) {
  285. e.printStackTrace();
  286. }
  287. }
  288. if (reader != null) {
  289. try {
  290. reader.close();
  291. } catch (Exception e) {
  292. e.printStackTrace();
  293. }
  294. }
  295. }
  296. }
  297. final static Map<String, String> setNameReplacement = new HashMap<String, String>() {
  298. {
  299. put("SOM", "scars-of-mirrodin");
  300. put("M11", "magic-2011");
  301. put("ROE", "rise-of-the-eldrazi");
  302. put("PVC", "duel-decks-phyrexia-vs-the-coalition");
  303. put("WWK", "worldwake");
  304. put("ZEN", "zendikar");
  305. put("HOP", "planechase");
  306. put("M10", "magic-2010");
  307. put("GVL", "duel-decks-garruk-vs-liliana");
  308. put("ARB", "alara-reborn");
  309. put("DVD", "duel-decks-divine-vs-demonic");
  310. put("CON", "conflux");
  311. put("JVC", "duel-decks-jace-vs-chandra");
  312. put("ALA", "shards-of-alara");
  313. put("EVE", "eventide");
  314. put("SHM", "shadowmoor");
  315. put("EVG", "duel-decks-elves-vs-goblins");
  316. put("MOR", "morningtide");
  317. put("LRW", "lorwyn");
  318. put("10E", "tenth-edition");
  319. put("CSP", "coldsnap");
  320. }
  321. private static final long serialVersionUID = 1L;
  322. };
  323. private static String generateTokenUrl(String name, String set) {
  324. String _name = name.replaceAll(" ", "-").toLowerCase();
  325. String _set = "not-supported-set";
  326. if (setNameReplacement.containsKey(set)) {
  327. _set = setNameReplacement.get(set);
  328. } else {
  329. _set += "-" + set;
  330. }
  331. String url = "http://magiccards.info/extras/token/" + _set + "/" + _name + ".jpg";
  332. return url;
  333. }
  334. private class ProxyHandler implements ChangeListener {
  335. private int type;
  336. public ProxyHandler(int type) {
  337. this.type = type;
  338. }
  339. public void stateChanged(ChangeEvent e) {
  340. if (((AbstractButton) e.getSource()).isSelected()) {
  341. DownloadPictures.this.type = type;
  342. addr.setEnabled(type != 0);
  343. port.setEnabled(type != 0);
  344. }
  345. }
  346. }
  347. public void run() {
  348. BufferedInputStream in;
  349. BufferedOutputStream out;
  350. File base = new File(Constants.IO.imageBaseDir);
  351. if (!base.exists()) {
  352. base.mkdir();
  353. }
  354. Proxy p = null;
  355. if (type == 0)
  356. p = Proxy.NO_PROXY;
  357. else
  358. try {
  359. p = new Proxy(types[type], new InetSocketAddress(addr.getText(), Integer.parseInt(port.getText())));
  360. } catch (Exception ex) {
  361. throw new RuntimeException("Gui_DownloadPictures : error 1 - " + ex);
  362. }
  363. if (p != null) {
  364. byte[] buf = new byte[1024];
  365. int len;
  366. HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls();
  367. for (update(0); (checkBox.isSelected() ? cardIndex < cardsInGame.size() : cardIndex < cards.size()) && !cancel; update(cardIndex + 1)) {
  368. try {
  369. CardUrl card = checkBox.isSelected() ? cardsInGame.get(cardIndex) : cards.get(cardIndex);
  370. log.info("Downloading card: " + card.name + " (" + card.set + ")");
  371. URL url = new URL(CardImageUtils.generateURL(card.collector, card.set));
  372. if (ignoreUrls.contains(card.set) || card.token) {
  373. // we have card in scripts, but we should ignore
  374. // downloading image for it
  375. // (e.g. for cards from custom or not released yet sets
  376. // such urls should come from card-pictures files
  377. // instead
  378. if (card.collector != 0) {
  379. continue;
  380. }
  381. url = new URL(card.url);
  382. }
  383. in = new BufferedInputStream(url.openConnection(p).getInputStream());
  384. createDirForCard(card);
  385. boolean withCollectorId = false;
  386. if (card.name.equals("Forest") || card.name.equals("Mountain") || card.name.equals("Swamp")
  387. || card.name.equals("Island") || card.name.equals("Plains")) {
  388. withCollectorId = true;
  389. }
  390. File fileOut = new File(CardImageUtils.getImagePath(card, withCollectorId));
  391. out = new BufferedOutputStream(new FileOutputStream(fileOut));
  392. while ((len = in.read(buf)) != -1) {
  393. // user cancelled
  394. if (cancel) {
  395. in.close();
  396. out.flush();
  397. out.close();
  398. // delete what was written so far
  399. fileOut.delete();
  400. return;
  401. }
  402. out.write(buf, 0, len);
  403. }
  404. in.close();
  405. out.flush();
  406. out.close();
  407. } catch (Exception ex) {
  408. log.error(ex, ex);
  409. /*
  410. * int more = JOptionPane.showConfirmDialog(null,
  411. * "Some error occured. Continue downloading pictures?",
  412. * "Error", JOptionPane.YES_NO_OPTION); if (more ==
  413. * JOptionPane.NO_OPTION) { break; }
  414. */
  415. }
  416. }
  417. }
  418. close.setText("Close");
  419. }
  420. private static File createDirForCard(CardUrl card) throws Exception {
  421. File setDir = new File(CardImageUtils.getImageDir(card));
  422. if (!setDir.exists()) {
  423. setDir.mkdirs();
  424. }
  425. return setDir;
  426. }
  427. private void update(int card) {
  428. this.cardIndex = card;
  429. final class Worker implements Runnable {
  430. private int card;
  431. Worker(int card) {
  432. this.card = card;
  433. }
  434. public void run() {
  435. fireStateChanged();
  436. if (checkBox.isSelected()) {
  437. int count = DownloadPictures.this.cardsInGame.size();
  438. int countLeft = count - card;
  439. float mb = (countLeft * 70.0f) / 1024;
  440. bar.setString(String.format(this.card == count ? "%d of %d cards finished! Please close!"
  441. : "%d of %d cards finished! Please wait! [%.1f Mb]", this.card, count, mb));
  442. } else {
  443. int count = DownloadPictures.this.cards.size();
  444. int countLeft = count - card;
  445. float mb = (countLeft * 70.0f) / 1024;
  446. bar.setString(String.format(cardIndex == count ? "%d of %d cards finished! Please close!"
  447. : "%d of %d cards finished! Please wait! [%.1f Mb]", this.card, count, mb));
  448. }
  449. }
  450. }
  451. EventQueue.invokeLater(new Worker(card));
  452. }
  453. private static final Logger log = Logger.getLogger(DownloadPictures.class);
  454. private static final long serialVersionUID = 1L;
  455. }