#30 WIP - adds radio reference web service lookup of broadcastify feed settings dialog.

This commit is contained in:
Denny
2016-12-09 19:50:14 -05:00
parent f44892c62b
commit 293dec8a1c
16 changed files with 809 additions and 41 deletions

View File

@@ -4,13 +4,7 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/imports/async-http-client-2.0.18.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/async-http-client-netty-utils-2.0.18.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-buffer-4.0.42.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-common-4.0.42.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/slf4j-api-1.7.21.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-codec-http-4.0.42.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-codec-4.0.42.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-transport-4.0.42.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-handler-4.0.42.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-transport-native-epoll-4.0.42.Final-linux-x86_64.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-resolver-dns-2.0.18.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-resolver-2.0.18.jar!/" />
@@ -18,6 +12,21 @@
<root url="jar://$PROJECT_DIR$/imports/reactive-streams-1.0.0.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-reactive-streams-1.0.8.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/javassist-3.20.0-GA.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-buffer-4.1.6.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-codec-4.1.6.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-codec-http-4.1.6.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-common-4.1.6.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-handler-4.1.6.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-resolver-dns-2.0.19.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-transport-4.1.6.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/netty-transport-native-epoll-4.1.6.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/axis.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/jaxrpc.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/commons-discovery-0.2.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/activation-1.1.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/java-mail-1.4.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/wsdl4j-1.5.1.jar!/" />
<root url="jar://$PROJECT_DIR$/imports/radioreference-14.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />

15
.idea/misc.xml generated
View File

@@ -38,20 +38,7 @@
<property name="caretWidth" class="java.lang.Integer" />
</properties>
</component>
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

BIN
imports/activation-1.1.jar Normal file

Binary file not shown.

BIN
imports/axis.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
imports/java-mail-1.4.jar Normal file

Binary file not shown.

BIN
imports/jaxrpc.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
imports/wsdl4j-1.5.1.jar Normal file

Binary file not shown.

View File

@@ -242,18 +242,26 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Audio
public void removeBroadcastConfiguration(BroadcastConfiguration broadcastConfiguration)
{
mLog.debug("Removing broadcast configuration: " + broadcastConfiguration.getName());
if(broadcastConfiguration != null && mBroadcastConfigurations.contains(broadcastConfiguration))
{
int index = mBroadcastConfigurations.indexOf(broadcastConfiguration);
mLog.debug("Removing configuration. Index was:" + index);
mBroadcastConfigurations.remove(broadcastConfiguration);
mLog.debug("Removing configuration from map. Index was:" + index);
mBroadcastConfigurationMap.remove(broadcastConfiguration.getName());
broadcast( new BroadcastEvent( broadcastConfiguration, BroadcastEvent.Event.CONFIGURATION_DELETE) );
mLog.debug("Broadcasting config delete event");
process(new BroadcastEvent( broadcastConfiguration, BroadcastEvent.Event.CONFIGURATION_DELETE));
fireTableRowsDeleted( index, index );
}
else
{
mLog.debug("Config was null or not in the broadcaast configs list");
}
}
/**
@@ -331,10 +339,12 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Audio
*/
private void deleteBroadcaster(String name)
{
mLog.debug("Deleting broadcaster: " + name);
if(name != null && mBroadcasterMap.containsKey(name))
{
AudioBroadcaster audioBroadcaster = mBroadcasterMap.remove(name);
mLog.debug("Found the broadcaster: " + (audioBroadcaster != null));
if(audioBroadcaster != null)
{
audioBroadcaster.stop();
@@ -350,6 +360,7 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Audio
broadcast(new BroadcastEvent(audioBroadcaster, BroadcastEvent.Event.BROADCASTER_DELETE));
}
}
mLog.debug("Finished deleting broadcaster: " + name);
}
private DefaultAsyncHttpClient getDefaultAsyncHttpClient()
@@ -390,15 +401,8 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Audio
/**
* Broadcasts the broadcastAudio configuration change event
*/
public void broadcast( BroadcastEvent event )
private void broadcast(BroadcastEvent event)
{
if( event.getEvent() == BroadcastEvent.Event.CONFIGURATION_CHANGE)
{
int index = mBroadcastConfigurations.indexOf( event.getBroadcastConfiguration() );
fireTableRowsUpdated( index, index );
}
mBroadcastEventBroadcaster.broadcast( event );
}
@@ -416,6 +420,8 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Audio
break;
case CONFIGURATION_CHANGE:
BroadcastConfiguration broadcastConfiguration = broadcastEvent.getBroadcastConfiguration();
int index = mBroadcastConfigurations.indexOf(broadcastConfiguration);
fireTableRowsUpdated( index, index );
//Delete and recreate the broadcaster for any broadcast configuration changes
String previousChannelName = cleanupMapAssociations(broadcastConfiguration);

