Click here to Skip to main content
15,897,371 members
Articles / Web Development / HTML

Mambo CMS Article Control

Rate me:
Please Sign up or sign in to vote.
4.60/5 (5 votes)
23 Oct 2011CPOL13 min read 26.5K   1.7K   9  
The code implements a system to create articles using MS-Word for use in the Mambo CMS. The majority of the code is a C# project that reads and parses HTML text created using MS Word. The support projects are a VBA macro for creating the needed HTML and an export/import system for getting localhost
//
// Text2Mambo - convert HTML to mambo CMS
// Copyright (C) 2009-2011 John Janssen
// http://www.travelisfun.org 
//
// This program is free software; you can redistribute it and/or modify
// it any way you want as long as the above copyright statement is maintained.
//
// 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.  
//

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Security;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Reflection;
using Microsoft.Win32;
using Text2Mambo.Tools;
using TIFTools;

namespace Text2Mambo.Controls
{
  public partial class UCSyncOnline : MyUserControl
  {
    enum COPYMETHOD
    {
      CopyAll,
      CopySizeDiffers,
      CopyTimeDiffers,
      CopySizeTimeDiffers
    }

    enum WORKERSTATUS
    {
      Start,
      TryLogin,
      CheckFolders,
      CollectFileInfo,
      CopyFiles,
      Finished
    }

    private Collection<FileObject> files = new Collection<FileObject>();

    private class SynchronizeObject
    {
      public Collection<String> RemoteFolders = new Collection<string>();
      public Collection<FileObject> RemoteFiles = new Collection<FileObject>();
      public WORKERSTATUS WorkerStatus = WORKERSTATUS.Start;
      public COPYMETHOD CopyMethod = COPYMETHOD.CopyAll;
      public Collection<FileObject> LocalFiles;
      public String RemoteImportFolder;
      public String RemoteImageBaseFolder;

      private FTPCredentials credentials = null;
      public BackgroundWorker worker = null;
      public FTPTools ftpTools = new FTPTools();
      public Dictionary<String, Collection<FTPFileInfo>> RemoteFileInfo = new Dictionary<string, Collection<FTPFileInfo>>();

      public SynchronizeObject(Collection<FileObject> files)
      {
        LocalFiles = files;
      }

      public FTPCredentials Credentials
      {
        set { credentials = value; }
        get { return credentials; }
      }

      public void AddRemotePath(String folder)
      {
        folder = folder.Replace('\\', '/');
        if (!RemoteFolders.Contains(folder))
          RemoteFolders.Add(folder);
      }
      /// <summary>
      /// This is a bastard of a method.
      /// It looks if for the corresponding local file a file on the server exist.
      /// This file should be in the RemoteFileInfo dictionary
      /// So mapping something like:
      ///             Local                                   remote
      ///  relative   images\2011september\image001.jpg       images\2011september\image001.jpg
      ///  prefix     c:\websites\apache\htdocs\mambo         ftp.travelisfun.org/htdocs/mambo/images 
      /// </summary>
      /// <param name="fo"></param>
      /// <returns></returns>
      public FTPFileInfo FindRemoteFile(FileObject fo)
      {
        // The first is finding the correct dictionary entry, mapping the remote path
        Collection<FTPFileInfo> list;
        try
        {
          list = RemoteFileInfo[Path.GetDirectoryName(fo.RemoteFilename)];
          String fn = Path.GetFileName(fo.FullFilename);
          var ffi = (from a in list where a.Name == fn select a).First();
          return ffi; 
        }
        catch
        {
          return null;
        }
      }
    }

    private SynchronizeObject syncObject = null;

