Package primarydatamanager.mirrorupdater

Source Code of primarydatamanager.mirrorupdater.MirrorUpdater

/*
* TV-Browser
* Copyright (C) 04-2003 Martin Oberhauser (darras@users.sourceforge.net)
*
* 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.
*
* CVS information:
*  $RCSfile$
*   $Source$
*     $Date: 2010-06-28 19:33:48 +0200 (Mon, 28 Jun 2010) $
*   $Author: bananeweizen $
* $Revision: 6662 $
*/
package primarydatamanager.mirrorupdater;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Locale;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import primarydatamanager.mirrorupdater.config.Configuration;
import primarydatamanager.mirrorupdater.config.PropertiesConfiguration;
import primarydatamanager.mirrorupdater.data.DataSource;
import primarydatamanager.mirrorupdater.data.DataTarget;
import primarydatamanager.tvlistingstool.HtmlMirrorVisualizer;
import primarydatamanager.tvlistingstool.MirrorVisualizer;
import tvbrowserdataservice.file.ChannelList;
import tvbrowserdataservice.file.DayProgramFile;
import tvbrowserdataservice.file.SummaryFile;
import util.io.Mirror;
import util.io.VerySimpleFormatter;
import devplugin.Channel;
import devplugin.Date;

/**
*
*
* @author Til Schneider, www.murfman.de
*/
public class MirrorUpdater {

  private static final Logger mLog = Logger.getLogger(MirrorUpdater.class.getName());
 
  private static final int MAX_DAYS_WITHOUT_DATA = 14;

  private DataSource mDataSource;
  private DataTarget mDataTarget;
  private String mPrimaryServerUrl;
 
  private Date mDeadlineDay;
 
  private String[] mChannelGroupArr;
  private String[] mTargetFileArr;
   
  private static final String PROGRAM_TITLE = "MirrorUpdater for TV-Browser v0.2";


  public MirrorUpdater(Configuration config) {
    Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit").setLevel(Level.INFO);
    mDataSource = config.getDataSource();
    mDataTarget = config.getDataTarget();
    mPrimaryServerUrl = config.getPrimaryServerUrl();
    mChannelGroupArr=config.getChannelgroups();
    mDeadlineDay = new Date().addDays(-2);
  }
   

  public void updateMirror() throws UpdateException {
    try {
      // First have a look what we already have on the mirror
      mTargetFileArr = mDataTarget.listFiles();
     
      // Delete the outdated files
      for (int i = 0; i < mTargetFileArr.length; i++) {
        if (isDayProgramFile(mTargetFileArr[i])) {
          if (! dayProgramFileIsUpToDate(mTargetFileArr[i])) {
            mDataTarget.deleteFile(mTargetFileArr[i]);
          }
        }
      }
     
      // Get the channellist
      Channel[] channelArr = updateChannelLists();
     
      // Update the day programs for all channels
      for (Channel element : channelArr) {
        for (int j = 0; j < DayProgramFile.getLevels().length; j++) {
          updateDayProgramsFor(element, DayProgramFile.getLevels()[j].getId());
        }
      }
     
      // Update the meta files
      updateMetaFiles(channelArr);
     
      if (mChannelGroupArr != null) {
        MirrorVisualizer visualizer = new HtmlMirrorVisualizer(mDataSource, mDataTarget, mChannelGroupArr);
        visualizer.visualize();
      }
     
    }
    finally {
      // Close data source and data target
      mDataSource.close();
      mDataTarget.close();
    }
  }
 
 
 
  private boolean isDayProgramFile(String fileName) {
    return fileName.endsWith(".prog.gz");
  }



  private boolean dayProgramFileIsUpToDate(String fileName)
    throws UpdateException
  {
    try {
      int year = Integer.parseInt(fileName.substring(0, 4));
      int month = Integer.parseInt(fileName.substring(5, 7));
      int day = Integer.parseInt(fileName.substring(8, 10));
      Date date = new Date(year, month, day);
     
      return date.compareTo(mDeadlineDay) >= 0;
    }
    catch (Exception exc) {
      throw new UpdateException("Day program file name has wrong pattern: "
        + fileName, exc);
    }
  }


  private Channel[] updateChannelLists() throws UpdateException {
   
    HashSet<Channel> channelSet=new HashSet<Channel>();
    for (String element : mChannelGroupArr) {
      Channel[] ch=updateChannelList(element);
      for (Channel element2 : ch) {
        channelSet.add(element2);
      }
    }
   
    Channel[] channels=new Channel[channelSet.size()];
    channelSet.toArray(channels);
    return channels;
   
  }