View File

@@ -93,10 +93,4 @@ public class BroadcastifyConfiguration extends IcecastTCPConfiguration
{
mFeedID = feedID;
}
@Override
public boolean isValid()
{
return super.isValid() && (mFeedID > 0);
}
}

View File

@@ -24,10 +24,12 @@ import audio.broadcast.BroadcastConfigurationEditor;
import audio.broadcast.BroadcastEvent;
import audio.broadcast.BroadcastModel;
import audio.broadcast.BroadcastServerType;
import com.radioreference.api.soap2.UserFeedBroadcast;
import gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import settings.SettingsManager;
import javax.swing.*;
@@ -35,7 +37,7 @@ import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEditor
public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEditor implements Listener<UserFeedBroadcast>
{
private final static Logger mLog = LoggerFactory.getLogger( BroadcastifyConfigurationEditor.class );
@@ -44,6 +46,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
private JTextField mPort;
private JTextField mMountPoint;
private JTextField mPassword;
private JTextField mFeedID;
private JButton mSaveButton;
private JButton mResetButton;
private JCheckBox mEnabled;
@@ -58,7 +61,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
private void init()
{
setLayout( new MigLayout( "fill,wrap 2", "[align right][grow,fill]", "[][][][][][][][][][grow,fill]" ) );
setLayout( new MigLayout( "fill,wrap 2", "[align right][grow,fill]", "[][][][][][][][][][][grow,fill]" ) );
setPreferredSize(new Dimension(150,400));
@@ -66,9 +69,31 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
ImageIcon broadcastifyIcon = mSettingsManager.getImageIcon(BroadcastServerType.BROADCASTIFY.getIconName(), 25);
channelLabel.setIcon(broadcastifyIcon);
add(channelLabel, "span, align center");
JButton lookupButton = new JButton("Lookup ...");
lookupButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
final UserFeedSelectionDialog dialog = new UserFeedSelectionDialog(BroadcastifyConfigurationEditor.this);
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
dialog.setLocationRelativeTo(BroadcastifyConfigurationEditor.this);
dialog.setVisible(true);
}
});
}
});
add(new JLabel(""));
add(lookupButton, "grow,wrap");
add(new JLabel("Name:"));
mName = new JTextField();
mName.getDocument().addDocumentListener(this);
@@ -99,6 +124,12 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
mPassword.setToolTipText("Password. See MyBCFY feed details, Technicals tab");
add(mPassword);
add(new JLabel("Feed ID:"));
mFeedID = new JTextField();
mFeedID.getDocument().addDocumentListener(this);
mFeedID.setToolTipText("Feed ID (optional). See MyBCFY feed details");
add(mFeedID);
mEnabled = new JCheckBox("Enabled");
mEnabled.setToolTipText("Enable (checked) or disable this stream");
mEnabled.addActionListener(new ActionListener()
@@ -109,7 +140,8 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
setModified(true);
}
});
add(mEnabled, "span");
add(new JLabel());
add(mEnabled);
mSaveButton = new JButton("Save");
mSaveButton.setEnabled(false);
@@ -162,6 +194,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
mPort.setText(config.getPort() != 0 ? String.valueOf(config.getPort()) : null);
mMountPoint.setText(config.getMountPoint());
mPassword.setText(config.getPassword());
mFeedID.setText(String.valueOf(config.getFeedID()));
mEnabled.setSelected(config.isEnabled());
}
else
@@ -171,6 +204,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
mPort.setText(null);
mMountPoint.setText(null);
mPassword.setText(null);
mFeedID.setText(null);
mEnabled.setSelected(false);
}
@@ -189,6 +223,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
config.setPort(getPort());
config.setMountPoint(mMountPoint.getText());
config.setPassword(mPassword.getText());
config.setFeedID(getFeedID());
config.setEnabled(mEnabled.isSelected());
setModified(false);
@@ -267,4 +302,37 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
return 0;
}
/**
* Parses an Integer from the port text control or returns 0 if the control doesn't contain an integer value.
*/
private int getFeedID()
{
String feedID = mFeedID.getText();
if(feedID != null && !feedID.isEmpty())
{
try
{
return Integer.parseInt(feedID);
}
catch(Exception e)
{
//Do nothing, we couldn't parse the number value
}
}
return 0;
}
@Override
public void receive(UserFeedBroadcast userFeedBroadcast)
{
mName.setText(userFeedBroadcast.getDescr());
mServer.setText(userFeedBroadcast.getHostname());
mPort.setText(userFeedBroadcast.getPort());
mMountPoint.setText(userFeedBroadcast.getMount());
mPassword.setText(userFeedBroadcast.getPassword());
mFeedID.setText(String.valueOf(userFeedBroadcast.getFeedId()));
}
}

