/*
* P2P-Radio - Peer to peer streaming system
* Project homepage: http://p2p-radio.sourceforge.net/
* Copyright (C) 2003-2004 Michael Kaufmann <hallo@michael-kaufmann.ch>
*
* ---------------------------------------------------------------------------
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------
*/
package p2pradio.sources;
import p2pradio.Radio;
import p2pradio.Messages;
import p2pradio.Metadata;
import p2pradio.logging.Logger;
import java.io.*;
import java.net.*;
public class YellowPages extends Thread
{
public static final int FIRST_WAIT_TIME = 15;
public static final int DEFAULT_WAIT_TIME = 5 * 60;
public static final String YP_HOST = "p2p-radio.sourceforge.net"; //$NON-NLS-1$
public static final String YP_DIR = "/stations/"; //$NON-NLS-1$
public static final int ACTION_ADD = 1;
public static final int ACTION_UPDATE = 2;
public static final int ACTION_REMOVE = 3;
private BroadcastBuffer buffer;
private int port;
private String ID;
private String lastContentType;
private String lastStationName;
private String lastStationURL;
private String lastGenre;
private String lastDescription;
private int waitTime = FIRST_WAIT_TIME;
boolean shutdown = false;
public YellowPages(BroadcastBuffer buffer, int port)
{
super(Messages.getString("YellowPages.THREAD_NAME")); //$NON-NLS-1$
this.buffer = buffer;
this.port = port;
setDaemon(true);
}
public void run()
{
Logger.finer("YellowPages", "YellowPages.THREAD_RUNNING"); //$NON-NLS-1$ //$NON-NLS-2$
try
{
while (true)
{
Thread.sleep(waitTime * 1000);
if (shutdown)
{
return;
}
// Always re-check if the station is public
if (buffer.getMetadata().isPublic())
{
if (ID == null)
{
touchYP(ACTION_ADD);
}
else
{
touchYP(ACTION_UPDATE);
}
}
}
}
catch (Exception e)
{
Logger.severe("YellowPages", "INTERNAL_ERROR", e); //$NON-NLS-1$ //$NON-NLS-2$
}
}
public boolean touchYP(int action)
{
Metadata metadata = buffer.getMetadata();
InputStream inputStream = null;
boolean error = true;
boolean gotID = false;
boolean secondTry = false;
String errorDescription = "Invalid answer"; //$NON-NLS-1$
waitTime = DEFAULT_WAIT_TIME;
if ((ID == null) && ((action == ACTION_UPDATE) || (action == ACTION_REMOVE)))
{
return false;
}
try
{
String url = "http://" + YP_HOST + YP_DIR; //$NON-NLS-1$
if (action == ACTION_ADD)
{
url += "add.php?" + getMetadataString(metadata); //$NON-NLS-1$
}
else if (action == ACTION_UPDATE)
{
// Save bandwidth if possible
boolean update_everything = true;
update_everything = !(metadata.getContentType().equals(lastContentType)
&& metadata.getStationName().equals(lastStationName)
&& metadata.getStationURL().equals(lastStationURL)
&& metadata.getGenre().equals(lastGenre)
&& metadata.getDescription().equals(lastDescription));
if (update_everything)
{
url += "update.php?" + getUpdateMetadataString(metadata); //$NON-NLS-1$
}
else
{
url += "updateSong.php?" + getUpdateMetadataStringShort(metadata); //$NON-NLS-1$
}
}
else if (action == ACTION_REMOVE)
{
url += "remove.php?ID=" + ID; //$NON-NLS-1$
ID = null;
}
URLConnection urlConnection = new URL(url).openConnection();
// Set the connection parameters
urlConnection.setAllowUserInteraction(false);
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("User-Agent", Radio.NameSlashVersion); //$NON-NLS-1$
urlConnection.setRequestProperty("Accept", "*/*"); //$NON-NLS-1$ //$NON-NLS-2$
inputStream = urlConnection.getInputStream();
// Read the answer
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while ((line = reader.readLine())!= null)
{
if (line.equals("YP: 1")) //$NON-NLS-1$
{
error = false;
}
else if (line.startsWith("ID: ")) //$NON-NLS-1$
{
ID = line.substring(4, line.length());
gotID = true;
}
else if (line.equals("YP: 0")) //$NON-NLS-1$
{
error = true;
}
else if (line.startsWith("Error: ")) //$NON-NLS-1$
{
errorDescription = line.substring(7, line.length());
}
else if (line.startsWith("Interval: ")) //$NON-NLS-1$
{
String interval = line.substring(10, line.length());
try
{
waitTime = Integer.parseInt(interval);
}
catch (NumberFormatException e)
{
waitTime = DEFAULT_WAIT_TIME;
}
}
}
if (error && (action == ACTION_ADD) && gotID)
{
// Maybe the add was unnecessary because the station
// is already listed
// Try to modify it
error = touchYP(ACTION_UPDATE);
secondTry = true;
}
}
catch (IOException e)
{
Logger.fine("YellowPages", "IO_ERROR", e); //$NON-NLS-1$ //$NON-NLS-2$
error = true;
errorDescription = e.getMessage();
}
catch (Exception e)
{
Logger.severe("YellowPages", "INTERNAL_ERROR", e); //$NON-NLS-1$ //$NON-NLS-2$
error = true;
errorDescription = e.getMessage();
}
finally
{
if (inputStream != null)
{
try
{
inputStream.close();
}
catch (IOException e)
{
}
}
}
if (!secondTry)
{
if (!error)
{
updateLastData(metadata);
Logger.fine("YellowPages", "YellowPages.YP_TOUCH_SUCCESSFUL"); //$NON-NLS-1$ //$NON-NLS-2$)
}
else
{
ID = null;
Logger.warning("YellowPages", "YellowPages.YP_TOUCH_FAILED", errorDescription); //$NON-NLS-1$ //$NON-NLS-2$)
}
}
return (!error);
}
private String getMetadataString(Metadata metadata)
{
return "Port=" + port //$NON-NLS-1$
+ encode("ContentType", metadata.getContentType()) //$NON-NLS-1$
+ encode("StationName", metadata.getStationName()) //$NON-NLS-1$
+ encode("StationURL", metadata.getStationURL()) //$NON-NLS-1$
+ encode("Genre", metadata.getGenre()) //$NON-NLS-1$
+ encode("Description", metadata.getDescription()) //$NON-NLS-1$
+ encode("Genre", metadata.getGenre()) //$NON-NLS-1$
+ encode("SongTitle", metadata.getSongTitle()) //$NON-NLS-1$
+ encode("SongURL", metadata.getSongURL()) //$NON-NLS-1$
+ encode("Byterate", Integer.toString(metadata.getByterate())) //$NON-NLS-1$
+ encode("AverageByterate", Integer.toString(metadata.getAverageByterate())); //$NON-NLS-1$
}
private String getUpdateMetadataStringShort(Metadata metadata)
{
return "ID=" + ID //$NON-NLS-1$
+ "&Port=" + port //$NON-NLS-1$
+ encode("SongTitle", metadata.getSongTitle()) //$NON-NLS-1$
+ encode("SongURL", metadata.getSongURL()) //$NON-NLS-1$
+ encode("Byterate", Integer.toString(metadata.getByterate())) //$NON-NLS-1$
+ encode("AverageByterate", Integer.toString(metadata.getAverageByterate())); //$NON-NLS-1$
}
private String getUpdateMetadataString(Metadata metadata)
{
return "ID=" + ID + "&" + getMetadataString(metadata); //$NON-NLS-1$ //$NON-NLS-2$
}
private String encode(String what, String content)
{
try
{
if ((content.length() != 0))
{
return "&" + what + "=" + URLEncoder.encode(content, "ISO-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
else
{
return ""; //$NON-NLS-1$
}
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
return ""; //$NON-NLS-1$
}
}
private void updateLastData(Metadata metadata)
{
lastContentType = metadata.getContentType();
lastStationName = metadata.getStationName();
lastStationURL = metadata.getStationURL();
lastGenre = metadata.getGenre();
lastDescription = metadata.getDescription();
}
public void shutdown()
{
if (ID != null)
{
touchYP(ACTION_REMOVE);
}
}
}