  private Channel[] updateChannelList(String groupname) throws UpdateException {
    byte[] data = mDataSource.loadFile(groupname+"_"+ChannelList.FILE_NAME);
   
    // Read the channel list
    Channel[] channelArr;
    try {
      ByteArrayInputStream stream = new ByteArrayInputStream(data);
     
      ChannelList list = new ChannelList(groupname);
      list.readFromStream(stream, null);
      channelArr = list.createChannelArray();
    }
    catch (Exception exc) {
      throw new UpdateException("Reading channel list for group "+groupname+" failed", exc);
    }
   
    // Store the (new) channel list
    mDataTarget.writeFile(groupname+"_"+ChannelList.FILE_NAME, data);
   
    return channelArr;
  }



  public void updateDayProgramsFor(Channel channel, String level)
    throws UpdateException
  {
    Date date = new Date().addDays(-1);
    int daysWithNoData = 0;
   
    while (daysWithNoData < MAX_DAYS_WITHOUT_DATA) {
      String completeFileName = DayProgramFile.getProgramFileName(date,
        channel.getCountry(), channel.getId(), level);
       
      // Check which version is on the source
      // version -1 means there is no version
      int versionAtSource = -1;
      if (mDataSource.fileExists(completeFileName)) {
        versionAtSource = 1;
        boolean finished = false;
        do {
          String updateFileName = DayProgramFile.getProgramFileName(date,
            channel.getCountry(), channel.getId(), level, versionAtSource);
          if (mDataSource.fileExists(updateFileName)) {
            // There is an update file for the current version
            // -> The version of the complete file must be at least one higher
            versionAtSource++;
          } else {
            finished = true;
          }
        } while (! finished);
      }
     
      if (versionAtSource == -1) {
        daysWithNoData++;
      } else {
        daysWithNoData = 0;
       
        // Check which version is on the mirror
        // version -1 means there is no version
        int versionOnMirror = -1;
        if (fileIsOnMirror(completeFileName)) {
          versionOnMirror = 1;
          boolean finished = false;
          do {
            String updateFileName = DayProgramFile.getProgramFileName(date,
              channel.getCountry(), channel.getId(), level, versionOnMirror);
            if (fileIsOnMirror(updateFileName)) {
              // There is an update file for the current version
              // -> The version of the complete file must be at least one higher
              versionOnMirror++;
            } else {
              finished = true;
            }
          } while (! finished);
        }
       
        // Check whether the mirror needs an update
        if (versionOnMirror < versionAtSource) {
          String additionalFileName = null;
          if (versionOnMirror == -1) {
            mLog.fine("Adding version " + versionAtSource
              + ": " + completeFileName);
          } else {
            mLog.fine("Updating from version "
              + versionOnMirror + " to " + versionAtSource
              + ": " + completeFileName);
          }
         
         
          int index = completeFileName.indexOf("_update_");
           
          if(index != -1) {
            additionalFileName = completeFileName.substring(0,index) + completeFileName.substring(index+8,completeFileName.indexOf(".prog.gz")) + "_additional.prog.gz";
          } else {
            additionalFileName = completeFileName.substring(0,completeFileName.indexOf(".prog.gz")) + "_additional.prog.gz";
          }

          mLog.log(Level.INFO, "Checking for old additional file: " + additionalFileName);
          for(String value : mTargetFileArr) {
            if(value.compareTo(additionalFileName) == 0) {
              mLog.fine("Deleting old additional file: " + additionalFileName);
              mDataTarget.deleteFile(additionalFileName);
              break;
            }
          }

          if(mDataSource.fileExists(additionalFileName)) {
            mLog.fine("Adding new additional file: " + additionalFileName);
            byte[] data = mDataSource.loadFile(additionalFileName);
            mDataTarget.writeFile(additionalFileName, data);
          }
                     
         
          // Update the mirror
          byte[] data = mDataSource.loadFile(completeFileName);
          mDataTarget.writeFile(completeFileName, data);
         
          for (int version = 0; version < versionAtSource; version++) {
            String updateFileName = DayProgramFile.getProgramFileName(date,
              channel.getCountry(), channel.getId(), level, version);

            data = mDataSource.loadFile(updateFileName);
            mDataTarget.writeFile(updateFileName, data);
          }
        } else {
          mLog.fine("File already up to date (version " + versionOnMirror + "): "
            + completeFileName);
        }
      }
     
      // Go on with the next day
      date = date.addDays(1);
    }
  }



  private boolean fileIsOnMirror(String fileName) {
    for (String element : mTargetFileArr) {
      if (element.equals(fileName)) {
        return true;
      }
    }
   
    return false;
  }

  private void writeGroupFile(DataTarget target, byte[] data, String fName) throws UpdateException {
   
    for (String group : mChannelGroupArr) {
      target.writeFile(group+"_"+fName, data);
    }
  }

  private void copyGroupFile(DataTarget target, DataSource source, String fName) throws UpdateException {
   
    for (String group : mChannelGroupArr) {
      byte[] data = mDataSource.loadFile(group+"_"+fName);
      target.writeFile(group+"_"+fName, data);
    }
   
  }