    public UCSyncOnline()
    {
      InitializeComponent();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override String ToString()
    {
      return "Sync online";
    }
    /// <summary>
    /// 
    /// </summary>
    public override void Closing()
    {
      base.Closing();
    }

    private delegate void ClearListDelegate();
    public void ClearList()
    {
      files.Clear();
      if (checkedListBox1.InvokeRequired)
        this.BeginInvoke(new ClearListDelegate(ClearList), null);
      else
        checkedListBox1.Items.Clear();
    }

    private delegate void RefreshListViewDelegate();
    private void RefreshListView()
    {
      if (checkedListBox1.InvokeRequired)
      {
        this.BeginInvoke(new RefreshListViewDelegate(RefreshListView), null);
      }
      else
      {
        checkedListBox1.BeginUpdate();
        checkedListBox1.Items.Clear();
        foreach (FileObject fo in files)
        {
          int index = checkedListBox1.Items.Add(fo);
          checkedListBox1.SetItemChecked(index, fo.Process);
        }
        checkedListBox1.EndUpdate();
      }
    }

    /// <summary>
    /// Adding a file to the upload file list.
    /// </summary>
    /// <param name="filename"></param>
    /// <param name="type"></param>
    public void AddFile(String filename, FileObject.FileType type)
    {
      foreach (FileObject fo in files)
      {
        if (fo.Filename == filename)
          return;
      }
      files.Add(new FileObject(filename, type));
      RefreshListView();
    }
    /// <summary>
    /// Adding a file to the upload file list.
    /// </summary>
    /// <param name="filename"></param>
    /// <param name="absPath"></param>
    /// <param name="type"></param>
    public void AddFile(String filename, String absPath, FileObject.FileType type)
    {
      foreach (FileObject fo in files)
      {
        if (fo.Filename == filename)
          return;
      }
      files.Add(new FileObject(filename, absPath, type));
      RefreshListView();
    }
    /// <summary>
    /// Adding files to the upload file list.
    /// </summary>
    /// <param name="filenames"></param>
    /// <param name="type"></param>
    public void AddFiles(String[] filenames, FileObject.FileType type)
    {
      foreach (String s in filenames)
      {
        files.Add(new FileObject(s, type));
      }
      RefreshListView();
    }
    /// <summary>
    /// 
    /// </summary>
    private void ReadRegistry()
    {
      textBoxLocalImageBase.Text = ProgramSettings.GetRegValue(@"SyncOnline\LocalImageBase", MyGenericTools.GetApacheRootPath());
      textBoxRemoteImportFolder.Text = ProgramSettings.GetRegValue(@"SyncOnline\ImportFolder", "/htdocs/mambo");
      textBoxRemoteImageBase.Text = ProgramSettings.GetRegValue(@"SyncOnline\ImageBase", "/htdocs/mambo/images");

      int i = ProgramSettings.GetRegValue(@"SyncOnline\CopySetting", 0);
      radioButtonCopyAlways.Checked = (i == 0);
      radioButtonCopySizeDiff.Checked = (i == 1);
      radioButtonSizeAndTime.Checked = (i == 2);
    }
    /// <summary>
    /// 
    /// </summary>
    private void WriteRegistry()
    {
      ProgramSettings.SetRegValue(@"SyncOnline\LocalImageBase", textBoxLocalImageBase.Text);
      ProgramSettings.SetRegValue(@"SyncOnline\ImportFolder", textBoxRemoteImportFolder.Text);
      ProgramSettings.SetRegValue(@"SyncOnline\ImageBase", textBoxRemoteImageBase.Text);
      int i = 0;
      if (radioButtonCopyAlways.Checked)
        i = 0;
      else if (radioButtonCopySizeDiff.Checked)
        i = 1;
      else if (radioButtonSizeAndTime.Checked)
        i = 2;
      ProgramSettings.SetRegValue(@"SyncOnline\CopySetting", i);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="Enabled"></param>
    private void EnableExportButtons(bool Enabled)
    {
      buttonSyncOnline.Enabled = Enabled;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonSyncOnline_Click(object sender, EventArgs e)
    {
      WriteRegistry();

      if (backgroundWorker.IsBusy)
      {
        if (MessageBox.Show("A copy transaction is already running.\x0D\x0A" +
            "Should this  acion be cancelled?",
          "Text2Mambo",
          MessageBoxButtons.YesNo,
          MessageBoxIcon.Question) == DialogResult.No)
        {
          return;
        }
        backgroundWorker.CancelAsync();
        while (backgroundWorker.IsBusy)
          Thread.Sleep(100);
      }

      listBoxStatus.Items.Clear();

      toolStripStatusLabel1.Text = "Synchronize running";

      // Set those fileobject.process property to false if the 
      // object is not checked in the checkedlistbox.
      foreach (Object o in checkedListBox1.Items)
      {
        FileObject fo = o as FileObject;
        if (fo.Process)
        {
          if (!checkedListBox1.CheckedItems.Contains(o))
            fo.Process = false;
        }
      }

      // No determine the full path of each file and fill in the fileinfo.
      foreach (FileObject fo in files)
      {
        if (fo.Process)
        {
          if (!fo.SetInfo(textBoxLocalImageBase.Text))
          {
            UpdateStatus("Can't find file: " + fo.FullPath);
            fo.Process = false;
          }
          else
          {
            UpdateStatus("Added file: " + fo.FullPath);
          }
        }
      }

      syncObject = new SynchronizeObject(files);
      syncObject.RemoteImportFolder = textBoxRemoteImportFolder.Text;
      syncObject.RemoteImageBaseFolder = textBoxRemoteImageBase.Text;
      syncObject.Credentials = MainForm.FtpLogin.ftpCredentials;
      syncObject.ftpTools.ReportStatus = UpdateStatus;
      if (radioButtonCopyAlways.Checked)
        syncObject.CopyMethod = COPYMETHOD.CopyAll;
      else if (radioButtonCopySizeDiff.Checked)
        syncObject.CopyMethod = COPYMETHOD.CopySizeDiffers;
      else if (radioButtonSizeAndTime.Checked)
        syncObject.CopyMethod = COPYMETHOD.CopySizeTimeDiffers;

      backgroundWorker.RunWorkerAsync(syncObject);

    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonFolderBrowse_Click(object sender, EventArgs e)
    {
      folderBrowserDlg.RootFolder = Environment.SpecialFolder.Desktop;
      folderBrowserDlg.SelectedPath = textBoxLocalImageBase.Text;
      if (folderBrowserDlg.ShowDialog() == DialogResult.OK)
      {
        textBoxLocalImageBase.Text = folderBrowserDlg.SelectedPath;
        WriteRegistry();
      }
    }
    private void UpdateStatus(String line)
    {
      UpdateStatus(line, -1, 0);
    }

    private delegate void AddStatusDelegate(String line, int maxPos, int curPos);
    private void UpdateStatus(String line, int maxPos, int curPos)
    {
      if (listBoxStatus.InvokeRequired)
      {
        listBoxStatus.Invoke(new AddStatusDelegate(UpdateStatus), new Object[] { line, maxPos, curPos });
      }
      else
      {
        if (maxPos != -1)
        {
          toolStripStatusLabel2.Text = line;
          toolStripProgressBar1.Maximum = maxPos;
          toolStripProgressBar1.Value = curPos;
          line = String.Format("{0} Done {1}%", line, (curPos * 100) / maxPos);
        }
        listBoxStatus.SelectedIndex = listBoxStatus.Items.Add(line);
        //listBoxStatus.Update();
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void UCSyncOnline_Load(object sender, EventArgs e)
    {
      BackColor = ProgramSettings.TabPageBackColor;
      ResizeToParent();

      ReadRegistry();
      webBrowser.AllowNavigation = false;

      toolStripStatusLabel1.Text = String.Empty;
      toolStripStatusLabel2.Text = String.Empty;
      toolTip1.SetToolTip(webBrowser, "Read this help text to understand what this software does, a little bit then.");
      toolTip1.SetToolTip(listBoxStatus, "The status of the synchronizing process.");
      toolTip1.SetToolTip(textBoxRemoteImageBase, "Remote paths must be written with forward slaces.");
      toolTip1.SetToolTip(textBoxRemoteImportFolder, "The folder where the import.php script is located.");

      panel1.Left = checkedListBox1.Left + checkedListBox1.Width - 1;
      panel1.Top = checkedListBox1.Top;
      panel1.Height = checkedListBox1.Height;

      listBoxStatus.Top = checkedListBox1.Top + checkedListBox1.Height - 1;
      listBoxStatus.Left = checkedListBox1.Left;
      listBoxStatus.Width = checkedListBox1.Width + panel1.Width - 1;

      SetWebbrowserText();

      // If the webbrowser.Visible is set the true in the designer then
      // the Load event is not fired correctly.
      webBrowser.Visible = true;
    }
    /// <summary>
    /// 
    /// </summary>
    private void SetWebbrowserText()
    {
      webBrowser.SetWebbrowserText(Assembly.GetExecutingAssembly(), "SyncOnline.htm");
      if (webBrowser.DocumentText.Length == 0)
      {
        webBrowser.DocumentText = @"<html><body>Help text is not found.</body></html>";
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
      BackgroundWorker worker = sender as BackgroundWorker;
      SynchronizeObject syncObj = e.Argument as SynchronizeObject;
      syncObj.worker = worker;
      syncObj.ftpTools.ReportStatus = UpdateStatus;

      WORKERSTATUS[] workerSequence = new WORKERSTATUS[]
      { 
        WORKERSTATUS.Start, 
        WORKERSTATUS.TryLogin, 
        WORKERSTATUS.CheckFolders, 
        WORKERSTATUS.CollectFileInfo,
        WORKERSTATUS.CopyFiles,
        WORKERSTATUS.Finished
      };
      int sequenceIndex = 0;

      do
      {
        if (worker.CancellationPending)
        {
          e.Cancel = true;
        }
        else
        {
          switch (workerSequence[sequenceIndex])
          {
            case WORKERSTATUS.Start:
              workerStart(syncObj);
              break;

            case WORKERSTATUS.TryLogin:
              workerLogin(syncObj);
              break;

            case WORKERSTATUS.CheckFolders:
              WorkerCheckFolders(syncObj);
              break;

            case WORKERSTATUS.CollectFileInfo:
              WorkerCollectFileInfo(syncObj);
              break;

            case WORKERSTATUS.CopyFiles:
              WorkerCopyFiles(syncObj);
              syncObj.WorkerStatus = WORKERSTATUS.Finished;
              break;
          }
          if (++sequenceIndex >= workerSequence.Length)
            break;
        }
      } while (!e.Cancel && syncObj.WorkerStatus != WORKERSTATUS.Finished);

      // delete the Sync object.
      syncObj = null;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="syncObj"></param>
    private void workerStart(SynchronizeObject syncObj)
    {
      syncObj.WorkerStatus = WORKERSTATUS.TryLogin;
      return;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="syncObj"></param>
    /// <returns></returns>
    private bool workerLogin(SynchronizeObject syncObj)
    {
      UpdateStatus(String.Format("Login in using: {0}, {1}",
        syncObj.Credentials.Host, syncObj.Credentials.Username));
      
      try
      {
        syncObj.ftpTools.ListDirectory(syncObj.Credentials, "/");
      }
      catch (Exception ex)
      {
        UpdateStatus("Failed login: " + ex.Message);
        syncObj.WorkerStatus = WORKERSTATUS.Finished;
        return false;
      }
      return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="syncObj"></param>
    private void WorkerCheckFolders(SynchronizeObject syncObj)
    {
      foreach (FileObject fo in syncObj.LocalFiles)
      {
        if (fo.Type == FileObject.FileType.Configuration)
        {
          fo.RemoteFilename = Path.Combine(syncObj.RemoteImportFolder, Path.GetFileName(fo.FullFilename));
          syncObj.AddRemotePath(syncObj.RemoteImportFolder);
        }
        else if (fo.Type == FileObject.FileType.ImageFile)
        {
          String imagePath = MyGenericTools.SpecialCombine(syncObj.RemoteImageBaseFolder, fo.Filename);
          imagePath = Path.GetDirectoryName(imagePath);
          fo.RemoteFilename = Path.Combine(imagePath, Path.GetFileName(fo.FullFilename));
          syncObj.AddRemotePath(imagePath);
        }
      }

      // Create all the folders that are needed.
      // No check if they already exists.
      foreach (String folder in syncObj.RemoteFolders)
      {
        try
        {
          syncObj.ftpTools.MkDir(syncObj.Credentials, folder);
        }
        catch
        {
          // do nothing.
        }
      }
      syncObj.WorkerStatus = WORKERSTATUS.CollectFileInfo;
    }
    /// <summary>
    /// Retrieve 
    /// </summary>
    /// <param name="syncObj"></param>
    private void WorkerCollectFileInfo(SynchronizeObject syncObj)
    {
      if (syncObj.CopyMethod == COPYMETHOD.CopyAll)
        return;

      foreach (String folder in syncObj.RemoteFolders)
      {
        if (syncObject.worker.CancellationPending)
          return;

        // retrieve the directionary information fro all the entries in the folder.
        syncObj.RemoteFileInfo[folder] = syncObj.ftpTools.GetFolderListInfo(syncObj.Credentials, folder);
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="syncObj"></param>
    private void WorkerCopyFiles(SynchronizeObject syncObj)
    {
      foreach (FileObject fo in syncObj.LocalFiles)
      {
        if (syncObj.worker.CancellationPending)
          return;

        if (!fo.Process)
          continue;

        bool copy = false;
        FTPFileInfo remoteFile = syncObj.FindRemoteFile(fo);
        if (remoteFile == null) // does the remote file exists?
        {
          copy = true;
        }
        else
        {
          switch (syncObj.CopyMethod)
          {
            case COPYMETHOD.CopyAll:
              copy = true;
              break;

            case COPYMETHOD.CopySizeDiffers:
              copy = (fo.FileSize != remoteFile.Size);
              break;

            case COPYMETHOD.CopySizeTimeDiffers:
              copy = (fo.FileSize != remoteFile.Size || fo.LastWriteTime > remoteFile.FileTime);
              break;

            case COPYMETHOD.CopyTimeDiffers:
              copy = (fo.LastWriteTime > remoteFile.FileTime);
              break;
          }
        }
        if (copy)
        {
          syncObj.ftpTools.UploadFile(syncObj.Credentials, fo.FullFilename, fo.RemoteFilename, fo.FileSize);
        }
        fo.Process = false;
        RefreshListView(); // update the list of files.
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      if (e.Cancelled)
      {
        UpdateStatus("Sync online cancelled.");
      }
      else
      {
        UpdateStatus("Sync online is finished.");
      }
      toolStripStatusLabel1.Text = "Synchronize stopped.";
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {

    }
  }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
South Africa South Africa
Started in 1988 programming in Pascal, making a 68000 emulator on a DOS platform. Then from Pascal to Clipper, to C++ and now using C#. I've been programming for all walks of businesses; opticians, opthomologist, carbage collectors, reinforcement steel producers, retail chains, and more.
I'm now travelling through Africa with a home-build expedition truck.

Comments and Discussions