///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.Collections;
using System.IO;
using Ini;
using JetBrains.Omea.Base;
using JetBrains.Omea.HTML;
using JetBrains.DataStructures;
namespace JetBrains.Omea.Favorites
{
///
/// the MozillaBookmark class describes properties of a bookmark
///
internal class MozillaBookmark
{
public MozillaBookmark( string id, string Url, string name, int level )
{
_id = id;
_url = Url;
_name = name;
_level = level;
}
public MozillaBookmark( string id, string folder, int level )
{
_id = id;
_folder = folder;
_level = level;
}
public bool IsFolder
{
get { return _folder != null; }
}
public string Id
{
get { return _id; }
}
public string Folder
{
get { return _folder; }
}
public string Url
{
get { return _url; }
}
public string Name
{
get { return _name; }
}
public string Description
{
get { return _description; }
set { _description = value; }
}
public int Level
{
get { return _level; }
}
private string _id;
private string _folder;
private string _url;
private string _name;
private string _description;
private int _level;
}
///
/// the MozillaProfile class encapsulates properties of Mozilla or Firefox profile
/// allows to enumerate its bookmarks
///
internal class MozillaProfile : IEnumerable
{
public MozillaProfile( string path )
{
_name = null;
_path = path;
DirectoryInfo di = IOTools.GetParent( path );
if( di != null )
{
di = IOTools.GetParent( IOTools.GetFullName( di ) );
}
string firefoxDir = IOTools.Combine( Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData ), @"Mozilla\Firefox" );
string profileDir = IOTools.GetFileName( path );
if( di != null )
{
if( String.Compare( di.Name, "Firefox", true ) == 0 )
{
firefoxDir = IOTools.GetFullName( di );
}
else if( String.Compare( di.Name, "Profiles", true ) == 0 )
{
_name = di.Name + " - " + profileDir; // Mozilla
firefoxDir = null;
}
}
if( firefoxDir != null )
{
Ini.IniFile profilesIni = new IniFile( IOTools.Combine( firefoxDir, "profiles.ini" ) );
for( int i = 0; ; ++i )
{
string profile = "Profile" + i;
string dir = profilesIni.ReadString( profile, "Path" );
if( dir == null || dir.Length == 0 )
{
break;
}
if( profilesIni.ReadBool( profile, "IsRelative", false ) )
{
dir = IOTools.Combine( firefoxDir, dir ).Replace( '/', '\\' );
}
if( String.Compare( dir, path, true ) == 0 )
{
_name = "Firefox - " + profilesIni.ReadString( profile, "Name" );
break;
}
}
}
}
public string Name
{
get { return _name; }
}
public string Path
{
get { return _path; }
}
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return new BookmarkEnumerator( _path );
}
private class BookmarkEnumerator : IEnumerator, IDisposable
{
public BookmarkEnumerator( string path )
{
DirectoryInfo[] dirs = IOTools.GetDirectories( path, "*.slt" );
if( dirs != null && dirs.Length > 0 )
{
path = dirs[ 0 ].FullName;
}
_path = path;
Reset();
}
#region IEnumerator Members
public void Reset()
{
FileInfo[] bookmarkFiles = IOTools.GetFiles( _path, "bookmarks.html" );
if( bookmarkFiles == null || bookmarkFiles.Length == 0 )
{
_parser = null;
}
else
{
_parser = new HTMLParser( new StreamReader( bookmarkFiles[ 0 ].FullName ), true );
_parser.BreakWords = false;
_parser.AddTagHandler( "dl", new HTMLParser.TagHandler( OnDLTag ) );
_parser.AddTagHandler( "/dl", new HTMLParser.TagHandler( OnDLClosedTag ) );
_parser.AddTagHandler( "h3", new HTMLParser.TagHandler( OnHeaderTag ) );
_parser.AddTagHandler( "/h3", new HTMLParser.TagHandler( OnHeaderClosedTag ) );
_parser.AddTagHandler( "a", new HTMLParser.TagHandler( OnLinkTag ) );
_parser.AddTagHandler( "/a", new HTMLParser.TagHandler( OnLinkClosedTag ) );
_parser.AddTagHandler( "dd", new HTMLParser.TagHandler( OnDescriptionTag ) );
_level = 0;
_inHeader = _inLink = _inDescription = false;
}
}
public object Current
{
get
{
if( _parser == null )
{
return null;
}
if( _description.Length > 0 )
{
return _description;
}
if( _folder.Length > 0 )
{
return new MozillaBookmark( _id, _folder, _level );
}
return new MozillaBookmark( _id, _url, _name, _level );
}
}
public bool MoveNext()
{
if( _parser != null )
{
_id = _folder = _url = _name = _description = string.Empty;
_isFeed = false;
for( ; ; )
{
if( _parser.Finished )
{
_parser.Dispose();
_parser = null;
break;
}
string frag = _parser.ReadNextFragment();
if( !_isFeed )
{
if( _inLink )
{
_name = frag;
return true;
}
if( _inHeader )
{
_folder = frag;
return true;
}
if( _inDescription )
{
_description = frag;
_inDescription = false;
return true;
}
}
}
}
return false;
}
#endregion
#region HTML tag handlers
private void OnDLTag( HTMLParser instance, string tag )
{
++_level;
}
private void OnDLClosedTag( HTMLParser instance, string tag )
{
--_level;
}
private void OnHeaderTag( HTMLParser instance, string tag )
{
_inHeader = true;
HashMap attrMap = instance.ParseAttributes( tag );
if( ( _id = (string) attrMap[ "id" ] ) == null )
{
_id = string.Empty;
}
}
private void OnHeaderClosedTag( HTMLParser instance, string tag )
{
_inHeader = false;
}
private void OnLinkTag( HTMLParser instance, string tag )
{
_inLink = true;
HashMap attrMap = instance.ParseAttributes( tag );
if( ( _url = (string) attrMap[ "href" ] ) == null )
{
_url = string.Empty;
}
if( ( _id = (string) attrMap[ "id" ] ) == null )
{
_id = string.Empty;
}
_isFeed = attrMap[ "feedurl" ] != null;
}
private void OnLinkClosedTag( HTMLParser instance, string tag )
{
_inLink = false;
}
private void OnDescriptionTag( HTMLParser instance, string tag )
{
_inDescription = true;
}
#endregion
#region IDisposable Members
public void Dispose()
{
if( _parser != null )
{
_parser.Dispose();
}
}
#endregion
private string _path;
private string _folder = string.Empty;
private string _url = string.Empty;
private string _id = string.Empty;
private string _name = string.Empty;
private string _description = string.Empty;
private int _level;
private bool _inHeader;
private bool _inLink;
private bool _inDescription;
private bool _isFeed;
private HTMLParser _parser;
}
#endregion
private string _name;
private string _path;
}
///
/// the MozillaProfiles class enumerates Mozilla and Firefox profiles
///
internal class MozillaProfiles
{
public static bool PresentOnComputer
{
get { return new RelativeProfilesEnumerator( _mozillaFolder ).MoveNext() ||
new RelativeProfilesEnumerator( _firefoxFolder ).MoveNext() ||
new RelativeProfilesEnumerator( _firefox09Folder ).MoveNext() ||
new AbsoluteFirefoxProfilesEnumerator().MoveNext(); }
}
public static IEnumerable GetMozillaProfiles()
{
return new RelativeProfilesCollection( _mozillaFolder );
}
public static IEnumerable GetFirefoxProfiles()
{
return new RelativeProfilesCollection( _firefoxFolder );
}
public static IEnumerable GetFirefox09Profiles()
{
return new RelativeProfilesCollection( _firefox09Folder );
}
public static IEnumerable GetAbsoluteFirefoxProfiles()
{
return new AbsoluteFirefoxProfilesCollection();
}
public static MozillaProfile GetProfile( string name )
{
MozillaProfile profile = SearchForProfile( GetMozillaProfiles(), name );
if( profile == null )
{
profile = SearchForProfile( GetFirefoxProfiles(), name );
if( profile == null )
{
profile = SearchForProfile( GetFirefox09Profiles(), name );
if( profile == null )
{
profile = SearchForProfile( GetAbsoluteFirefoxProfiles(), name );
}
}
}
return profile;
}
private static MozillaProfile SearchForProfile( IEnumerable profiles, string name )
{
foreach( MozillaProfile profile in profiles )
{
if( String.Compare( profile.Name, name, true ) == 0 )
{
return profile;
}
}
return null;
}
private class RelativeProfilesCollection : IEnumerable
{
public RelativeProfilesCollection( string profileType )
{
_profileType = profileType;
}
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return new RelativeProfilesEnumerator( _profileType );
}
#endregion
private string _profileType;
}
private class RelativeProfilesEnumerator : IEnumerator
{
public RelativeProfilesEnumerator( string profileType )
{
_path = IOTools.Combine(
Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData ), profileType );
_path = IOTools.Combine( _path, "Profiles" );
Reset();
}
#region IEnumerator Members
public void Reset()
{
DirectoryInfo[] directories = IOTools.GetDirectories( _path );
if( directories == null )
{
_dirEnumerator = null;
}
else
{
_dirEnumerator = directories.GetEnumerator();
_dirEnumerator.Reset();
}
}
public object Current
{
get
{
return ( _dirEnumerator == null ) ? null : _currentProfile;
}
}
public bool MoveNext()
{
_currentProfile = null;
if( _dirEnumerator != null )
{
while( _dirEnumerator.MoveNext() )
{
_currentProfile = new MozillaProfile( ( (DirectoryInfo) _dirEnumerator.Current ).FullName );
if( _currentProfile.Name != null )
{
return true;
}
}
}
return false;
}
#endregion
private string _path;
private MozillaProfile _currentProfile;
private IEnumerator _dirEnumerator;
}
private class AbsoluteFirefoxProfilesCollection : IEnumerable
{
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return new AbsoluteFirefoxProfilesEnumerator();
}
#endregion
}
private class AbsoluteFirefoxProfilesEnumerator : IEnumerator
{
public AbsoluteFirefoxProfilesEnumerator()
{
_path = IOTools.Combine( Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData ), @"Mozilla\Firefox\profiles.ini" );
Reset();
}
#region IEnumerator Members
public void Reset()
{
_profilesIni = new IniFile( _path );
_profileNumber = 0;
}
public object Current
{
get
{
return _currentProfile;
}
}
public bool MoveNext()
{
string profile = "Profile" + _profileNumber++;
_profilePath = _profilesIni.ReadString( profile, "Path" );
if( _profilePath == null || _profilePath.Length == 0 )
{
return false;
}
if( _profilesIni.ReadBool( profile, "IsRelative", false ) )
{
return MoveNext();
}
_currentProfile = new MozillaProfile( _profilePath );
if( _currentProfile.Name == null )
{
return MoveNext();
}
return true;
}
#endregion
private string _path;
private Ini.IniFile _profilesIni;
private int _profileNumber;
private string _profilePath;
private MozillaProfile _currentProfile;
}
private const string _mozillaFolder = "Mozilla";
private const string _firefoxFolder = "Phoenix";
private const string _firefox09Folder = @"Mozilla\Firefox";
}
}