  private void updateMetaFiles(Channel[] channelArr) throws UpdateException {
    byte[] data;
   
    // Create the primaryserver file
    data = mPrimaryServerUrl.getBytes();
    mDataTarget.writeFile("primaryserver", data);

    // Copy the mirrorlist.gz
    copyGroupFile(mDataTarget,mDataSource,Mirror.MIRROR_LIST_FILE_NAME);
   
    // Copy the summary.gz
    //copyGroupFile(mDataTarget,mDataSource,SummaryFile.SUMMARY_FILE_NAME);
    if (mChannelGroupArr!=null) {
      for (String group : mChannelGroupArr) {
        data = mDataSource.loadFile(group+"_"+SummaryFile.SUMMARY_FILE_NAME);
        mDataTarget.writeFile(group+"_"+SummaryFile.SUMMARY_FILE_NAME, data);
      }
    }
   
   
    // Copy the group files
    if (mChannelGroupArr!=null) {
      for (String element : mChannelGroupArr) {
        data = mDataSource.loadFile(element+"_info");
        mDataTarget.writeFile(element+"_info", data);
      }
    }
   
    // Create the lastupdate file
    Calendar cal = Calendar.getInstance();
    int year = cal.get(Calendar.YEAR);
    int month = cal.get(Calendar.MONTH) + 1;
    int day = cal.get(Calendar.DAY_OF_MONTH);
    int hour = cal.get(Calendar.HOUR_OF_DAY);
    int minute = cal.get(Calendar.MINUTE);
    int second = cal.get(Calendar.SECOND);
    String lastUpdate = year + "-"
      + ((month < 10? "0" : "") + month  + "-"
      + ((day < 10)    ? "0" : "") + day    + " "
      + ((hour < 10)   ? "0" : "") + hour   + ":"
      + ((minute < 10) ? "0" : "") + minute + ":"
      + ((second < 10) ? "0" : "") + second;
    data = lastUpdate.getBytes();
   
    writeGroupFile(mDataTarget,data,"lastupdate");
   
  }



 
  private String createIndexHtmlOLD(Channel[] channelArr) {
    StringBuilder buffer = new StringBuilder(1024);
   
    buffer.append("<html><head>");
    buffer.append("<title>TV-Browser Mirror</title>");
    buffer.append("</head><body>");
    buffer.append("<p>This is a mirror of <code>");
    buffer.append(mPrimaryServerUrl + "</code> for the ");
    buffer.append("<a href=\"http://www.tvbrowser.org\">TV-Browser project</a>.</p>");
   
    buffer.append("<p><b>Warning:</b> The data provided here may only be used ");
    buffer.append("by the TV-Browser project. Any other use is illegal!</p>");
   
    buffer.append("The mirror was last updated on <code>");
    DateFormat format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
      DateFormat.MEDIUM, Locale.UK);
    buffer.append(format.format(new java.util.Date()));
    buffer.append("</code>.</p>");

    buffer.append("<p>It contains the TV-Data of the following channels:");
    buffer.append("<ul>");
    for (Channel element : channelArr) {
      buffer.append("<li><code>" + element.getName()
        + "</code> from <code>" + element.getCountry() + "</code></li>");
    }
    buffer.append("</ul></p>");

    buffer.append("</body></html>");
   
    return buffer.toString();
  }


 
  public static void main(String[] args) {
    System.out.println(PROGRAM_TITLE);
    String configFileName;
   
    if (args.length>0) {
      configFileName=args[0];
    }
    else {
      configFileName="config/MirrorUpdater.ini";
    }
   
    // setup logging
    try {
      // Get the default Logger
      Logger mainLogger = Logger.getLogger("");
      mainLogger.setLevel(Level.FINEST);
     
      Handler consoleHandler = mainLogger.getHandlers()[0];
      consoleHandler.setLevel(Level.FINEST);
      consoleHandler.setFormatter(new VerySimpleFormatter());
     
      // Add a file handler
      new File("log").mkdir();
      Handler fileHandler = new FileHandler("log/mirrorupdater.log", 50000, 2, true);
      fileHandler.setLevel(Level.INFO);
      mainLogger.addHandler(fileHandler);
    }
    catch (IOException exc) {
      System.out.println("Can't create log file");
    }

    // Set the String to use for indicating the user agent in http requests
    System.setProperty("http.agent", PROGRAM_TITLE);

    // Start the update
   
    try {
      Configuration config = new PropertiesConfiguration(configFileName);
      MirrorUpdater updater = new MirrorUpdater(config);
      updater.updateMirror();
    }
    catch (UpdateException exc) {
      exc.printStackTrace();
    }
  }

}
TOP

Related Classes of primarydatamanager.mirrorupdater.MirrorUpdater

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.