View File

@@ -0,0 +1,247 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2016 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
******************************************************************************/
package audio.broadcast.broadcastify;
import com.radioreference.api.soap2.UserFeedBroadcast;
import external.radioreference.RadioReferenceService;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.xml.rpc.ServiceException;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
public class UserFeedSelectionDialog extends JDialog implements DocumentListener
{
private final static Logger mLog = LoggerFactory.getLogger( UserFeedSelectionDialog.class );
private Listener<UserFeedBroadcast> mListener;
private JTextField mUserNameText;
private JTextField mPasswordText;
private JButton mLookupButton;
private JList mUserFeedBroadcastList;
private JButton mOKButton;
public UserFeedSelectionDialog(Listener<UserFeedBroadcast> listener)
{
mListener = listener;
init();
}
private void init()
{
JPanel panel = new JPanel();
panel.setLayout(new MigLayout("","[align right,grow,fill][align left,grow,fill][]","[][][][][grow][]"));
panel.add(new JLabel("Please enter your credentials"), "align left,span");
panel.add(new JLabel("User Name:"));
mUserNameText = new JTextField();
mUserNameText.getDocument().addDocumentListener(this);
panel.add(mUserNameText, "wrap");
panel.add(new JLabel("Password:"));
mPasswordText = new JTextField();
mPasswordText.getDocument().addDocumentListener(this);
panel.add(mPasswordText, "wrap");
mLookupButton = new JButton("Get Feeds");
mLookupButton.setEnabled(false);
mLookupButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
mLookupButton.setEnabled(false);
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
try
{
RadioReferenceService service =
new RadioReferenceService(mUserNameText.getText(), mPasswordText.getText());
UserFeedBroadcast[] feeds = service.getUserFeedBroadcasts();
mUserFeedBroadcastList.setListData(feeds);
}
catch(ServiceException se)
{
JOptionPane.showMessageDialog(UserFeedSelectionDialog.this,
"Unable to create radio reference web service client. See log file.",
"Error", JOptionPane.ERROR_MESSAGE);
mLog.error("Error creating the radio reference web service client", se);
}
catch(RemoteException re)
{
Throwable cause = re.getCause();
if(cause == null)
{
JOptionPane.showMessageDialog(UserFeedSelectionDialog.this,
re.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
else if(cause instanceof UnknownHostException)
{
JOptionPane.showMessageDialog(UserFeedSelectionDialog.this,
"Broadcastify server is unavailable", "No Server",
JOptionPane.ERROR_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(UserFeedSelectionDialog.this,
"An unknown error has occurred. Please see log file.", "" +
"Unknown Error", JOptionPane.ERROR_MESSAGE);
mLog.error("Error retrieving user broadcast feed configurations from radio reference " +
"service: ", re);
}
}
mLookupButton.setEnabled(true);
}
});
}
});
panel.add(mLookupButton,"grow,span");
mUserFeedBroadcastList = new JList();
mUserFeedBroadcastList.setVisibleRowCount(3);
mUserFeedBroadcastList.setLayoutOrientation(JList.VERTICAL);
mUserFeedBroadcastList.setCellRenderer(new CellRenderer());
mUserFeedBroadcastList.addListSelectionListener(new ListSelectionListener()
{
@Override
public void valueChanged(ListSelectionEvent e)
{
mOKButton.setEnabled(mUserFeedBroadcastList.getSelectedValue() != null);
}
});
JScrollPane listScrollPane = new JScrollPane(mUserFeedBroadcastList);
panel.add(listScrollPane, "grow,span");
mOKButton = new JButton("Ok");
mOKButton.setEnabled(false);
mOKButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
if(mListener != null)
{
mListener.receive((UserFeedBroadcast)mUserFeedBroadcastList.getSelectedValue());
}
dispose();
}
});
panel.add(mOKButton,"grow");
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
dispose();
}
});
panel.add(cancelButton, "wrap");
setTitle("Broadcastify Feed Lookup");
setLayout(new BorderLayout());
add(panel, BorderLayout.CENTER);
setSize(300,250);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setModalityType(ModalityType.APPLICATION_MODAL);
}
private void updateButtons()
{
String username = mUserNameText.getText();
String password = mPasswordText.getText();
mLookupButton.setEnabled(username != null && !username.isEmpty() && password != null && !password.isEmpty());
}
@Override
public void insertUpdate(DocumentEvent e)
{
updateButtons();
}
@Override
public void removeUpdate(DocumentEvent e)
{
updateButtons();
}
@Override
public void changedUpdate(DocumentEvent e)
{
updateButtons();
}
private class CellRenderer extends JLabel implements ListCellRenderer<UserFeedBroadcast>
{
public CellRenderer()
{
setOpaque(true);
setHorizontalAlignment(LEFT);
setVerticalAlignment(CENTER);
}
@Override
public Component getListCellRendererComponent(JList<? extends UserFeedBroadcast> list,
UserFeedBroadcast value,
int index,
boolean isSelected,
boolean cellHasFocus)
{
if (isSelected)
{
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
}
else
{
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setText(value.getDescr());
return this; }
}
}

