From 49c7c1cf6172dba617ada3f5ab3cbcdff478235b Mon Sep 17 00:00:00 2001 From: skylarmt Date: Thu, 16 Apr 2015 17:49:27 -0600 Subject: [PATCH] Improve pad sharing --- src/net/apocalypselabs/symat/FileUtils.java | 11 ++ src/net/apocalypselabs/symat/License.java | 10 +- src/net/apocalypselabs/symat/Pads.java | 22 +-- src/net/apocalypselabs/symat/SharePad.form | 40 ++++- src/net/apocalypselabs/symat/SharePad.java | 157 ++++++++++++++++---- 5 files changed, 198 insertions(+), 42 deletions(-) diff --git a/src/net/apocalypselabs/symat/FileUtils.java b/src/net/apocalypselabs/symat/FileUtils.java index bc798be..1f27f5d 100644 --- a/src/net/apocalypselabs/symat/FileUtils.java +++ b/src/net/apocalypselabs/symat/FileUtils.java @@ -49,9 +49,12 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.net.MalformedURLException; +import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.Scanner; import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; @@ -132,4 +135,12 @@ public class FileUtils { } return null; } + + public static String getUrl(String url) throws MalformedURLException, IOException { + String out; + try (Scanner sc = new Scanner(new URL("http://www.google.com").openStream(), "UTF-8")) { + out = sc.useDelimiter("\\A").next(); + } + return out; + } } diff --git a/src/net/apocalypselabs/symat/License.java b/src/net/apocalypselabs/symat/License.java index d4f036a..eed98eb 100644 --- a/src/net/apocalypselabs/symat/License.java +++ b/src/net/apocalypselabs/symat/License.java @@ -295,8 +295,7 @@ public class License extends javax.swing.JInternalFrame { }//GEN-LAST:event_exitBtnActionPerformed private boolean checkRegex() { - String regex = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]+$"; - if (emailBox.getText().matches(regex)) { + if (checkEmail(emailBox.getText())) { contBtn.setEnabled(true); return true; } else { @@ -304,6 +303,11 @@ public class License extends javax.swing.JInternalFrame { return false; } } + + public static boolean checkEmail(String email) { + String regex = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]+$"; + return (email.matches(regex)); + } public void exit() { dispose(); @@ -323,7 +327,7 @@ public class License extends javax.swing.JInternalFrame { @Override public void run() { try { - Debug.println("Checking license..."); + System.out.println("Checking license..."); URL url = new URL(API_URL + "liccheck.php?email=" + email); String line; try (InputStream is = url.openStream(); diff --git a/src/net/apocalypselabs/symat/Pads.java b/src/net/apocalypselabs/symat/Pads.java index c902d05..11ec818 100644 --- a/src/net/apocalypselabs/symat/Pads.java +++ b/src/net/apocalypselabs/symat/Pads.java @@ -169,7 +169,7 @@ public class Pads extends javax.swing.JInternalFrame { } /** - * Generate a random pad ID with length 15. + * Generate a random pad ID with length 15. *
There are about 1.217 x 10^26 possibilities (121 septillion). *
If this starts giving out used IDs, I'll be too rich to care. * @@ -197,14 +197,18 @@ public class Pads extends javax.swing.JInternalFrame { * @throws IOException if things break. */ public static EPLiteClient getClient() throws Exception { - // Load the API key from a file, so it's not included with Git. String apikey; - BufferedReader reader = new BufferedReader( - new InputStreamReader( - Pads.class - .getResourceAsStream("/padkey"))); - apikey = reader.readLine(); - + // Enable key change without full SyMAT update + if (!PrefStorage.getSetting("padkey-override", "").equals("")) { + apikey = PrefStorage.getSetting("padkey-override", ""); + } else { + // Load the API key from a file, so it's not included with Git. + BufferedReader reader = new BufferedReader( + new InputStreamReader( + Pads.class + .getResourceAsStream("/padkey"))); + apikey = reader.readLine(); + } // New client return new EPLiteClient(PADS_URL, apikey); } @@ -220,7 +224,7 @@ public class Pads extends javax.swing.JInternalFrame { try { text = getClient().getText(id).getOrDefault("text", "").toString(); } catch (Exception ex) { - text = "Error: Could not get pad contents: " + ex.getMessage(); + text = "Error: " + ex.getMessage(); } return text; } diff --git a/src/net/apocalypselabs/symat/SharePad.form b/src/net/apocalypselabs/symat/SharePad.form index 826baf0..bcf7b58 100644 --- a/src/net/apocalypselabs/symat/SharePad.form +++ b/src/net/apocalypselabs/symat/SharePad.form @@ -38,13 +38,14 @@ - + - + + @@ -74,9 +75,15 @@ - + + + + + + + @@ -86,7 +93,13 @@ - + + + + + + + @@ -108,6 +121,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/net/apocalypselabs/symat/SharePad.java b/src/net/apocalypselabs/symat/SharePad.java index 9f8d879..6bf1b16 100644 --- a/src/net/apocalypselabs/symat/SharePad.java +++ b/src/net/apocalypselabs/symat/SharePad.java @@ -2,40 +2,40 @@ * CODE LICENSE ===================== * Copyright (c) 2015, Apocalypse Laboratories * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this + * + * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, + * + * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software without + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without * specific prior written permission. - * + * * 4. You adhere to the Media License detailed below. If you do not, this license * is automatically revoked and you must purge all copies of the software you * possess, in source or binary form. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * MEDIA LICENSE ==================== * All images and other graphical files (the "graphics") included with this * software are copyright (c) 2015 Apocalypse Laboratories. You may not distribute - * the graphics or any program, source code repository, or other digital storage + * the graphics or any program, source code repository, or other digital storage * media containing them without written permission from Apocalypse Laboratories. * This ban on distribution only applies to publicly available systems. * A password-protected network file share, USB drive, or other storage scheme that @@ -48,6 +48,9 @@ package net.apocalypselabs.symat; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.SwingUtilities; /** * @@ -56,8 +59,10 @@ import java.awt.datatransfer.StringSelection; public class SharePad extends javax.swing.JPanel { String padid = ""; + /** * Creates new form SharePad + * * @param id The pad ID to share. */ public SharePad(String id) { @@ -80,6 +85,9 @@ public class SharePad extends javax.swing.JPanel { jPanel1 = new javax.swing.JPanel(); copyIDBtn = new javax.swing.JButton(); copyLinkBtn = new javax.swing.JButton(); + emailBtn = new javax.swing.JButton(); + emailBox = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); setMinimumSize(new java.awt.Dimension(188, 172)); @@ -103,14 +111,35 @@ public class SharePad extends javax.swing.JPanel { } }); + emailBtn.setText("Send Email"); + emailBtn.setEnabled(false); + emailBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + emailBtnActionPerformed(evt); + } + }); + + emailBox.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyTyped(java.awt.event.KeyEvent evt) { + emailBoxKeyTyped(evt); + } + }); + + jLabel2.setText("Email Link:"); + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(copyIDBtn) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(copyLinkBtn)) + .addComponent(emailBox) + .addComponent(emailBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel2) + .addGap(0, 0, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -118,7 +147,13 @@ public class SharePad extends javax.swing.JPanel { .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(copyIDBtn) .addComponent(copyLinkBtn)) - .addGap(0, 77, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(emailBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(emailBtn) + .addGap(5, 5, 5)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -138,12 +173,13 @@ public class SharePad extends javax.swing.JPanel { layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap(17, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(padIDBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(18, 18, 18) - .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(7, 7, 7)) ); }// //GEN-END:initComponents @@ -152,9 +188,75 @@ public class SharePad extends javax.swing.JPanel { }//GEN-LAST:event_copyIDBtnActionPerformed private void copyLinkBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_copyLinkBtnActionPerformed - toClipboard(Pads.PADS_URL+"/p/"+padid); + toClipboard(Pads.PADS_URL + "/p/" + padid); }//GEN-LAST:event_copyLinkBtnActionPerformed + private void emailBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_emailBtnActionPerformed + if (License.checkEmail(emailBox.getText())) { + emailBtn.setEnabled(false); + emailBtn.setText("Sending..."); + new EmailThread(emailBox.getText(), padid).start(); + } + }//GEN-LAST:event_emailBtnActionPerformed + + private class EmailThread extends Thread { + + private final String email; + private final String pad; + + @Override + public void run() { + try { + String f = FileUtils.getUrl( + Main.API_URL + "sendpad.php?email=" + + email + "&padid=" + pad); + if (f.contains("OK")) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + emailBtn.setText("Link Sent!"); + } + }); + } else { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + emailBtn.setText("Error."); + } + }); + } + } catch (Exception ex) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + emailBtn.setText("Error, retry?"); + } + }); + } + try { + Thread.sleep(1500); + } catch (InterruptedException ex) { + + } + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + emailBtn.setEnabled(true); + emailBtn.setText("Send Email"); + } + }); + } + + public EmailThread(String e, String p) { + email = e; + pad = p; + } + } + + private void emailBoxKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_emailBoxKeyTyped + emailBtn.setEnabled(License.checkEmail(emailBox.getText())); + }//GEN-LAST:event_emailBoxKeyTyped + private void toClipboard(String text) { StringSelection stringSelection = new StringSelection(text); Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); @@ -164,7 +266,10 @@ public class SharePad extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton copyIDBtn; private javax.swing.JButton copyLinkBtn; + private javax.swing.JTextField emailBox; + private javax.swing.JButton emailBtn; private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; private javax.swing.JPanel jPanel1; private javax.swing.JTextField padIDBox; // End of variables declaration//GEN-END:variables