Package swedbtvdataservice

Source Code of swedbtvdataservice.SweDBTvDataService

/*
* SweDBTvDataService.java
*
* Created on den 31 oktober 2005, 13:09
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/

package swedbtvdataservice;

import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
import java.util.Set;
import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.Icon;

import org.apache.commons.lang.StringUtils;

import tvdataservice.SettingsPanel;
import tvdataservice.TvDataUpdateManager;
import util.exc.TvBrowserException;
import util.io.IOUtilities;
import util.io.Mirror;
import util.misc.SoftReferenceCache;
import util.tvdataservice.IconLoader;
import util.ui.Localizer;
import devplugin.Channel;
import devplugin.ChannelGroup;
import devplugin.Date;
import devplugin.Plugin;
import devplugin.PluginInfo;
import devplugin.ProgressMonitor;
import devplugin.Version;

public class SweDBTvDataService extends devplugin.AbstractTvDataService {
  /** The default plugins download URL */
  private static final String DEFAULT_PLUGINS_DOWNLOAD_URL = "http://www.tvbrowser.org/mirrorlists";

  private static final Localizer mLocalizer = Localizer.getLocalizerFor(SweDBTvDataService.class);

  private static final Logger mLog = Logger.getLogger(SweDBTvDataService.class.getName());

  private static final Version VERSION = new Version(3,0);

  private File mWorkingDirectory;

  private DataHydraSettings mSettings = new DataHydraSettings();

  private HashMap<String, DataHydraChannelGroup> mChannelGroups;

  private HashMap<Channel, DataHydraChannelContainer> mInternalChannels = new HashMap<Channel, DataHydraChannelContainer>();

  private HashMap<ChannelGroup, Long> mLastGroupUpdate = new HashMap<ChannelGroup, Long>();

  private ArrayList<Channel> mChannels;

  private SoftReferenceCache<String, File> mIconCache = new SoftReferenceCache<String, File>();

  private boolean mHasRightToDownloadIcons;

  private DataHydraFileParser mParser = new DataHydraFileParser();

  private IconLoader iconLoader;
  static final String SHOW_REGISTER_TEXT = "showRegisterText";

  /**
   * Creates a new instance of SweDBTvDataService
   */
  public SweDBTvDataService() {
    mHasRightToDownloadIcons = false;
    mChannelGroups = new HashMap<String, DataHydraChannelGroup>();
    addGroup(new DataHydraChannelGroup("SweDB", "SweDB.se", "(c) swedb.se", "http://tv.swedb.se", "swedb_channels.xml.gz", "se"));
    addGroup(new DataHydraChannelGroup("MSPC", "mspc.no", "(c) mspc.no", "http://www.mspc.no", "mspc_channels.xml.gz", "no"));
    addGroup(new DataHydraChannelGroup("gonix", "gonix.net", "(c) gonix.net", "http://www.gonix.net", "hrv_channels.xml.gz", "hr", false));
    addGroup(new DataHydraChannelGroup("oztivo", "oztivo.net", "(c) oztivo.net", "http://www.oztivo.net/", "au_channels.xml.gz", "au"));
  }

  private void addGroup(DataHydraChannelGroup dataHydraChannelGroup) {
    mChannelGroups.put(dataHydraChannelGroup.getId(), dataHydraChannelGroup);
  }

  public boolean supportsDynamicChannelList() {
    return true;
  }

  public boolean supportsDynamicChannelGroups() {
    return true;
  }

  public boolean hasSettingsPanel() {
    return false;
  }

  public SettingsPanel getSettingsPanel() {
    return new DataHydraSettingsPanel(mSettings);
  }

  public void setWorkingDirectory(File dataDir) {
    mLog.info("DataHydraTvDataService setting directory to " + dataDir.toString());
    mWorkingDirectory = dataDir;
  }

  /**
   * @return an array of the available channel groups.
   */
  public ChannelGroup[] getAvailableGroups() {
    Set<String> keys = mChannelGroups.keySet();

    final ArrayList<ChannelGroup> groups = new ArrayList<ChannelGroup>();

    for (String key : keys) {
      groups.add(mChannelGroups.get(key));
    }

    return groups.toArray(new ChannelGroup[groups.size()]);
  }

  /**
   * Updates the TV listings provided by this data service.
   *
   * @throws util.exc.TvBrowserException
   */
  public void updateTvData(TvDataUpdateManager updateManager,
                           Channel[] channelArr, Date startDate, int dateCount,
                           ProgressMonitor monitor) throws TvBrowserException {
    // Check for connection
    if (!updateManager.checkConnection()) {
      return;
    }

    mHasRightToDownloadIcons = true;
    mLog.info("Starting update for DataHydraTvDataService from " + startDate.toString() + " for " + dateCount + " days");

    monitor.setMaximum(channelArr.length);
    devplugin.Date testStart = new devplugin.Date(startDate);

    int counter = 0;
    for (Channel channel : channelArr) {
      mParser.loadDataForChannel(this, updateManager, startDate, dateCount, monitor, testStart, mInternalChannels.get(channel), channel);
      monitor.setValue(counter++);
    }

    mHasRightToDownloadIcons = false;
  }

  /**
   * Called by the host-application during start-up. Implement this method to
   * load your data services settings from the file system.
   */
  public void loadSettings(Properties properties) {
    mLog.info("Loading settings in DataHydraTvDataService");

    for (ChannelGroup group : getAvailableGroups()) {
      long lastupdate = Long.parseLong(properties.getProperty("LastChannelUpdate-" + group.getId(), "0"));
      mLastGroupUpdate.put(group, lastupdate);
    }

    int numChannels = Integer.parseInt(properties.getProperty(
            "NumberOfChannels", "0"));

    ArrayList<Channel> channels = new ArrayList<Channel>();

    // create channels sorted by group to avoid recreation of icon loader
    for (ChannelGroup group : getAvailableGroups()) {
      String groupId = group.getId();
      DataHydraChannelGroup dataHydraChannelGroup = mChannelGroups.get(groupId);
      for (int i = 0; i < numChannels; i++) {
        String channelGroupId = properties.getProperty("ChannelGroup-" + i);
        if (channelGroupId == null) {
          channelGroupId = "SweDB";
        }
        if (groupId.equals(channelGroupId)) {
          // create the icon loader on demand to avoid disk access for non used groups
          if (iconLoader == null) {
            initializeIconLoader(dataHydraChannelGroup);
          }
          DataHydraChannelContainer container = new DataHydraChannelContainer(properties.getProperty(
                  "ChannelId-" + i, ""), properties.getProperty("ChannelTitle-" + i,
                  ""), properties.getProperty("ChannelBaseUrl-" + i, ""), properties
                  .getProperty("ChannelIconUrl-" + i, ""), properties.getProperty(
                  "ChannelLastUpdate-" + i, ""));

          Channel ch = createTVBrowserChannel(dataHydraChannelGroup, container);
          mInternalChannels.put(ch, container);
          channels.add(ch);
        }
      }
      closeIconLoader(dataHydraChannelGroup);
    }

    mChannels = channels;
    mSettings.setShowRegisterText(Boolean.parseBoolean(properties.getProperty(SweDBTvDataService.SHOW_REGISTER_TEXT, "true")));

    mLog.info("Finished loading settings for DataHydraTvDataService");
  }

  /**
   * Called by the host-application during shut-down. Implements this method to
   * store your dataservices settings to the file system.
   */
  public Properties storeSettings() {
    mLog.info("Storing settings for DataHydraTvDataService");

    Properties properties = new Properties();
    for (ChannelGroup group : getAvailableGroups()) {
      String value = "0";
      if (mLastGroupUpdate.get(group) != null) {
        value = mLastGroupUpdate.get(group).toString();
      }
      properties.setProperty("LastChannelUpdate-" + group.getId(), value);
    }

    properties.setProperty("NumberOfChannels", Integer.toString(mChannels.size()));

    for (int i = 0; i < mChannels.size(); i++) {
      final Channel channel = mChannels.get(i);
      DataHydraChannelContainer container = mInternalChannels.get(channel);
      properties.setProperty("ChannelId-" + i, container.getId());
      properties.setProperty("ChannelTitle-" + i, container.getName());
      properties.setProperty("ChannelBaseUrl-" + i, container.getBaseUrl());
      properties.setProperty("ChannelIconUrl-" + i, container.getIconUrl());
      properties.setProperty("ChannelLastUpdate-" + i, container.getLastUpdateString());
      properties.setProperty("ChannelGroup-" + i, channel.getGroup().getId());
    }
    properties.setProperty(SweDBTvDataService.SHOW_REGISTER_TEXT, String.valueOf(mSettings.getShowRegisterText()));

    mLog.info("Finished storing settings for DataHydraTvDataService. Returning properties...");
    return properties;
  }

  /**
   * Gets the list of the channels that are available for the given channel
   * group.
   */
  public Channel[] getAvailableChannels(ChannelGroup group) {
    if (mChannels == null) {
      return new Channel[0];
    }
    ArrayList<Channel> tempList = new ArrayList<Channel>();
    for (Channel channel : mChannels) {
      if (channel.getGroup().getId().equalsIgnoreCase(group.getId())) {
        tempList.add(channel);
      }
    }
    return tempList.toArray(new Channel[tempList.size()]);
  }

  public Channel[] checkForAvailableChannels(ChannelGroup group, ProgressMonitor monitor) throws TvBrowserException {
    if (!(group instanceof DataHydraChannelGroup)) {
      return new Channel[0];
    }
    DataHydraChannelGroup hydraGroup = (DataHydraChannelGroup) group;
    mHasRightToDownloadIcons = true;

    Channel[] channels;

    try {
      if (monitor != null) {
        monitor.setMessage(mLocalizer.msg("Progressmessage.10",
                "Getting messages"));
      }

      mLog.log(Level.ALL, "Loading Channel file : " + hydraGroup.getChannelFile());

      String urlMirror = getMirror().getUrl();

      URL url = new URL(urlMirror + (urlMirror.endsWith("/") ? "" : "/") + hydraGroup.getChannelFile());

      // Download the mirror list for the next run
      try {
        IOUtilities.download(new URL(urlMirror + (urlMirror.endsWith("/") ? "" : "/") + "main_" + Mirror.MIRROR_LIST_FILE_NAME), new File(mWorkingDirectory , "main_" + Mirror.MIRROR_LIST_FILE_NAME));
      } catch(Exception ee) {}

      if (monitor != null) {
        monitor.setMessage(mLocalizer.msg("Progressmessage.20",
                "Getting channel list from")
                + " " + hydraGroup.getProviderName());
      }

      long lastUpdate = 0;
      if (mLastGroupUpdate.get(hydraGroup) != null) {
        lastUpdate = mLastGroupUpdate.get(hydraGroup);
      }

      mLog.log(Level.ALL, "Loading URL : " + url.toString());

      HttpURLConnection con = (HttpURLConnection) url.openConnection();
      con.setReadTimeout(Plugin.getPluginManager().getTvBrowserSettings()
              .getDefaultNetworkConnectionTimeout());
      con.setIfModifiedSince(lastUpdate);

      int responseCode = con.getResponseCode();

      if (responseCode == 200) {
        if (monitor != null) {
          monitor.setMessage(mLocalizer.msg("Progressmessage.30",
                  "Parsing channel list"));
        }
        int fileSize = con.getContentLength();
        if (fileSize == 0) {
          throw new TvBrowserException(SweDBTvDataService.class,
              "errorEmptyChannelList",
              "Channel list file for group \"{0}\" is empty: {1}.", group.getName(), url);
        }
        else {
          DataHydraChannelContainer[] DataHydracontainers = DataHydraChannelParser.parse(IOUtilities.openSaveGZipInputStream(con.getInputStream()));

          if (monitor != null) {
            monitor.setMessage(mLocalizer.msg("Progressmessage.40", "Found {0} channels, downloading channel icons...", DataHydracontainers.length));
          }

          mLastGroupUpdate.put(hydraGroup, con.getLastModified());
          con.disconnect();

          ArrayList<Channel> loadedChannels = new ArrayList<Channel>();

          for (DataHydraChannelContainer container : DataHydracontainers) {
            initializeIconLoader(hydraGroup);
            Channel ch = createTVBrowserChannel(hydraGroup, container);
            closeIconLoader(hydraGroup);
            mInternalChannels.put(ch, container);
            loadedChannels.add(ch);
          }

          channels = loadedChannels.toArray(new Channel[loadedChannels.size()]);

          if (monitor != null) {
            monitor.setMessage(mLocalizer.msg("Progressmessage.50",
                    "All channels have been retrieved"));
          }

          /**
           * Update Channel list of the data plugin
           */

          // Remove all Channels of current Group
          Channel[] chs = getAvailableChannels(hydraGroup);
          for (Channel ch : chs) {
            mChannels.remove(ch);
          }

          // Add all Channels for current Group
          mChannels.addAll(loadedChannels);
        }
      } else if (responseCode == 304) {
        channels = getAvailableChannels(hydraGroup);
      } else {
        throw new TvBrowserException(SweDBTvDataService.class,
                "availableResponse",
                "Unknown response during check for available channels in Swedb plugin: {0}", responseCode);
      }
    } catch (Exception e) {
      e.printStackTrace();
      throw new TvBrowserException(SweDBTvDataService.class,
              "checkAvailableError",
              "Error checking for available channels in Swedb plugin: {0}", e
              .getLocalizedMessage());
    }

    mHasRightToDownloadIcons = false;

    return channels;
  }

  private Mirror getMirror() {
    File file = new File(mWorkingDirectory , "main_" + Mirror.MIRROR_LIST_FILE_NAME);

    try {
      return Mirror.chooseUpToDateMirror(Mirror.readMirrorListFromFile(file),null,"DataHydra", "main", SweDBTvDataService.class, mLocalizer.msg("error.additional"," Please inform the TV-Browser team."));
    } catch (Exception exc) {
      try {
        String[] defaultMirrors = getDefaultMirrors();
        if(defaultMirrors.length > 0) {
          Mirror[] mirr = new Mirror[defaultMirrors.length];

          for(int i = 0; i < defaultMirrors.length; i++) {
            mirr[i] = new Mirror(defaultMirrors[i]);
          }

          return Mirror.chooseUpToDateMirror(mirr,null,"DataHydra", "main", SweDBTvDataService.class, mLocalizer.msg("error.additional"," Please inform the TV-Browser team."));
        } else {
          throw exc;
        }
      }catch (Exception exc2) {
        return new Mirror(DEFAULT_PLUGINS_DOWNLOAD_URL);
      }
    }
  }


  private Channel createTVBrowserChannel(DataHydraChannelGroup group, DataHydraChannelContainer container) {
    if (mWorkingDirectory != null) {
      int category = Channel.CATEGORY_TV;

      if (group.getId().equals("MSPC")) {
        if (container.getName().startsWith("[R]")) {
          container.setName(container.getName().substring(4));
          category = Channel.CATEGORY_RADIO;
        }
      }

      Channel channel = new Channel(this, container.getName(),
              container.getId(), TimeZone.getTimeZone("UTC"), group.getCountry(),
              group.getCopyright(), group.getUrl(), group, null, category);

      if (StringUtils.isNotEmpty(container.getIconUrl())) {
        try {
          Icon icon = iconLoader.getIcon(container.getId(), container.getIconUrl());
          channel.setDefaultIcon(icon);
        } catch (IOException e) {
          mLog.severe("Unable to load icon for "
                  + container.getId() + " on URL "
                  + container.getIconUrl());
        }
      }
      return channel;
    } else {
      mLog.info("DataHydraTvDataService: Working directory has not been initialized yet. Icons not loaded");
    }

    return null;
  }

  private void closeIconLoader(DataHydraChannelGroup group) {
    try {
      if (iconLoader != null) {
        iconLoader.close();
      }
    } catch (IOException e) {
      mLog.severe("Unable to close IconLoader for group ID "
              + group.getId() + " in working directory "
              + this.mWorkingDirectory);
    }
    iconLoader = null;
  }

  private void initializeIconLoader(DataHydraChannelGroup group) {
    iconLoader = null;
    try {
      iconLoader = getIconLoader(group.getId(), mWorkingDirectory);
    } catch (IOException e) {
      mLog.severe("Unable to initialize IconLoader for group ID "
              + group.getId() + " in working directory "
              + this.mWorkingDirectory);
    }
  }

  public boolean hasRightToDownloadIcons() {
    return mHasRightToDownloadIcons;
  }

  public SoftReferenceCache<String, File> getIconCache() {
    return mIconCache;
  }

  public ChannelGroup[] checkForAvailableChannelGroups(ProgressMonitor monitor)
          throws TvBrowserException {
    return getAvailableGroups();
  }

  public static Version getVersion() {
    return VERSION;
  }

  public PluginInfo getInfo() {
    return new devplugin.PluginInfo(
            SweDBTvDataService.class,
            mLocalizer.msg("PluginInfo.name", "DataHydra TV-Data Plugin"),
            mLocalizer.msg("PluginInfo.description",
                    "A TV Data Service plugin which uses XMLTV-data from TV.SWEDB.SE and mspc.no"),
            "TV-Browser Team",
            mLocalizer
                    .msg("PluginInfo.support",
                    "Support the SWEDB and the mspc crew - Don't forget to register with http://tv.swedb.se/ and http://www.mspc.no"));
  }

  public boolean getShowRegisterText() {
    return mSettings.getShowRegisterText();
  }

}
TOP

Related Classes of swedbtvdataservice.SweDBTvDataService

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.