View File

@@ -42,8 +42,7 @@ public class IcecastHTTPConfiguration extends BroadcastConfiguration
}
/**
* Icecast 2.3.x and 2.4.x compatible configuration
* @param format
* Icecast 2.4.x+ compatible configuration
*/
public IcecastHTTPConfiguration(BroadcastFormat format)
{

View File

@@ -0,0 +1,267 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2016 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
******************************************************************************/
package audio.broadcast.icecast;
import alias.AliasModel;
import audio.broadcast.BroadcastConfiguration;
import audio.broadcast.BroadcastConfigurationEditor;
import audio.broadcast.BroadcastEvent;
import audio.broadcast.BroadcastModel;
import audio.broadcast.BroadcastServerType;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import settings.SettingsManager;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class IcecastHTTPConfigurationEditor extends BroadcastConfigurationEditor
{
private final static Logger mLog = LoggerFactory.getLogger( IcecastHTTPConfigurationEditor.class );
private JTextField mName;
private JTextField mServer;
private JTextField mPort;
private JTextField mMountPoint;
private JTextField mPassword;
private JButton mSaveButton;
private JButton mResetButton;
private JCheckBox mEnabled;
public IcecastHTTPConfigurationEditor(BroadcastModel broadcastModel, AliasModel aliasModel,
SettingsManager settingsManager)
{
super(broadcastModel, aliasModel, settingsManager);
init();
}
private void init()
{
setLayout( new MigLayout( "fill,wrap 2", "[align right][grow,fill]", "[][][][][][][][][][grow,fill]" ) );
setPreferredSize(new Dimension(150,400));
JLabel channelLabel = new JLabel("Icecast 2.4+ Stream");
ImageIcon icon = mSettingsManager.getImageIcon(BroadcastServerType.ICECAST_HTTP.getIconName(), 25);
channelLabel.setIcon(icon);
add(channelLabel, "span, align center");
add(new JLabel("Name:"));
mName = new JTextField();
mName.getDocument().addDocumentListener(this);
mName.setToolTipText("Unique name for this stream");
add(mName);
add(new JLabel("Server:"));
mServer = new JTextField();
mServer.getDocument().addDocumentListener(this);
mServer.setToolTipText("Server address (e.g. audio1.icecast.com or localhost)");
add(mServer);
add(new JLabel("Port:"));
mPort = new JTextField();
mPort.getDocument().addDocumentListener(this);
mPort.setToolTipText("Server port number (e.g. 80)");
add(mPort);
add(new JLabel("Mount:"));
mMountPoint = new JTextField();
mMountPoint.getDocument().addDocumentListener(this);
mMountPoint.setToolTipText("Mount point (e.g. \\12345)");
add(mMountPoint);
add(new JLabel("Password:"));
mPassword = new JTextField();
mPassword.getDocument().addDocumentListener(this);
mPassword.setToolTipText("Password for the stream");
add(mPassword);
mEnabled = new JCheckBox("Enabled");
mEnabled.setToolTipText("Enable (checked) or disable this stream");
mEnabled.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
setModified(true);
}
});
add(mEnabled, "span");
mSaveButton = new JButton("Save");
mSaveButton.setEnabled(false);
mSaveButton.setToolTipText("Click to save configuration information");
mSaveButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
save();
}
});
add(mSaveButton);
mResetButton = new JButton("Reset");
mResetButton.setEnabled(false);
mResetButton.setToolTipText("Click to reset any changes you've made since the last save");
mResetButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
setModified(false);
setItem(getItem());
}
});
add(mResetButton);
}
@Override
public void setModified(boolean modified)
{
super.setModified(modified);
mSaveButton.setEnabled(modified);
mResetButton.setEnabled(modified);
}
@Override
public void setItem(BroadcastConfiguration item)
{
super.setItem(item);
if(hasItem())
{
IcecastHTTPConfiguration config = (IcecastHTTPConfiguration)getItem();
mName.setText(config.getName());
mServer.setText(config.getHost());
mPort.setText(config.getPort() != 0 ? String.valueOf(config.getPort()) : null);
mMountPoint.setText(config.getMountPoint());
mPassword.setText(config.getPassword());
mEnabled.setSelected(config.isEnabled());
}
else
{
mName.setText(null);
mServer.setText(null);
mPort.setText(null);
mMountPoint.setText(null);
mPassword.setText(null);
mEnabled.setSelected(false);
}
setModified(false);
}
@Override
public void save()
{
IcecastHTTPConfiguration config = (IcecastHTTPConfiguration)getItem();
if(validateConfiguration())
{
updateConfigurationName(config, mName.getText());
config.setHost(mServer.getText());
config.setPort(getPort());
config.setMountPoint(mMountPoint.getText());
config.setPassword(mPassword.getText());
config.setEnabled(mEnabled.isSelected());
setModified(false);
mBroadcastModel.process(new BroadcastEvent(getItem(), BroadcastEvent.Event.CONFIGURATION_CHANGE));
}
}
/**
* Validates the user specified values in the controls prior to saving them to the configuration
*/
private boolean validateConfiguration()
{
String name = mName.getText();
//A unique stream name is required
if(!mBroadcastModel.isUniqueName(name, getItem()))
{
String message = (name == null || name.isEmpty()) ?
"Please specify a stream name." : "Stream name " + name +
"is already in use.\nPlease choose another name.";
JOptionPane.showMessageDialog(IcecastHTTPConfigurationEditor.this,
message, "Invalid Stream Name", JOptionPane.ERROR_MESSAGE);
mName.requestFocus();
return false;
}
//Server address is optional, but required
if(!validateTextField(mServer, "Invalid Server Address", "Please specify a server address."))
{
return true;
}
//Port is optional, but required
if(!validateIntegerTextField(mPort, "Invalid Port Number", "Please specify a port number (1 <> 65535)", 1, 65535))
{
return true;
}
//Mount Point is optional, but required
if(!validateTextField(mMountPoint, "Invalid Mount Point", "Please specify a mount point."))
{
return true;
}
//Password is optional, but required
if(!validateTextField(mPassword, "Invalid Password", "Please specify a password."))
{
return true;
}
return true;
}
/**
* Parses an Integer from the port text control or returns 0 if the control doesn't contain an integer value.
*/
private int getPort()
{
String port = mPort.getText();
if(port != null && !port.isEmpty())
{
try
{
return Integer.parseInt(port);
}
catch(Exception e)
{
//Do nothing, we couldn't parse the number value
}
}
return 0;
}
}

View File

@@ -0,0 +1,191 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2016 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
******************************************************************************/
package external.radioreference;
import com.radioreference.api.soap2.AuthInfo;
import com.radioreference.api.soap2.RRWsdlLocator;
import com.radioreference.api.soap2.RRWsdlPortType;
import com.radioreference.api.soap2.UserFeedBroadcast;
import com.radioreference.api.soap2.UserInfo;
import org.apache.axis.AxisFault;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.rpc.ServiceException;
import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class RadioReferenceService
{
private final static Logger mLog = LoggerFactory.getLogger( RadioReferenceService.class );
private final SimpleDateFormat SDF = new SimpleDateFormat("MM-dd-yyyy");
public static final String SDRTRUNK_APP_KEY = "88969092";
public static final String RADIO_REFERENCE_API_VERSION = "14";
public static final String SOAP_RPC_RESPONSE_STYLE = "rpc";
private RRWsdlLocator mService = new RRWsdlLocator();
private RRWsdlPortType mClient;
private Long mAccountExpiration;
private AuthInfo mUserAuthorization;
/**
* Creates a SOAP web service client for interaction with the radioreference.com server.
*
* @param username for a premium subscriber
* @param password for a premium subscriber
* @throws ServiceException if the client can't be created
* @throws IllegalArgumentException if either the username or password is null or empty
*/
public RadioReferenceService(String username, String password) throws ServiceException
{
mClient = mService.getRRWsdlPort();
setAuthorizationInformation(username, password);
}
/**
* Sets new premium subscriber user credentials to authenticate to the server.
* @param username for a premium subscriber on radioreference.com
* @param password for a premium subscriber
*/
public void setAuthorizationInformation(String username, String password) throws IllegalArgumentException
{
if(username == null || username.isEmpty() || password == null || password.isEmpty())
{
throw new IllegalArgumentException("Username [" + username + "] and/or password [" + password +
"] cannot be null or empty");
}
mUserAuthorization = new AuthInfo(username, password, SDRTRUNK_APP_KEY, RADIO_REFERENCE_API_VERSION,
SOAP_RPC_RESPONSE_STYLE);
}
/**
* Indicates if the service has a non-null user authorization
*/
public void checkCredentials() throws IllegalArgumentException
{
if(mUserAuthorization == null)
{
throw new IllegalStateException("Authorization information (username/password) required");
}
}
/**
* Account expiration date
*
* @return expiration date in millis since epoch
* @throws AxisFault for remote server errors
* @throws IllegalStateException for null or empty login credentials
* @throws RemoteException for web service client errors
*/
public long getAccountExpirationDate() throws IllegalStateException, RemoteException
{
checkCredentials();
if(mAccountExpiration == null)
{
UserInfo userInfo = mClient.getUserData(mUserAuthorization);
if(userInfo != null)
{
String expiration = userInfo.getSubExpireDate();
if(expiration != null)
{
try
{
mAccountExpiration = SDF.parse(expiration).getTime();
}
catch(Exception e)
{
mLog.error("Couldn't parse account expiration date from web service response: " + expiration, e);
}
}
}
}
return mAccountExpiration;
}
/**
* Indicates if the radio reference user account is active (ie not expired)
*
* @throws IllegalStateException for null or empty login credentials
* @throws RemoteException for web service client errors
*/
public boolean isAccountActive() throws IllegalStateException, RemoteException
{
Long expiration = getAccountExpirationDate();
if(expiration != null)
{
return System.currentTimeMillis() < expiration;
}
return false;
}
public UserFeedBroadcast[] getUserFeedBroadcasts() throws IllegalArgumentException, RemoteException
{
checkCredentials();
return mClient.getUserFeedBroadcasts(mUserAuthorization);
}
public static void main(String[] args)
{
try
{
RadioReferenceService service = new RadioReferenceService("dsheirer", "1dodgeram");
Long expiration = service.getAccountExpirationDate();
mLog.debug("Expiration Date:" + (expiration != null ? new Date(expiration).toString() : "unknown"));
mLog.debug("Is Active: " + service.isAccountActive());
UserFeedBroadcast[] feeds = service.getUserFeedBroadcasts();
for(UserFeedBroadcast feed: feeds)
{
mLog.debug("Feed ID: " + feed.getFeedId() + " Desc:" + feed.getDescr());
}
}
catch(AxisFault af)
{
mLog.debug("Hey, I caught an axis fault!");
mLog.debug("Reason:" + af.getFaultReason());
}
catch(RemoteException re)
{
re.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
mLog.debug("Finished!");
}
}