diff --git a/releases/1.1/Data/Book.cs b/releases/1.1/Data/Book.cs deleted file mode 100644 index 3fe6b92..0000000 --- a/releases/1.1/Data/Book.cs +++ /dev/null @@ -1,82 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the Book class - * - ************************************************************/ - -using System; -using System.IO; -using System.Linq; -using System.Text; -using System.Collections.Generic; -using System.Drawing; - -namespace TinyOPDS.Data -{ - /// - /// Supported book types - /// - public enum BookType - { - FB2, - EPUB, - } - - /// - /// Base data class - /// - public class Book - { - public Book(string fileName = "") - { - Version = 1; - FileName = fileName; - if (!string.IsNullOrEmpty(FileName) && FileName.IndexOf(Library.LibraryPath)==0) - { - FileName = FileName.Substring(Library.LibraryPath.Length+1); - } - Title = Sequence = Annotation = Language = string.Empty; - HasCover = false; - BookDate = DocumentDate = DateTime.MinValue; - NumberInSequence = 0; - Authors = new List(); - Translators = new List(); - Genres = new List(); - } - private string _id = string.Empty; - public string ID - { - get { return _id; } - set - { - // Book ID always must be in GUID form - Guid guid; - if (!string.IsNullOrEmpty(value) && Guid.TryParse(value, out guid)) _id = value; else _id = Utils.CreateGuid(Utils.IsoOidNamespace, FileName).ToString(); - } - } - public float Version { get; set; } - public string FileName { get; private set; } - public string FilePath { get { return Path.Combine(Library.LibraryPath, FileName); } } - public string Title { get; set; } - public string Language { get; set; } - public bool HasCover { get; set; } - public DateTime BookDate { get; set; } - public DateTime DocumentDate { get; set; } - public string Sequence { get; set; } - public UInt32 NumberInSequence { get; set; } - public string Annotation { get; set; } - public UInt32 DocumentSize { get; set; } - public List Authors { get; set; } - public List Translators { get; set; } - public List Genres { get; set; } - public BookType BookType { get { return Path.GetExtension(FilePath).ToLower().Contains("epub") ? BookType.EPUB : Data.BookType.FB2; } } - public bool IsValid { get { return (!string.IsNullOrEmpty(Title) && Title.IsValidUTF() && Authors.Count > 0 && Genres.Count > 0); } } - public DateTime AddedDate { get; set; } - } -} diff --git a/releases/1.1/Data/CoverImage.cs b/releases/1.1/Data/CoverImage.cs deleted file mode 100644 index e147c83..0000000 --- a/releases/1.1/Data/CoverImage.cs +++ /dev/null @@ -1,132 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the CoverImage class and Image extensions - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using System.Drawing; -using System.Drawing.Imaging; -using System.Drawing.Drawing2D; - -using Ionic.Zip; -using TinyOPDS.Parsers; - -namespace TinyOPDS.Data -{ - /// - /// - /// - public class CoverImage - { - public static Size CoverSize = new Size(480, 800); - public static Size ThumbnailSize = new Size(48, 80); - - private Image _cover; - private Image _thumbnail { get { return (_cover != null) ? _cover.Resize(ThumbnailSize) : null; } } - public Stream CoverImageStream { get { return _cover.ToStream(ImageFormat.Jpeg); } } - public Stream ThumbnailImageStream { get { return _thumbnail.ToStream(ImageFormat.Jpeg); } } - public bool HasImages { get { return _cover != null; } } - public string ID { get; set; } - - public CoverImage(Book book) - { - _cover = null; - ID = book.ID; - try - { - using (MemoryStream memStream = new MemoryStream()) - { - if (book.FilePath.ToLower().Contains(".zip@")) - { - string[] pathParts = book.FilePath.Split('@'); - using (ZipFile zipFile = new ZipFile(pathParts[0])) - { - ZipEntry entry = zipFile.Entries.First(e => e.FileName.Contains(pathParts[1])); - if (entry != null) entry.Extract(memStream); - } - } - else - { - using (FileStream stream = new FileStream(book.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - stream.CopyTo(memStream); - } - - _cover = (book.BookType == BookType.EPUB) ? new ePubParser().GetCoverImage(memStream, book.FilePath) - : new FB2Parser().GetCoverImage(memStream, book.FilePath); - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "file {0}, exception {1}", book.FilePath, e.Message); - } - } - } - - public static class ImageExtensions - { - public static Stream ToStream(this Image image, ImageFormat format) - { - MemoryStream stream = null; - try - { - stream = new MemoryStream(); - if (image != null) - { - image.Save(stream, format); - stream.Position = 0; - } - } - catch - { - if (stream != null) stream.Dispose(); - } - return stream; - } - - public static Image Resize(this Image image, Size size, bool preserveAspectRatio = true) - { - if (image == null) return null; - int newWidth, newHeight; - if (preserveAspectRatio) - { - int originalWidth = image.Width; - int originalHeight = image.Height; - float percentWidth = (float)size.Width / (float)originalWidth; - float percentHeight = (float)size.Height / (float)originalHeight; - float percent = percentHeight < percentWidth ? percentHeight : percentWidth; - newWidth = (int)(originalWidth * percent); - newHeight = (int)(originalHeight * percent); - } - else - { - newWidth = size.Width; - newHeight = size.Height; - } - Image newImage = null; - try - { - newImage = new Bitmap(newWidth, newHeight); - using (Graphics graphicsHandle = Graphics.FromImage(newImage)) - { - graphicsHandle.InterpolationMode = InterpolationMode.HighQualityBicubic; - graphicsHandle.DrawImage(image, 0, 0, newWidth, newHeight); - } - } - catch - { - if (newImage != null) newImage.Dispose(); - } - return newImage; - } - } -} diff --git a/releases/1.1/Data/Genre.cs b/releases/1.1/Data/Genre.cs deleted file mode 100644 index 5e4c1fa..0000000 --- a/releases/1.1/Data/Genre.cs +++ /dev/null @@ -1,27 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the Genre class (book genre) - * - ************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace TinyOPDS.Data -{ - public class Genre - { - public string Tag { get; set; } - public string Name { get; set; } - public string Translation { get; set; } - public List Subgenres = new List(); - } -} diff --git a/releases/1.1/Data/ImagesCache.cs b/releases/1.1/Data/ImagesCache.cs deleted file mode 100644 index 51739b7..0000000 --- a/releases/1.1/Data/ImagesCache.cs +++ /dev/null @@ -1,47 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * Simple image caching class - * - * TODO: add disk caching - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using System.ComponentModel; -using System.Threading; -using System.Drawing; - -namespace TinyOPDS.Data -{ - public static class ImagesCache - { - private static Dictionary _cache; - - static ImagesCache() - { - _cache = new Dictionary(); - } - - public static void Add(CoverImage image) - { - if (!_cache.ContainsKey(image.ID)) - { - if (_cache.Count >= 1000) _cache.Remove(_cache.First().Key); - _cache[image.ID] = image; - } - } - - public static bool HasImage(string id) { return _cache.ContainsKey(id); } - - public static CoverImage GetImage(string id) { return _cache[id]; } - } -} diff --git a/releases/1.1/Data/Library.cs b/releases/1.1/Data/Library.cs deleted file mode 100644 index fe415f6..0000000 --- a/releases/1.1/Data/Library.cs +++ /dev/null @@ -1,593 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * One of the base project classes, the Library class - * We are using static dictionaries instead of database - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Xml.Linq; -using System.Reflection; - -namespace TinyOPDS.Data -{ - public static class Library - { - public static event EventHandler LibraryLoaded; - private static Dictionary _paths = new Dictionary(); - private static Dictionary _books = new Dictionary(); - private static string _databaseFullPath; - private static List _genres; - private static Dictionary _soundexedGenres; - private static bool _converted = false; - - /// - /// Default constructor - /// Opens library"books.db" from the executable file location - /// - static Library() - { - LoadAsync(); - - // Load and parse genres - try - { - var doc = XDocument.Load(Assembly.GetExecutingAssembly().GetManifestResourceStream("TinyOPDS.genres.xml")); - _genres = doc.Root.Descendants("genre").Select(g => - new Genre() - { - Name = g.Attribute("name").Value, - Translation = g.Attribute("ru").Value, - Subgenres = g.Descendants("subgenre").Select(sg => - new Genre() - { - Name = sg.Value, - Tag = sg.Attribute("tag").Value, - Translation = sg.Attribute("ru").Value, - }).ToList() - }).ToList(); - - _soundexedGenres = new Dictionary(); - foreach (Genre genre in _genres) - foreach (Genre subgenre in genre.Subgenres) - { - _soundexedGenres[subgenre.Name.SoundexByWord()] = subgenre.Tag; - string reversed = string.Join(" ", subgenre.Name.Split(' ', ',').Reverse()).Trim(); - _soundexedGenres[reversed.SoundexByWord()] = subgenre.Tag; - } - - } - catch { } - } - - /// - /// Load library database in background - /// - public static void LoadAsync() - { - // Clear library and free memory - FB2Count = EPUBCount = 0; - _books.Clear(); - _paths.Clear(); - GC.Collect(); - - // Create unique database name, based on library path - LibraryPath = Properties.Settings.Default.LibraryPath; - string databaseFileName = Utils.CreateGuid(Utils.IsoOidNamespace, LibraryPath).ToString() + ".db"; - _databaseFullPath = Path.Combine(Utils.ServiceFilesLocation, databaseFileName); - - // Load database in the background thread - BackgroundWorker worker = new BackgroundWorker(); - worker.DoWork += (_, __) => - { - _converted = false; - Load(); - if (LibraryLoaded != null) LibraryLoaded(null, null); - if (_converted) - { - Save(); - Log.WriteLine(LogLevel.Info, "Database successfully converted to the format 1.1"); - } - worker.Dispose(); - }; - worker.RunWorkerAsync(); - } - - /// - /// Full path to the library folder - /// - public static string LibraryPath { get; set; } - - /// - /// Library changed flag (we should save!) - /// - public static bool IsChanged { get; set; } - - /// - /// - /// - /// - /// - public static bool Contains(string bookPath) - { - lock (_paths) - { - return _paths.ContainsKey(bookPath); - } - } - - /// - /// - /// - /// - /// - public static Book GetBook(string id) - { - lock (_books) - { - Book book = null; - if (_books.ContainsKey(id)) - { - book = _books[id]; - } - return book; - } - } - - /// - /// Add unique book descriptor to the library and saves the library - /// - /// - public static bool Add(Book book) - { - lock (_books) - { - // Prevent incorrect duplicates detection (same ID but different titles) - if (_books.ContainsKey(book.ID) && !book.Title.Equals(_books[book.ID].Title)) - { - book.ID = Utils.CreateGuid(Utils.IsoOidNamespace, book.FileName).ToString(); - } - - // Check for duplicates - if (!_books.ContainsKey(book.ID) || (_books.ContainsKey(book.ID) && _books[book.ID].Version < book.Version)) - { - // Remember duplicate flag - bool isDuplicate = _books.ContainsKey(book.ID); - book.AddedDate = DateTime.Now; - // Make relative path - _books[book.ID] = book; - lock (_paths) _paths[book.FileName] = book.ID; - if (!isDuplicate) - { - IsChanged = true; - if (book.BookType == BookType.FB2) FB2Count++; else EPUBCount++; - } - else - { - Log.WriteLine(LogLevel.Warning, "Replaced duplicate. File name {0}, book version {1}", book.FileName, book.Version); - } - return !isDuplicate; - } - Log.WriteLine(LogLevel.Warning, "Found duplicate. File name {0}, book version {1}", book.FileName, book.Version); - return false; - } - } - - /// - /// Delete all books with specific file path from the library - /// - /// - public static bool Delete(string fileName) - { - bool result = false; - lock (_books) - { - if (!string.IsNullOrEmpty(fileName) && fileName.Length > Library.LibraryPath.Length + 1) - { - // Extract relative file name - fileName = fileName.Substring(Library.LibraryPath.Length + 1); - string ext = Path.GetExtension(fileName.ToLower()); - - // Assume it's a single file - if (ext.Equals(".epub") || ext.Equals(".fb2") || (ext.Equals(".zip") && fileName.ToLower().Contains(".fb2.zip"))) - { - if (Contains(fileName)) - { - Book book = _books[_paths[fileName]]; - if (book != null) - { - _books.Remove(book.ID); - _paths.Remove(book.FileName); - if (book.BookType == BookType.FB2) FB2Count--; else EPUBCount--; - result = IsChanged = true; - } - } - } - // removed object should be archive or directory: let's remove all books with that path or zip - else - { - List booksForRemove = _books.Where(b => b.Value.FileName.Contains(fileName)).Select(b => b.Value).ToList(); - foreach (Book book in booksForRemove) - { - _books.Remove(book.ID); - _paths.Remove(book.FileName); - if (book.BookType == BookType.FB2) FB2Count--; else EPUBCount--; - } - if (booksForRemove.Count > 0) - { - result = IsChanged = true; - } - } - } - } - return result; - } - - - /// - /// Total number of books in library - /// - public static int Count - { - get - { - lock (_books) return _books.Count; - } - } - - /// - /// Returns FB2 books count - /// - public static int FB2Count { get; private set; } - - /// - /// Returns EPUB books count - /// - public static int EPUBCount { get; private set; } - - /// - /// Returns list of the books titles sorted in alphabetical order - /// - public static List Titles - { - get - { - lock (_books) - { - return _books.Values.Select(b => b.Title).Distinct().OrderBy(a => a, new OPDSComparer(Localizer.Language.Equals("ru"))).ToList(); - } - } - } - - /// - /// Returns list of the authors sorted in alphabetical order - /// - public static List Authors - { - get - { - lock (_books) - { - return ((_books.Values.SelectMany(b => b.Authors)).ToList()).Distinct().OrderBy(a => a, new OPDSComparer(Localizer.Language.Equals("ru"))).Where(с => с.Length > 1).ToList(); - } - } - } - - /// - /// Returns list of the library books series sorted in alphabetical order - /// - public static List Sequences - { - get - { - lock (_books) - { - return ((_books.Values.Select(b => b.Sequence)).ToList()).Distinct().OrderBy(a => a, new OPDSComparer(Localizer.Language.Equals("ru"))).Where(с => с.Length > 1).ToList(); - } - } - } - - /// - /// All genres supported by fb2 format - /// - public static List FB2Genres - { - get - { - return _genres; - } - } - - public static Dictionary SoundexedGenres - { - get - { - return _soundexedGenres; - } - } - - /// - /// Returns sorted in alphabetical order list of library books genres - /// - public static List Genres - { - get - { - lock (_books) - { - var libGenres = _books.Values.SelectMany(b => b.Genres).ToList().Distinct().OrderBy(a => a, new OPDSComparer(Localizer.Language.Equals("ru"))).Where(с => с.Length > 1).Select(g => g.ToLower().Trim()).ToList(); - return _genres.SelectMany(g => g.Subgenres).Where(sg => libGenres.Contains(sg.Tag) || libGenres.Contains(sg.Name.ToLower()) || libGenres.Contains(sg.Translation.ToLower())).ToList(); - } - } - } - - /// - /// Search authors by name - /// - /// - /// - public static List GetAuthorsByName(string name, bool isOpenSearch) - { - List authors = new List(); - lock (_books) - { - if (isOpenSearch) authors = Authors.Where(a => a.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0).ToList(); - else authors = Authors.Where(a => a.StartsWith(name, StringComparison.OrdinalIgnoreCase)).ToList(); - if (isOpenSearch && authors.Count == 0) - { - string reversedName = name.Reverse(); - authors = Authors.Where(a => a.IndexOf(reversedName, StringComparison.OrdinalIgnoreCase) >= 0).ToList(); - } - return authors; - } - } - - /// - /// Return books by title - /// - /// - /// - public static List GetBooksByTitle(string title) - { - lock (_books) return _books.Values.Where(b => b.Title.IndexOf(title, StringComparison.OrdinalIgnoreCase) >= 0 || b.Sequence.IndexOf(title, StringComparison.OrdinalIgnoreCase) >= 0).ToList(); - } - - /// - /// Return books by selected author(s) - /// - /// - /// - public static List GetBooksByAuthor(string author) - { - lock (_books) return _books.Values.Where(b => b.Authors.Contains(author)).ToList(); - } - - /// - /// Return books by selected sequence - /// - /// - /// - public static List GetBooksBySequence(string sequence) - { - lock (_books) return _books.Values.Where(b => b.Sequence.Contains(sequence)).ToList(); - } - - /// - /// Return books by selected genre - /// - /// - /// - public static List GetBooksByGenre(string genre) - { - lock (_books) return _books.Values.Where(b => b.Genres.Contains(genre)).ToList(); - } - - #region Serialization and deserialization - - /// - /// Load library - /// - public static void Load() - { - int numRecords = 0; - DateTime start = DateTime.Now; - - // MemoryStream can save us about 1 second on 106 Mb database load time - MemoryStream memStream = null; - if (File.Exists(_databaseFullPath)) - { - _books.Clear(); - memStream = new MemoryStream(); - - try - { - using (Stream fileStream = new FileStream(_databaseFullPath, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - fileStream.CopyTo(memStream); - } - memStream.Position = 0; - using (BinaryReader reader = new BinaryReader(memStream)) - { - bool newFormat = reader.ReadString().Equals("VER1.1"); - if (!newFormat) - { - reader.BaseStream.Position = 0; - _converted = true; - } - - DateTime now = DateTime.Now; - - while (reader.BaseStream.Position < reader.BaseStream.Length) - { - try - { - string fileName = reader.ReadString(); - Book book = new Book(Path.Combine(LibraryPath,fileName)); - book.ID = reader.ReadString(); - book.Version = reader.ReadSingle(); - book.Title = reader.ReadString(); - book.Language = reader.ReadString(); - book.HasCover = reader.ReadBoolean(); - book.BookDate = DateTime.FromBinary(reader.ReadInt64()); - book.DocumentDate = DateTime.FromBinary(reader.ReadInt64()); - book.Sequence = reader.ReadString(); - book.NumberInSequence = reader.ReadUInt32(); - book.Annotation = reader.ReadString(); - book.DocumentSize = reader.ReadUInt32(); - int count = reader.ReadInt32(); - for (int i = 0; i < count; i++) book.Authors.Add(reader.ReadString()); - count = reader.ReadInt32(); - for (int i = 0; i < count; i++) book.Translators.Add(reader.ReadString()); - count = reader.ReadInt32(); - for (int i = 0; i < count; i++) book.Genres.Add(reader.ReadString()); - lock (_books) _books[book.ID] = book; - lock (_paths) _paths[book.FileName] = book.ID; - book.AddedDate = newFormat ? DateTime.FromBinary(reader.ReadInt64()) : now; - - numRecords++; - } - catch (EndOfStreamException) - { - break; - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, e.Message); - break; - } - } - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "Load books exception {0}", e.Message); - } - finally - { - if (memStream != null) - { - memStream.Dispose(); - memStream = null; - } - // Call garbage collector now - GC.Collect(); - - FB2Count = _books.Count(b => b.Value.BookType == BookType.FB2); - EPUBCount = _books.Count(b => b.Value.BookType == BookType.EPUB); - - IsChanged = false; - } - } - - Log.WriteLine(LogLevel.Info, "Database load time = {0}, {1} book records loaded", DateTime.Now.Subtract(start), numRecords); - } - - /// - /// Save whole library - /// - /// Remark: new database format is used! - public static void Save() - { - // Do nothing if we have no records - if (_books.Count == 0) return; - - int numRecords = 0; - DateTime start = DateTime.Now; - - Stream fileStream = null; - try - { - fileStream = new FileStream(_databaseFullPath, FileMode.Create, FileAccess.Write, FileShare.Write); - using (BinaryWriter writer = new BinaryWriter(fileStream)) - { - fileStream = null; - writer.Write("VER1.1"); - - // Create shallow copy (to prevent exception on dictionary modifications during foreach loop) - Dictionary shallowCopy = null; - lock (_books) shallowCopy = new Dictionary(_books); - foreach (Book book in shallowCopy.Values) - { - writeBook(book, writer); - numRecords++; - } - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "Save books exception {0}", e.Message); - } - finally - { - if (fileStream != null) fileStream.Dispose(); - IsChanged = false; - Log.WriteLine(LogLevel.Info, "Database save time = {0}, {1} book records written to disk", DateTime.Now.Subtract(start), numRecords); - } - } - - /// - /// Append one book descriptor to the library file - /// - /// - public static void Append(Book book) - { - Stream fileStream = null; - try - { - fileStream = new FileStream(_databaseFullPath, FileMode.Append, FileAccess.Write, FileShare.Write); - using (BinaryWriter writer = new BinaryWriter(fileStream)) - { - fileStream = null; - writeBook(book, writer); - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "Can't append book {0}, exception {1}", book.FilePath, e.Message); - } - finally - { - if (fileStream != null) - { - fileStream.Dispose(); - } - IsChanged = false; - } - } - - private static void writeBook(Book book, BinaryWriter writer) - { - writer.Write(book.FileName); - writer.Write(book.ID); - writer.Write(book.Version); - writer.Write(book.Title); - writer.Write(book.Language); - writer.Write(book.HasCover); - writer.Write(book.BookDate.ToBinary()); - writer.Write(book.DocumentDate.ToBinary()); - writer.Write(book.Sequence); - writer.Write(book.NumberInSequence); - writer.Write(book.Annotation); - writer.Write(book.DocumentSize); - writer.Write((Int32)book.Authors.Count); - foreach (string author in book.Authors) writer.Write(author); - writer.Write((Int32)book.Translators.Count); - foreach (string translator in book.Translators) writer.Write(translator); - writer.Write((Int32)book.Genres.Count); - foreach (string genre in book.Genres) writer.Write(genre); - writer.Write(book.AddedDate.ToBinary()); - } - - #endregion - } -} diff --git a/releases/1.1/Icons/..svnbridge/Thumbs.db b/releases/1.1/Icons/..svnbridge/Thumbs.db deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/Thumbs.db +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/TinyOPDS.ico b/releases/1.1/Icons/..svnbridge/TinyOPDS.ico deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/TinyOPDS.ico +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/authors.ico b/releases/1.1/Icons/..svnbridge/authors.ico deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/authors.ico +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/authors.png b/releases/1.1/Icons/..svnbridge/authors.png deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/authors.png +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/book.png b/releases/1.1/Icons/..svnbridge/book.png deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/book.png +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/book2.png b/releases/1.1/Icons/..svnbridge/book2.png deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/book2.png +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/book3.png b/releases/1.1/Icons/..svnbridge/book3.png deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/book3.png +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/books.ico b/releases/1.1/Icons/..svnbridge/books.ico deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/books.ico +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/books.png b/releases/1.1/Icons/..svnbridge/books.png deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/books.png +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/favicon.ico b/releases/1.1/Icons/..svnbridge/favicon.ico deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/favicon.ico +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/folder.png b/releases/1.1/Icons/..svnbridge/folder.png deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/folder.png +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/genres.ico b/releases/1.1/Icons/..svnbridge/genres.ico deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/genres.ico +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/genres.png b/releases/1.1/Icons/..svnbridge/genres.png deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/genres.png +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/genres2.png b/releases/1.1/Icons/..svnbridge/genres2.png deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/genres2.png +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/..svnbridge/lib.png b/releases/1.1/Icons/..svnbridge/lib.png deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Icons/..svnbridge/lib.png +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Icons/Thumbs.db b/releases/1.1/Icons/Thumbs.db deleted file mode 100644 index 5c4c23d..0000000 Binary files a/releases/1.1/Icons/Thumbs.db and /dev/null differ diff --git a/releases/1.1/Icons/TinyOPDS.ico b/releases/1.1/Icons/TinyOPDS.ico deleted file mode 100644 index 901fcc4..0000000 Binary files a/releases/1.1/Icons/TinyOPDS.ico and /dev/null differ diff --git a/releases/1.1/Icons/authors.ico b/releases/1.1/Icons/authors.ico deleted file mode 100644 index 1a835e2..0000000 Binary files a/releases/1.1/Icons/authors.ico and /dev/null differ diff --git a/releases/1.1/Icons/authors.png b/releases/1.1/Icons/authors.png deleted file mode 100644 index cfc64cd..0000000 Binary files a/releases/1.1/Icons/authors.png and /dev/null differ diff --git a/releases/1.1/Icons/book.png b/releases/1.1/Icons/book.png deleted file mode 100644 index e46995b..0000000 Binary files a/releases/1.1/Icons/book.png and /dev/null differ diff --git a/releases/1.1/Icons/book2.png b/releases/1.1/Icons/book2.png deleted file mode 100644 index 116ec38..0000000 Binary files a/releases/1.1/Icons/book2.png and /dev/null differ diff --git a/releases/1.1/Icons/book3.png b/releases/1.1/Icons/book3.png deleted file mode 100644 index eff3d43..0000000 Binary files a/releases/1.1/Icons/book3.png and /dev/null differ diff --git a/releases/1.1/Icons/books.ico b/releases/1.1/Icons/books.ico deleted file mode 100644 index 57d6e9f..0000000 Binary files a/releases/1.1/Icons/books.ico and /dev/null differ diff --git a/releases/1.1/Icons/books.png b/releases/1.1/Icons/books.png deleted file mode 100644 index 4593e0b..0000000 Binary files a/releases/1.1/Icons/books.png and /dev/null differ diff --git a/releases/1.1/Icons/favicon.ico b/releases/1.1/Icons/favicon.ico deleted file mode 100644 index d8f35aa..0000000 Binary files a/releases/1.1/Icons/favicon.ico and /dev/null differ diff --git a/releases/1.1/Icons/folder.png b/releases/1.1/Icons/folder.png deleted file mode 100644 index 3241bb3..0000000 Binary files a/releases/1.1/Icons/folder.png and /dev/null differ diff --git a/releases/1.1/Icons/genres.ico b/releases/1.1/Icons/genres.ico deleted file mode 100644 index 45c3d60..0000000 Binary files a/releases/1.1/Icons/genres.ico and /dev/null differ diff --git a/releases/1.1/Icons/genres.png b/releases/1.1/Icons/genres.png deleted file mode 100644 index b698c8f..0000000 Binary files a/releases/1.1/Icons/genres.png and /dev/null differ diff --git a/releases/1.1/Icons/genres2.png b/releases/1.1/Icons/genres2.png deleted file mode 100644 index 9fa31ef..0000000 Binary files a/releases/1.1/Icons/genres2.png and /dev/null differ diff --git a/releases/1.1/Icons/lib.png b/releases/1.1/Icons/lib.png deleted file mode 100644 index 040ac5c..0000000 Binary files a/releases/1.1/Icons/lib.png and /dev/null differ diff --git a/releases/1.1/Libs/..svnbridge/FB2Library.dll b/releases/1.1/Libs/..svnbridge/FB2Library.dll deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Libs/..svnbridge/FB2Library.dll +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Libs/..svnbridge/FB2Library.dll.gz b/releases/1.1/Libs/..svnbridge/FB2Library.dll.gz deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Libs/..svnbridge/FB2Library.dll.gz +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Libs/..svnbridge/Ionic.Zip.Reduced.dll b/releases/1.1/Libs/..svnbridge/Ionic.Zip.Reduced.dll deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Libs/..svnbridge/Ionic.Zip.Reduced.dll +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Libs/..svnbridge/Ionic.Zip.Reduced.dll.gz b/releases/1.1/Libs/..svnbridge/Ionic.Zip.Reduced.dll.gz deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Libs/..svnbridge/Ionic.Zip.Reduced.dll.gz +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Libs/..svnbridge/eBdb.EpubReader.dll b/releases/1.1/Libs/..svnbridge/eBdb.EpubReader.dll deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Libs/..svnbridge/eBdb.EpubReader.dll +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Libs/..svnbridge/eBdb.EpubReader.dll.gz b/releases/1.1/Libs/..svnbridge/eBdb.EpubReader.dll.gz deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Libs/..svnbridge/eBdb.EpubReader.dll.gz +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Libs/..svnbridge/gzip.exe b/releases/1.1/Libs/..svnbridge/gzip.exe deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Libs/..svnbridge/gzip.exe +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Libs/FB2Library.dll b/releases/1.1/Libs/FB2Library.dll deleted file mode 100644 index 88553b9..0000000 Binary files a/releases/1.1/Libs/FB2Library.dll and /dev/null differ diff --git a/releases/1.1/Libs/FB2Library.dll.gz b/releases/1.1/Libs/FB2Library.dll.gz deleted file mode 100644 index 8b309d0..0000000 Binary files a/releases/1.1/Libs/FB2Library.dll.gz and /dev/null differ diff --git a/releases/1.1/Libs/Ionic.Zip.Reduced.dll b/releases/1.1/Libs/Ionic.Zip.Reduced.dll deleted file mode 100644 index 606c333..0000000 Binary files a/releases/1.1/Libs/Ionic.Zip.Reduced.dll and /dev/null differ diff --git a/releases/1.1/Libs/Ionic.Zip.Reduced.dll.gz b/releases/1.1/Libs/Ionic.Zip.Reduced.dll.gz deleted file mode 100644 index b2ae064..0000000 Binary files a/releases/1.1/Libs/Ionic.Zip.Reduced.dll.gz and /dev/null differ diff --git a/releases/1.1/Libs/eBdb.EpubReader.dll b/releases/1.1/Libs/eBdb.EpubReader.dll deleted file mode 100644 index f6a1dd3..0000000 Binary files a/releases/1.1/Libs/eBdb.EpubReader.dll and /dev/null differ diff --git a/releases/1.1/Libs/eBdb.EpubReader.dll.gz b/releases/1.1/Libs/eBdb.EpubReader.dll.gz deleted file mode 100644 index ef0fc64..0000000 Binary files a/releases/1.1/Libs/eBdb.EpubReader.dll.gz and /dev/null differ diff --git a/releases/1.1/Libs/gzip.cs b/releases/1.1/Libs/gzip.cs deleted file mode 100644 index 9e99965..0000000 --- a/releases/1.1/Libs/gzip.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.IO; -using System.IO.Compression; - -namespace zip -{ - public class Program - { - public static void Main(string[] args) - { - if (args.Length < 1) - { - Console.WriteLine("Usage: gzip [-d] file"); - } - else if (args[0] != "-d") Compress(new FileInfo(args[0])); else Decompress(new FileInfo(args[1])); - } - - public static void Compress(FileInfo fi) - { - // Get the stream of the source file. - using (FileStream inFile = fi.OpenRead()) - { - // Prevent compressing hidden and - // already compressed files. - if ((File.GetAttributes(fi.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden & fi.Extension != ".gz") - { - // Create the compressed file - using (FileStream outFile = File.Create(fi.FullName + ".gz")) - { - using (GZipStream Compress = new GZipStream(outFile, CompressionMode.Compress)) - { - // Copy the source file into the compression stream. - inFile.CopyTo(Compress); - Console.WriteLine("Compressed {0} from {1} to {2} bytes.", - fi.Name, fi.Length.ToString(), outFile.Length.ToString()); - } - } - } - } - } - - public static void Decompress(FileInfo fi) - { - // Get the stream of the source file. - using (FileStream inFile = fi.OpenRead()) - { - // Get original file extension - string curFile = fi.FullName; - string origName = curFile.Remove(curFile.Length - fi.Extension.Length); - - //Create the decompressed file. - using (FileStream outFile = File.Create(origName)) - { - using (GZipStream Decompress = new GZipStream(inFile, CompressionMode.Decompress)) - { - // Copy the decompression stream into the output file. - Decompress.CopyTo(outFile); - Console.WriteLine("Decompressed: {0}", fi.Name); - } - } - } - } - } -} \ No newline at end of file diff --git a/releases/1.1/Libs/gzip.exe b/releases/1.1/Libs/gzip.exe deleted file mode 100644 index c4d28a9..0000000 Binary files a/releases/1.1/Libs/gzip.exe and /dev/null differ diff --git a/releases/1.1/License.txt b/releases/1.1/License.txt deleted file mode 100644 index 73d6051..0000000 --- a/releases/1.1/License.txt +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Public License (Ms-PL) - -This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. - -1. Definitions - -The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. - -A "contribution" is the original software, or any additions or changes to the software. - -A "contributor" is any person that distributes its contribution under this license. - -"Licensed patents" are a contributor's patent claims that read directly on its contribution. - -2. Grant of Rights - -(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. - -(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. - -3. Conditions and Limitations - -(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. - -(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. - -(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. - -(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. diff --git a/releases/1.1/MainForm.Designer.cs b/releases/1.1/MainForm.Designer.cs deleted file mode 100644 index de0ac40..0000000 --- a/releases/1.1/MainForm.Designer.cs +++ /dev/null @@ -1,1418 +0,0 @@ -namespace TinyOPDS -{ - partial class MainForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - if (_watcher != null) _watcher.Dispose(); - if (_upnpController != null) _upnpController.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - this.tabControl1 = new System.Windows.Forms.TabControl(); - this.tabPage1 = new System.Windows.Forms.TabPage(); - this.databaseFileName = new System.Windows.Forms.TextBox(); - this.label21 = new System.Windows.Forms.Label(); - this.useWatcher = new System.Windows.Forms.CheckBox(); - this.duplicates = new System.Windows.Forms.Label(); - this.label16 = new System.Windows.Forms.Label(); - this.label15 = new System.Windows.Forms.Label(); - this.status = new System.Windows.Forms.Label(); - this.label14 = new System.Windows.Forms.Label(); - this.rate = new System.Windows.Forms.Label(); - this.label12 = new System.Windows.Forms.Label(); - this.elapsedTime = new System.Windows.Forms.Label(); - this.label10 = new System.Windows.Forms.Label(); - this.startTime = new System.Windows.Forms.Label(); - this.label6 = new System.Windows.Forms.Label(); - this.booksProcessed = new System.Windows.Forms.Label(); - this.label5 = new System.Windows.Forms.Label(); - this.invalidBooks = new System.Windows.Forms.Label(); - this.label9 = new System.Windows.Forms.Label(); - this.skippedBooks = new System.Windows.Forms.Label(); - this.label7 = new System.Windows.Forms.Label(); - this.booksFound = new System.Windows.Forms.Label(); - this.booksInDB = new System.Windows.Forms.Label(); - this.folderButton = new System.Windows.Forms.Button(); - this.label2 = new System.Windows.Forms.Label(); - this.label1 = new System.Windows.Forms.Label(); - this.scannerButton = new System.Windows.Forms.Button(); - this.libraryPath = new System.Windows.Forms.TextBox(); - this.tabPage2 = new System.Windows.Forms.TabPage(); - this.useAbsoluteUri = new System.Windows.Forms.CheckBox(); - this.interfaceCombo = new System.Windows.Forms.ComboBox(); - this.label29 = new System.Windows.Forms.Label(); - this.statUniqueClients = new System.Windows.Forms.Label(); - this.label26 = new System.Windows.Forms.Label(); - this.statImages = new System.Windows.Forms.Label(); - this.label27 = new System.Windows.Forms.Label(); - this.statBooks = new System.Windows.Forms.Label(); - this.label25 = new System.Windows.Forms.Label(); - this.statRequests = new System.Windows.Forms.Label(); - this.label23 = new System.Windows.Forms.Label(); - this.extLink = new System.Windows.Forms.LinkLabel(); - this.intLink = new System.Windows.Forms.LinkLabel(); - this.label13 = new System.Windows.Forms.Label(); - this.extIPlabel = new System.Windows.Forms.Label(); - this.intIPlabel = new System.Windows.Forms.Label(); - this.label4 = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.serverButton = new System.Windows.Forms.Button(); - this.openPort = new System.Windows.Forms.CheckBox(); - this.serverPort = new System.Windows.Forms.TextBox(); - this.useUPnP = new System.Windows.Forms.CheckBox(); - this.rootPrefix = new System.Windows.Forms.TextBox(); - this.serverName = new System.Windows.Forms.TextBox(); - this.tabPage5 = new System.Windows.Forms.TabPage(); - this.statBannedClients = new System.Windows.Forms.Label(); - this.label31 = new System.Windows.Forms.Label(); - this.label24 = new System.Windows.Forms.Label(); - this.statWrongLogins = new System.Windows.Forms.Label(); - this.label30 = new System.Windows.Forms.Label(); - this.statGoodLogins = new System.Windows.Forms.Label(); - this.label28 = new System.Windows.Forms.Label(); - this.dataGridView1 = new System.Windows.Forms.DataGridView(); - this.wrongAttemptsCount = new System.Windows.Forms.NumericUpDown(); - this.banClients = new System.Windows.Forms.CheckBox(); - this.rememberClients = new System.Windows.Forms.CheckBox(); - this.useHTTPAuth = new System.Windows.Forms.CheckBox(); - this.tabPage3 = new System.Windows.Forms.TabPage(); - this.label32 = new System.Windows.Forms.Label(); - this.updateCombo = new System.Windows.Forms.ComboBox(); - this.label22 = new System.Windows.Forms.Label(); - this.logVerbosity = new System.Windows.Forms.ComboBox(); - this.converterLinkLabel = new System.Windows.Forms.LinkLabel(); - this.label11 = new System.Windows.Forms.Label(); - this.langCombo = new System.Windows.Forms.ComboBox(); - this.label8 = new System.Windows.Forms.Label(); - this.convertorFolder = new System.Windows.Forms.Button(); - this.convertorPath = new System.Windows.Forms.TextBox(); - this.saveLog = new System.Windows.Forms.CheckBox(); - this.closeToTray = new System.Windows.Forms.CheckBox(); - this.startMinimized = new System.Windows.Forms.CheckBox(); - this.startWithWindows = new System.Windows.Forms.CheckBox(); - this.tabPage4 = new System.Windows.Forms.TabPage(); - this.linkLabel5 = new System.Windows.Forms.LinkLabel(); - this.linkLabel4 = new System.Windows.Forms.LinkLabel(); - this.linkLabel3 = new System.Windows.Forms.LinkLabel(); - this.label20 = new System.Windows.Forms.Label(); - this.label19 = new System.Windows.Forms.Label(); - this.linkLabel2 = new System.Windows.Forms.LinkLabel(); - this.label18 = new System.Windows.Forms.Label(); - this.linkLabel1 = new System.Windows.Forms.LinkLabel(); - this.label17 = new System.Windows.Forms.Label(); - this.appVersion = new System.Windows.Forms.Label(); - this.appName = new System.Windows.Forms.Label(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.donateButton = new System.Windows.Forms.Button(); - this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); - this.windowMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.serverMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); - this.exitMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.tabControl1.SuspendLayout(); - this.tabPage1.SuspendLayout(); - this.tabPage2.SuspendLayout(); - this.tabPage5.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.wrongAttemptsCount)).BeginInit(); - this.tabPage3.SuspendLayout(); - this.tabPage4.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - this.contextMenuStrip.SuspendLayout(); - this.SuspendLayout(); - // - // tabControl1 - // - this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.tabControl1.Controls.Add(this.tabPage1); - this.tabControl1.Controls.Add(this.tabPage2); - this.tabControl1.Controls.Add(this.tabPage5); - this.tabControl1.Controls.Add(this.tabPage3); - this.tabControl1.Controls.Add(this.tabPage4); - this.tabControl1.ItemSize = new System.Drawing.Size(91, 30); - this.tabControl1.Location = new System.Drawing.Point(-3, -1); - this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(481, 327); - this.tabControl1.TabIndex = 8; - // - // tabPage1 - // - this.tabPage1.BackColor = System.Drawing.SystemColors.Control; - this.tabPage1.Controls.Add(this.databaseFileName); - this.tabPage1.Controls.Add(this.label21); - this.tabPage1.Controls.Add(this.useWatcher); - this.tabPage1.Controls.Add(this.duplicates); - this.tabPage1.Controls.Add(this.label16); - this.tabPage1.Controls.Add(this.label15); - this.tabPage1.Controls.Add(this.status); - this.tabPage1.Controls.Add(this.label14); - this.tabPage1.Controls.Add(this.rate); - this.tabPage1.Controls.Add(this.label12); - this.tabPage1.Controls.Add(this.elapsedTime); - this.tabPage1.Controls.Add(this.label10); - this.tabPage1.Controls.Add(this.startTime); - this.tabPage1.Controls.Add(this.label6); - this.tabPage1.Controls.Add(this.booksProcessed); - this.tabPage1.Controls.Add(this.label5); - this.tabPage1.Controls.Add(this.invalidBooks); - this.tabPage1.Controls.Add(this.label9); - this.tabPage1.Controls.Add(this.skippedBooks); - this.tabPage1.Controls.Add(this.label7); - this.tabPage1.Controls.Add(this.booksFound); - this.tabPage1.Controls.Add(this.booksInDB); - this.tabPage1.Controls.Add(this.folderButton); - this.tabPage1.Controls.Add(this.label2); - this.tabPage1.Controls.Add(this.label1); - this.tabPage1.Controls.Add(this.scannerButton); - this.tabPage1.Controls.Add(this.libraryPath); - this.tabPage1.Location = new System.Drawing.Point(4, 34); - this.tabPage1.Name = "tabPage1"; - this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(473, 289); - this.tabPage1.TabIndex = 0; - this.tabPage1.Text = "Scanner settings"; - // - // databaseFileName - // - this.databaseFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.databaseFileName.Location = new System.Drawing.Point(125, 62); - this.databaseFileName.Name = "databaseFileName"; - this.databaseFileName.ReadOnly = true; - this.databaseFileName.Size = new System.Drawing.Size(336, 20); - this.databaseFileName.TabIndex = 32; - // - // label21 - // - this.label21.AutoSize = true; - this.label21.Location = new System.Drawing.Point(15, 66); - this.label21.Name = "label21"; - this.label21.Size = new System.Drawing.Size(104, 13); - this.label21.TabIndex = 31; - this.label21.Text = "Database file name: "; - // - // useWatcher - // - this.useWatcher.AutoSize = true; - this.useWatcher.Checked = global::TinyOPDS.Properties.Settings.Default.WatchLibrary; - this.useWatcher.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "WatchLibrary", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.useWatcher.Location = new System.Drawing.Point(329, 34); - this.useWatcher.Name = "useWatcher"; - this.useWatcher.Size = new System.Drawing.Size(135, 17); - this.useWatcher.TabIndex = 30; - this.useWatcher.Text = "Monitor library changes"; - this.useWatcher.UseVisualStyleBackColor = true; - this.useWatcher.CheckedChanged += new System.EventHandler(this.useWatcher_CheckedChanged); - // - // duplicates - // - this.duplicates.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.duplicates.AutoSize = true; - this.duplicates.Location = new System.Drawing.Point(122, 209); - this.duplicates.MinimumSize = new System.Drawing.Size(50, 0); - this.duplicates.Name = "duplicates"; - this.duplicates.Size = new System.Drawing.Size(50, 13); - this.duplicates.TabIndex = 29; - this.duplicates.Text = "0"; - // - // label16 - // - this.label16.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label16.AutoSize = true; - this.label16.Location = new System.Drawing.Point(15, 209); - this.label16.Name = "label16"; - this.label16.Size = new System.Drawing.Size(60, 13); - this.label16.TabIndex = 28; - this.label16.Text = "Duplicates:"; - // - // label15 - // - this.label15.AutoSize = true; - this.label15.Location = new System.Drawing.Point(14, 16); - this.label15.Name = "label15"; - this.label15.Size = new System.Drawing.Size(105, 13); - this.label15.TabIndex = 27; - this.label15.Text = "Path to books folder:"; - // - // status - // - this.status.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.status.AutoSize = true; - this.status.Location = new System.Drawing.Point(360, 209); - this.status.MinimumSize = new System.Drawing.Size(50, 0); - this.status.Name = "status"; - this.status.Size = new System.Drawing.Size(58, 13); - this.status.TabIndex = 26; - this.status.Text = "STOPPED"; - // - // label14 - // - this.label14.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label14.AutoSize = true; - this.label14.Location = new System.Drawing.Point(253, 209); - this.label14.Name = "label14"; - this.label14.Size = new System.Drawing.Size(40, 13); - this.label14.TabIndex = 25; - this.label14.Text = "Status:"; - // - // rate - // - this.rate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.rate.AutoSize = true; - this.rate.Location = new System.Drawing.Point(360, 183); - this.rate.MinimumSize = new System.Drawing.Size(50, 0); - this.rate.Name = "rate"; - this.rate.Size = new System.Drawing.Size(66, 13); - this.rate.TabIndex = 24; - this.rate.Text = "0 books/min"; - // - // label12 - // - this.label12.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label12.AutoSize = true; - this.label12.Location = new System.Drawing.Point(253, 183); - this.label12.Name = "label12"; - this.label12.Size = new System.Drawing.Size(33, 13); - this.label12.TabIndex = 23; - this.label12.Text = "Rate:"; - // - // elapsedTime - // - this.elapsedTime.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.elapsedTime.AutoSize = true; - this.elapsedTime.Location = new System.Drawing.Point(360, 157); - this.elapsedTime.MinimumSize = new System.Drawing.Size(50, 0); - this.elapsedTime.Name = "elapsedTime"; - this.elapsedTime.Size = new System.Drawing.Size(50, 13); - this.elapsedTime.TabIndex = 22; - this.elapsedTime.Text = "00:00:00"; - // - // label10 - // - this.label10.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label10.AutoSize = true; - this.label10.Location = new System.Drawing.Point(253, 157); - this.label10.Name = "label10"; - this.label10.Size = new System.Drawing.Size(70, 13); - this.label10.TabIndex = 21; - this.label10.Text = "Elapsed time:"; - // - // startTime - // - this.startTime.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.startTime.AutoSize = true; - this.startTime.Location = new System.Drawing.Point(360, 131); - this.startTime.MinimumSize = new System.Drawing.Size(50, 0); - this.startTime.Name = "startTime"; - this.startTime.Size = new System.Drawing.Size(50, 13); - this.startTime.TabIndex = 20; - this.startTime.Text = "00:00:00"; - // - // label6 - // - this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(253, 131); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(54, 13); - this.label6.TabIndex = 19; - this.label6.Text = "Start time:"; - // - // booksProcessed - // - this.booksProcessed.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.booksProcessed.AutoSize = true; - this.booksProcessed.Location = new System.Drawing.Point(123, 235); - this.booksProcessed.MinimumSize = new System.Drawing.Size(50, 0); - this.booksProcessed.Name = "booksProcessed"; - this.booksProcessed.Size = new System.Drawing.Size(50, 13); - this.booksProcessed.TabIndex = 18; - this.booksProcessed.Text = "0"; - // - // label5 - // - this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(15, 235); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(92, 13); - this.label5.TabIndex = 17; - this.label5.Text = "Books processed:"; - // - // invalidBooks - // - this.invalidBooks.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.invalidBooks.AutoSize = true; - this.invalidBooks.Location = new System.Drawing.Point(123, 157); - this.invalidBooks.MinimumSize = new System.Drawing.Size(50, 0); - this.invalidBooks.Name = "invalidBooks"; - this.invalidBooks.Size = new System.Drawing.Size(50, 13); - this.invalidBooks.TabIndex = 16; - this.invalidBooks.Text = "0"; - // - // label9 - // - this.label9.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(15, 157); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(73, 13); - this.label9.TabIndex = 15; - this.label9.Text = "Invalid books:"; - // - // skippedBooks - // - this.skippedBooks.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.skippedBooks.AutoSize = true; - this.skippedBooks.Location = new System.Drawing.Point(123, 183); - this.skippedBooks.MinimumSize = new System.Drawing.Size(50, 0); - this.skippedBooks.Name = "skippedBooks"; - this.skippedBooks.Size = new System.Drawing.Size(50, 13); - this.skippedBooks.TabIndex = 14; - this.skippedBooks.Text = "0"; - // - // label7 - // - this.label7.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(15, 183); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(81, 13); - this.label7.TabIndex = 13; - this.label7.Text = "Skipped books:"; - // - // booksFound - // - this.booksFound.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.booksFound.AutoSize = true; - this.booksFound.Location = new System.Drawing.Point(123, 131); - this.booksFound.MinimumSize = new System.Drawing.Size(50, 0); - this.booksFound.Name = "booksFound"; - this.booksFound.Size = new System.Drawing.Size(79, 13); - this.booksFound.TabIndex = 12; - this.booksFound.Text = "fb2: 0 epub: 0"; - // - // booksInDB - // - this.booksInDB.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.booksInDB.AutoSize = true; - this.booksInDB.Location = new System.Drawing.Point(123, 92); - this.booksInDB.MinimumSize = new System.Drawing.Size(50, 0); - this.booksInDB.Name = "booksInDB"; - this.booksInDB.Size = new System.Drawing.Size(127, 13); - this.booksInDB.TabIndex = 11; - this.booksInDB.Text = "0 fb2: 0 epub: 0"; - // - // folderButton - // - this.folderButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.folderButton.Image = global::TinyOPDS.Properties.Resources.folder; - this.folderButton.Location = new System.Drawing.Point(287, 30); - this.folderButton.Name = "folderButton"; - this.folderButton.Size = new System.Drawing.Size(29, 23); - this.folderButton.TabIndex = 10; - this.folderButton.UseVisualStyleBackColor = true; - this.folderButton.Click += new System.EventHandler(this.folderButton_Click); - // - // label2 - // - this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(15, 92); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(101, 13); - this.label2.TabIndex = 9; - this.label2.Text = "Books in database: "; - // - // label1 - // - this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(15, 131); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(70, 13); - this.label1.TabIndex = 8; - this.label1.Text = "Books found:"; - // - // scannerButton - // - this.scannerButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.scannerButton.Location = new System.Drawing.Point(255, 241); - this.scannerButton.Name = "scannerButton"; - this.scannerButton.Size = new System.Drawing.Size(210, 40); - this.scannerButton.TabIndex = 7; - this.scannerButton.Text = "Start scanning"; - this.scannerButton.UseVisualStyleBackColor = true; - this.scannerButton.Click += new System.EventHandler(this.scannerButton_Click); - // - // libraryPath - // - this.libraryPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.libraryPath.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::TinyOPDS.Properties.Settings.Default, "LibraryPath", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.libraryPath.Location = new System.Drawing.Point(17, 32); - this.libraryPath.Name = "libraryPath"; - this.libraryPath.Size = new System.Drawing.Size(268, 20); - this.libraryPath.TabIndex = 6; - this.libraryPath.Text = global::TinyOPDS.Properties.Settings.Default.LibraryPath; - this.libraryPath.Validated += new System.EventHandler(this.libraryPath_Validated); - // - // tabPage2 - // - this.tabPage2.BackColor = System.Drawing.SystemColors.Control; - this.tabPage2.Controls.Add(this.useAbsoluteUri); - this.tabPage2.Controls.Add(this.interfaceCombo); - this.tabPage2.Controls.Add(this.label29); - this.tabPage2.Controls.Add(this.statUniqueClients); - this.tabPage2.Controls.Add(this.label26); - this.tabPage2.Controls.Add(this.statImages); - this.tabPage2.Controls.Add(this.label27); - this.tabPage2.Controls.Add(this.statBooks); - this.tabPage2.Controls.Add(this.label25); - this.tabPage2.Controls.Add(this.statRequests); - this.tabPage2.Controls.Add(this.label23); - this.tabPage2.Controls.Add(this.extLink); - this.tabPage2.Controls.Add(this.intLink); - this.tabPage2.Controls.Add(this.label13); - this.tabPage2.Controls.Add(this.extIPlabel); - this.tabPage2.Controls.Add(this.intIPlabel); - this.tabPage2.Controls.Add(this.label4); - this.tabPage2.Controls.Add(this.label3); - this.tabPage2.Controls.Add(this.serverButton); - this.tabPage2.Controls.Add(this.openPort); - this.tabPage2.Controls.Add(this.serverPort); - this.tabPage2.Controls.Add(this.useUPnP); - this.tabPage2.Controls.Add(this.rootPrefix); - this.tabPage2.Controls.Add(this.serverName); - this.tabPage2.Location = new System.Drawing.Point(4, 34); - this.tabPage2.Name = "tabPage2"; - this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(473, 289); - this.tabPage2.TabIndex = 1; - this.tabPage2.Text = "OPDS server settings"; - // - // useAbsoluteUri - // - this.useAbsoluteUri.AutoSize = true; - this.useAbsoluteUri.Checked = global::TinyOPDS.Properties.Settings.Default.UseAbsoluteUri; - this.useAbsoluteUri.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "UseAbsoluteUri", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.useAbsoluteUri.Location = new System.Drawing.Point(294, 126); - this.useAbsoluteUri.Name = "useAbsoluteUri"; - this.useAbsoluteUri.Size = new System.Drawing.Size(91, 17); - this.useAbsoluteUri.TabIndex = 48; - this.useAbsoluteUri.Text = "Absolute links"; - this.useAbsoluteUri.UseVisualStyleBackColor = true; - // - // interfaceCombo - // - this.interfaceCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.interfaceCombo.FormattingEnabled = true; - this.interfaceCombo.Location = new System.Drawing.Point(294, 35); - this.interfaceCombo.Name = "interfaceCombo"; - this.interfaceCombo.Size = new System.Drawing.Size(113, 21); - this.interfaceCombo.TabIndex = 47; - this.interfaceCombo.SelectedIndexChanged += new System.EventHandler(this.interfaceCombo_SelectedIndexChanged); - // - // label29 - // - this.label29.AutoSize = true; - this.label29.Location = new System.Drawing.Point(292, 16); - this.label29.Name = "label29"; - this.label29.Size = new System.Drawing.Size(94, 13); - this.label29.TabIndex = 46; - this.label29.Text = "Network interface:"; - // - // statUniqueClients - // - this.statUniqueClients.AutoSize = true; - this.statUniqueClients.Location = new System.Drawing.Point(144, 229); - this.statUniqueClients.Name = "statUniqueClients"; - this.statUniqueClients.Size = new System.Drawing.Size(13, 13); - this.statUniqueClients.TabIndex = 45; - this.statUniqueClients.Text = "0"; - // - // label26 - // - this.label26.AutoSize = true; - this.label26.Location = new System.Drawing.Point(20, 229); - this.label26.Name = "label26"; - this.label26.Size = new System.Drawing.Size(77, 13); - this.label26.TabIndex = 44; - this.label26.Text = "Unique clients:"; - // - // statImages - // - this.statImages.AutoSize = true; - this.statImages.Location = new System.Drawing.Point(445, 201); - this.statImages.Name = "statImages"; - this.statImages.Size = new System.Drawing.Size(13, 13); - this.statImages.TabIndex = 43; - this.statImages.Text = "0"; - // - // label27 - // - this.label27.AutoSize = true; - this.label27.Location = new System.Drawing.Point(352, 201); - this.label27.Name = "label27"; - this.label27.Size = new System.Drawing.Size(67, 13); - this.label27.TabIndex = 42; - this.label27.Text = "Images sent:"; - // - // statBooks - // - this.statBooks.AutoSize = true; - this.statBooks.Location = new System.Drawing.Point(297, 201); - this.statBooks.Name = "statBooks"; - this.statBooks.Size = new System.Drawing.Size(13, 13); - this.statBooks.TabIndex = 41; - this.statBooks.Text = "0"; - // - // label25 - // - this.label25.AutoSize = true; - this.label25.Location = new System.Drawing.Point(200, 201); - this.label25.Name = "label25"; - this.label25.Size = new System.Drawing.Size(63, 13); - this.label25.TabIndex = 40; - this.label25.Text = "Books sent:"; - // - // statRequests - // - this.statRequests.AutoSize = true; - this.statRequests.Location = new System.Drawing.Point(144, 201); - this.statRequests.Name = "statRequests"; - this.statRequests.Size = new System.Drawing.Size(13, 13); - this.statRequests.TabIndex = 39; - this.statRequests.Text = "0"; - // - // label23 - // - this.label23.AutoSize = true; - this.label23.Location = new System.Drawing.Point(20, 201); - this.label23.Name = "label23"; - this.label23.Size = new System.Drawing.Size(77, 13); - this.label23.TabIndex = 38; - this.label23.Text = "Total requests:"; - // - // extLink - // - this.extLink.Location = new System.Drawing.Point(112, 152); - this.extLink.Name = "extLink"; - this.extLink.Size = new System.Drawing.Size(176, 13); - this.extLink.TabIndex = 37; - this.extLink.TabStop = true; - this.extLink.Text = "- - - - - -"; - this.extLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel_LinkClicked); - // - // intLink - // - this.intLink.Location = new System.Drawing.Point(112, 126); - this.intLink.Name = "intLink"; - this.intLink.Size = new System.Drawing.Size(176, 13); - this.intLink.TabIndex = 36; - this.intLink.TabStop = true; - this.intLink.Text = "- - - - - -"; - this.intLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel_LinkClicked); - // - // label13 - // - this.label13.AutoSize = true; - this.label13.Location = new System.Drawing.Point(19, 72); - this.label13.Name = "label13"; - this.label13.Size = new System.Drawing.Size(127, 13); - this.label13.TabIndex = 18; - this.label13.Text = "OPDS root catalog prefix:"; - // - // extIPlabel - // - this.extIPlabel.AutoSize = true; - this.extIPlabel.Location = new System.Drawing.Point(19, 153); - this.extIPlabel.Name = "extIPlabel"; - this.extIPlabel.Size = new System.Drawing.Size(73, 13); - this.extIPlabel.TabIndex = 14; - this.extIPlabel.Text = "External URL:"; - // - // intIPlabel - // - this.intIPlabel.AutoSize = true; - this.intIPlabel.Location = new System.Drawing.Point(19, 127); - this.intIPlabel.Name = "intIPlabel"; - this.intIPlabel.Size = new System.Drawing.Size(61, 13); - this.intIPlabel.TabIndex = 13; - this.intIPlabel.Text = "Local URL:"; - // - // label4 - // - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(17, 16); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(70, 13); - this.label4.TabIndex = 11; - this.label4.Text = "Server name:"; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(419, 16); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(29, 13); - this.label3.TabIndex = 9; - this.label3.Text = "Port:"; - // - // serverButton - // - this.serverButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.serverButton.Location = new System.Drawing.Point(255, 241); - this.serverButton.Name = "serverButton"; - this.serverButton.Size = new System.Drawing.Size(210, 40); - this.serverButton.TabIndex = 8; - this.serverButton.Text = "Start server"; - this.serverButton.Click += new System.EventHandler(this.serverButton_Click); - // - // openPort - // - this.openPort.AutoSize = true; - this.openPort.Checked = global::TinyOPDS.Properties.Settings.Default.OpenNATPort; - this.openPort.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "OpenNATPort", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.openPort.Enabled = false; - this.openPort.Location = new System.Drawing.Point(294, 97); - this.openPort.Name = "openPort"; - this.openPort.Size = new System.Drawing.Size(130, 17); - this.openPort.TabIndex = 15; - this.openPort.Text = "Forward port on router"; - this.openPort.UseVisualStyleBackColor = true; - this.openPort.CheckedChanged += new System.EventHandler(this.openPort_CheckedChanged); - // - // serverPort - // - this.serverPort.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::TinyOPDS.Properties.Settings.Default, "ServerPort", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.serverPort.Location = new System.Drawing.Point(421, 35); - this.serverPort.Name = "serverPort"; - this.serverPort.Size = new System.Drawing.Size(44, 20); - this.serverPort.TabIndex = 10; - this.serverPort.Text = global::TinyOPDS.Properties.Settings.Default.ServerPort; - this.serverPort.Validated += new System.EventHandler(this.serverPort_Validated); - // - // useUPnP - // - this.useUPnP.AutoSize = true; - this.useUPnP.Checked = global::TinyOPDS.Properties.Settings.Default.UseUPnP; - this.useUPnP.CheckState = System.Windows.Forms.CheckState.Checked; - this.useUPnP.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "UseUPnP", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.useUPnP.Location = new System.Drawing.Point(294, 68); - this.useUPnP.Name = "useUPnP"; - this.useUPnP.Size = new System.Drawing.Size(76, 17); - this.useUPnP.TabIndex = 35; - this.useUPnP.Text = "Use UPnP"; - this.useUPnP.UseVisualStyleBackColor = true; - this.useUPnP.CheckStateChanged += new System.EventHandler(this.useUPnP_CheckStateChanged); - // - // rootPrefix - // - this.rootPrefix.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::TinyOPDS.Properties.Settings.Default, "RootPrefix", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.rootPrefix.Location = new System.Drawing.Point(22, 92); - this.rootPrefix.Name = "rootPrefix"; - this.rootPrefix.Size = new System.Drawing.Size(254, 20); - this.rootPrefix.TabIndex = 19; - this.rootPrefix.Text = global::TinyOPDS.Properties.Settings.Default.RootPrefix; - this.rootPrefix.TextChanged += new System.EventHandler(this.rootPrefix_TextChanged); - // - // serverName - // - this.serverName.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::TinyOPDS.Properties.Settings.Default, "ServerName", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.serverName.Location = new System.Drawing.Point(20, 35); - this.serverName.Name = "serverName"; - this.serverName.Size = new System.Drawing.Size(256, 20); - this.serverName.TabIndex = 12; - this.serverName.Text = global::TinyOPDS.Properties.Settings.Default.ServerName; - // - // tabPage5 - // - this.tabPage5.BackColor = System.Drawing.SystemColors.Control; - this.tabPage5.Controls.Add(this.statBannedClients); - this.tabPage5.Controls.Add(this.label31); - this.tabPage5.Controls.Add(this.label24); - this.tabPage5.Controls.Add(this.statWrongLogins); - this.tabPage5.Controls.Add(this.label30); - this.tabPage5.Controls.Add(this.statGoodLogins); - this.tabPage5.Controls.Add(this.label28); - this.tabPage5.Controls.Add(this.dataGridView1); - this.tabPage5.Controls.Add(this.wrongAttemptsCount); - this.tabPage5.Controls.Add(this.banClients); - this.tabPage5.Controls.Add(this.rememberClients); - this.tabPage5.Controls.Add(this.useHTTPAuth); - this.tabPage5.Location = new System.Drawing.Point(4, 34); - this.tabPage5.Name = "tabPage5"; - this.tabPage5.Padding = new System.Windows.Forms.Padding(3); - this.tabPage5.Size = new System.Drawing.Size(473, 289); - this.tabPage5.TabIndex = 4; - this.tabPage5.Text = "Authentication"; - // - // statBannedClients - // - this.statBannedClients.AutoSize = true; - this.statBannedClients.Location = new System.Drawing.Point(429, 254); - this.statBannedClients.Name = "statBannedClients"; - this.statBannedClients.Size = new System.Drawing.Size(13, 13); - this.statBannedClients.TabIndex = 48; - this.statBannedClients.Text = "0"; - this.statBannedClients.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // label31 - // - this.label31.AutoSize = true; - this.label31.Location = new System.Drawing.Point(334, 254); - this.label31.Name = "label31"; - this.label31.Size = new System.Drawing.Size(80, 13); - this.label31.TabIndex = 47; - this.label31.Text = "Banned clients:"; - // - // label24 - // - this.label24.AutoSize = true; - this.label24.Location = new System.Drawing.Point(329, 51); - this.label24.Name = "label24"; - this.label24.Size = new System.Drawing.Size(75, 13); - this.label24.TabIndex = 46; - this.label24.Text = "failed attempts"; - // - // statWrongLogins - // - this.statWrongLogins.AutoSize = true; - this.statWrongLogins.Location = new System.Drawing.Point(279, 254); - this.statWrongLogins.Name = "statWrongLogins"; - this.statWrongLogins.Size = new System.Drawing.Size(13, 13); - this.statWrongLogins.TabIndex = 43; - this.statWrongLogins.Text = "0"; - this.statWrongLogins.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // label30 - // - this.label30.AutoSize = true; - this.label30.Location = new System.Drawing.Point(185, 254); - this.label30.Name = "label30"; - this.label30.Size = new System.Drawing.Size(68, 13); - this.label30.TabIndex = 42; - this.label30.Text = "Failed logins:"; - // - // statGoodLogins - // - this.statGoodLogins.AutoSize = true; - this.statGoodLogins.Location = new System.Drawing.Point(128, 254); - this.statGoodLogins.Name = "statGoodLogins"; - this.statGoodLogins.Size = new System.Drawing.Size(13, 13); - this.statGoodLogins.TabIndex = 41; - this.statGoodLogins.Text = "0"; - this.statGoodLogins.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // label28 - // - this.label28.AutoSize = true; - this.label28.Location = new System.Drawing.Point(23, 254); - this.label28.Name = "label28"; - this.label28.Size = new System.Drawing.Size(92, 13); - this.label28.TabIndex = 40; - this.label28.Text = "Successful logins:"; - // - // dataGridView1 - // - this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView1.Location = new System.Drawing.Point(26, 83); - this.dataGridView1.Name = "dataGridView1"; - this.dataGridView1.Size = new System.Drawing.Size(419, 150); - this.dataGridView1.TabIndex = 1; - this.dataGridView1.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.dataGridView1_CellFormatting); - // - // wrongAttemptsCount - // - this.wrongAttemptsCount.DataBindings.Add(new System.Windows.Forms.Binding("Value", global::TinyOPDS.Properties.Settings.Default, "WrongAttemptsCount", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.wrongAttemptsCount.Location = new System.Drawing.Point(283, 46); - this.wrongAttemptsCount.Minimum = new decimal(new int[] { - 3, - 0, - 0, - 0}); - this.wrongAttemptsCount.Name = "wrongAttemptsCount"; - this.wrongAttemptsCount.Size = new System.Drawing.Size(40, 20); - this.wrongAttemptsCount.TabIndex = 45; - this.wrongAttemptsCount.Value = global::TinyOPDS.Properties.Settings.Default.WrongAttemptsCount; - // - // banClients - // - this.banClients.AutoSize = true; - this.banClients.Checked = global::TinyOPDS.Properties.Settings.Default.BanClients; - this.banClients.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "BanClients", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.banClients.Location = new System.Drawing.Point(283, 23); - this.banClients.Name = "banClients"; - this.banClients.Size = new System.Drawing.Size(102, 17); - this.banClients.TabIndex = 44; - this.banClients.Text = "Ban clients after"; - this.banClients.UseVisualStyleBackColor = true; - this.banClients.CheckedChanged += new System.EventHandler(this.banClients_CheckedChanged); - // - // rememberClients - // - this.rememberClients.AutoSize = true; - this.rememberClients.Checked = global::TinyOPDS.Properties.Settings.Default.RememberClients; - this.rememberClients.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "RememberClients", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.rememberClients.Location = new System.Drawing.Point(26, 51); - this.rememberClients.Name = "rememberClients"; - this.rememberClients.Size = new System.Drawing.Size(162, 17); - this.rememberClients.TabIndex = 2; - this.rememberClients.Text = "Remember authorized clients"; - this.rememberClients.UseVisualStyleBackColor = true; - // - // useHTTPAuth - // - this.useHTTPAuth.AutoSize = true; - this.useHTTPAuth.Checked = global::TinyOPDS.Properties.Settings.Default.UseHTTPAuth; - this.useHTTPAuth.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "UseHTTPAuth", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.useHTTPAuth.Location = new System.Drawing.Point(26, 23); - this.useHTTPAuth.Name = "useHTTPAuth"; - this.useHTTPAuth.Size = new System.Drawing.Size(175, 17); - this.useHTTPAuth.TabIndex = 0; - this.useHTTPAuth.Text = "Use HTTP basic authentication"; - this.useHTTPAuth.UseVisualStyleBackColor = true; - this.useHTTPAuth.CheckedChanged += new System.EventHandler(this.useHTTPAuth_CheckedChanged); - // - // tabPage3 - // - this.tabPage3.BackColor = System.Drawing.SystemColors.Control; - this.tabPage3.Controls.Add(this.label32); - this.tabPage3.Controls.Add(this.updateCombo); - this.tabPage3.Controls.Add(this.label22); - this.tabPage3.Controls.Add(this.logVerbosity); - this.tabPage3.Controls.Add(this.converterLinkLabel); - this.tabPage3.Controls.Add(this.label11); - this.tabPage3.Controls.Add(this.langCombo); - this.tabPage3.Controls.Add(this.label8); - this.tabPage3.Controls.Add(this.convertorFolder); - this.tabPage3.Controls.Add(this.convertorPath); - this.tabPage3.Controls.Add(this.saveLog); - this.tabPage3.Controls.Add(this.closeToTray); - this.tabPage3.Controls.Add(this.startMinimized); - this.tabPage3.Controls.Add(this.startWithWindows); - this.tabPage3.Location = new System.Drawing.Point(4, 34); - this.tabPage3.Name = "tabPage3"; - this.tabPage3.Padding = new System.Windows.Forms.Padding(3); - this.tabPage3.Size = new System.Drawing.Size(473, 289); - this.tabPage3.TabIndex = 2; - this.tabPage3.Text = "Miscellaneous"; - // - // label32 - // - this.label32.AutoSize = true; - this.label32.Location = new System.Drawing.Point(298, 143); - this.label32.Name = "label32"; - this.label32.Size = new System.Drawing.Size(92, 13); - this.label32.TabIndex = 38; - this.label32.Text = "Check for update:"; - // - // updateCombo - // - this.updateCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.updateCombo.FormattingEnabled = true; - this.updateCombo.Items.AddRange(new object[] { - "Never", - "Once a week", - "Once a month"}); - this.updateCombo.Location = new System.Drawing.Point(299, 166); - this.updateCombo.Name = "updateCombo"; - this.updateCombo.Size = new System.Drawing.Size(127, 21); - this.updateCombo.TabIndex = 37; - this.updateCombo.SelectedIndexChanged += new System.EventHandler(this.updateCombo_SelectedIndexChanged); - // - // label22 - // - this.label22.AutoSize = true; - this.label22.Location = new System.Drawing.Point(13, 195); - this.label22.Name = "label22"; - this.label22.Size = new System.Drawing.Size(95, 13); - this.label22.TabIndex = 36; - this.label22.Text = "Log verbosity level"; - // - // logVerbosity - // - this.logVerbosity.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.logVerbosity.FormattingEnabled = true; - this.logVerbosity.Items.AddRange(new object[] { - "Info, warnings and errors", - "Warnings and errors", - "Errors only"}); - this.logVerbosity.Location = new System.Drawing.Point(14, 218); - this.logVerbosity.Name = "logVerbosity"; - this.logVerbosity.Size = new System.Drawing.Size(246, 21); - this.logVerbosity.TabIndex = 35; - this.logVerbosity.SelectedIndexChanged += new System.EventHandler(this.logVerbosity_SelectedIndexChanged); - // - // converterLinkLabel - // - this.converterLinkLabel.AutoSize = true; - this.converterLinkLabel.Location = new System.Drawing.Point(12, 55); - this.converterLinkLabel.Name = "converterLinkLabel"; - this.converterLinkLabel.Size = new System.Drawing.Size(268, 13); - this.converterLinkLabel.TabIndex = 34; - this.converterLinkLabel.TabStop = true; - this.converterLinkLabel.Text = "Click here to download latest version of ePub converter"; - this.converterLinkLabel.Visible = false; - this.converterLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel3_LinkClicked); - // - // label11 - // - this.label11.AutoSize = true; - this.label11.Location = new System.Drawing.Point(296, 82); - this.label11.Name = "label11"; - this.label11.Size = new System.Drawing.Size(130, 13); - this.label11.TabIndex = 32; - this.label11.Text = "GUI and OPDS language:"; - // - // langCombo - // - this.langCombo.DisplayMember = "Value"; - this.langCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.langCombo.FormattingEnabled = true; - this.langCombo.Location = new System.Drawing.Point(299, 107); - this.langCombo.Name = "langCombo"; - this.langCombo.Size = new System.Drawing.Size(127, 21); - this.langCombo.TabIndex = 31; - this.langCombo.ValueMember = "Key"; - this.langCombo.SelectedValueChanged += new System.EventHandler(this.langCombo_SelectedValueChanged); - // - // label8 - // - this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(8, 12); - this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(138, 13); - this.label8.TabIndex = 30; - this.label8.Text = "Path to the ePub converter:"; - // - // convertorFolder - // - this.convertorFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.convertorFolder.Image = global::TinyOPDS.Properties.Resources.folder; - this.convertorFolder.Location = new System.Drawing.Point(430, 26); - this.convertorFolder.Name = "convertorFolder"; - this.convertorFolder.Size = new System.Drawing.Size(29, 23); - this.convertorFolder.TabIndex = 29; - this.convertorFolder.UseVisualStyleBackColor = true; - this.convertorFolder.Click += new System.EventHandler(this.folderButton_Click); - // - // convertorPath - // - this.convertorPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.convertorPath.Location = new System.Drawing.Point(11, 28); - this.convertorPath.Name = "convertorPath"; - this.convertorPath.Size = new System.Drawing.Size(415, 20); - this.convertorPath.TabIndex = 28; - this.convertorPath.Validated += new System.EventHandler(this.convertorPath_Validated); - // - // saveLog - // - this.saveLog.AutoSize = true; - this.saveLog.Checked = global::TinyOPDS.Properties.Settings.Default.SaveLogToDisk; - this.saveLog.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "SaveLogToDisk", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.saveLog.Location = new System.Drawing.Point(14, 166); - this.saveLog.Name = "saveLog"; - this.saveLog.Size = new System.Drawing.Size(96, 17); - this.saveLog.TabIndex = 33; - this.saveLog.Text = "Save log to file"; - this.saveLog.UseVisualStyleBackColor = true; - this.saveLog.CheckedChanged += new System.EventHandler(this.saveLog_CheckedChanged); - // - // closeToTray - // - this.closeToTray.AutoSize = true; - this.closeToTray.Checked = global::TinyOPDS.Properties.Settings.Default.CloseToTray; - this.closeToTray.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "CloseToTray", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.closeToTray.Location = new System.Drawing.Point(14, 138); - this.closeToTray.Name = "closeToTray"; - this.closeToTray.Size = new System.Drawing.Size(138, 17); - this.closeToTray.TabIndex = 2; - this.closeToTray.Text = "Close or minimize to tray"; - this.closeToTray.UseVisualStyleBackColor = true; - this.closeToTray.CheckedChanged += new System.EventHandler(this.closeToTray_CheckedChanged); - // - // startMinimized - // - this.startMinimized.AutoSize = true; - this.startMinimized.Checked = global::TinyOPDS.Properties.Settings.Default.StartMinimized; - this.startMinimized.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "StartMinimized", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.startMinimized.Location = new System.Drawing.Point(14, 110); - this.startMinimized.Name = "startMinimized"; - this.startMinimized.Size = new System.Drawing.Size(96, 17); - this.startMinimized.TabIndex = 1; - this.startMinimized.Text = "Start minimized"; - this.startMinimized.UseVisualStyleBackColor = true; - // - // startWithWindows - // - this.startWithWindows.AutoSize = true; - this.startWithWindows.Checked = global::TinyOPDS.Properties.Settings.Default.StartWithWindows; - this.startWithWindows.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TinyOPDS.Properties.Settings.Default, "StartWithWindows", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.startWithWindows.Location = new System.Drawing.Point(14, 82); - this.startWithWindows.Name = "startWithWindows"; - this.startWithWindows.Size = new System.Drawing.Size(117, 17); - this.startWithWindows.TabIndex = 0; - this.startWithWindows.Text = "Start with Windows"; - this.startWithWindows.UseVisualStyleBackColor = true; - this.startWithWindows.CheckedChanged += new System.EventHandler(this.startWithWindows_CheckedChanged); - // - // tabPage4 - // - this.tabPage4.BackColor = System.Drawing.SystemColors.Control; - this.tabPage4.Controls.Add(this.linkLabel5); - this.tabPage4.Controls.Add(this.linkLabel4); - this.tabPage4.Controls.Add(this.linkLabel3); - this.tabPage4.Controls.Add(this.label20); - this.tabPage4.Controls.Add(this.label19); - this.tabPage4.Controls.Add(this.linkLabel2); - this.tabPage4.Controls.Add(this.label18); - this.tabPage4.Controls.Add(this.linkLabel1); - this.tabPage4.Controls.Add(this.label17); - this.tabPage4.Controls.Add(this.appVersion); - this.tabPage4.Controls.Add(this.appName); - this.tabPage4.Controls.Add(this.pictureBox1); - this.tabPage4.Controls.Add(this.donateButton); - this.tabPage4.Location = new System.Drawing.Point(4, 34); - this.tabPage4.Name = "tabPage4"; - this.tabPage4.Padding = new System.Windows.Forms.Padding(3); - this.tabPage4.Size = new System.Drawing.Size(473, 289); - this.tabPage4.TabIndex = 3; - this.tabPage4.Text = "About program"; - // - // linkLabel5 - // - this.linkLabel5.AutoSize = true; - this.linkLabel5.Location = new System.Drawing.Point(195, 212); - this.linkLabel5.Name = "linkLabel5"; - this.linkLabel5.Size = new System.Drawing.Size(97, 13); - this.linkLabel5.TabIndex = 12; - this.linkLabel5.TabStop = true; - this.linkLabel5.Text = "ePubReader library"; - this.linkLabel5.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel3_LinkClicked); - // - // linkLabel4 - // - this.linkLabel4.AutoSize = true; - this.linkLabel4.Location = new System.Drawing.Point(195, 235); - this.linkLabel4.Name = "linkLabel4"; - this.linkLabel4.Size = new System.Drawing.Size(86, 13); - this.linkLabel4.TabIndex = 11; - this.linkLabel4.TabStop = true; - this.linkLabel4.Text = "DotNetZip library"; - this.linkLabel4.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel3_LinkClicked); - // - // linkLabel3 - // - this.linkLabel3.AutoSize = true; - this.linkLabel3.Location = new System.Drawing.Point(193, 190); - this.linkLabel3.Name = "linkLabel3"; - this.linkLabel3.Size = new System.Drawing.Size(267, 13); - this.linkLabel3.TabIndex = 10; - this.linkLabel3.TabStop = true; - this.linkLabel3.Text = "Lord KiRon, author of fb2librarynet library and converter"; - this.linkLabel3.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel3_LinkClicked); - // - // label20 - // - this.label20.Location = new System.Drawing.Point(9, 190); - this.label20.Name = "label20"; - this.label20.Size = new System.Drawing.Size(161, 13); - this.label20.TabIndex = 9; - this.label20.Text = "Special thanks:"; - this.label20.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // label19 - // - this.label19.AutoSize = true; - this.label19.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.label19.Location = new System.Drawing.Point(192, 89); - this.label19.Name = "label19"; - this.label19.Size = new System.Drawing.Size(220, 20); - this.label19.TabIndex = 8; - this.label19.Text = "Copyright © 2013, SeNSSoFT"; - // - // linkLabel2 - // - this.linkLabel2.AutoSize = true; - this.linkLabel2.Location = new System.Drawing.Point(193, 167); - this.linkLabel2.Name = "linkLabel2"; - this.linkLabel2.Size = new System.Drawing.Size(184, 13); - this.linkLabel2.TabIndex = 7; - this.linkLabel2.TabStop = true; - this.linkLabel2.Text = "http://tinyopds.codeplex.com/license"; - this.linkLabel2.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel_LinkClicked); - // - // label18 - // - this.label18.Location = new System.Drawing.Point(11, 167); - this.label18.Name = "label18"; - this.label18.Size = new System.Drawing.Size(159, 13); - this.label18.TabIndex = 6; - this.label18.Text = "Project license:"; - this.label18.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // linkLabel1 - // - this.linkLabel1.AutoSize = true; - this.linkLabel1.Location = new System.Drawing.Point(193, 144); - this.linkLabel1.Name = "linkLabel1"; - this.linkLabel1.Size = new System.Drawing.Size(151, 13); - this.linkLabel1.TabIndex = 5; - this.linkLabel1.TabStop = true; - this.linkLabel1.Text = "http://tinyopds.codeplex.com/"; - this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel_LinkClicked); - // - // label17 - // - this.label17.Location = new System.Drawing.Point(8, 144); - this.label17.Name = "label17"; - this.label17.Size = new System.Drawing.Size(162, 13); - this.label17.TabIndex = 4; - this.label17.Text = "Project home page:"; - this.label17.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // appVersion - // - this.appVersion.AutoSize = true; - this.appVersion.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.appVersion.Location = new System.Drawing.Point(262, 58); - this.appVersion.Name = "appVersion"; - this.appVersion.Size = new System.Drawing.Size(85, 20); - this.appVersion.TabIndex = 3; - this.appVersion.Text = "version 1.0"; - // - // appName - // - this.appName.AutoSize = true; - this.appName.Font = new System.Drawing.Font("Microsoft Sans Serif", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.appName.Location = new System.Drawing.Point(190, 14); - this.appName.Name = "appName"; - this.appName.Size = new System.Drawing.Size(226, 31); - this.appName.TabIndex = 2; - this.appName.Text = "TinyOPDS server"; - // - // pictureBox1 - // - this.pictureBox1.ErrorImage = null; - this.pictureBox1.Image = global::TinyOPDS.Properties.Resources.TinyOPDS; - this.pictureBox1.Location = new System.Drawing.Point(8, 9); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(103, 103); - this.pictureBox1.TabIndex = 1; - this.pictureBox1.TabStop = false; - // - // donateButton - // - this.donateButton.Image = global::TinyOPDS.Properties.Resources.donate; - this.donateButton.Location = new System.Drawing.Point(9, 223); - this.donateButton.Name = "donateButton"; - this.donateButton.Size = new System.Drawing.Size(157, 56); - this.donateButton.TabIndex = 0; - this.donateButton.UseVisualStyleBackColor = true; - this.donateButton.Click += new System.EventHandler(this.donateButton_Click); - // - // contextMenuStrip - // - this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.windowMenuItem, - this.serverMenuItem, - this.toolStripMenuItem1, - this.exitMenuItem}); - this.contextMenuStrip.Name = "contextMenuStrip1"; - this.contextMenuStrip.Size = new System.Drawing.Size(145, 76); - // - // windowMenuItem - // - this.windowMenuItem.Name = "windowMenuItem"; - this.windowMenuItem.Size = new System.Drawing.Size(144, 22); - this.windowMenuItem.Text = "Hide window"; - this.windowMenuItem.Click += new System.EventHandler(this.windowMenuItem_Click); - // - // serverMenuItem - // - this.serverMenuItem.Name = "serverMenuItem"; - this.serverMenuItem.Size = new System.Drawing.Size(144, 22); - this.serverMenuItem.Text = "Stop server"; - this.serverMenuItem.Click += new System.EventHandler(this.serverButton_Click); - // - // toolStripMenuItem1 - // - this.toolStripMenuItem1.Name = "toolStripMenuItem1"; - this.toolStripMenuItem1.Size = new System.Drawing.Size(141, 6); - // - // exitMenuItem - // - this.exitMenuItem.Name = "exitMenuItem"; - this.exitMenuItem.Size = new System.Drawing.Size(144, 22); - this.exitMenuItem.Text = "Exit"; - this.exitMenuItem.Click += new System.EventHandler(this.exitMenuItem_Click); - // - // MainForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(474, 322); - this.Controls.Add(this.tabControl1); - this.DoubleBuffered = true; - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.Name = "MainForm"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "TinyOPDS server"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainForm_FormClosed); - this.Resize += new System.EventHandler(this.MainForm_Resize); - this.tabControl1.ResumeLayout(false); - this.tabPage1.ResumeLayout(false); - this.tabPage1.PerformLayout(); - this.tabPage2.ResumeLayout(false); - this.tabPage2.PerformLayout(); - this.tabPage5.ResumeLayout(false); - this.tabPage5.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.wrongAttemptsCount)).EndInit(); - this.tabPage3.ResumeLayout(false); - this.tabPage3.PerformLayout(); - this.tabPage4.ResumeLayout(false); - this.tabPage4.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - this.contextMenuStrip.ResumeLayout(false); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.TabControl tabControl1; - private System.Windows.Forms.TabPage tabPage1; - private System.Windows.Forms.Button folderButton; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Button scannerButton; - private System.Windows.Forms.TextBox libraryPath; - private System.Windows.Forms.TabPage tabPage2; - private System.Windows.Forms.TextBox serverPort; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.Button serverButton; - private System.Windows.Forms.TabPage tabPage3; - private System.Windows.Forms.Label invalidBooks; - private System.Windows.Forms.Label label9; - private System.Windows.Forms.Label skippedBooks; - private System.Windows.Forms.Label label7; - private System.Windows.Forms.Label booksFound; - private System.Windows.Forms.Label booksInDB; - private System.Windows.Forms.Label label15; - private System.Windows.Forms.Label status; - private System.Windows.Forms.Label label14; - private System.Windows.Forms.Label rate; - private System.Windows.Forms.Label label12; - private System.Windows.Forms.Label elapsedTime; - private System.Windows.Forms.Label label10; - private System.Windows.Forms.Label startTime; - private System.Windows.Forms.Label label6; - private System.Windows.Forms.Label booksProcessed; - private System.Windows.Forms.Label label5; - private System.Windows.Forms.TextBox serverName; - private System.Windows.Forms.Label label4; - private System.Windows.Forms.CheckBox closeToTray; - private System.Windows.Forms.CheckBox startMinimized; - private System.Windows.Forms.CheckBox startWithWindows; - private System.Windows.Forms.Label label8; - private System.Windows.Forms.Button convertorFolder; - private System.Windows.Forms.TextBox convertorPath; - private System.Windows.Forms.Label label11; - private System.Windows.Forms.ComboBox langCombo; - private System.Windows.Forms.CheckBox openPort; - private System.Windows.Forms.Label extIPlabel; - private System.Windows.Forms.Label intIPlabel; - private System.Windows.Forms.ContextMenuStrip contextMenuStrip; - private System.Windows.Forms.ToolStripMenuItem windowMenuItem; - private System.Windows.Forms.ToolStripMenuItem serverMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; - private System.Windows.Forms.ToolStripMenuItem exitMenuItem; - private System.Windows.Forms.CheckBox saveLog; - private System.Windows.Forms.Label duplicates; - private System.Windows.Forms.Label label16; - private System.Windows.Forms.TextBox rootPrefix; - private System.Windows.Forms.Label label13; - private System.Windows.Forms.CheckBox useWatcher; - private System.Windows.Forms.TabPage tabPage4; - private System.Windows.Forms.CheckBox useUPnP; - private System.Windows.Forms.LinkLabel converterLinkLabel; - private System.Windows.Forms.Button donateButton; - private System.Windows.Forms.PictureBox pictureBox1; - private System.Windows.Forms.Label label19; - private System.Windows.Forms.LinkLabel linkLabel2; - private System.Windows.Forms.Label label18; - private System.Windows.Forms.LinkLabel linkLabel1; - private System.Windows.Forms.Label label17; - private System.Windows.Forms.Label appVersion; - private System.Windows.Forms.Label appName; - private System.Windows.Forms.Label label20; - private System.Windows.Forms.LinkLabel intLink; - private System.Windows.Forms.LinkLabel extLink; - private System.Windows.Forms.LinkLabel linkLabel5; - private System.Windows.Forms.LinkLabel linkLabel4; - private System.Windows.Forms.LinkLabel linkLabel3; - private System.Windows.Forms.TextBox databaseFileName; - private System.Windows.Forms.Label label21; - private System.Windows.Forms.TabPage tabPage5; - private System.Windows.Forms.CheckBox useHTTPAuth; - private System.Windows.Forms.DataGridView dataGridView1; - private System.Windows.Forms.CheckBox rememberClients; - private System.Windows.Forms.Label label22; - private System.Windows.Forms.ComboBox logVerbosity; - private System.Windows.Forms.Label statImages; - private System.Windows.Forms.Label label27; - private System.Windows.Forms.Label statBooks; - private System.Windows.Forms.Label label25; - private System.Windows.Forms.Label statRequests; - private System.Windows.Forms.Label label23; - private System.Windows.Forms.Label statUniqueClients; - private System.Windows.Forms.Label label26; - private System.Windows.Forms.Label statGoodLogins; - private System.Windows.Forms.Label label28; - private System.Windows.Forms.Label statWrongLogins; - private System.Windows.Forms.Label label30; - private System.Windows.Forms.Label label24; - private System.Windows.Forms.NumericUpDown wrongAttemptsCount; - private System.Windows.Forms.CheckBox banClients; - private System.Windows.Forms.Label statBannedClients; - private System.Windows.Forms.Label label31; - private System.Windows.Forms.Label label32; - private System.Windows.Forms.ComboBox updateCombo; - private System.Windows.Forms.ComboBox interfaceCombo; - private System.Windows.Forms.Label label29; - private System.Windows.Forms.CheckBox useAbsoluteUri; - } -} - diff --git a/releases/1.1/MainForm.cs b/releases/1.1/MainForm.cs deleted file mode 100644 index eda26ff..0000000 --- a/releases/1.1/MainForm.cs +++ /dev/null @@ -1,824 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * TinyOPDS main UI thread - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Windows.Forms; -using System.Xml.Linq; -using System.Threading; -using System.Net; - -using TinyOPDS.Data; -using TinyOPDS.Scanner; -using TinyOPDS.OPDS; -using TinyOPDS.Server; -using UPnP; - -namespace TinyOPDS -{ - public partial class MainForm : Form - { - OPDSServer _server; - Thread _serverThread; - FileScanner _scanner = new FileScanner(); - Watcher _watcher; - DateTime _scanStartTime; - UPnPController _upnpController = new UPnPController(); - NotifyIcon _notifyIcon = new NotifyIcon(); - BindingSource bs = new BindingSource(); - System.Windows.Forms.Timer _updateChecker = new System.Windows.Forms.Timer(); - string _updateUrl = string.Empty; - - #region Statistical information - int _fb2Count, _epubCount, _skippedFiles, _invalidFiles, _duplicates; - #endregion - - private const string urlTemplate = "http://{0}:{1}/{2}"; - - #region Initialization and startup - - public MainForm() - { - Log.SaveToFile = Properties.Settings.Default.SaveLogToDisk; - - AppDomain currentDomain = AppDomain.CurrentDomain; - currentDomain.UnhandledException += currentDomain_UnhandledException; - - InitializeComponent(); - - // Assign combo data source to the list of all available interfaces - interfaceCombo.DataSource = UPnPController.LocalInterfaces; - interfaceCombo.DataBindings.Add(new Binding("SelectedIndex", Properties.Settings.Default, "LocalInterfaceIndex", false, DataSourceUpdateMode.OnPropertyChanged)); - - logVerbosity.DataBindings.Add(new Binding("SelectedIndex", Properties.Settings.Default, "LogLevel", false, DataSourceUpdateMode.OnPropertyChanged)); - updateCombo.DataBindings.Add(new Binding("SelectedIndex", Properties.Settings.Default, "UpdatesCheck", false, DataSourceUpdateMode.OnPropertyChanged)); - - this.PerformLayout(); - - // Manually assign icons from resources (fix for Mono) - this.Icon = Properties.Resources.trayIcon; - _notifyIcon.ContextMenuStrip = this.contextMenuStrip; - _notifyIcon.Icon = Properties.Resources.trayIcon; - _notifyIcon.MouseClick += notifyIcon1_MouseClick; - _notifyIcon.BalloonTipClicked += _notifyIcon_BalloonTipClicked; - _notifyIcon.BalloonTipClosed += _notifyIcon_BalloonTipClosed; - - // Init localization service - Localizer.Init(); - Localizer.AddMenu(contextMenuStrip); - langCombo.DataSource = Localizer.Languages.ToArray(); - - // Load application settings - LoadSettings(); - - // Initialize update checker timer - _updateChecker.Interval = 1000 * 30; - _updateChecker.Tick += _updateChecker_Tick; - - // Setup credentials grid - bs.AddingNew += bs_AddingNew; - bs.AllowNew = true; - bs.DataSource = HttpProcessor.Credentials; - dataGridView1.DataSource = bs; - bs.CurrentItemChanged += bs_CurrentItemChanged; - foreach (DataGridViewColumn col in dataGridView1.Columns) col.Width = 180; - - Library.LibraryPath = Properties.Settings.Default.LibraryPath; - Library.LibraryLoaded += (_, __) => - { - UpdateInfo(); - _watcher.DirectoryToWatch = Library.LibraryPath; - _watcher.IsEnabled = Properties.Settings.Default.WatchLibrary; - }; - - // Create file watcher - _watcher = new Watcher(Library.LibraryPath); - _watcher.OnBookAdded += (object sender, BookAddedEventArgs e) => - { - if (e.BookType == BookType.FB2) _fb2Count++; else _epubCount++; - UpdateInfo(); - Log.WriteLine(LogLevel.Info, "Added: \"{0}\"", e.BookPath); - }; - _watcher.OnInvalidBook += (_, __) => - { - _invalidFiles++; - UpdateInfo(); - }; - _watcher.OnFileSkipped += (object _sender, FileSkippedEventArgs _e) => - { - _skippedFiles = _e.Count; - UpdateInfo(); - }; - - _watcher.OnBookDeleted += (object sender, BookDeletedEventArgs e) => - { - UpdateInfo(); - Log.WriteLine(LogLevel.Info, "Deleted: \"{0}\"", e.BookPath); - }; - _watcher.IsEnabled = false; - - intLink.Text = string.Format(urlTemplate, _upnpController.LocalIP.ToString(), Properties.Settings.Default.ServerPort, Properties.Settings.Default.RootPrefix); - _upnpController.DiscoverCompleted += _upnpController_DiscoverCompleted; - _upnpController.DiscoverAsync(Properties.Settings.Default.UseUPnP); - - Log.WriteLine("TinyOPDS version {0}.{1} started", Utils.Version.Major, Utils.Version.Minor); - - // Start OPDS server - StartHttpServer(); - - // Set server statistics handler - HttpServer.ServerStatistics.StatisticsUpdated += (_, __) => - { - this.BeginInvoke((MethodInvoker)delegate - { - statRequests.Text = HttpServer.ServerStatistics.GetRequests.ToString(); - statBooks.Text = HttpServer.ServerStatistics.BooksSent.ToString(); - statImages.Text = HttpServer.ServerStatistics.ImagesSent.ToString(); - statUniqueClients.Text = HttpServer.ServerStatistics.UniqueClientsCount.ToString(); - statGoodLogins.Text = HttpServer.ServerStatistics.SuccessfulLoginAttempts.ToString(); - statWrongLogins.Text = HttpServer.ServerStatistics.WrongLoginAttempts.ToString(); - statBannedClients.Text = HttpServer.ServerStatistics.BannedClientsCount.ToString(); - }); - }; - - _scanStartTime = DateTime.Now; - _notifyIcon.Visible = Properties.Settings.Default.CloseToTray; - } - - /// - /// Process unhandled exceptions - /// - /// - /// - void currentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs args) - { - Exception e = (Exception) args.ExceptionObject; - Log.WriteLine(LogLevel.Error, "{2}: {0}\nStack trace: {1}", e.Message, e.StackTrace, args.IsTerminating ? "Fatal exception" : "Unhandled exception"); - } - - void _upnpController_DiscoverCompleted(object sender, EventArgs e) - { - if (!IsDisposed && _upnpController != null) - { - this.BeginInvoke((MethodInvoker)delegate - { - extLink.Text = string.Format(urlTemplate, _upnpController.ExternalIP.ToString(), Properties.Settings.Default.ServerPort, Properties.Settings.Default.RootPrefix); - if (_upnpController.UPnPReady) - { - openPort.Enabled = true; - if (Properties.Settings.Default.OpenNATPort) openPort_CheckedChanged(this, null); - } - }); - } - } - - #endregion - - #region Application settings - - private void LoadSettings() - { - // Setup link labels - converterLinkLabel.Links.Add(0, converterLinkLabel.Text.Length, "http://fb2epub.net/files/Fb2ePubSetup_1_1_3.zip"); - linkLabel3.Links.Add(0, linkLabel3.Text.Length, "https://code.google.com/p/fb2librarynet/"); - linkLabel5.Links.Add(0, linkLabel5.Text.Length, "http://epubreader.codeplex.com/"); - linkLabel4.Links.Add(0, linkLabel4.Text.Length, "http://dotnetzip.codeplex.com/"); - // Setup settings controls - if (!string.IsNullOrEmpty(Properties.Settings.Default.LibraryPath)) - { - databaseFileName.Text = Utils.CreateGuid(Utils.IsoOidNamespace, Properties.Settings.Default.LibraryPath).ToString() + ".db"; - } - if (Utils.IsLinux) startWithWindows.Enabled = false; - if (string.IsNullOrEmpty(Properties.Settings.Default.ConvertorPath)) - { - if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ProgramFiles"))) - { - if (File.Exists(Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles"), "FB2ePub\\Fb2ePub.exe"))) - { - convertorPath.Text = Properties.Settings.Default.ConvertorPath = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles"), "FB2ePub"); - } - } - } - else convertorPath.Text = Properties.Settings.Default.ConvertorPath; - converterLinkLabel.Visible = string.IsNullOrEmpty(convertorPath.Text); - - // We should update all invisible controls - interfaceCombo.SelectedIndex = Math.Min(UPnPController.LocalInterfaces.Count-1, Properties.Settings.Default.LocalInterfaceIndex); - logVerbosity.SelectedIndex = Math.Min(2, Properties.Settings.Default.LogLevel); - updateCombo.SelectedIndex = Math.Min(2, Properties.Settings.Default.UpdatesCheck); - langCombo.SelectedValue = Properties.Settings.Default.Language; - - openPort.Checked = Properties.Settings.Default.UseUPnP ? Properties.Settings.Default.OpenNATPort : false; - banClients.Enabled = rememberClients.Enabled = dataGridView1.Enabled = Properties.Settings.Default.UseHTTPAuth; - wrongAttemptsCount.Enabled = banClients.Checked && useHTTPAuth.Checked; - - _notifyIcon.Visible = Properties.Settings.Default.CloseToTray; - if (Properties.Settings.Default.UpdatesCheck > 0) _updateChecker.Start(); - - // Load saved credentials - try - { - HttpProcessor.Credentials.Clear(); - string[] pairs = Crypt.DecryptStringAES(Properties.Settings.Default.Credentials, urlTemplate).Split(';'); - foreach (string pair in pairs) - { - string[] cred = pair.Split(':'); - if (cred.Length == 2) HttpProcessor.Credentials.Add( new Credential(cred[0], cred[1])); - } - } - catch { } - } - - private void SaveSettings() - { - Properties.Settings.Default.Language = langCombo.SelectedValue as string; - Properties.Settings.Default.Save(); - } - - #endregion - - #region Credentials handling - - private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) - { - if (dataGridView1.Columns[e.ColumnIndex].Name == "Password" && e.Value != null) - { - dataGridView1.Rows[e.RowIndex].Tag = e.Value; - e.Value = new String('*', e.Value.ToString().Length); - } - } - - void bs_AddingNew(object sender, AddingNewEventArgs e) - { - e.NewObject = new Credential("", ""); - } - - void bs_CurrentItemChanged(object sender, EventArgs e) - { - string s = string.Empty; - foreach (Credential cred in HttpProcessor.Credentials) s += cred.User + ":" + cred.Password + ";"; - try - { - Properties.Settings.Default.Credentials = string.IsNullOrEmpty(s) ? string.Empty : Crypt.EncryptStringAES(s, urlTemplate); - } - finally - { - Properties.Settings.Default.Save(); - } - } - - #endregion - - #region Library scanning support - - private void libraryPath_Validated(object sender, EventArgs e) - { - if (!string.IsNullOrEmpty(Properties.Settings.Default.LibraryPath) && - !Library.LibraryPath.Equals(Properties.Settings.Default.LibraryPath) && - Directory.Exists(Properties.Settings.Default.LibraryPath)) - { - if (Library.IsChanged) Library.Save(); - Library.LibraryPath = Properties.Settings.Default.LibraryPath; - booksInDB.Text = string.Format("{0} fb2: {1} epub: {2}", 0, 0, 0); - databaseFileName.Text = Utils.CreateGuid(Utils.IsoOidNamespace, Properties.Settings.Default.LibraryPath).ToString() + ".db"; - _watcher.IsEnabled = false; - // Reload library - Library.LoadAsync(); - } - else libraryPath.Undo(); - } - - private void folderButton_Click(object sender, EventArgs e) - { - using (FolderBrowserDialog dialog = new FolderBrowserDialog()) - { - dialog.SelectedPath = (sender as Button == folderButton) ? libraryPath.Text : convertorPath.Text; - if (dialog.ShowDialog() == DialogResult.OK) - { - if (sender as Button == folderButton) - { - libraryPath.Text = dialog.SelectedPath; - libraryPath_Validated(sender, e); - } - else - { - convertorPath.Text = dialog.SelectedPath; - convertorPath_Validated(sender, e); - } - } - } - } - - private void scannerButton_Click(object sender, EventArgs e) - { - if (_scanner.Status != FileScannerStatus.SCANNING) - { - _scanner.OnBookFound += scanner_OnBookFound; - _scanner.OnInvalidBook += (_, __) => { _invalidFiles++; }; - _scanner.OnFileSkipped += (object _sender, FileSkippedEventArgs _e) => - { - _skippedFiles = _e.Count; - UpdateInfo(); - }; - _scanner.OnScanCompleted += (_, __) => - { - Library.Save(); - UpdateInfo(true); - - Log.WriteLine("Directory scanner completed"); - }; - _fb2Count = _epubCount = _skippedFiles = _invalidFiles = _duplicates = 0; - _scanStartTime = DateTime.Now; - startTime.Text = _scanStartTime.ToString(@"hh\:mm\:ss"); - _scanner.Start(libraryPath.Text); - scannerButton.Text = Localizer.Text("Stop scanning"); - - Log.WriteLine("Directory scanner started"); - } - else - { - _scanner.Stop(); - Library.Save(); - UpdateInfo(true); - scannerButton.Text = Localizer.Text("Start scanning"); - - Log.WriteLine("Directory scanner stopped"); - } - } - - void scanner_OnBookFound(object sender, BookFoundEventArgs e) - { - if (Library.Add(e.Book)) - { - if (e.Book.BookType == BookType.FB2) _fb2Count++; else _epubCount++; - } - else _duplicates++; - if (Library.Count % 500 == 0) Library.Save(); - UpdateInfo(); - } - - private void UpdateInfo(bool IsScanFinished = false) - { - if (this.InvokeRequired) { this.BeginInvoke((MethodInvoker)delegate { internalUpdateInfo(IsScanFinished); }); } - else { internalUpdateInfo(IsScanFinished); } - } - - private void internalUpdateInfo(bool IsScanFinished) - { - booksInDB.Text = string.Format("{0} fb2: {1} epub: {2}", Library.Count, Library.FB2Count, Library.EPUBCount); - booksFound.Text = string.Format("fb2: {0} epub: {1}", _fb2Count, _epubCount); - skippedBooks.Text = _skippedFiles.ToString(); - invalidBooks.Text = _invalidFiles.ToString(); - duplicates.Text = _duplicates.ToString(); - int totalBooksProcessed = _fb2Count + _epubCount + _skippedFiles + _invalidFiles + _duplicates; - booksProcessed.Text = totalBooksProcessed.ToString(); - - TimeSpan dt = DateTime.Now.Subtract(_scanStartTime); - elapsedTime.Text = dt.ToString(@"hh\:mm\:ss"); - rate.Text = (dt.TotalSeconds) > 0 ? string.Format("{0:0.} books/min", totalBooksProcessed / dt.TotalSeconds * 60) : "---"; - if (scannerButton.Enabled) - { - status.Text = IsScanFinished ? Localizer.Text("FINISHED") : (_scanner.Status == FileScannerStatus.SCANNING ? Localizer.Text("SCANNING") : Localizer.Text("STOPPED")); - scannerButton.Text = (_scanner.Status == FileScannerStatus.SCANNING) ? Localizer.Text("Stop scanning") : Localizer.Text("Start scanning"); - } - } - - #endregion - - #region HTTP (OPDS) server & network support - - private void serverButton_Click(object sender, EventArgs e) - { - if (_server == null) StartHttpServer(); else StopHttpServer(); - } - - private void StartHttpServer() - { - // Create and start HTTP server - HttpProcessor.AuthorizedClients.Clear(); - HttpProcessor.BannedClients.Clear(); - _server = new OPDSServer(_upnpController.LocalIP, int.Parse(Properties.Settings.Default.ServerPort)); - - _serverThread = new Thread(new ThreadStart(_server.Listen)); - _serverThread.Priority = ThreadPriority.BelowNormal; - _serverThread.Start(); - _server.ServerReady.WaitOne(TimeSpan.FromMilliseconds(500)); - if (!_server.IsActive) - { - if (_server.ServerException != null) - { - if (_server.ServerException is System.Net.Sockets.SocketException) - { - MessageBox.Show(string.Format(Localizer.Text("Probably, port {0} is already in use. Please try different port value."), Properties.Settings.Default.ServerPort)); - } - else - { - MessageBox.Show(_server.ServerException.Message); - } - _server.StopServer(); - _serverThread = null; - _server = null; - } - } - else - { - serverButton.Text = serverMenuItem.Text = Localizer.Text("Stop server"); - Log.WriteLine("HTTP server started"); - } - } - - private void StopHttpServer() - { - if (_server != null) - { - _server.StopServer(); - _serverThread = null; - _server = null; - Log.WriteLine("HTTP server stopped"); - } - serverButton.Text = serverMenuItem.Text = Localizer.Text("Start server"); - } - - private void RestartHttpServer() - { - StopHttpServer(); - StartHttpServer(); - } - - private void useUPnP_CheckStateChanged(object sender, EventArgs e) - { - if (useUPnP.Checked) - { - // Re-detect IP addresses using UPnP - _upnpController.DiscoverAsync(true); - } - else - { - openPort.Enabled = openPort.Checked = false; - } - } - - private void openPort_CheckedChanged(object sender, EventArgs e) - { - if (_upnpController != null && _upnpController.UPnPReady) - { - int port = int.Parse(Properties.Settings.Default.ServerPort); - if (openPort.Checked) - { - _upnpController.ForwardPort(port, System.Net.Sockets.ProtocolType.Tcp, "TinyOPDS server"); - - Log.WriteLine("Port {0} forwarded by UPnP", port); - } - else - { - _upnpController.DeleteForwardingRule(port, System.Net.Sockets.ProtocolType.Tcp); - - Log.WriteLine("Port {0} closed", port); - } - } - } - - private void interfaceCombo_SelectedIndexChanged(object sender, EventArgs e) - { - if (_upnpController != null && _upnpController.InterfaceIndex != interfaceCombo.SelectedIndex) - { - _upnpController.InterfaceIndex = interfaceCombo.SelectedIndex; - intLink.Text = string.Format(urlTemplate, _upnpController.LocalIP.ToString(), Properties.Settings.Default.ServerPort, Properties.Settings.Default.RootPrefix); - if (Properties.Settings.Default.UseUPnP && openPort.Checked) - { - int port = int.Parse(Properties.Settings.Default.ServerPort); - _upnpController.DeleteForwardingRule(port, System.Net.Sockets.ProtocolType.Tcp); - _upnpController.ForwardPort(port, System.Net.Sockets.ProtocolType.Tcp, "TinyOPDS server"); - } - RestartHttpServer(); - } - } - - #endregion - - #region Form minimizing and closing - - private void MainForm_Resize(object sender, EventArgs e) - { - if (Properties.Settings.Default.CloseToTray) - { - Visible = (WindowState == FormWindowState.Normal); - windowMenuItem.Text = Localizer.Text("Show window"); - } - } - - private void windowMenuItem_Click(object sender, EventArgs e) - { - if (!ShowInTaskbar) ShowInTaskbar = true; else Visible = !Visible; - if (Visible) WindowState = FormWindowState.Normal; - windowMenuItem.Text = Localizer.Text(Visible ? "Hide window" : "Show window"); - } - - private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) - { - if (e.Button == System.Windows.Forms.MouseButtons.Left) windowMenuItem_Click(this, null); - } - - private bool realExit = false; - private void MainForm_FormClosing(object sender, FormClosingEventArgs e) - { - if (Properties.Settings.Default.CloseToTray && !realExit) - { - e.Cancel = true; - Visible = false; - WindowState = FormWindowState.Minimized; - windowMenuItem.Text = Localizer.Text("Show window"); - } - } - - private void MainForm_FormClosed(object sender, FormClosedEventArgs e) - { - SaveSettings(); - if (_server != null && _server._isActive) - { - _server.StopServer(); - _serverThread = null; - _server = null; - } - - if (_scanner.Status == FileScannerStatus.SCANNING) _scanner.Stop(); - if (Library.IsChanged) Library.Save(); - - if (_upnpController != null) - { - _upnpController.DiscoverCompleted -= _upnpController_DiscoverCompleted; - _upnpController.Dispose(); - } - - _notifyIcon.Visible = false; - - // Remove port forwarding - openPort.Checked = false; - - Log.WriteLine("TinyOPDS closed\n"); - } - - private void exitMenuItem_Click(object sender, EventArgs e) - { - realExit = true; - Close(); - } - - #endregion - - #region Form controls handling - - private void convertorPath_Validated(object sender, EventArgs e) - { - if (!string.IsNullOrEmpty(convertorPath.Text) && Directory.Exists(convertorPath.Text) && File.Exists(Path.Combine(convertorPath.Text, Utils.IsLinux ? "fb2toepub" : "Fb2ePub.exe"))) - { - Properties.Settings.Default.ConvertorPath = convertorPath.Text; - } - else - { - convertorPath.Text = Properties.Settings.Default.ConvertorPath; - } - } - - private void useWatcher_CheckedChanged(object sender, EventArgs e) - { - if (_watcher != null && _watcher.IsEnabled != useWatcher.Checked) - { - _watcher.IsEnabled = useWatcher.Checked; - } - } - - private void closeToTray_CheckedChanged(object sender, EventArgs e) - { - _notifyIcon.Visible = closeToTray.Checked; - } - - private void startWithWindows_CheckedChanged(object sender, EventArgs e) - { - Microsoft.Win32.RegistryKey registryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); - bool exists = (registryKey.GetValue("TinyOPDS") != null); - if (startWithWindows.Checked && !exists) registryKey.SetValue("TinyOPDS", Application.ExecutablePath); - else if (exists && !startWithWindows.Checked) registryKey.DeleteValue("TinyOPDS"); - } - - private void saveLog_CheckedChanged(object sender, EventArgs e) - { - Log.SaveToFile = label22.Enabled = logVerbosity.Enabled = saveLog.Checked; - } - - private void UpdateServerLinks() - { - if (_upnpController != null) - { - if (_upnpController.LocalIP != null) - intLink.Text = string.Format(urlTemplate, _upnpController.LocalIP.ToString(), Properties.Settings.Default.ServerPort, rootPrefix.Text); - if (_upnpController.ExternalIP != null) - extLink.Text = string.Format(urlTemplate, _upnpController.ExternalIP.ToString(), Properties.Settings.Default.ServerPort, rootPrefix.Text); - } - } - - /// - /// Handle server's root prefix change - /// - /// - /// - private void rootPrefix_TextChanged(object sender, EventArgs e) - { - if (_upnpController != null && _upnpController.UPnPReady) - { - while (rootPrefix.Text.IndexOf("/") >= 0) rootPrefix.Text = rootPrefix.Text.Replace("/", ""); - UpdateServerLinks(); - } - } - - /// - /// Validate server port - /// - /// - /// - private void serverPort_Validated(object sender, EventArgs e) - { - int port = 8080; - bool valid = int.TryParse(serverPort.Text, out port); - if (valid && port >= 1 && port <= 65535) - { - if (_upnpController != null && _upnpController.UPnPReady && openPort.Checked) - { - openPort.Checked = false; - Properties.Settings.Default.ServerPort = port.ToString(); - openPort.Checked = true; - } - else Properties.Settings.Default.ServerPort = port.ToString(); - if (_server != null && _server.IsActive) - { - RestartHttpServer(); - } - } - else - { - MessageBox.Show(Localizer.Text("Invalid port value: value must be numeric and in range from 1 to 65535")); - serverPort.Text = Properties.Settings.Default.ServerPort.ToString(); - } - // Update link labels - UpdateServerLinks(); - } - - /// - /// Set UI language - /// - /// - /// - private void langCombo_SelectedValueChanged(object sender, EventArgs e) - { - Localizer.SetLanguage(this, langCombo.SelectedValue as string); - appVersion.Text = string.Format(Localizer.Text("version {0}.{1} {2}"), Utils.Version.Major, Utils.Version.Minor, Utils.Version.Major == 0?" (beta)":""); - scannerButton.Text = Localizer.Text( (_scanner.Status == FileScannerStatus.STOPPED) ? "Start scanning" : "Stop scanning"); - serverButton.Text = Localizer.Text((_server == null) ? "Start server" : "Stop server"); - serverMenuItem.Text = Localizer.Text((_server == null) ? "Start server" : "Stop server"); - windowMenuItem.Text = Localizer.Text(Visible || ShowInTaskbar ? "Hide window" : "Show window"); - logVerbosity.Items[0] = Localizer.Text("Info, warnings and errors"); - logVerbosity.Items[1] = Localizer.Text("Warnings and errors"); - logVerbosity.Items[2] = Localizer.Text("Errors only"); - updateCombo.Items[0] = Localizer.Text("Never"); - updateCombo.Items[1] = Localizer.Text("Once a week"); - updateCombo.Items[2] = Localizer.Text("Once a month"); - } - - /// - /// Handle PayPal donation - /// - /// - /// - private void donateButton_Click(object sender, EventArgs e) - { - const string business = "sens.boston@gmail.com", description = "Donation%20for%20the%20TinyOPDS", country = "US", currency = "USD"; - string url = string.Format("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business={0}&lc={1}&item_name={2}¤cy_code={3}&bn=PP%2dDonationsBF", - business, country, description, currency); - System.Diagnostics.Process.Start(url); - } - - private bool checkUrl(string uriName) - { - Uri uriResult; - bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult); - return result && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); - } - - private void linkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - if (sender is LinkLabel && checkUrl((sender as LinkLabel).Text)) - { - System.Diagnostics.Process.Start((sender as LinkLabel).Text); - } - } - - private void linkLabel3_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - if (sender is LinkLabel && checkUrl((sender as LinkLabel).Links[0].LinkData as string)) - { - System.Diagnostics.Process.Start((sender as LinkLabel).Links[0].LinkData as string); - } - } - - private void useHTTPAuth_CheckedChanged(object sender, EventArgs e) - { - dataGridView1.Enabled = banClients.Enabled = rememberClients.Enabled = useHTTPAuth.Checked; - wrongAttemptsCount.Enabled = banClients.Enabled && banClients.Checked; - } - - private void banClients_CheckedChanged(object sender, EventArgs e) - { - wrongAttemptsCount.Enabled = banClients.Checked; - } - - private void logVerbosity_SelectedIndexChanged(object sender, EventArgs e) - { - Log.VerbosityLevel = (LogLevel)logVerbosity.SelectedIndex; - } - - private void updateCombo_SelectedIndexChanged(object sender, EventArgs e) - { - if (Properties.Settings.Default.UpdatesCheck == 0) _updateChecker.Stop(); else _updateChecker.Start(); - } - - #endregion - - #region TinyOPDS updates checker - - /// - /// This timer event should be raised every hour - /// - /// - /// - static int[] checkIntervals = new int[] { 0, 60 * 24 * 7, 60 * 24 * 30, 1}; - void _updateChecker_Tick(object sender, EventArgs e) - { - if (Properties.Settings.Default.UpdatesCheck >= 0) - { - _updateUrl = string.Empty; - int minutesFromLastCheck = (int) Math.Round(DateTime.Now.Subtract(Properties.Settings.Default.LastCheck).TotalMinutes); - if (minutesFromLastCheck >= checkIntervals[Properties.Settings.Default.UpdatesCheck]) - { - Log.WriteLine(LogLevel.Info, "Checking software update. Minutes from the last check: {0}", minutesFromLastCheck); - WebClient wc = new WebClient(); - wc.DownloadStringCompleted += wc_DownloadStringCompleted; - wc.DownloadStringAsync(new Uri("http://senssoft.com/tinyopds.txt")); - } - } - } - - void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) - { - if (e.Error == null) - { - Properties.Settings.Default.LastCheck = DateTime.Now; - Properties.Settings.Default.Save(); - - string[] s = e.Result.Split('\n'); - if (s.Length == 2) - { - s[0] = s[0].Replace("\r", ""); - double currentVersion = 0, newVersion = 0; - if (double.TryParse(string.Format("{0}.{1}", Utils.Version.Major, Utils.Version.Minor), out currentVersion)) - { - if (double.TryParse(s[0], out newVersion)) - { - if (newVersion > currentVersion) - { - _updateUrl = s[1]; - _notifyIcon.Visible = true; - _notifyIcon.ShowBalloonTip(30000, Localizer.Text("TinyOPDS: update found"), string.Format(Localizer.Text("Click here to download update v {0}"), s[0]), ToolTipIcon.Info); - } - } - } - } - } - } - - void _notifyIcon_BalloonTipClicked(object sender, EventArgs e) - { - System.Diagnostics.Process.Start(_updateUrl); - } - - void _notifyIcon_BalloonTipClosed(object sender, EventArgs e) - { - _notifyIcon.Visible = Properties.Settings.Default.CloseToTray; - } - - #endregion - } -} diff --git a/releases/1.1/MainForm.resx b/releases/1.1/MainForm.resx deleted file mode 100644 index acce9e6..0000000 --- a/releases/1.1/MainForm.resx +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - \ No newline at end of file diff --git a/releases/1.1/Misc/Crypt.cs b/releases/1.1/Misc/Crypt.cs deleted file mode 100644 index b383fc4..0000000 --- a/releases/1.1/Misc/Crypt.cs +++ /dev/null @@ -1,155 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module contains string extensions and some helpers - * - ************************************************************/ - -using System; -using System.IO; -using System.Text; -using System.Security.Cryptography; - -namespace TinyOPDS -{ - public class Crypt - { - private static byte[] _salt = Encoding.ASCII.GetBytes("o6806642kbM7c5"); - - /// - /// Encrypt the given string using AES. The string can be decrypted using - /// DecryptStringAES(). The sharedSecret parameters must match. - /// - /// The text to encrypt. - /// A password used to generate a key for encryption. - public static string EncryptStringAES(string plainText, string sharedSecret) - { - if (string.IsNullOrEmpty(plainText)) - throw new ArgumentNullException("plainText"); - if (string.IsNullOrEmpty(sharedSecret)) - throw new ArgumentNullException("sharedSecret"); - - string outStr = null; // Encrypted string to return - RijndaelManaged aesAlg = null; // RijndaelManaged object used to encrypt the data. - - try - { - // generate the key from the shared secret and the salt - Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt); - - // Create a RijndaelManaged object - aesAlg = new RijndaelManaged(); - aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); - - // Create a decrytor to perform the stream transform. - ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); - - // Create the streams used for encryption. - using (MemoryStream msEncrypt = new MemoryStream()) - { - // prepend the IV - msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int)); - msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length); - using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) - { - using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) - { - //Write all data to the stream. - swEncrypt.Write(plainText); - } - } - outStr = Convert.ToBase64String(msEncrypt.ToArray()); - } - } - finally - { - // Clear the RijndaelManaged object. - if (aesAlg != null) - aesAlg.Clear(); - } - - // Return the encrypted bytes from the memory stream. - return outStr; - } - - /// - /// Decrypt the given string. Assumes the string was encrypted using - /// EncryptStringAES(), using an identical sharedSecret. - /// - /// The text to decrypt. - /// A password used to generate a key for decryption. - public static string DecryptStringAES(string cipherText, string sharedSecret) - { - if (string.IsNullOrEmpty(cipherText)) - throw new ArgumentNullException("cipherText"); - if (string.IsNullOrEmpty(sharedSecret)) - throw new ArgumentNullException("sharedSecret"); - - // Declare the RijndaelManaged object - // used to decrypt the data. - RijndaelManaged aesAlg = null; - - // Declare the string used to hold - // the decrypted text. - string plaintext = null; - - try - { - // generate the key from the shared secret and the salt - Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt); - - // Create the streams used for decryption. - byte[] bytes = Convert.FromBase64String(cipherText); - using (MemoryStream msDecrypt = new MemoryStream(bytes)) - { - // Create a RijndaelManaged object - // with the specified key and IV. - aesAlg = new RijndaelManaged(); - aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); - // Get the initialization vector from the encrypted stream - aesAlg.IV = ReadByteArray(msDecrypt); - // Create a decrytor to perform the stream transform. - ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); - using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) - { - using (StreamReader srDecrypt = new StreamReader(csDecrypt)) - - // Read the decrypted bytes from the decrypting stream - // and place them in a string. - plaintext = srDecrypt.ReadToEnd(); - } - } - } - finally - { - // Clear the RijndaelManaged object. - if (aesAlg != null) - aesAlg.Clear(); - } - - return plaintext; - } - - private static byte[] ReadByteArray(Stream s) - { - byte[] rawLength = new byte[sizeof(int)]; - if (s.Read(rawLength, 0, rawLength.Length) != rawLength.Length) - { - throw new SystemException("Stream did not contain properly formatted byte array"); - } - - byte[] buffer = new byte[BitConverter.ToInt32(rawLength, 0)]; - if (s.Read(buffer, 0, buffer.Length) != buffer.Length) - { - throw new SystemException("Did not read byte array properly"); - } - - return buffer; - } - } -} diff --git a/releases/1.1/Misc/CustomSettingsProvider.cs b/releases/1.1/Misc/CustomSettingsProvider.cs deleted file mode 100644 index 3b5830e..0000000 --- a/releases/1.1/Misc/CustomSettingsProvider.cs +++ /dev/null @@ -1,268 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines custom settings provider, to define - * straightforward settings folder - * - * That code was copied from the StackOverflow site: - * http://stackoverflow.com/questions/2265271/custom-path-of-the-user-config - * - * - ************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Configuration; -using System.Reflection; -using System.Xml.Linq; -using System.IO; - -namespace TinyOPDS -{ - class CustomSettingsProvider : SettingsProvider - { - const string NAME = "name"; - const string SERIALIZE_AS = "serializeAs"; - const string CONFIG = "configuration"; - const string USER_SETTINGS = "userSettings"; - const string SETTING = "setting"; - - /// - /// Loads the file into memory. - /// - public CustomSettingsProvider() - { - SettingsDictionary = new Dictionary(); - } - - /// - /// Override. - /// - public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) - { - base.Initialize(ApplicationName, config); - } - - /// - /// Override. - /// - public override string ApplicationName - { - get - { - return System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name; - } - set - { - //do nothing - } - } - - /// - /// Must override this, this is the bit that matches up the designer properties to the dictionary values - /// - /// - /// - /// - public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection) - { - //load the file - if (!_loaded) - { - _loaded = true; - LoadValuesFromFile(); - } - - //collection that will be returned. - SettingsPropertyValueCollection values = new SettingsPropertyValueCollection(); - - //iterate thought the properties we get from the designer, checking to see if the setting is in the dictionary - foreach (SettingsProperty setting in collection) - { - SettingsPropertyValue value = new SettingsPropertyValue(setting); - value.IsDirty = false; - - //need the type of the value for the strong typing - var t = Type.GetType(setting.PropertyType.FullName); - - if (SettingsDictionary.ContainsKey(setting.Name)) - { - value.SerializedValue = SettingsDictionary[setting.Name].value; - value.PropertyValue = Convert.ChangeType(SettingsDictionary[setting.Name].value, t); - } - else //use defaults in the case where there are no settings yet - { - value.SerializedValue = setting.DefaultValue; - value.PropertyValue = Convert.ChangeType(setting.DefaultValue, t); - } - - values.Add(value); - } - return values; - } - - /// - /// Must override this, this is the bit that does the saving to file. Called when Settings.Save() is called - /// - /// - /// - public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) - { - //grab the values from the collection parameter and update the values in our dictionary. - foreach (SettingsPropertyValue value in collection) - { - var setting = new SettingStruct() - { - value = (value.PropertyValue == null ? String.Empty : value.PropertyValue.ToString()), - name = value.Name, - serializeAs = value.Property.SerializeAs.ToString() - }; - - if (!SettingsDictionary.ContainsKey(value.Name)) - { - SettingsDictionary.Add(value.Name, setting); - } - else - { - SettingsDictionary[value.Name] = setting; - } - } - - //now that our local dictionary is up-to-date, save it to disk. - SaveValuesToFile(); - } - - /// - /// Loads the values of the file into memory. - /// - private void LoadValuesFromFile() - { - if (!File.Exists(UserConfigPath)) - { - //if the config file is not where it's supposed to be create a new one. - CreateEmptyConfig(); - } - - //load the xml - var configXml = XDocument.Load(UserConfigPath); - - //get all of the elements. - var settingElements = configXml.Element(CONFIG).Element(USER_SETTINGS).Element(typeof(Properties.Settings).FullName).Elements(SETTING); - - //iterate through, adding them to the dictionary, (checking for nulls, xml no likey nulls) - //using "String" as default serializeAs...just in case, no real good reason. - foreach (var element in settingElements) - { - var newSetting = new SettingStruct() - { - name = element.Attribute(NAME) == null ? String.Empty : element.Attribute(NAME).Value, - serializeAs = element.Attribute(SERIALIZE_AS) == null ? "String" : element.Attribute(SERIALIZE_AS).Value, - value = element.Value ?? String.Empty - }; - SettingsDictionary.Add(element.Attribute(NAME).Value, newSetting); - } - } - - /// - /// Creates an empty user.config file...looks like the one MS creates. - /// This could be overkill a simple key/value pairing would probably do. - /// - private void CreateEmptyConfig() - { - var doc = new XDocument(); - var declaration = new XDeclaration("1.0", "utf-8", "true"); - var config = new XElement(CONFIG); - var userSettings = new XElement(USER_SETTINGS); - var group = new XElement(typeof(Properties.Settings).FullName); - userSettings.Add(group); - config.Add(userSettings); - doc.Add(config); - doc.Declaration = declaration; - string dirName = Path.GetDirectoryName(UserConfigPath); - try - { - if (!Directory.Exists(dirName)) Directory.CreateDirectory(dirName); - doc.Save(UserConfigPath); - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, e.Message); - } - } - - /// - /// Saves the in memory dictionary to the user config file - /// - private void SaveValuesToFile() - { - //load the current xml from the file. - var import = XDocument.Load(UserConfigPath); - - //get the settings group (e.g. ) - var settingsSection = import.Element(CONFIG).Element(USER_SETTINGS).Element(typeof(Properties.Settings).FullName); - - //iterate though the dictionary, either updating the value or adding the new setting. - foreach (var entry in SettingsDictionary) - { - var setting = settingsSection.Elements().FirstOrDefault(e => e.Attribute(NAME).Value == entry.Key); - if (setting == null) //this can happen if a new setting is added via the .settings designer. - { - var newSetting = new XElement(SETTING); - newSetting.Add(new XAttribute(NAME, entry.Value.name)); - newSetting.Add(new XAttribute(SERIALIZE_AS, entry.Value.serializeAs)); - newSetting.Value = (entry.Value.value ?? String.Empty); - settingsSection.Add(newSetting); - } - else //update the value if it exists. - { - setting.Value = (entry.Value.value ?? String.Empty); - } - } - try - { - import.Save(UserConfigPath); - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, e.Message); - } - } - - /// - /// The setting key this is returning must set before the settings are used. - /// e.g. Properties.Settings.Default.SettingsKey = @"C:\temp\user.config"; - /// - private string UserConfigPath - { - get - { - return Path.Combine(Utils.ServiceFilesLocation, "user.config"); - } - } - - /// - /// In memory storage of the settings values - /// - private Dictionary SettingsDictionary { get; set; } - - /// - /// Helper structure - /// - internal struct SettingStruct - { - internal string name; - internal string serializeAs; - internal string value; - } - - bool _loaded; - } -} - diff --git a/releases/1.1/Misc/Localizer.cs b/releases/1.1/Misc/Localizer.cs deleted file mode 100644 index 1551237..0000000 --- a/releases/1.1/Misc/Localizer.cs +++ /dev/null @@ -1,217 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * Very simple but very effective application localization - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Linq; -#if !CONSOLE -using System.Windows.Forms; -#endif -using System.Reflection; - -namespace TinyOPDS -{ - public static class Localizer - { - private static string _lang = "en"; - private static Dictionary _translations = new Dictionary(); - private static XDocument _xml = null; -#if !CONSOLE - private static List _menuItems = new List(); -#endif - /// - /// Static classes don't have a constructors but we need to initialize translations - /// - /// Name of xml translations, added to project as an embedded resource - public static void Init(string xmlFile = "translation.xml") - { - try - { - _xml = XDocument.Load(Assembly.GetExecutingAssembly().GetManifestResourceStream("TinyOPDS."+xmlFile)); - } - catch (Exception e) - { - Log.WriteLine("Localizer.Init({0}) exception: {1}", xmlFile, e.Message); - } - } - -#if !CONSOLE - /// - /// Add menu to translator - /// - /// - public static void AddMenu(ContextMenuStrip menu) - { - foreach (ToolStripItem item in menu.Items) _menuItems.Add(item); - } -#endif - /// - /// Returns supported translations in Dictionary - /// - public static Dictionary Languages - { - get - { - return _xml != null ? _xml.Descendants("language").ToDictionary(d => d.Attribute("id").Value, d => d.Value) : null; - } - } - - /// - /// Current selected language - /// - public static string Language { get { return _lang; } } - -#if !CONSOLE - /// - /// Sets current language - /// - /// - /// - public static void SetLanguage(Form form, string lang) - { - if (_lang != lang && _xml != null) - { - _lang = lang; - try - { - // Update localized string dictionary - List t = _xml.Descendants("property") // .Where(a => !a.HasAttributes) - .Descendants("text").Where(b => b.Attribute("lang").Value == "en" || b.Attribute("lang").Value == _lang) - .Select(c => c.Value).ToList(); - _translations.Clear(); - - if (lang.Equals("en")) - { - for (int i = 0; i < t.Count; i++) - if (!string.IsNullOrEmpty(t[i])) - _translations.Add(t[i], t[i]); - } - else - { - for (int i = 0; i < t.Count / 2; i++) - if (!string.IsNullOrEmpty(t[i * 2])) - _translations.Add(t[i * 2], t[i * 2 + 1]); - } - - // Update form controls - UpdateControls(form); - } - catch (Exception e) - { - Log.WriteLine(".SetLanguage({0},{1}) exception: {2}", form, lang, e.Message); - } - } - } -#endif - - /// - /// Translation helper - /// - /// - /// - public static string Text(string source) - { - return (_translations.ContainsKey(source)) ? _translations[source] : source; - } - -#if !CONSOLE - /// - /// Updates texts for all form controls (if translation exists) - /// - /// Form to be updated - private static void UpdateControls(Form form) - { - // Find all controls - var controls = GetAllControls(form); - - foreach (Control ctrl in new IteratorIsolateCollection(controls)) - { - var xmlProp = _xml.Descendants("property").Where(e => e.Attribute("form") != null && e.Attribute("form").Value.Equals(form.Name) && - e.Attribute("ctrl") != null && e.Attribute("ctrl").Value == ctrl.Name); - if (xmlProp != null && xmlProp.Count() > 0) - { - var trans = xmlProp.FirstOrDefault().Descendants("text").Where(p => p.Attribute("lang").Value == _lang).Select(p => p.Value); - if (trans != null && trans.Count() > 0) ctrl.Text = trans.First() as string; - } - } - - foreach (ToolStripItem ctrl in _menuItems) - { - var xmlProp = _xml.Descendants("property").Where(e => e.Attribute("ctrl") != null && e.Attribute("ctrl").Value == ctrl.Name); - if (xmlProp != null && xmlProp.Count() > 0) - { - var trans = xmlProp.First().Descendants("text").Where(p => p.Attribute("lang").Value == _lang).Select(p => p.Value); - if (trans != null && trans.Count() > 0) ctrl.Text = trans.First() as string; - } - - } - } - - /// - /// Localization helper: scans form and return xml document with controls names and texts - /// - /// Form to localize - /// Current form language - /// Xml document - public static XDocument Setup(Form form, string srcLang = "en") - { - XDocument doc = new XDocument(); - doc.Add(new XElement("root", new XElement("languages"), new XElement("properties"))); - - if (form != null) - { - - var controls = GetAllControls(form); - - foreach (Control ctrl in controls) - { - foreach (var propInfo in ctrl.GetType().GetProperties()) - { - if (propInfo.Name == "Text") - { - try - { - var value = propInfo.GetValue(ctrl, null); - doc.Root.Element("properties").Add( - new XElement("property", - new XAttribute("form", form.Name), - new XAttribute("ctrl", ctrl.Name), - new XElement("text", - new XAttribute("lang", srcLang), value)) - ); - } - catch - { } - } - } - } - } - - return doc; - } - - /// - /// Enums all controls on the form - /// - /// - /// - private static List GetAllControls(Control control) - { - var controls = control.Controls.Cast(); - return (controls.SelectMany(ctrl => GetAllControls(ctrl)).Concat(controls)).ToList(); - } -#endif - } -} diff --git a/releases/1.1/Misc/Log.cs b/releases/1.1/Misc/Log.cs deleted file mode 100644 index 39628a9..0000000 --- a/releases/1.1/Misc/Log.cs +++ /dev/null @@ -1,118 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the Log class - * - * TODO: add threading for performance reason (may be, should check) - * - ************************************************************/ - -using System; -using System.IO; -using System.Diagnostics; - -namespace TinyOPDS -{ - /// - /// A lightweight logging class for Silverlight. - /// - internal static class Log - { - private static string _logFileName = "TinyOPDS.log"; - - /// - /// - /// - internal static LogLevel VerbosityLevel = LogLevel.Info; - - /// - /// Enable or disable logging to file - /// - private static bool _saveToFile = false; - internal static bool SaveToFile - { - get { return _saveToFile; } - set - { - _logFileName = Path.Combine(Utils.ServiceFilesLocation, "TinyOPDS.log"); - _saveToFile = value; - } - } - - /// - /// Writes the args to the default logging output using the format provided. - /// - internal static void WriteLine(string format, params object[] args) - { - WriteLine(LogLevel.Info, format, args); - } - - /// - /// Writes the args to the default logging output using the format provided. - /// - internal static void WriteLine(LogLevel level, string format, params object[] args) - { - if (level >= VerbosityLevel) - { - string caller = new StackTrace().GetFrame(2).GetMethod().ReflectedType.Name; - if (caller.StartsWith("<>")) caller = new StackTrace().GetFrame(1).GetMethod().ReflectedType.Name; - string prefix = string.Format("{0}\t{1}\t{2}", (level == LogLevel.Info) ? 'I' : ((level == LogLevel.Warning) ? 'W' : 'E'), caller, (caller.Length > 7 ? "" : "\t")); - - string message = string.Format(prefix + format, args); - Debug.WriteLine(message); - if (SaveToFile) WriteToFile(message); - } - } - - private static object fileSyncObject = new object(); - - /// - /// Writes a line to the current log file. - /// - /// - private static void WriteToFile(string message) - { - lock (fileSyncObject) - { - FileStream fileStream = null; - try - { - fileStream = new FileStream(_logFileName, (File.Exists(_logFileName) ? FileMode.Append : FileMode.Create), FileAccess.Write, FileShare.ReadWrite); - using (StreamWriter writer = new StreamWriter(fileStream)) - { - fileStream = null; - writer.WriteLine(string.Format("{0:MM/dd/yyyy HH:mm:ss.f}\t{1}", DateTime.Now, message), _logFileName); - } - } - finally - { - if (fileStream != null) fileStream.Dispose(); - } - } - } - } - - /// - /// The type of error to log - /// - public enum LogLevel - { - /// - /// A message containing information only. - /// - Info = 0, - /// - /// A non-critical warning error message. - /// - Warning = 1, - /// - /// A fatal error message. - /// - Error = 2 - } -} \ No newline at end of file diff --git a/releases/1.1/Misc/OPDSComparer.cs b/releases/1.1/Misc/OPDSComparer.cs deleted file mode 100644 index 391327a..0000000 --- a/releases/1.1/Misc/OPDSComparer.cs +++ /dev/null @@ -1,64 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the custom comparer class - * - * TODO: should sort down some rare used chars - * - ************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using TinyOPDS.Data; - -namespace TinyOPDS -{ - public class OPDSComparer : IComparer - { - private bool _cyrillcFirst; - - public OPDSComparer(bool cyrillicFirst = true) - { - _cyrillcFirst = cyrillicFirst; - } - - public int Compare(object x, object y) - { - string x1 = string.Empty, y1 = string.Empty; - if (x is string) - { - x1 = x as string; - y1 = y as string; - } - else if (x is Genre) - { - x1 = _cyrillcFirst ? (x as Genre).Translation : (x as Genre).Name; - y1 = _cyrillcFirst ? (y as Genre).Translation : (y as Genre).Name; - } - // Shift "garbage" characters and digits to the end - if (x1.Length > 0 && y1.Length > 0) - { - if (char.IsLetter(x1[0]) && !char.IsLetter(y1[0])) return -1; - else if (!char.IsLetter(x1[0]) && char.IsLetter(y1[0])) return 1; - else if (char.IsLetterOrDigit(x1[0]) && !char.IsLetterOrDigit(y1[0])) return -1; - else if (!char.IsLetterOrDigit(x1[0]) && char.IsLetterOrDigit(y1[0])) return 1; - } - if (_cyrillcFirst && x1.Length > 0 && y1.Length > 0) - { - // Cyrillic letter came first - if (x1[0] > 400 && y1[0] < 400) return -1; - if (x1[0] < 400 && y1[0] > 400) return 1; - } - return string.Compare(x1, y1, true); - } - } - -} diff --git a/releases/1.1/Misc/ProcessHelper.cs b/releases/1.1/Misc/ProcessHelper.cs deleted file mode 100644 index aa70483..0000000 --- a/releases/1.1/Misc/ProcessHelper.cs +++ /dev/null @@ -1,157 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines helper to run console processes in - * background, with output (including errout) collection - * - ************************************************************/ - -using System; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.ComponentModel; -using System.Windows; -using System.Threading; -using System.Security.Permissions; -using System.Diagnostics; - -namespace TinyOPDS -{ - /// - /// Helper for the external console apps execution in background (no visible window) - /// Stores process output to the observable collection (so, we can bind output to the ListBox) - /// - public class ProcessHelper : IDisposable - { - private bool _disposed = false; - private Process _process = null; - private ObservableCollection _output = new ObservableCollection(); - - /// - /// Default constructor - /// - /// - /// - /// - /// - [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted = true)] - public ProcessHelper(string commandPath, string arguments) - { - _process = new Process(); - _process.StartInfo.FileName = commandPath; - _process.StartInfo.Arguments = arguments; - - // set up output redirection - _process.StartInfo.RedirectStandardOutput = true; - _process.StartInfo.RedirectStandardError = true; - _process.EnableRaisingEvents = true; - _process.StartInfo.CreateNoWindow = true; - _process.StartInfo.UseShellExecute = false; - // see below for output handler - _process.ErrorDataReceived += proc_DataReceived; - _process.OutputDataReceived += proc_DataReceived; - _process.Exited += (__, ____) => { if (OnExited != null) OnExited(this, new EventArgs()); }; - } - - [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted = true)] - protected virtual void Dispose(bool disposing) - { - if (!this._disposed && disposing) - { - if (_process != null) - { - if (!_process.HasExited && IsRunning) _process.Kill(); - _process.Dispose(); - } - _disposed = true; - } - } - - [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted = true)] - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void proc_DataReceived(object sender, DataReceivedEventArgs e) - { - if (e.Data != null) - { - _output.Add(e.Data); - } - } - - public void Run() - { - if (_process.Start()) - { - _process.PriorityClass = ProcessPriorityClass.Normal; - _process.BeginErrorReadLine(); - _process.BeginOutputReadLine(); - _isRunning = true; - _process.WaitForExit(); - ExitCode = _process.ExitCode; - _isRunning = false; - } - } - - public void RunAsync(AutoResetEvent waitEvent) - { - BackgroundWorker worker = new BackgroundWorker(); - worker.DoWork += (_, __) => - { - try - { - if (_process.Start()) - { - _process.PriorityClass = ProcessPriorityClass.Normal; - _process.BeginErrorReadLine(); - _process.BeginOutputReadLine(); - _isRunning = true; - _process.WaitForExit(); - ExitCode = _process.ExitCode; - } - } - catch(Exception e) - { - Log.WriteLine(LogLevel.Error, "exception {0}", e.Message); - } - finally - { - if (waitEvent != null) waitEvent.Set(); - _isRunning = false; - worker.Dispose(); - } - }; - worker.RunWorkerAsync(); - } - - /// - /// Raised on process completion - /// - public event EventHandler OnExited; - - /// - /// Process output to stdout - /// - public ObservableCollection ProcessOutput { get { return _output; } } - - /// - /// Return current state of process - /// - private bool _isRunning = false; - public bool IsRunning { get { return _isRunning; } } - - /// - /// Return process exit code - /// - public int ExitCode { get; private set; } - } -} diff --git a/releases/1.1/Misc/StringUtils.cs b/releases/1.1/Misc/StringUtils.cs deleted file mode 100644 index b22970f..0000000 --- a/releases/1.1/Misc/StringUtils.cs +++ /dev/null @@ -1,177 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines some specific String extensions classes: - * Soundex and Transliteration - * - ************************************************************/ - -using System; -using System.Text; -using System.Collections.Generic; - -namespace TinyOPDS -{ - public static class StringExtensions - { - public static string Reverse(this string sentence) - { - string[] words = sentence.Split(' '); - Array.Reverse(words); - return string.Join(" ", words); - } - - public static string DecodeFromBase64(this string encodedData) - { - byte[] encodedDataAsBytes = Convert.FromBase64String(encodedData); - return Encoding.UTF8.GetString(encodedDataAsBytes); - } - - public static string SanitizeFileName(this string fileName) - { - return String.Join("", fileName.Split(System.IO.Path.GetInvalidFileNameChars())); - } - - public static int WordsCount(this string s) - { - return s.Split(' ', ',').Length; - } - - public static string UrlCombine(this string uri1, string uri2) - { - uri1 = uri1.TrimEnd('/'); - uri2 = uri2.TrimStart('/'); - return string.Format("{0}/{1}", uri1, uri2).TrimEnd('/'); - } - - public static bool IsValidUTF(this string s) - { - bool valid = true; - foreach (char c in s) valid &= c != 0xFFFD; - return valid; - } - - public static string SoundexByWord(this string data) - { - var soundexes = new List(); - foreach (var str in data.Split(' ', ',')) - { - soundexes.Add(Soundex(str)); - } - return string.Join(" ", soundexes); - } - - public static string Soundex(string word) - { - word = Transliteration.Front(word, TransliterationType.ISO); - StringBuilder result = new StringBuilder(); - if (word != null && word.Length > 0) - { - string previousCode = "", currentCode = "", currentLetter = ""; - result.Append(word.Substring(0, 1)); - for (int i = 1; i < word.Length; i++) - { - currentLetter = word.Substring(i, 1).ToLower(); - currentCode = ""; - - if ("bfpv".IndexOf(currentLetter) > -1) currentCode = "1"; - else if ("cgjkqsxz".IndexOf(currentLetter) > -1) currentCode = "2"; - else if ("dt".IndexOf(currentLetter) > -1) currentCode = "3"; - else if (currentLetter == "l") currentCode = "4"; - else if ("mn".IndexOf(currentLetter) > -1) currentCode = "5"; - else if (currentLetter == "r") currentCode = "6"; - - if (currentCode != previousCode) result.Append(currentCode); - if (result.Length == 4) break; - if (currentCode != "") previousCode = currentCode; - } - } - - if (result.Length < 4) - result.Append(new String('0', 4 - result.Length)); - - return result.ToString().ToUpper(); - } - } - - #region Transliteration - - public enum TransliterationType - { - GOST, - ISO - } - - public static class Transliteration - { - //ГОСТ 16876-71 - private static Dictionary gostFront = new Dictionary() { - {'Є', "Eh"}, {'І', "I"}, {'і', "i"}, {'№', "#"}, {'є', "eh"}, {'А', "A"}, {'Б', "B"}, {'В', "V"}, {'Г', "G"}, {'Д', "D"}, {'Е', "E"}, {'Ё', "Jo"}, - {'Ж', "Zh"}, {'З', "Z"}, {'И', "I"}, {'Й', "JJ"}, {'К', "K"}, {'Л', "L"}, {'М', "M"}, {'Н', "N"}, {'О', "O"}, {'П', "P"}, {'Р', "R"}, {'С', "S"}, - {'Т', "T"}, {'У', "U"}, {'Ф', "F"}, {'Х', "Kh"}, {'Ц', "C"}, {'Ч', "Ch"}, {'Ш', "Sh"}, {'Щ', "Shh"}, {'Ъ', "'"}, {'Ы', "Y"}, {'Ь', ""}, {'Э', "Eh"}, - {'Ю', "Yu"}, {'Я', "Ya"}, {'а', "a"}, {'б', "b"}, {'в', "v"}, {'г', "g"}, {'д', "d"}, {'е', "e"}, {'ё', "jo"}, {'ж', "zh"}, {'з', "z"}, {'и', "i"}, - {'й', "jj"}, {'к', "k"}, {'л', "l"}, {'м', "m"}, {'н', "n"}, {'о', "o"}, {'п', "p"}, {'р', "r"}, {'с', "s"}, {'т', "t"}, {'у', "u"}, {'ф', "f"}, - {'х', "kh"}, {'ц', "c"}, {'ч', "ch"}, {'ш', "sh"}, {'щ', "shh"}, {'ъ', ""}, {'ы', "y"}, {'ь', ""}, {'э', "eh"}, {'ю', "yu"}, {'я', "ya"}, - {'«', ""}, {'»', ""}, {'—', "-"}, {' ', "_"} - }; - - private static Dictionary gostBack = new Dictionary(); - - //ISO 9-95 - private static Dictionary isoFront = new Dictionary() { - { 'Є', "Ye" }, { 'І', "I" }, { 'Ѓ', "G" }, { 'і', "i" }, { '№', "#" }, { 'є', "ye" }, { 'ѓ', "g" }, { 'А', "A" }, { 'Б', "B" }, { 'В', "V" }, { 'Г', "G" }, - { 'Д', "D" }, { 'Е', "E" }, { 'Ё', "Yo" }, { 'Ж', "Zh" }, { 'З', "Z" }, { 'И', "I" }, { 'Й', "J" }, { 'К', "K" }, { 'Л', "L" }, { 'М', "M" }, { 'Н', "N" }, - { 'О', "O" }, { 'П', "P" }, { 'Р', "R" }, { 'С', "S" }, { 'Т', "T" }, { 'У', "U" }, { 'Ф', "F" }, { 'Х', "X" }, { 'Ц', "C" }, { 'Ч', "Ch" }, { 'Ш', "Sh" }, - { 'Щ', "Shh" }, { 'Ъ', "'" }, { 'Ы', "Y" }, { 'Ь', "" }, { 'Э', "E" }, { 'Ю', "YU" }, { 'Я', "YA" }, { 'а', "a" }, { 'б', "b" }, { 'в', "v" }, { 'г', "g" }, - { 'д', "d" }, { 'е', "e" }, { 'ё', "yo" }, { 'ж', "zh" }, { 'з', "z" }, { 'и', "i" }, { 'й', "j" }, { 'к', "k" }, { 'л', "l" }, { 'м', "m" }, { 'н', "n" }, - { 'о', "o" }, { 'п', "p" }, { 'р', "r" }, { 'с', "s" }, { 'т', "t" }, { 'у', "u" }, { 'ф', "f" }, { 'х', "x" }, { 'ц', "c" }, { 'ч', "ch" }, { 'ш', "sh" }, - { 'щ', "shh" }, { 'ъ', "" }, { 'ы', "y" }, { 'ь', "" }, { 'э', "e" }, { 'ю', "yu" }, { 'я', "ya" }, { '«', "" }, { '»', "" }, { '—', "-" }, { ' ', "_" } - }; - - private static Dictionary isoBack = new Dictionary(); - - static Transliteration() - { - foreach (KeyValuePair pair in gostFront) gostBack[pair.Value] = pair.Key; - foreach (KeyValuePair pair in isoFront) isoBack[pair.Value] = pair.Key; - } - - public static string Front(string text, TransliterationType type = TransliterationType.GOST) - { - string output = string.Empty; - Dictionary dict = (type == TransliterationType.ISO) ? isoFront : gostFront; - foreach (char c in text) output += dict.ContainsKey(c) ? dict[c] : c.ToString(); - return output; - } - - public static string Back(string text, TransliterationType type = TransliterationType.GOST) - { - int l = text.Length; - string output = string.Empty; - Dictionary dict = (type == TransliterationType.ISO) ? isoBack : gostBack; - int i = 0; - while (i < l) - { - string s = text.Substring(i, Math.Min(3, l - i)); - do - { - if (dict.ContainsKey(s)) - { - output += dict[s]; - i += s.Length; - break; - } - s = s.Remove(s.Length - 1); - } while (s.Length > 0); - i += s.Length == 0 ? 3 : 0; - } - return output; - } - } - #endregion -} diff --git a/releases/1.1/Misc/UPnP.cs b/releases/1.1/Misc/UPnP.cs deleted file mode 100644 index 830bc50..0000000 --- a/releases/1.1/Misc/UPnP.cs +++ /dev/null @@ -1,313 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * Simple implementation of UPnP controller. Works fine with - * some D-Link and NetGear router models (need more tests) - * - * Based on the Harold Aptroot article & code - * http://www.codeproject.com/Articles/27992/ - * - * TODO: check compatibility with other routers - * - ************************************************************/ - -using System; -using System.Linq; -using System.Collections.Generic; -using System.Text; -using System.Text.RegularExpressions; -using System.Net.Sockets; -using System.Net; -using System.Xml; -using System.IO; -using System.Net.NetworkInformation; -using System.ComponentModel; - -namespace UPnP -{ - public class UPnPController : IDisposable - { - private bool _disposed = false; - private string _serviceUrl; - private BackgroundWorker _worker; - private WebClient _webClient; - - public bool Discovered { get; private set; } - public event EventHandler DiscoverCompleted; - - public bool UPnPReady { get { return !string.IsNullOrEmpty(_serviceUrl); } } - - public UPnPController () - { - Discovered = false; - } - - protected virtual void Dispose(bool disposing) - { - if (!this._disposed && disposing) - { - if (_webClient != null && _webClient.IsBusy) - { - _webClient.CancelAsync(); - _webClient.Dispose(); - } - if (_worker != null) - { - _worker.Dispose(); - } - DiscoverCompleted = null; - _disposed = true; - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public void DiscoverAsync(bool useUPnP) - { - _worker = new BackgroundWorker(); - _worker.DoWork += new DoWorkEventHandler(_worker_DoWork); - _worker.RunWorkerAsync(useUPnP); - } - - void _worker_DoWork(object sender, DoWorkEventArgs e) - { - bool detectUPnP = (bool) e.Argument; - if (detectUPnP) - { - NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces(); - foreach (NetworkInterface adapter in adapters) - { - IPInterfaceProperties properties = adapter.GetIPProperties(); - if (properties.GatewayAddresses != null && properties.GatewayAddresses.Count > 0) - { - foreach (IPAddressInformation uniAddr in properties.UnicastAddresses) - { - if (uniAddr.Address.AddressFamily == AddressFamily.InterNetwork) - { - using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) - { - socket.Bind(new IPEndPoint(uniAddr.Address, 0)); - socket.ReceiveTimeout = 2000; - socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); - string req = "M-SEARCH * HTTP/1.1\r\n" + - "HOST: 239.255.255.250:1900\r\n" + - "ST:upnp:rootdevice\r\n" + - "MAN:\"ssdp:discover\"\r\n" + - "MX:3\r\n\r\n"; - byte[] data = Encoding.ASCII.GetBytes(req); - IPEndPoint ipe = new IPEndPoint(IPAddress.Broadcast, 1900); - byte[] buffer = new byte[0x1000]; - - for (int i = 0; i < 3; i++) socket.SendTo(data, ipe); - - int length = 0; - do - { - try { length = socket.Receive(buffer); } - catch { break; } - string resp = Encoding.ASCII.GetString(buffer, 0, length).ToLower(); - if (resp.Contains("upnp:rootdevice")) - { - resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9); - resp = resp.Substring(0, resp.IndexOf("\r")).Trim(); - if (!string.IsNullOrEmpty(_serviceUrl = GetServiceUrl(resp))) - { - break; - } - } - } while (length > 0); - } - if (UPnPReady) - { - string ip = "127.0.0.0"; - XmlDocument xdoc = SOAPRequest(_serviceUrl, - "" + - "", "GetExternalIPAddress"); - if (xdoc.OuterXml.Contains("NewExternalIPAddress")) - { - XmlNamespaceManager nsMgr = new XmlNamespaceManager(xdoc.NameTable); - nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0"); - ip = xdoc.SelectSingleNode("//NewExternalIPAddress/text()", nsMgr).Value; - } - ExternalIP = IPAddress.Parse(ip); - } - Discovered = true; - if (UPnPReady && DiscoverCompleted != null) DiscoverCompleted(this, new EventArgs()); - } - } - } - } - } - // Just detect external IP address - else - { - _webClient = new WebClient(); - _webClient.DownloadStringCompleted += (object o, DownloadStringCompletedEventArgs ea) => - { - if (!_disposed && ea.Error == null && ea.Result != null) - { - Regex ip = new Regex(@"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"); - MatchCollection result = ip.Matches(ea.Result); - try { ExternalIP = IPAddress.Parse(result[0].Value); } - catch { ExternalIP = IPAddress.Parse("0.0.0.0"); } - if (DiscoverCompleted != null) DiscoverCompleted(this, new EventArgs()); - } - }; - _webClient.DownloadStringAsync(new Uri("http://myip.dnsdynamic.org")); //new Uri("http://checkip.dyndns.org")); - } - } - - private string GetServiceUrl(string resp) - { -#if false - // UPDATE: registry fix eliminate the IOException but completely ruins UPnP detection (after reboot) - // Prevent IOException - // See https://connect.microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception-on-the-first-call#details - RegistryKey registryKey = null; - registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Wow6432Node\\Microsoft\\.NETFramework", true); - if (registryKey == null) registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\.NETFramework", true); - if (registryKey.GetValue("LegacyWPADSupport") == null) registryKey.SetValue("LegacyWPADSupport", 0); -#endif - try - { - XmlDocument desc = new XmlDocument(); - desc.Load(WebRequest.Create(resp).GetResponse().GetResponseStream()); - XmlNamespaceManager nsMgr = new XmlNamespaceManager(desc.NameTable); - nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0"); - XmlNode typen = desc.SelectSingleNode("//tns:device/tns:deviceType/text()", nsMgr); - if (!typen.Value.Contains("InternetGatewayDevice")) return null; - XmlNode node = desc.SelectSingleNode("//tns:service[tns:serviceType=\"urn:schemas-upnp-org:service:WANIPConnection:1\"]/tns:controlURL/text()", nsMgr); - if (node == null) return null; - return CombineUrls(resp, node.Value); - } - catch - { - return null; - } - } - - private string CombineUrls(string resp, string p) - { - int n = resp.IndexOf("://"); - n = resp.IndexOf('/', n + 3); - return resp.Substring(0, n) + p; - } - - public void ForwardPort(int port, ProtocolType protocol, string description) - { - if (UPnPReady) - { - SOAPRequest(_serviceUrl, - "" + - "" + port.ToString() + "" + protocol.ToString().ToUpper() + "" + - "" + port.ToString() + "" + LocalIP.ToString() + - "1" + description + - "0", "AddPortMapping"); - } - } - - public void DeleteForwardingRule(int port, ProtocolType protocol) - { - if (UPnPReady) - { - SOAPRequest(_serviceUrl, - "" + - "" + - "" + - "" + port + "" + - "" + protocol.ToString().ToUpper() + "" + - "", "DeletePortMapping"); - } - } - - /// - /// Local network interface index - /// - private int _interfaceIndex = 0; - public int InterfaceIndex - { - get { return _interfaceIndex; } - set { if (value >= 0 && value < LocalInterfaces.Count) _interfaceIndex = value; } - } - - /// - /// Local IP address - /// - /// - public IPAddress LocalIP { get { return LocalInterfaces[InterfaceIndex]; } } - - /// - /// List of all local network interfaces with gateways - /// - private static List _localInterfaces = null; - public static List LocalInterfaces - { - get - { - if (_localInterfaces == null) - { - _localInterfaces = new List(); - foreach (NetworkInterface netif in NetworkInterface.GetAllNetworkInterfaces()) - { - IPInterfaceProperties properties = netif.GetIPProperties(); - foreach (GatewayIPAddressInformation gw in properties.GatewayAddresses) - { - if (!gw.Address.ToString().Equals("0.0.0.0")) - { - foreach (IPAddressInformation unicast in properties.UnicastAddresses) - { - // Lets skip "link local" addresses (RFC 3927), probably this address is disabled - if (unicast.Address.ToString().StartsWith("169.254")) break; - if (unicast.Address.AddressFamily == AddressFamily.InterNetwork) - { - _localInterfaces.Add(unicast.Address); - } - } - } - } - } - // If no network interface detected, add at least a local loopback (127.0.0.1) - if (_localInterfaces.Count == 0) _localInterfaces.Add(IPAddress.Loopback); - } - return _localInterfaces; - } - } - - public IPAddress ExternalIP { get; private set;} - - private static XmlDocument SOAPRequest(string url, string soap, string function) - { - XmlDocument resp = new XmlDocument(); - try - { - string req = "" + - "" + - "" + - soap + - "" + - ""; - WebRequest r = HttpWebRequest.Create(url); - r.Method = "POST"; - byte[] b = Encoding.UTF8.GetBytes(req); - r.Headers.Add("SOAPACTION", "\"urn:schemas-upnp-org:service:WANIPConnection:1#" + function + "\""); - r.ContentType = "text/xml; charset=\"utf-8\""; - r.ContentLength = b.Length; - r.GetRequestStream().Write(b, 0, b.Length); - WebResponse wres = r.GetResponse(); - Stream ress = wres.GetResponseStream(); - resp.Load(ress); - } - catch { } - return resp; - } - } -} diff --git a/releases/1.1/Misc/Utils.cs b/releases/1.1/Misc/Utils.cs deleted file mode 100644 index 468d2de..0000000 --- a/releases/1.1/Misc/Utils.cs +++ /dev/null @@ -1,279 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module contains string extensions and some helpers - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; -using System.Security.Cryptography; -using System.Linq; -using System.Text; - -namespace TinyOPDS -{ - public static class StringExtension - { - /// - /// Capitalize words in the string (for example, author's name: first, middle last), by converting first char of every word to uppercase - /// - /// source string - /// capitalize first word only - /// - public static string Capitalize(this string str, bool onlyFirstWord = false) - { - string[] words = str.Split(' '); - str = string.Empty; - for (int i = 0; i < words.Length; i++) - { - if (!onlyFirstWord || (onlyFirstWord && i == 0)) - { - if (words[i].Length > 1) - { - if (words[i].IsUpper()) words[i] = words[i].ToLower(); - words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1); - } - else - { - words[i] = words[i].ToUpper(); - } - } - str += words[i] + " "; - } - return str.Trim(); - } - - public static bool IsUpper(this string str) - { - bool isUpper = true; - foreach (char c in str) isUpper &= char.IsUpper(c); - return isUpper; - } - } - - public class Utils - { - private static string[] fb2Clients = new string[] { "fbreader", "moon+ reader" }; - /// - /// Detect eBook readers with fb2 support - /// - /// - /// true if reader supports fb2 format - public static bool DetectFB2Reader(string userAgent) - { - if (!string.IsNullOrEmpty(userAgent)) - { - foreach (string s in fb2Clients) - { - if (userAgent.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0) return true; - } - } - return false; - } - - private static string[] browsers = new string[] { "opera", "aol", "msie", "firefox", "chrome", "mozilla", "safari", "netscape", "navigator", "mosaic", "lynx", - "amaya", "omniweb", "avant", "camino", "flock", "seamonkey", "konqueror", "gecko", "yandex.browser" }; - /// - /// Detect browsers by User-Agent - /// - /// - /// true if it's browser request - public static bool DetectBrowser(string userAgent) - { - if (!string.IsNullOrEmpty(userAgent)) - { - foreach (string s in browsers) - { - if (userAgent.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0) return true; - } - } - return false; - } - - /// - /// Helper for project Mono - /// - public static bool IsLinux - { - get - { - int p = (int)Environment.OSVersion.Platform; - return (p == 4) || (p == 6) || (p == 128); - } - } - - // Default path to service files: databases, log, setting - public static string ServiceFilesLocation - { - get - { - //return Properties.Settings.Default.ServiceFilesPath; - return Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); - } - } - - // Assembly version - public static Version Version - { - get - { - return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; - } - } - - public static string ServerVersionName - { - get - { - return string.Format("running on TinyOPDS server version {0}.{1}", Version.Major, Version.Minor); - } - } - - /// - /// Creates a name-based UUID using the algorithm from RFC 4122 §4.3. - /// - /// The ID of the namespace. - /// The name (within that namespace). - /// The version number of the UUID to create; this value must be either - /// A UUID derived from the namespace and name. - public static Guid CreateGuid(Guid namespaceId, string name) - { - if (name == null) throw new ArgumentNullException("name"); - // convert the name to a sequence of octets (as defined by the standard or conventions of its namespace) (step 3) - // ASSUME: UTF-8 encoding is always appropriate - byte[] nameBytes = Encoding.UTF8.GetBytes(name); - - // convert the namespace UUID to network order (step 3) - byte[] namespaceBytes = namespaceId.ToByteArray(); - SwapByteOrder(namespaceBytes); - - // compute the hash of the name space ID concatenated with the name (step 4) - byte[] hash = namespaceId.ToByteArray(); - using (SHA256 algorithm = new SHA256Managed()) - { - algorithm.TransformBlock(namespaceBytes, 0, namespaceBytes.Length, hash, 0); - algorithm.TransformFinalBlock(nameBytes, 0, nameBytes.Length); - hash = algorithm.Hash; - } - - // most bytes from the hash are copied straight to the bytes of the new GUID (steps 5-7, 9, 11-12) - byte[] newGuid = new byte[16]; - Array.Copy(hash, 0, newGuid, 0, 16); - - // set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the appropriate 4-bit version number from Section 4.1.3 (step 8) - newGuid[6] = (byte) ((newGuid[6] & 0x0F) | (5 << 4)); - - // set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively (step 10) - newGuid[8] = (byte) ((newGuid[8] & 0x3F) | 0x80); - - // convert the resulting UUID to local byte order (step 13) - SwapByteOrder(newGuid); - return new Guid(newGuid); - } - - /// - /// The namespace for fully-qualified domain names (from RFC 4122, Appendix C). - /// - public static readonly Guid DnsNamespace = new Guid("6ba7b810-9dad-11d1-80b4-00c04fd430c8"); - - /// - /// The namespace for URLs (from RFC 4122, Appendix C). - /// - public static readonly Guid UrlNamespace = new Guid("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); - - /// - /// The namespace for ISO OIDs (from RFC 4122, Appendix C). - /// - public static readonly Guid IsoOidNamespace = new Guid("6ba7b812-9dad-11d1-80b4-00c04fd430c8"); - - // Converts a GUID (expressed as a byte array) to/from network order (MSB-first). - internal static void SwapByteOrder(byte[] guid) - { - SwapBytes(guid, 0, 3); - SwapBytes(guid, 1, 2); - SwapBytes(guid, 4, 5); - SwapBytes(guid, 6, 7); - } - - private static void SwapBytes(byte[] guid, int left, int right) - { - byte temp = guid[left]; - guid[left] = guid[right]; - guid[right] = temp; - } - } - - /// - /// Gives us a handy way to modify a collection while we're iterating through it. - /// - /// - /// Example of usage: - /// foreach (Book book in new IteratorIsolateCollection(Library.Books.Values)) - /// { - /// book.Title = book.Title.ToUpper(); - /// } - public class IteratorIsolateCollection : IEnumerable - { - IEnumerable _enumerable; - - public IteratorIsolateCollection(IEnumerable enumerable) - { - _enumerable = enumerable; - } - - public IEnumerator GetEnumerator() - { - return new IteratorIsolateEnumerator(_enumerable.GetEnumerator()); - } - - internal class IteratorIsolateEnumerator : IEnumerator - { - ArrayList items = new ArrayList(); - int currentItem; - - internal IteratorIsolateEnumerator(IEnumerator enumerator) - { - while (enumerator.MoveNext() != false) - { - items.Add(enumerator.Current); - } - IDisposable disposable = enumerator as IDisposable; - if (disposable != null) - { - disposable.Dispose(); - } - currentItem = -1; - } - - public void Reset() - { - currentItem = -1; - } - - public bool MoveNext() - { - currentItem++; - if (currentItem == items.Count) - return false; - - return true; - } - - public object Current - { - get - { - return items[currentItem]; - } - } - } - } -} diff --git a/releases/1.1/OPDS/AuthorsCatalog.cs b/releases/1.1/OPDS/AuthorsCatalog.cs deleted file mode 100644 index 471ee39..0000000 --- a/releases/1.1/OPDS/AuthorsCatalog.cs +++ /dev/null @@ -1,112 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the OPDS AuthorsCatalog class - * - ************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Linq; -using System.Web; - -using TinyOPDS.Data; - -namespace TinyOPDS.OPDS -{ - /// - /// Authors acquisition feed class - /// - public class AuthorsCatalog - { - /// - /// - /// - /// - /// - /// - public XDocument GetCatalog(string searchPattern, bool isOpenSearch = false, int threshold = 50) - { - if (!string.IsNullOrEmpty(searchPattern)) searchPattern = Uri.UnescapeDataString(searchPattern).Replace('+', ' ').ToLower(); - - XDocument doc = new XDocument( - // Add root element and namespaces - new XElement("feed", new XAttribute(XNamespace.Xmlns + "dc", Namespaces.dc), new XAttribute(XNamespace.Xmlns + "os", Namespaces.os), new XAttribute(XNamespace.Xmlns + "opds", Namespaces.opds), - new XElement("title", Localizer.Text("Books by authors")), - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("icon", "/authors.ico"), - // Add links - Links.opensearch, Links.search, Links.start) - ); - - // Get all authors names starting with searchPattern - List Authors = Library.GetAuthorsByName(searchPattern, isOpenSearch); - - // For search, also check transliterated names - if (isOpenSearch) - { - // Try transliteration - string translit = Transliteration.Back(searchPattern, TransliterationType.GOST); - if (!string.IsNullOrEmpty(translit)) - { - List transAuthors = Library.GetAuthorsByName(translit, isOpenSearch); - if (transAuthors.Count > 0) Authors.AddRange(transAuthors); - } - } - - if (Authors.Count > threshold) - { - Dictionary authors = null; - do - { - authors = (from a in Authors - group a by (a.Length > searchPattern.Length ? a.Substring(0, searchPattern.Length + 1) : a) into g - where g.Count() > 1 - select new { Name = g, Count = g.Count() }).ToDictionary(x => x.Name.Key, y => y.Count); - if (authors.Count == 1) searchPattern = authors.First().Key; - } while (authors.Count <= 1); - - // Add catalog entries - foreach (KeyValuePair author in authors) - { - doc.Root.Add( - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:authors:" + author.Key), - new XElement("title", author.Key), - new XElement("content", string.Format(Localizer.Text("Total authors on {0}: {1}"), author.Key, author.Value), new XAttribute("type", "text")), - new XElement("link", new XAttribute("href", "/authorsindex/" + Uri.EscapeDataString(author.Key)), new XAttribute("type", "application/atom+xml;profile=opds-catalog")) - ) - ); - } - } - // - else - { - // Add catalog entries - foreach (string author in Authors) - { - var booksCount = Library.GetBooksByAuthor(author).Count; - - doc.Root.Add( - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:authors:" + author), - new XElement("title", author), - new XElement("content", string.Format(Localizer.Text("Books: {0}"), booksCount), new XAttribute("type", "text")), - new XElement("link", new XAttribute("href", "/author/" + Uri.EscapeDataString(author)), new XAttribute("type", "application/atom+xml;profile=opds-catalog")) - ) - ); - } - } - return doc; - } - } -} diff --git a/releases/1.1/OPDS/BooksCatalog.cs b/releases/1.1/OPDS/BooksCatalog.cs deleted file mode 100644 index b8d6d5d..0000000 --- a/releases/1.1/OPDS/BooksCatalog.cs +++ /dev/null @@ -1,286 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the OPDS BookCatalog class - * - * - ************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Linq; -using System.Web; - -using TinyOPDS.Data; - -namespace TinyOPDS.OPDS -{ - public class BooksCatalog - { - private enum SearchFor - { - Author = 0, - Sequence, - Genre, - Title - } - - /// - /// Returns books catalog by selected author - /// - /// - /// - public XDocument GetCatalogByAuthor(string author, bool fb2Only) - { - return GetCatalog(author, SearchFor.Author, fb2Only); - } - - /// - /// Returns books catalog by selected sequence (series) - /// - /// - /// - public XDocument GetCatalogBySequence(string sequence, bool fb2Only) - { - return GetCatalog(sequence, SearchFor.Sequence, fb2Only); - } - - /// - /// Returns books catalog by selected genre - /// - /// - /// - public XDocument GetCatalogByGenre(string genre, bool fb2Only) - { - return GetCatalog(genre, SearchFor.Genre, fb2Only); - } - - - /// - /// Returns books catalog by selected genre - /// - /// - /// - public XDocument GetCatalogByTitle(string title, bool fb2Only, int pageNumber = 0, int threshold = 50) - { - return GetCatalog(title, SearchFor.Title, fb2Only, threshold); - } - - /// - /// Returns books catalog for specific search - /// - /// Keyword to search - /// Type of search - /// Client can accept fb2 files - /// Items per page - /// - private XDocument GetCatalog(string searchPattern, SearchFor searchFor, bool acceptFB2, int threshold = 50) - { - if (!string.IsNullOrEmpty(searchPattern)) searchPattern = Uri.UnescapeDataString(searchPattern).Replace('+', ' '); - - XDocument doc = new XDocument( - // Add root element and namespaces - new XElement("feed", new XAttribute(XNamespace.Xmlns + "dc", Namespaces.dc), new XAttribute(XNamespace.Xmlns + "os", Namespaces.os), new XAttribute(XNamespace.Xmlns + "opds", Namespaces.opds), - new XElement("title", Localizer.Text("Books by author ") + searchPattern), - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("icon", "/icons/books.ico"), - // Add links - Links.opensearch, Links.search, Links.start) - ); - - int pageNumber = 0; - // Extract and remove page number from the search patter - int j = searchPattern.IndexOf('/'); - if (j > 0) - { - int.TryParse(searchPattern.Substring(j + 1), out pageNumber); - searchPattern = searchPattern.Substring(0, j); - } - - // Get author's books - string catalogType = string.Empty; - List books = new List(); - switch (searchFor) - { - case SearchFor.Author: - books = Library.GetBooksByAuthor(searchPattern); - catalogType = "/author/" + Uri.EscapeDataString(searchPattern); - break; - case SearchFor.Sequence: - books = Library.GetBooksBySequence(searchPattern); - catalogType = "/sequence/" + Uri.EscapeDataString(searchPattern); - break; - case SearchFor.Genre: - books = Library.GetBooksByGenre(searchPattern); - catalogType = "/genre/" + Uri.EscapeDataString(searchPattern); - break; - case SearchFor.Title: - books = Library.GetBooksByTitle(searchPattern); - // For search, also return books by - if (threshold > 50) - { - string translit = Transliteration.Back(searchPattern, TransliterationType.GOST); - if (!string.IsNullOrEmpty(translit)) - { - List transTitles = Library.GetBooksByTitle(translit); - if (transTitles.Count > 0) books.AddRange(transTitles); - } - } - break; - } - - // For sequences, sort books by sequence number - if (searchFor == SearchFor.Sequence) - { - books = books.OrderBy(b => b.NumberInSequence).ToList(); - } - // else sort by title - else - { - books = books.OrderBy(b => b.Title, new OPDSComparer(Localizer.Language.Equals("ru"))).ToList(); - } - - int startIndex = pageNumber * threshold; - int endIndex = startIndex + ((books.Count / threshold == 0) ? books.Count : Math.Min(threshold, books.Count - startIndex)); - - if (searchFor == SearchFor.Title) - { - if ((pageNumber + 1) * threshold < books.Count) - { - catalogType = string.Format("/search?searchType=books&searchTerm={0}&pageNumber={1}", Uri.EscapeDataString(searchPattern), pageNumber + 1); - doc.Root.Add(new XElement("link", - new XAttribute("href", catalogType), - new XAttribute("rel", "next"), - new XAttribute("type", "application/atom+xml;profile=opds-catalog"))); - } - } - else if ((pageNumber + 1) * threshold < books.Count) - { - catalogType += "/" + (pageNumber + 1); - doc.Root.Add(new XElement("link", - new XAttribute("href", catalogType), - new XAttribute("rel", "next"), - new XAttribute("type", "application/atom+xml;profile=opds-catalog"))); - - } - - bool useCyrillic = Localizer.Language.Equals("ru"); - - List genres = Library.Genres; - - // Add catalog entries - for (int i = startIndex; i < endIndex; i++) - { - Book book = books.ElementAt(i); - - XElement entry = - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:book:" + book.ID), - new XElement("title", book.Title) - ); - - foreach (string author in book.Authors) - { - entry.Add( - new XElement("author", - new XElement("name", author), - new XElement("uri", "/author/" + Uri.EscapeDataString(author) - ))); - } - - foreach (string genreStr in book.Genres) - { - Genre genre = genres.Where(g => g.Tag.Equals(genreStr)).FirstOrDefault(); - if (genre != null) - entry.Add(new XElement("category", new XAttribute("term", (useCyrillic ? genre.Translation : genre.Name)), new XAttribute("label", (useCyrillic ? genre.Translation : genre.Name)))); - } - - // Build a content entry (translator(s), year, size, annotation etc.) - string bookInfo = string.Empty; - - if (!string.IsNullOrEmpty(book.Annotation)) - { - bookInfo += string.Format("

{0}


", book.Annotation); - } - if (book.Translators.Count > 0) - { - bookInfo += string.Format("{0} ", Localizer.Text("Translation:")); - foreach (string translator in book.Translators) bookInfo += translator + " "; - bookInfo += "
"; - } - if (book.BookDate != DateTime.MinValue) - { - bookInfo += string.Format("{0} {1}
", Localizer.Text("Year of publication:"), book.BookDate.Year); - } - bookInfo += string.Format("{0} {1}
", Localizer.Text("Format:"), book.BookType == BookType.EPUB ? "epub" : "fb2"); - bookInfo += string.Format("{0} {1} Kb
", Localizer.Text("Size:"), (int) book.DocumentSize / 1024); - if (!string.IsNullOrEmpty(book.Sequence)) - { - bookInfo += string.Format("{0} {1} #{2}
", Localizer.Text("Series:"), book.Sequence, book.NumberInSequence); - } - - entry.Add( - new XElement(Namespaces.dc + "language", book.Language), - new XElement(Namespaces.dc + "format", book.BookType == BookType.FB2 ? "fb2+zip" : "epub+zip"), - new XElement("content", new XAttribute("type", "text/html"), bookInfo)); - - if (book.HasCover) - { - entry.Add( - // Adding cover page and thumbnail links - new XElement("link", new XAttribute("href", "/cover/" + book.ID + ".jpeg"), new XAttribute("rel", "http://opds-spec.org/image"), new XAttribute("type", "image/jpeg")), - new XElement("link", new XAttribute("href", "/cover/" + book.ID + ".jpeg"), new XAttribute("rel", "x-stanza-cover-image"), new XAttribute("type", "image/jpeg")), - new XElement("link", new XAttribute("href", "/thumbnail/" + book.ID + ".jpeg"), new XAttribute("rel", "http://opds-spec.org/thumbnail"), new XAttribute("type", "image/jpeg")), - new XElement("link", new XAttribute("href", "/thumbnail/" + book.ID + ".jpeg"), new XAttribute("rel", "x-stanza-cover-image-thumbnail"), new XAttribute("type", "image/jpeg")) - // Adding download links - ); - } - - string fileName = Uri.EscapeDataString(Transliteration.Front(string.Format("{0}_{1}", book.Authors.First(), book.Title)).SanitizeFileName()); - string url = "/" + string.Format("{0}/{1}", book.ID, fileName); - if (book.BookType == BookType.EPUB || (book.BookType == BookType.FB2 && !acceptFB2 && !string.IsNullOrEmpty(Properties.Settings.Default.ConvertorPath))) - { - entry.Add(new XElement("link", new XAttribute("href", url+".epub"), new XAttribute("rel", "http://opds-spec.org/acquisition/open-access"), new XAttribute("type", "application/epub+zip"))); - } - - if (book.BookType == BookType.FB2) - { - entry.Add(new XElement("link", new XAttribute("href", url+".fb2.zip"), new XAttribute("rel", "http://opds-spec.org/acquisition/open-access"), new XAttribute("type", "application/fb2+zip"))); - } - - // For search requests, lets add navigation links for author and series (if any) - if (searchFor != SearchFor.Author) - { - foreach (string author in book.Authors) - { - entry.Add(new XElement("link", - new XAttribute("href", "/author/" + Uri.EscapeDataString(author)), - new XAttribute("rel", "related"), - new XAttribute("type", "application/atom+xml;profile=opds-catalog"), - new XAttribute("title", string.Format(Localizer.Text("All books by author {0}"), author)))); - } - } - - if (searchFor != SearchFor.Sequence && !string.IsNullOrEmpty(book.Sequence)) - { - entry.Add(new XElement("link", - new XAttribute("href", "/sequence/" + Uri.EscapeDataString(book.Sequence)), - new XAttribute("rel", "related"), - new XAttribute("type", "application/atom+xml;profile=opds-catalog"), - new XAttribute("title", string.Format(Localizer.Text("All books by series {0}"), book.Sequence)))); - } - - doc.Root.Add(entry); - } - return doc; - } - } -} \ No newline at end of file diff --git a/releases/1.1/OPDS/GenresCatalog.cs b/releases/1.1/OPDS/GenresCatalog.cs deleted file mode 100644 index a2cd066..0000000 --- a/releases/1.1/OPDS/GenresCatalog.cs +++ /dev/null @@ -1,87 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the OPDS GenresCatalog class - * - ************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Linq; -using System.Web; - -using TinyOPDS.Data; - -namespace TinyOPDS.OPDS -{ - /// - /// Genres acquisition feed class - /// - public class GenresCatalog - { - public XDocument GetCatalog(string searchPattern, int threshold = 50) - { - if (!string.IsNullOrEmpty(searchPattern)) searchPattern = Uri.UnescapeDataString(searchPattern).Replace('+', ' '); - - XDocument doc = new XDocument( - // Add root element and namespaces - new XElement("feed", new XAttribute(XNamespace.Xmlns + "dc", Namespaces.dc), new XAttribute(XNamespace.Xmlns + "os", Namespaces.os), new XAttribute(XNamespace.Xmlns + "opds", Namespaces.opds), - new XElement("title", Localizer.Text("Books by genres")), - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("icon", "/genres.ico"), - // Add links - Links.opensearch, Links.search, Links.start) - ); - - bool topLevel = true; - bool useCyrillic = Localizer.Language.Equals("ru"); - - List libGenres = Library.Genres; - List genres = null; - - // Is it top level (main genres)? - if (string.IsNullOrEmpty(searchPattern)) - { - genres = (from g in Library.FB2Genres from sg in g.Subgenres where libGenres.Contains(sg) select g).Distinct().ToList(); - } - // Is it a second level (subgenres)? - else - { - Genre genre = Library.FB2Genres.Where(g => g.Name.Equals(searchPattern) || g.Translation.Equals(searchPattern)).FirstOrDefault(); - if (genre != null) - { - genres = (from g in libGenres where genre.Subgenres.Contains(g) select g).Distinct().ToList(); - topLevel = false; - } - } - - if (genres != null) - { - genres.Sort(new OPDSComparer(useCyrillic)); - - // Add catalog entries - foreach (Genre genre in genres) - { - doc.Root.Add( - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:root:genre:" + (useCyrillic ? genre.Translation : genre.Name)), - new XElement("title", (useCyrillic ? genre.Translation : genre.Name)), - new XElement("content", string.Format(Localizer.Text("Books in genre «{0}»"), (useCyrillic ? genre.Translation : genre.Name)), new XAttribute("type", "text")), - new XElement("link", new XAttribute("href", "/" + (topLevel ? "genres/" : "genre/") + (topLevel ? Uri.EscapeDataString((useCyrillic ? genre.Translation : genre.Name)) : genre.Tag)), new XAttribute("type", "application/atom+xml;profile=opds-catalog")) - ) - ); - } - } - - return doc; - } - } -} diff --git a/releases/1.1/OPDS/Links.cs b/releases/1.1/OPDS/Links.cs deleted file mode 100644 index 41c22ee..0000000 --- a/releases/1.1/OPDS/Links.cs +++ /dev/null @@ -1,39 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines static OPDS links - * - ************************************************************/ - -using System.Xml.Linq; - -namespace TinyOPDS.OPDS -{ - public class Links - { - public static XElement opensearch = new XElement("link", - new XAttribute("href", "/opds-opensearch.xml"), - new XAttribute("rel", "search"), - new XAttribute("type", "application/opensearchdescription+xml")); - - public static XElement search = new XElement("link", - new XAttribute("href","/search?searchTerm={searchTerms}"), - new XAttribute("rel","search"), - new XAttribute("type","application/atom+xml")); - - public static XElement start = new XElement("link", - new XAttribute("href", ""), - new XAttribute("rel","start"), - new XAttribute("type","application/atom+xml")); - - public static XElement self = new XElement("link", - new XAttribute("href", ""), - new XAttribute("rel","self"), - new XAttribute("type","application/atom+xml")); - } -} diff --git a/releases/1.1/OPDS/Namespaces.cs b/releases/1.1/OPDS/Namespaces.cs deleted file mode 100644 index 5ffdae4..0000000 --- a/releases/1.1/OPDS/Namespaces.cs +++ /dev/null @@ -1,24 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * OPDS xml namespaces - * - ************************************************************/ - -using System.Xml.Linq; - -namespace TinyOPDS.OPDS -{ - internal class Namespaces - { - internal static XNamespace xmlns = XNamespace.Get("http://www.w3.org/2005/Atom"); - internal static XNamespace dc = XNamespace.Get("http://purl.org/dc/terms/"); - internal static XNamespace os = XNamespace.Get("http://a9.com/-/spec/opensearch/1.1/"); - internal static XNamespace opds = XNamespace.Get("http://opds-spec.org/2010/catalog"); - } -} diff --git a/releases/1.1/OPDS/OpenSearch.cs b/releases/1.1/OPDS/OpenSearch.cs deleted file mode 100644 index 62c9783..0000000 --- a/releases/1.1/OPDS/OpenSearch.cs +++ /dev/null @@ -1,113 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module contains OPDS OpenSearch implementation - * - * TODO: implement SOUNDEX search - * - ************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Linq; -using System.Web; - -using TinyOPDS.Data; - -namespace TinyOPDS.OPDS -{ - public class OpenSearch - { - public XDocument OpenSearchDescription() - { - XDocument doc = new XDocument( - // Add root element and namespaces - new XElement("OpenSearchDescription", - new XElement("ShortName", "TinyOPDS"), - new XElement("LongName", "TinyOPDS"), - new XElement("Url", new XAttribute("type", "application/atom+xml"), new XAttribute("template", "/search?searchTerm={searchTerms}")), - new XElement("Image", "/favicon.ico", new XAttribute("width", "16"), new XAttribute("height", "16")), - new XElement("Tags"), - new XElement("Contact"), - new XElement("Developer"), - new XElement("Attribution"), - new XElement("SyndicationRight", "open"), - new XElement("AdultContent", "false"), - new XElement("Language", "*"), - new XElement("OutputEncoding", "UTF-8"), - new XElement("InputEncoding", "UTF-8"))); - - return doc; - } - - public XDocument Search(string searchPattern, string searchType = "", bool fb2Only = false, int pageNumber = 0, int threshold = 50) - { - if (!string.IsNullOrEmpty(searchPattern)) searchPattern = Uri.UnescapeDataString(searchPattern).Replace('+', ' ').ToLower(); - - XDocument doc = new XDocument( - // Add root element and namespaces - new XElement("feed", new XAttribute(XNamespace.Xmlns + "dc", Namespaces.dc), new XAttribute(XNamespace.Xmlns + "os", Namespaces.os), new XAttribute(XNamespace.Xmlns + "opds", Namespaces.opds), - new XElement("id", "tag:search:"+searchPattern), - new XElement("title", Localizer.Text("Search results")), - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("icon", "/series.ico"), - // Add links - Links.opensearch, Links.search, Links.start, Links.self) - ); - - List authors = new List(); - List titles = new List(); - - if (string.IsNullOrEmpty(searchType)) - { - string transSearchPattern = Transliteration.Back(searchPattern, TransliterationType.GOST); - authors = Library.GetAuthorsByName(searchPattern, true); - if (authors.Count == 0 && !string.IsNullOrEmpty(transSearchPattern)) - { - authors = Library.GetAuthorsByName(transSearchPattern, true); - } - titles = Library.GetBooksByTitle(searchPattern); - if (titles.Count == 0 && !string.IsNullOrEmpty(transSearchPattern)) - { - titles = Library.GetBooksByTitle(transSearchPattern); - } - } - - if (string.IsNullOrEmpty(searchType) && authors.Count > 0 && titles.Count > 0) - { - // Add two navigation entries: search by authors name and book title - doc.Root.Add( - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:search:author"), - new XElement("title", Localizer.Text("Search authors")), - new XElement("content", Localizer.Text("Search authors by name"), new XAttribute("type", "text")), - new XElement("link", new XAttribute("href", "/search?searchType=authors&searchTerm=" + Uri.EscapeDataString(searchPattern)), new XAttribute("type", "application/atom+xml;profile=opds-catalog"))), - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:search:title"), - new XElement("title", Localizer.Text("Search books")), - new XElement("content", Localizer.Text("Search books by title"), new XAttribute("type", "text")), - new XElement("link", new XAttribute("href", "/search?searchType=books&searchTerm=" + Uri.EscapeDataString(searchPattern)), new XAttribute("type", "application/atom+xml;profile=opds-catalog"))) - ); - } - else if (searchType.Equals("authors") || (authors.Count > 0 && titles.Count == 0)) - { - return new AuthorsCatalog().GetCatalog(searchPattern, true); - } - else if (searchType.Equals("books") || (titles.Count > 0 && authors.Count == 0)) - { - if (pageNumber > 0) searchPattern += "/" + pageNumber; - return new BooksCatalog().GetCatalogByTitle(searchPattern, fb2Only, 0, 1000); - } - return doc; - } - } -} diff --git a/releases/1.1/OPDS/RootCatalog.cs b/releases/1.1/OPDS/RootCatalog.cs deleted file mode 100644 index 2e9717d..0000000 --- a/releases/1.1/OPDS/RootCatalog.cs +++ /dev/null @@ -1,77 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the OPDS RootCatalog class - * - ************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Linq; - -using TinyOPDS.Data; - -namespace TinyOPDS.OPDS -{ - /// - /// Root catalog class - /// - class RootCatalog - { - public XDocument Catalog - { - get - { - return new XDocument( - // Add root element with namespaces - new XElement("feed", new XAttribute(XNamespace.Xmlns + "dc", Namespaces.dc), - new XAttribute(XNamespace.Xmlns + "os", Namespaces.os), - new XAttribute(XNamespace.Xmlns + "opds", Namespaces.opds), - - new XElement("id", "tag:root"), - new XElement("title", Properties.Settings.Default.ServerName), - new XElement("subtitle", Utils.ServerVersionName), - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("icon", "/favicon.ico"), - - // Add links - Links.opensearch, - Links.search, - Links.start, - Links.self, - - // Add catalog entries - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:root:authors"), - new XElement("title", Localizer.Text("By authors"), new XAttribute("type", "text")), - new XElement("content", string.Format(Localizer.Text("{0} books by {1} authors"), Library.Count, Library.Authors.Count), new XAttribute("type", "text")), - new XElement("link", new XAttribute("href", "/authorsindex"), new XAttribute("type", "application/atom+xml;profile=opds-catalog")) - ), - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:root:sequences"), - new XElement("title", Localizer.Text("By series"), new XAttribute("type", "text")), - new XElement("content", string.Format(Localizer.Text("{0} books by {1} series"), Library.Count, Library.Sequences.Count), new XAttribute("type", "text")), - new XElement("link", new XAttribute("href", "/sequencesindex"), new XAttribute("type", "application/atom+xml;profile=opds-catalog")) - ), - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:root:genre"), - new XElement("title", Localizer.Text("By genres"), new XAttribute("type", "text")), - new XElement("content", Localizer.Text("Books grouped by genres"), new XAttribute("type", "text")), - new XElement("link", new XAttribute("href", "/genres"), new XAttribute("type", "application/atom+xml;profile=opds-catalog")) - ) - ) - ); - } - } - } -} diff --git a/releases/1.1/OPDS/SequencesCatalog.cs b/releases/1.1/OPDS/SequencesCatalog.cs deleted file mode 100644 index f81d263..0000000 --- a/releases/1.1/OPDS/SequencesCatalog.cs +++ /dev/null @@ -1,90 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the OPDS SequencesCatalog class (book series) - * - ************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Linq; -using System.Web; - -using TinyOPDS.Data; - -namespace TinyOPDS.OPDS -{ - /// - /// Sequences acquisition feed class - /// - public class SequencesCatalog - { - public XDocument GetCatalog(string searchPattern, int threshold = 50) - { - if (!string.IsNullOrEmpty(searchPattern)) searchPattern = Uri.UnescapeDataString(searchPattern).Replace('+', ' '); - - XDocument doc = new XDocument( - // Add root element and namespaces - new XElement("feed", new XAttribute(XNamespace.Xmlns + "dc", Namespaces.dc), new XAttribute(XNamespace.Xmlns + "os", Namespaces.os), new XAttribute(XNamespace.Xmlns + "opds", Namespaces.opds), - new XElement("title", Localizer.Text("Book series")), - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("icon", "/series.ico"), - // Add links - Links.opensearch, Links.search, Links.start) - ); - - // Get all authors names starting with searchPattern - List Sequences = (from s in Library.Sequences where s.StartsWith(searchPattern) && s.Length > searchPattern.Length + 1 select s).ToList(); - - if (Sequences.Count > threshold) - { - Dictionary sequences = (from a in Sequences - group a by (a.Length > searchPattern.Length ? a.Substring(0, searchPattern.Length + 1) : a) into g - where g.Count() > 1 - select new { Name = g, Count = g.Count() }).ToDictionary(x => x.Name.Key, y => y.Count); - - // Add catalog entries - foreach (KeyValuePair sequence in sequences) - { - doc.Root.Add( - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:sequences:" + sequence.Key), - new XElement("title", sequence.Key), - new XElement("content", string.Format(Localizer.Text("Total series on {0}: {1}"), sequence.Key, sequence.Value), new XAttribute("type", "text")), - new XElement("link", new XAttribute("href", "/sequencesindex/" + Uri.EscapeDataString(sequence.Key)), new XAttribute("type", "application/atom+xml;profile=opds-catalog")) - ) - ); - } - } - // - else - { - List sequences = (from s in Sequences where s.StartsWith(searchPattern) select s).ToList(); - // Add catalog entries - foreach (string sequence in sequences) - { - var seriesCount = Library.GetBooksBySequence(sequence).Count; - - doc.Root.Add( - new XElement("entry", - new XElement("updated", DateTime.UtcNow.ToUniversalTime()), - new XElement("id", "tag:sequences:" + sequence), - new XElement("title", sequence), - new XElement("content", string.Format(Localizer.Text("{0} books in {1}"), seriesCount, sequence), new XAttribute("type", "text")), - new XElement("link", new XAttribute("href", "/sequence/" + Uri.EscapeDataString(sequence)), new XAttribute("type", "application/atom+xml;profile=opds-catalog")) - ) - ); - } - } - return doc; - } - } -} diff --git a/releases/1.1/Parsers/BookParser.cs b/releases/1.1/Parsers/BookParser.cs deleted file mode 100644 index 40146be..0000000 --- a/releases/1.1/Parsers/BookParser.cs +++ /dev/null @@ -1,63 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * Base class for book parsers - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using System.Drawing; - -using TinyOPDS.Data; - -namespace TinyOPDS.Parsers -{ - public abstract class BookParser - { - /// - /// - /// - /// - /// - /// - public abstract Book Parse(Stream stream, string fileName); - - /// - /// - /// - /// - /// - public Book Parse(string fileName) - { - using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) - return Parse(stream, fileName); - } - - /// - /// - /// - /// - /// - public abstract Image GetCoverImage(Stream stream, string fileName); - /// - /// - /// - /// - /// - /// - public Image GetCoverImage(string fileName) - { - using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) - return GetCoverImage(stream, fileName); - } - - } -} diff --git a/releases/1.1/Parsers/ePubParser.cs b/releases/1.1/Parsers/ePubParser.cs deleted file mode 100644 index 93cf32e..0000000 --- a/releases/1.1/Parsers/ePubParser.cs +++ /dev/null @@ -1,155 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * ePub parser class implementation - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using System.Drawing; -using System.Drawing.Imaging; - -using TinyOPDS.Data; -using eBdb.EpubReader; - -namespace TinyOPDS.Parsers -{ - public class ePubParser : BookParser - { - /// - /// - /// - /// - /// - /// - public override Book Parse(Stream stream, string fileName) - { - Book book = new Book(fileName); - try - { - book.DocumentSize = (UInt32)stream.Length; - stream.Position = 0; - Epub epub = new Epub(stream); - book.ID = epub.UUID; - if (epub.Date != null && epub.Date.Count > 0) - { - try { book.BookDate = DateTime.Parse(epub.Date.First().Date); } - catch - { - int year; - if (int.TryParse(epub.Date.First().Date, out year)) book.BookDate = new DateTime(year, 1, 1); - } - } - book.Title = epub.Title[0]; - book.Authors = new List(); - book.Authors.AddRange(epub.Creator); - for (int i = 0; i < book.Authors.Count; i++) book.Authors[i] = book.Authors[i].Capitalize(); - book.Genres = LookupGenres(epub.Subject); - if (epub.Description != null && epub.Description.Count > 0) book.Annotation = epub.Description.First(); - if (epub.Language != null && epub.Language.Count > 0) book.Language = epub.Language.First(); - - // Lookup cover - if (epub.ExtendedData != null) - { - foreach (ExtendedData value in epub.ExtendedData.Values) - { - string s = value.FileName.ToLower(); - if (s.Contains(".jpeg") || s.Contains(".jpg") || s.Contains(".png")) - { - if (value.ID.ToLower().Contains("cover") || s.Contains("cover")) - { - book.HasCover = true; - break; - } - } - } - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "exception {0}" , e.Message); - } - return book; - } - - /// - /// Epub's "subjects" are non-formal and extremely messy :( - /// This function will try to find a corresponding genres from the FB2 standard genres by using Soundex algorithm - /// - /// - /// - private List LookupGenres(List subjects) - { - List genres = new List(); - if (subjects == null || subjects.Count < 1) - { - genres.Add("prose"); - } - else - { - foreach (string subj in subjects) - { - var genre = Library.SoundexedGenres.Where(g => g.Key.StartsWith(subj.SoundexByWord()) && g.Key.WordsCount() <= subj.WordsCount()+1).FirstOrDefault(); - if (genre.Key != null) genres.Add(genre.Value); - } - if (genres.Count < 1) genres.Add("prose"); - } - return genres; - } - - /// - /// - /// - /// - /// - /// - public override Image GetCoverImage(Stream stream, string fileName) - { - Image image = null; - try - { - stream.Position = 0; - Epub epub = new Epub(stream); - if (epub.ExtendedData != null) - { - foreach (ExtendedData value in epub.ExtendedData.Values) - { - string s = value.FileName.ToLower(); - if (s.Contains(".jpeg") || s.Contains(".jpg") || s.Contains(".png")) - { - if (value.ID.ToLower().Contains("cover") || s.Contains("cover")) - { - using (MemoryStream memStream = new MemoryStream(value.GetContentAsBinary())) - { - image = Image.FromStream(memStream); - // Convert image to jpeg - string mimeType = value.MimeType.ToLower(); - ImageFormat fmt = mimeType.Contains("png") ? ImageFormat.Png : ImageFormat.Gif; - if (!mimeType.Contains("jpeg")) - { - image = Image.FromStream(image.ToStream(fmt)); - } - image = image.Resize(CoverImage.CoverSize); - } - break; - } - } - } - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "GetCoverImage exception {0}", e.Message); - } - return image; - } - } -} diff --git a/releases/1.1/Parsers/fb2Parser.cs b/releases/1.1/Parsers/fb2Parser.cs deleted file mode 100644 index 83f91be..0000000 --- a/releases/1.1/Parsers/fb2Parser.cs +++ /dev/null @@ -1,246 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * FB2 parser implementation - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Linq; -using System.Drawing; -using System.Drawing.Imaging; - -using FB2Library; -using FB2Library.HeaderItems; -using FB2Library.Elements; -using TinyOPDS.Data; - -namespace TinyOPDS.Parsers -{ - public class FB2Parser : BookParser - { - /// - /// - /// - /// - /// - /// - public override Book Parse(Stream stream, string fileName) - { - XDocument xml = null; - Book book = new Book(fileName); - book.DocumentSize = (UInt32)stream.Length; - - try - { - FB2File fb2 = new FB2File(); - // Load header only - stream.Position = 0; - - // Project Mono has a bug: Xdocument.Load() can't detect encoding - string encoding = string.Empty; - if (Utils.IsLinux) - { - using (StreamReader sr = new StreamReader(stream)) - { - encoding = sr.ReadLine(); - int idx = encoding.ToLower().IndexOf("encoding=\""); - if (idx > 0) - { - encoding = encoding.Substring(idx + 10); - encoding = encoding.Substring(0, encoding.IndexOf('"')); - stream.Position = 0; - using (StreamReader esr = new StreamReader(stream, Encoding.GetEncoding(encoding))) - { - string xmlStr = esr.ReadToEnd(); - try - { - xml = XDocument.Parse(xmlStr, LoadOptions.PreserveWhitespace); - } - catch (Exception e) - { - if (e.Message.IndexOf("nbsp", StringComparison.InvariantCultureIgnoreCase) > 0) - { - xmlStr = xmlStr.Replace(" ", " ").Replace("&NBSP;", " "); - xml = XDocument.Parse(xmlStr, LoadOptions.PreserveWhitespace); - } - else if (e.Message.IndexOf("is an invalid character", StringComparison.InvariantCultureIgnoreCase) > 0) - { - xml = XDocument.Parse(this.SanitizeXmlString(xmlStr), LoadOptions.PreserveWhitespace); - } - else throw e; - } - } - } - } - } - - if (xml == null) - { - try - { - xml = XDocument.Load(stream); - } - // This code will try to improve xml loading - catch (Exception e) - { - stream.Position = 0; - if (e.Message.IndexOf("nbsp", StringComparison.InvariantCultureIgnoreCase) > 0) - { - using (StreamReader sr = new StreamReader(stream)) - { - string xmlStr = sr.ReadToEnd(); - xmlStr = xmlStr.Replace(" ", " ").Replace("&NBSP;", " "); - xml = XDocument.Parse(xmlStr, LoadOptions.PreserveWhitespace); - } - } - else if (e.Message.IndexOf("is an invalid character", StringComparison.InvariantCultureIgnoreCase) > 0) - { - using (StreamReader sr = new StreamReader(stream)) - { - string xmlStr = sr.ReadToEnd(); - xml = XDocument.Parse(this.SanitizeXmlString(xmlStr), LoadOptions.PreserveWhitespace); - } - } - else throw e; - } - } - - if (xml != null) - { - fb2.Load(xml, true); - - if (fb2.DocumentInfo != null) - { - book.ID = fb2.DocumentInfo.ID; - if (fb2.DocumentInfo.DocumentVersion != null) book.Version = (float)fb2.DocumentInfo.DocumentVersion; - if (fb2.DocumentInfo.DocumentDate != null) book.DocumentDate = fb2.DocumentInfo.DocumentDate.DateValue; - } - - if (fb2.TitleInfo != null) - { - if (fb2.TitleInfo.Cover != null && fb2.TitleInfo.Cover.HasImages()) book.HasCover = true; - if (fb2.TitleInfo.BookTitle != null) book.Title = fb2.TitleInfo.BookTitle.Text; - if (fb2.TitleInfo.Annotation != null) book.Annotation = fb2.TitleInfo.Annotation.ToString(); - if (fb2.TitleInfo.Sequences != null && fb2.TitleInfo.Sequences.Count > 0) - { - book.Sequence = fb2.TitleInfo.Sequences.First().Name.Capitalize(true); - if (fb2.TitleInfo.Sequences.First().Number != null) - { - book.NumberInSequence = (UInt32)(fb2.TitleInfo.Sequences.First().Number); - } - } - if (fb2.TitleInfo.Language != null) book.Language = fb2.TitleInfo.Language; - if (fb2.TitleInfo.BookDate != null) book.BookDate = fb2.TitleInfo.BookDate.DateValue; - if (fb2.TitleInfo.BookAuthors != null && fb2.TitleInfo.BookAuthors.Count() > 0) - { - book.Authors = new List(); - book.Authors.AddRange(from ba in fb2.TitleInfo.BookAuthors select string.Concat(ba.LastName, " ", ba.FirstName, " ", ba.MiddleName).Replace(" ", " ").Capitalize()); - } - if (fb2.TitleInfo.Translators != null && fb2.TitleInfo.Translators.Count() > 0) - { - book.Translators = new List(); - book.Translators.AddRange(from ba in fb2.TitleInfo.Translators select string.Concat(ba.LastName, " ", ba.FirstName, " ", ba.MiddleName).Replace(" ", " ").Capitalize()); - } - if (fb2.TitleInfo.Genres != null && fb2.TitleInfo.Genres.Count() > 0) - { - book.Genres = new List(); - book.Genres.AddRange((from g in fb2.TitleInfo.Genres select g.Genre).ToList()); - } - } - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "Book.Parse() exception {0} on file: {1}", e.Message, fileName); - } - finally - { - // Dispose xml document - xml = null; - } - - return book; - } - - /// - /// - /// - /// - /// - public override Image GetCoverImage(Stream stream, string fileName) - { - Image image = null; - XDocument xml = null; - try - { - FB2File fb2 = new FB2File(); - stream.Position = 0; - xml = XDocument.Load(stream); - fb2.Load(xml, false); - - if (fb2.TitleInfo != null && fb2.TitleInfo.Cover != null && fb2.TitleInfo.Cover.HasImages() && fb2.Images.Count > 0) - { - string coverHRef = fb2.TitleInfo.Cover.CoverpageImages.First().HRef.Substring(1); - var binaryObject = fb2.Images.First(item => item.Value.Id == coverHRef); - if (binaryObject.Value.BinaryData != null && binaryObject.Value.BinaryData.Length > 0) - { - using (MemoryStream memStream = new MemoryStream(binaryObject.Value.BinaryData)) - { - image = Image.FromStream(memStream); - // Convert image to jpeg - ImageFormat fmt = binaryObject.Value.ContentType == ContentTypeEnum.ContentTypePng ? ImageFormat.Png : ImageFormat.Gif; - if (binaryObject.Value.ContentType != ContentTypeEnum.ContentTypeJpeg) - { - image = Image.FromStream(image.ToStream(fmt)); - } - image = image.Resize(CoverImage.CoverSize); - } - } - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "Book.GetCoverImage() exception {0} on file: {1}", e.Message, fileName); - } - // Dispose xml document - xml = null; - return image; - } - - /// - /// Remove illegal XML characters from a string. - /// - public string SanitizeXmlString(string xml) - { - StringBuilder buffer = new StringBuilder(xml.Length); - foreach (char c in xml) if (IsLegalXmlChar(c)) buffer.Append(c); - return buffer.ToString(); - } - - /// - /// Whether a given character is allowed by XML 1.0. - /// - public bool IsLegalXmlChar(int character) - { - return - ( - character == 0x9 /* == '\t' == 9 */ || - character == 0xA /* == '\n' == 10 */ || - character == 0xD /* == '\r' == 13 */ || - (character >= 0x20 && character <= 0xD7FF) || - (character >= 0xE000 && character <= 0xFFFD) || - (character >= 0x10000 && character <= 0x10FFFF) - ); - } - } -} diff --git a/releases/1.1/ProcessHelper.cs b/releases/1.1/ProcessHelper.cs deleted file mode 100644 index 29c8b13..0000000 --- a/releases/1.1/ProcessHelper.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.ComponentModel; -using System.Windows; -using System.Threading; -using System.Diagnostics; - -namespace TinyOPDS -{ - /// - /// Helper for the external console apps execution in background (no visible window) - /// Stores process output to the observable collection (so, we can bind output to the ListBox) - /// - public class ProcessHelper : IDisposable - { - private bool disposed = false; - private Process process = new Process(); - private ObservableCollection output = new ObservableCollection(); - ProcessPriorityClass priority; - public AutoResetEvent WaitForOutput = new AutoResetEvent(false); - - /// - /// Default constructor - /// - /// - /// - /// - /// - public ProcessHelper(string CommandPath, string Arguments, bool ParseOutput = false, ProcessPriorityClass Priority = ProcessPriorityClass.Normal) - { - process.StartInfo.FileName = CommandPath; - process.StartInfo.Arguments = Arguments; - - DoParseOutput = ParseOutput; - - // set up output redirection - process.StartInfo.RedirectStandardOutput = true; - process.StartInfo.RedirectStandardError = true; - process.EnableRaisingEvents = true; - process.StartInfo.CreateNoWindow = true; - process.StartInfo.UseShellExecute = false; - priority = Priority; - // see below for output handler - process.ErrorDataReceived += proc_DataReceived; - process.OutputDataReceived += proc_DataReceived; - process.Exited += (__, ____) => - { - if (OnExited != null) - { - if (DoParseOutput) WaitForOutput.WaitOne(3000); - OnExited(this, new EventArgs()); - } - }; - } - - /// - /// Default destructor - /// - ~ProcessHelper() - { - Dispose(); - } - - protected virtual void Dispose(bool disposing) - { - if (!this.disposed && disposing) - { - if (!process.HasExited && IsRunning) process.Kill(); - disposed = true; - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public bool DoParseOutput { set; get; } - - public virtual void ParseOutput(string outString) { } - - private void proc_DataReceived(object sender, DataReceivedEventArgs e) - { - if (e.Data != null) - { - output.Add(e.Data); - ParseOutput(e.Data); - } - } - - public void RunAsync() - { - BackgroundWorker worker = new BackgroundWorker(); - worker.DoWork += (_, __) => - { - try - { - if (process.Start()) - { - process.PriorityClass = priority; - process.BeginErrorReadLine(); - process.BeginOutputReadLine(); - _isRunning = true; - process.WaitForExit(); - } - } - catch(Exception e) - { - Debug.WriteLine("ProcessHelper exception: " + e.ToString()); - } - finally - { - _isRunning = false; - } - }; - worker.RunWorkerAsync(); - } - - /// - /// Raised on process completion - /// - public event EventHandler OnExited; - - /// - /// Process output to stdout - /// - public ObservableCollection ProcessOutput { get { return output; } } - - /// - /// Return current state of process - /// - bool _isRunning = false; - public bool IsRunning { get { return _isRunning; } } - - /// - /// Return status of the current process - /// - public bool IsCompleted { get { return IsRunning?process.HasExited:false; } } - - /// - /// Return process exit code - /// - public int ExitCode { get { return IsCompleted ? process.ExitCode : 0; } } - - /// - /// Associated process priority class - /// - public ProcessPriorityClass PriorityClass - { - get { return process.PriorityClass; } - set { process.PriorityClass = value; } - } - } -} diff --git a/releases/1.1/Program.cs b/releases/1.1/Program.cs deleted file mode 100644 index 96298c8..0000000 --- a/releases/1.1/Program.cs +++ /dev/null @@ -1,110 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * TinyOPDS application entry point - * - ************************************************************/ - -using System; -using System.IO; -using System.IO.Compression; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Forms; -using System.Reflection; -using System.Threading; -using System.Diagnostics; - -namespace TinyOPDS -{ - static class Program - { - static Mutex mutex = new Mutex(false, "tiny_opds_mutex"); - - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - - // Check for single instance - if (Utils.IsLinux) - { - if (IsApplicationRunningOnMono("TinyOPDS.exe")) return; - } - else - { - if (!mutex.WaitOne(TimeSpan.FromSeconds(1), false)) return; - } - - try - { - using (MainForm mainForm = new MainForm()) - { - mainForm.WindowState = (Properties.Settings.Default.StartMinimized) ? FormWindowState.Minimized : FormWindowState.Normal; - mainForm.ShowInTaskbar = (Properties.Settings.Default.StartMinimized && Properties.Settings.Default.CloseToTray) ? false : true; - Application.Run(mainForm); - } - } - finally - { - if (!Utils.IsLinux) mutex.ReleaseMutex(); - } - } - - static bool IsApplicationRunningOnMono(string processName) - { - var processFound = 0; - - Process[] monoProcesses; - ProcessModuleCollection processModuleCollection; - - // find all processes called 'mono', that's necessary because our app runs under the mono process! - monoProcesses = Process.GetProcessesByName("mono"); - - for (var i = 0; i <= monoProcesses.GetUpperBound(0); ++i) - { - processModuleCollection = monoProcesses[i].Modules; - - for (var j = 0; j < processModuleCollection.Count; ++j) - { - if (processModuleCollection[j].FileName.EndsWith(processName)) - { - processFound++; - } - } - } - - //we don't find the current process, but if there is already another one running, return true! - return (processFound == 1); - } - - static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) - { - Assembly asm = Assembly.GetExecutingAssembly(); - String resourceName = asm.GetName().Name + ".Libs." + new AssemblyName(args.Name).Name + ".dll.gz"; - using (var stream = asm.GetManifestResourceStream(resourceName)) - { - if (stream != null) - { - using (MemoryStream memStream = new MemoryStream()) - { - GZipStream decompress = new GZipStream(stream, CompressionMode.Decompress); - decompress.CopyTo(memStream); - return Assembly.Load(memStream.GetBuffer()); - } - } - else return null; - } - } - } -} diff --git a/releases/1.1/Properties/AssemblyInfo.cs b/releases/1.1/Properties/AssemblyInfo.cs deleted file mode 100644 index 7ce19c8..0000000 --- a/releases/1.1/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TinyOPDS server")] -[assembly: AssemblyDescription("Standalone and small OPDS server for Windows")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("SeNSSoFT")] -[assembly: AssemblyProduct("TinyOPDS server")] -[assembly: AssemblyCopyright("Copyright © 2013, SeNSSoFT Ltd.")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("627a3331-e8e6-4085-8a68-64322d5d4c3e")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.0.0")] -[assembly: AssemblyFileVersion("1.1.0.0")] diff --git a/releases/1.1/Properties/Resources.Designer.cs b/releases/1.1/Properties/Resources.Designer.cs deleted file mode 100644 index 27ac690..0000000 --- a/releases/1.1/Properties/Resources.Designer.cs +++ /dev/null @@ -1,91 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.586 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace TinyOPDS.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TinyOPDS.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - internal static System.Drawing.Bitmap donate { - get { - object obj = ResourceManager.GetObject("donate", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - internal static System.Drawing.Bitmap folder { - get { - object obj = ResourceManager.GetObject("folder", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - internal static System.Drawing.Bitmap TinyOPDS { - get { - object obj = ResourceManager.GetObject("TinyOPDS", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - internal static System.Drawing.Icon trayIcon { - get { - object obj = ResourceManager.GetObject("trayIcon", resourceCulture); - return ((System.Drawing.Icon)(obj)); - } - } - } -} diff --git a/releases/1.1/Properties/Resources.resx b/releases/1.1/Properties/Resources.resx deleted file mode 100644 index 89d56a5..0000000 --- a/releases/1.1/Properties/Resources.resx +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\TinyOPDS.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Icons\folder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\donate.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\TinyOPDS.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - \ No newline at end of file diff --git a/releases/1.1/Properties/Settings.Designer.cs b/releases/1.1/Properties/Settings.Designer.cs deleted file mode 100644 index 0242218..0000000 --- a/releases/1.1/Properties/Settings.Designer.cs +++ /dev/null @@ -1,315 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18046 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace TinyOPDS.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - [System.Configuration.SettingsProvider(typeof(TinyOPDS.CustomSettingsProvider))] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string LibraryPath { - get { - return ((string)(this["LibraryPath"])); - } - set { - this["LibraryPath"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("Моя домашняя библиотека")] - public string ServerName { - get { - return ((string)(this["ServerName"])); - } - set { - this["ServerName"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("8080")] - public string ServerPort { - get { - return ((string)(this["ServerPort"])); - } - set { - this["ServerPort"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool StartWithWindows { - get { - return ((bool)(this["StartWithWindows"])); - } - set { - this["StartWithWindows"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool StartMinimized { - get { - return ((bool)(this["StartMinimized"])); - } - set { - this["StartMinimized"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool CloseToTray { - get { - return ((bool)(this["CloseToTray"])); - } - set { - this["CloseToTray"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string ConvertorPath { - get { - return ((string)(this["ConvertorPath"])); - } - set { - this["ConvertorPath"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("en")] - public string Language { - get { - return ((string)(this["Language"])); - } - set { - this["Language"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool OpenNATPort { - get { - return ((bool)(this["OpenNATPort"])); - } - set { - this["OpenNATPort"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string ServiceFilesPath { - get { - return ((string)(this["ServiceFilesPath"])); - } - set { - this["ServiceFilesPath"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool SaveLogToDisk { - get { - return ((bool)(this["SaveLogToDisk"])); - } - set { - this["SaveLogToDisk"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string RootPrefix { - get { - return ((string)(this["RootPrefix"])); - } - set { - this["RootPrefix"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool WatchLibrary { - get { - return ((bool)(this["WatchLibrary"])); - } - set { - this["WatchLibrary"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("True")] - public bool UseUPnP { - get { - return ((bool)(this["UseUPnP"])); - } - set { - this["UseUPnP"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool UseHTTPAuth { - get { - return ((bool)(this["UseHTTPAuth"])); - } - set { - this["UseHTTPAuth"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string Credentials { - get { - return ((string)(this["Credentials"])); - } - set { - this["Credentials"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool BanClients { - get { - return ((bool)(this["BanClients"])); - } - set { - this["BanClients"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("0")] - public int LogLevel { - get { - return ((int)(this["LogLevel"])); - } - set { - this["LogLevel"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool RememberClients { - get { - return ((bool)(this["RememberClients"])); - } - set { - this["RememberClients"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("1")] - public int UpdatesCheck { - get { - return ((int)(this["UpdatesCheck"])); - } - set { - this["UpdatesCheck"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("2013-01-01")] - public global::System.DateTime LastCheck { - get { - return ((global::System.DateTime)(this["LastCheck"])); - } - set { - this["LastCheck"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("5")] - public decimal WrongAttemptsCount { - get { - return ((decimal)(this["WrongAttemptsCount"])); - } - set { - this["WrongAttemptsCount"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("0")] - public int LocalInterfaceIndex { - get { - return ((int)(this["LocalInterfaceIndex"])); - } - set { - this["LocalInterfaceIndex"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool UseAbsoluteUri { - get { - return ((bool)(this["UseAbsoluteUri"])); - } - set { - this["UseAbsoluteUri"] = value; - } - } - } -} diff --git a/releases/1.1/Properties/Settings.settings b/releases/1.1/Properties/Settings.settings deleted file mode 100644 index a162b81..0000000 --- a/releases/1.1/Properties/Settings.settings +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - Моя домашняя библиотека - - - 8080 - - - False - - - False - - - False - - - - - - en - - - False - - - - - - False - - - - - - False - - - True - - - False - - - - - - False - - - 0 - - - False - - - 1 - - - 2013-01-01 - - - 5 - - - 0 - - - False - - - \ No newline at end of file diff --git a/releases/1.1/Properties/app.manifest b/releases/1.1/Properties/app.manifest deleted file mode 100644 index 8df6208..0000000 --- a/releases/1.1/Properties/app.manifest +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/releases/1.1/Resources/..svnbridge/trayIcon.ico b/releases/1.1/Resources/..svnbridge/trayIcon.ico deleted file mode 100644 index 81efb3c..0000000 --- a/releases/1.1/Resources/..svnbridge/trayIcon.ico +++ /dev/null @@ -1 +0,0 @@ -svn:mime-typeapplication/octet-stream \ No newline at end of file diff --git a/releases/1.1/Resources/trayIcon.ico b/releases/1.1/Resources/trayIcon.ico deleted file mode 100644 index f1282c6..0000000 Binary files a/releases/1.1/Resources/trayIcon.ico and /dev/null differ diff --git a/releases/1.1/Scanner/FileScanner.cs b/releases/1.1/Scanner/FileScanner.cs deleted file mode 100644 index 067ab84..0000000 --- a/releases/1.1/Scanner/FileScanner.cs +++ /dev/null @@ -1,166 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the FileScanner class - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Xml; -using System.Xml.Linq; -using System.Text; -using System.ComponentModel; -using System.Windows; -using System.Threading; - -using TinyOPDS.Data; -using TinyOPDS.Parsers; - -namespace TinyOPDS.Scanner -{ - public enum FileScannerStatus - { - SCANNING, - STOPPED - } - - public class FileScanner - { - public int SkippedFiles { get; set; } - public FileScannerStatus Status { get; set; } - - public event BookFoundEventHandler OnBookFound; - private IEnumerable BookFoundEventHandlers() { return from d in OnBookFound.GetInvocationList() select (BookFoundEventHandler)d; } - - public event InvalidBookEventHandler OnInvalidBook; - private IEnumerable InvalidBookEventHandlers() { return from d in OnInvalidBook.GetInvocationList() select (InvalidBookEventHandler)d; } - - public event FileSkippedEventHandler OnFileSkipped; - private IEnumerable FileSkippedEventHandlers() { return from d in OnFileSkipped.GetInvocationList() select (FileSkippedEventHandler)d; } - - public event ScanCompletedEventHandler OnScanCompleted; - private IEnumerable ScanCompletedEventHandlers() { return from d in OnScanCompleted.GetInvocationList() select (ScanCompletedEventHandler)d; } - - private ZipScanner _zipScanner = null; - private bool _isRecursive; - - public FileScanner(bool IsRecursive = true) - { - Status = FileScannerStatus.STOPPED; - _isRecursive = IsRecursive; - } - - public void Stop() - { - Status = FileScannerStatus.STOPPED; - if (_zipScanner != null) _zipScanner.Status = FileScannerStatus.STOPPED; - - if (OnBookFound != null) OnBookFound -= BookFoundEventHandlers().Last(); - if (OnInvalidBook != null) OnInvalidBook -= InvalidBookEventHandlers().Last(); - if (OnFileSkipped != null) OnFileSkipped -= FileSkippedEventHandlers().Last(); - if (OnScanCompleted != null) OnScanCompleted -= ScanCompletedEventHandlers().Last(); - } - - /// - /// - /// - /// - public void Start(string Path) - { - SkippedFiles = 0; - - BackgroundWorker scanner = new BackgroundWorker(); - scanner.DoWork += (__, ___) => - { - ScanDirectory(new DirectoryInfo(Path)); - Status = FileScannerStatus.STOPPED; - if (OnScanCompleted != null) OnScanCompleted(this, new EventArgs()); - }; - Status = FileScannerStatus.SCANNING; - scanner.RunWorkerAsync(); - } - - /// - /// - /// - /// - /// - private void ScanDirectory(DirectoryInfo directory) - { - foreach (FileInfo file in directory.GetFiles()) - { - if (!Utils.IsLinux && Status == FileScannerStatus.STOPPED) break; - ScanFile(file.FullName); - } - - // Recursively scan all subdirectories - DirectoryInfo[] subDirectories = directory.GetDirectories(); - if (_isRecursive) - foreach (DirectoryInfo subDirectory in subDirectories) - if (Status == FileScannerStatus.SCANNING) - ScanDirectory(subDirectory); - } - - /// - /// - /// - /// - public void ScanFile(string fullName) - { - Book book = null; - string ext = Path.GetExtension(fullName).ToLower(); - - // Process accepted files - try - { - if (Library.Contains(fullName.Substring(Library.LibraryPath.Length + 1))) - { - SkippedFiles++; - if (OnFileSkipped != null) OnFileSkipped(this, new FileSkippedEventArgs(SkippedFiles)); - } - else if (ext.Contains(".epub")) - { - book = new ePubParser().Parse(fullName); - } - else if (ext.Contains(".fb2")) - { - book = new FB2Parser().Parse(fullName); - } - else if (ext.Contains(".zip")) - { - _zipScanner = new ZipScanner(fullName); - _zipScanner.OnBookFound += (object sender, BookFoundEventArgs e) => { if (OnBookFound != null) OnBookFound(sender, e); }; - _zipScanner.OnInvalidBook += (object sender, InvalidBookEventArgs e) => { if (OnInvalidBook != null) OnInvalidBook(sender, e); }; - _zipScanner.OnFileSkipped += (object sender, FileSkippedEventArgs e) => - { - SkippedFiles++; - if (OnFileSkipped != null) OnFileSkipped(sender, new FileSkippedEventArgs(SkippedFiles)); - }; - _zipScanner.Scan(); - } - - // Inform caller - if (book != null) - { - if (book.IsValid && OnBookFound != null) OnBookFound(this, new BookFoundEventArgs(book)); - else if (!book.IsValid && OnInvalidBook != null) OnInvalidBook(this, new InvalidBookEventArgs(fullName)); - } - - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, ".ScanFile: exception {0} on file: {1}", e.Message, fullName); - if (OnInvalidBook != null) OnInvalidBook(this, new InvalidBookEventArgs(fullName)); - } - } - } -} diff --git a/releases/1.1/Scanner/ScannerEvents.cs b/releases/1.1/Scanner/ScannerEvents.cs deleted file mode 100644 index 57a4c79..0000000 --- a/releases/1.1/Scanner/ScannerEvents.cs +++ /dev/null @@ -1,62 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * Events and handlers classes for scanners - * - ************************************************************/ - -using System; -using TinyOPDS.Data; - -namespace TinyOPDS.Scanner -{ - /// - /// Scanner delegated events and arguments declarations - /// - - public class BookFoundEventArgs : EventArgs - { - public Book Book; - public BookFoundEventArgs(Book book) { Book = book; } - } - - public class InvalidBookEventArgs : EventArgs - { - public string BookName; - public InvalidBookEventArgs(string bookName) { BookName = bookName; } - } - - public class FileSkippedEventArgs : EventArgs - { - public int Count; - public FileSkippedEventArgs(int count) { Count = count; } - } - - public class BookAddedEventArgs : EventArgs - { - public string BookPath; - public BookType BookType; - public BookAddedEventArgs(string bookPath) - { - BookPath = bookPath; - BookType = BookPath.ToLower().Contains(".epub") ? BookType.EPUB : BookType.FB2; - } - } - - public class BookDeletedEventArgs : BookAddedEventArgs - { - public BookDeletedEventArgs(string bookPath) : base(bookPath) {} - } - - public delegate void BookFoundEventHandler(object sender, BookFoundEventArgs e); - public delegate void InvalidBookEventHandler(object sender, InvalidBookEventArgs e); - public delegate void FileSkippedEventHandler(object sender, FileSkippedEventArgs e); - public delegate void ScanCompletedEventHandler(object sender, EventArgs e); - public delegate void BookAddedEventHandler(object sender, BookAddedEventArgs e); - public delegate void BookDeletedEventHandler(object sender, BookDeletedEventArgs e); -} diff --git a/releases/1.1/Scanner/Watcher.cs b/releases/1.1/Scanner/Watcher.cs deleted file mode 100644 index 626b9df..0000000 --- a/releases/1.1/Scanner/Watcher.cs +++ /dev/null @@ -1,235 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This is a file watcher class - * - * TODO: should disable UI "scan" button during Watcher's - * operations - * - ************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; -using System.Threading; -using System.ComponentModel; -using System.Security.Permissions; - -using TinyOPDS.Data; - -namespace TinyOPDS.Scanner -{ - public class Watcher : IDisposable - { - private FileSystemWatcher _fileWatcher; - private bool _disposed = false; - - private List _addedBooks = new List(); - private List _deletedBooks = new List(); - private BackgroundWorker _booksManager; - private FileScanner _scanner; - - public event BookAddedEventHandler OnBookAdded; - public event BookDeletedEventHandler OnBookDeleted; - public event InvalidBookEventHandler OnInvalidBook; - public event FileSkippedEventHandler OnFileSkipped; - - [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted = true)] - public Watcher(string path = "") - { - DirectoryToWatch = path; - _booksManager = new BackgroundWorker(); - _booksManager.DoWork += _booksManager_DoWork; - _scanner = new FileScanner(false); - _scanner.OnBookFound += (object s, BookFoundEventArgs be) => - { - if (Library.Add(be.Book)) - { - //Library.Append(be.Book); - if (OnBookAdded != null) OnBookAdded(this, new BookAddedEventArgs(be.Book.FileName)); - } - }; - _scanner.OnInvalidBook += (object _sender, InvalidBookEventArgs _e) => { if (OnInvalidBook != null) OnInvalidBook(_sender, _e); }; - _scanner.OnFileSkipped += (object _sender, FileSkippedEventArgs _e) => { if (OnFileSkipped != null) OnFileSkipped(_sender, _e); }; - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - // Check to see if Dispose has already been called. - if (!this._disposed) - { - if (disposing) - { - if (_booksManager != null) - { - _isEnabled = false; - _booksManager.Dispose(); - } - if (_fileWatcher != null) _fileWatcher.Dispose(); - } - _disposed = true; - } - } - - public string DirectoryToWatch - { - [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted=true)] - get - { - return (_fileWatcher == null) ? string.Empty : _fileWatcher.Path; - } - - [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted = true)] - set - { - if (!string.IsNullOrEmpty(value) && Directory.Exists(value)) - { - if (_fileWatcher != null) - { - _fileWatcher.Created -= _fileWatcher_Created; - _fileWatcher.Deleted -= _fileWatcher_Deleted; - _fileWatcher.Renamed -= _fileWatcher_Renamed; - _fileWatcher.Dispose(); - } - _fileWatcher = new FileSystemWatcher(value, "*"); - _fileWatcher.InternalBufferSize = 1024 * 64; - _fileWatcher.Created += new FileSystemEventHandler(_fileWatcher_Created); - _fileWatcher.Deleted += new FileSystemEventHandler(_fileWatcher_Deleted); - _fileWatcher.Renamed += new RenamedEventHandler(_fileWatcher_Renamed); - _fileWatcher.IncludeSubdirectories = true; - _fileWatcher.EnableRaisingEvents = _isEnabled; - } - } - } - - private bool _isEnabled = false; - public bool IsEnabled - { - get { return _isEnabled; } - set - { - if (_fileWatcher != null) - { - _fileWatcher.EnableRaisingEvents = _isEnabled = value; - if (_isEnabled) _booksManager.RunWorkerAsync(); - else - { - _addedBooks.Clear(); - _deletedBooks.Clear(); - } - } - } - } - - /// - /// Book manager thread - /// - /// - /// - void _booksManager_DoWork(object sender, DoWorkEventArgs e) - { - string fileName = string.Empty; - while (_isEnabled && !_disposed) - { - // First, check added books - if (_addedBooks.Count > 0) - { - fileName = _addedBooks.First(); - // If book scheduled for deletion, do not add it - if (_deletedBooks.Contains(fileName)) - { - _deletedBooks.Remove(fileName); - _addedBooks.Remove(fileName); - } - else - { - if (!IsFileInUse(fileName)) - { - _scanner.ScanFile(fileName); - _addedBooks.Remove(fileName); - } - else - { - _addedBooks.Remove(fileName); - _addedBooks.Add(fileName); - } - } - } - // Delete book from library (we don't care about actual file existence) - else if (_deletedBooks.Count > 0) - { - fileName = _deletedBooks.First(); - if (Library.Delete(fileName)) - { - if (OnBookDeleted != null) OnBookDeleted(this, new BookDeletedEventArgs(fileName)); - } - _deletedBooks.Remove(fileName); - } - // Get some rest for UI - else - { - Thread.Sleep(100); - } - } - } - - /// - /// New file (book or zip archive) added to the library - /// - /// - /// - private void _fileWatcher_Created(object sender, FileSystemEventArgs e) - { - lock (_addedBooks) _addedBooks.Add(e.FullPath); - } - - /// - /// Library file (book or zip archive) is renamed - /// - /// - /// - private void _fileWatcher_Renamed(object sender, RenamedEventArgs e) - { - lock (_deletedBooks) _deletedBooks.Add(e.FullPath); - } - - /// - /// Library file (book or zip archive) deleted from the library - /// - /// - /// - private void _fileWatcher_Deleted(object sender, FileSystemEventArgs e) - { - lock (_deletedBooks) _deletedBooks.Add(e.FullPath); - } - - - private bool IsFileInUse(string path) - { - if (string.IsNullOrEmpty(path)) throw new ArgumentException("'path' cannot be null or empty.", "path"); - - try - { - using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read)) { } - } - catch (IOException) - { - return true; - } - return false; - } - } -} diff --git a/releases/1.1/Scanner/ZipScanner.cs b/releases/1.1/Scanner/ZipScanner.cs deleted file mode 100644 index 5bd11a6..0000000 --- a/releases/1.1/Scanner/ZipScanner.cs +++ /dev/null @@ -1,139 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines the ZipScanner class (FileScanner analog - * for zip archives) - * - ************************************************************/ - -using System; -using System.IO; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Xml; -using System.Xml.Linq; -using System.Text; -using System.ComponentModel; -using System.Threading; - -using Ionic.Zip; -using TinyOPDS.Data; -using TinyOPDS.Parsers; - -namespace TinyOPDS.Scanner -{ - public class ZipScanner - { - public string ZipFileName { get; set; } - public FileScannerStatus Status { get; set; } - public int SkippedFiles { get; set; } - - public event BookFoundEventHandler OnBookFound; - private IEnumerable BookFoundEventHandlers() { return from d in OnBookFound.GetInvocationList() select (BookFoundEventHandler)d; } - - public event InvalidBookEventHandler OnInvalidBook; - private IEnumerable InvalidBookEventHandlers() { return from d in OnInvalidBook.GetInvocationList() select (InvalidBookEventHandler)d; } - - public event FileSkippedEventHandler OnFileSkipped; - private IEnumerable FileSkippedEventHandlers() { return from d in OnFileSkipped.GetInvocationList() select (FileSkippedEventHandler)d; } - - public ZipScanner(string zipFileName) - { - ZipFileName = zipFileName; - Status = FileScannerStatus.STOPPED; - SkippedFiles = 0; - } - - public void Stop() - { - Status = FileScannerStatus.STOPPED; - if (OnBookFound != null) OnBookFound -= BookFoundEventHandlers().Last(); - if (OnFileSkipped != null) OnFileSkipped -= FileSkippedEventHandlers().Last(); - } - - /// - /// Scan zip file - /// - public void Scan() - { - Status = FileScannerStatus.SCANNING; - ZipFile zipFile = null; - string entryFileName = string.Empty; - MemoryStream memStream = null; - - try - { - zipFile = new ZipFile(ZipFileName); - - foreach (ZipEntry entry in zipFile.Entries) - { - if (Status != FileScannerStatus.SCANNING) break; - - if (!string.IsNullOrEmpty(entry.FileName)) - { - entryFileName = entry.FileName; - - // Process accepted files - try - { - Book book = null; - memStream = new MemoryStream(); - - string ext = Path.GetExtension(entry.FileName).ToLower(); - - if (Library.Contains(ZipFileName.Substring(Library.LibraryPath.Length+1) + "@" + entryFileName)) - { - SkippedFiles++; - if (OnFileSkipped != null) OnFileSkipped(this, new FileSkippedEventArgs(SkippedFiles)); - } - else if (ext.Contains(".epub")) - { - entry.Extract(memStream); - book = new ePubParser().Parse(memStream, ZipFileName + "@" + entryFileName); - } - else if (ext.Contains(".fb2")) - { - entry.Extract(memStream); - book = new FB2Parser().Parse(memStream, ZipFileName + "@" + entryFileName); - } - - if (book != null) - { - if (book.IsValid && OnBookFound != null) { OnBookFound(this, new BookFoundEventArgs(book)); } - else if (!book.IsValid && OnInvalidBook != null) OnInvalidBook(this, new InvalidBookEventArgs(ZipFileName + "@" + entryFileName)); - } - - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, ".ScanDirectory: exception {0} on file: {1}", e.Message, ZipFileName + "@" + entryFileName); - if (OnInvalidBook != null) OnInvalidBook(this, new InvalidBookEventArgs(ZipFileName + "@" + entryFileName)); - } - finally - { - if (memStream != null) - { - memStream.Dispose(); - memStream = null; - } - } - } - } - } - finally - { - if (zipFile != null) - { - zipFile.Dispose(); - zipFile = null; - } - } - } - } -} diff --git a/releases/1.1/Server/HttpServer.cs b/releases/1.1/Server/HttpServer.cs deleted file mode 100644 index 4b011bb..0000000 --- a/releases/1.1/Server/HttpServer.cs +++ /dev/null @@ -1,533 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module contains simple HTTP processor implementation - * and abstract class for HTTP server - * Also, couple additional service classes are specified - * - * - ************************************************************/ - -using System; -using System.Linq; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Threading; -using System.ComponentModel; - -namespace TinyOPDS.Server -{ - /// - /// Basic credentials (unencrypted) - /// - public class Credential - { - public string User { get; set; } - public string Password { get; set; } - public Credential(string user, string password) { User = user; Password = password; } - } - - /// - /// Simple HTTP processor - /// - public class HttpProcessor : IDisposable - { - public TcpClient Socket; - public HttpServer Server; - - private Stream _inputStream; - public StreamWriter OutputStream; - - public String HttpMethod; - public String HttpUrl; - public String HttpProtocolVersion; - public Hashtable HttpHeaders = new Hashtable(); - - public static BindingList Credentials = new BindingList(); - public static List AuthorizedClients = new List(); - public static Dictionary BannedClients = new Dictionary(); - - // Maximum post size, 1 Mb - private const int MAX_POST_SIZE = 1024 * 1024; - - // Output buffer size, 64 Kb max - private const int OUTPUT_BUFFER_SIZE = 1024 * 1024; - - private bool _disposed = false; - - public HttpProcessor(TcpClient socket, HttpServer server) - { - this.Socket = socket; - this.Server = server; - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - // Check to see if Dispose has already been called. - - if (!this._disposed) - { - if (disposing) - { - if (OutputStream != null) OutputStream.Dispose(); - if (_inputStream != null) _inputStream.Dispose(); - } - _disposed = true; - } - } - - private string StreamReadLine(Stream inputStream) - { - int next_char = -1; - string data = string.Empty; - if (inputStream.CanRead) - { - while (true) - { - try { next_char = inputStream.ReadByte(); } catch { break; } - if (next_char == '\n') { break; } - if (next_char == '\r') { continue; } - if (next_char == -1) { Thread.Sleep(10); continue; }; - data += Convert.ToChar(next_char); - } - } - return data; - } - - public void Process(object param) - { - // We can't use a StreamReader for input, because it buffers up extra data on us inside it's - // "processed" view of the world, and we want the data raw after the headers - _inputStream = new BufferedStream(Socket.GetStream()); - - if (ParseRequest()) - { - // We probably shouldn't be using a StreamWriter for all output from handlers either - OutputStream = new StreamWriter(new BufferedStream(Socket.GetStream(), OUTPUT_BUFFER_SIZE)); - OutputStream.AutoFlush = true; - - try - { - ReadHeaders(); - - bool authorized = true; - bool checkLogin = true; - - // Compute client hash string based on User-Agent + IP address - string clientHash = string.Empty; - if (HttpHeaders.ContainsKey("User-Agent")) clientHash += HttpHeaders["User-Agent"]; - string remoteIP = (Socket.Client.RemoteEndPoint as IPEndPoint).Address.ToString(); - clientHash += remoteIP; - clientHash = Utils.CreateGuid(Utils.IsoOidNamespace, clientHash).ToString(); - - if (Properties.Settings.Default.UseHTTPAuth) - { - authorized = false; - - // Is remote IP banned? - if (Properties.Settings.Default.BanClients) - { - if (BannedClients.ContainsKey(remoteIP) && BannedClients[remoteIP] >= Properties.Settings.Default.WrongAttemptsCount) - { - checkLogin = false; - } - } - - if (checkLogin) - { - // First, check authorized client list (if enabled) - if (Properties.Settings.Default.RememberClients) - { - if (AuthorizedClients.Contains(clientHash)) - { - authorized = true; - } - } - - if (!authorized && HttpHeaders.ContainsKey("Authorization")) - { - string hash = HttpHeaders["Authorization"].ToString(); - if (hash.StartsWith("Basic ")) - { - try - { - string[] credential = hash.Substring(6).DecodeFromBase64().Split(':'); - if (credential.Length == 2) - { - foreach (Credential cred in Credentials) - if (cred.User.Equals(credential[0])) - { - authorized = cred.Password.Equals(credential[1]); - if (authorized) - { - AuthorizedClients.Add(clientHash); - HttpServer.ServerStatistics.SuccessfulLoginAttempts++; - } - break; - } - if (!authorized) - Log.WriteLine(LogLevel.Warning, "Authentication failed! IP: {0} user: {1} pass: {2}", remoteIP, credential[0], credential[1]); - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "Authentication exception: IP: {0}, {1}", remoteIP, e.Message); - } - } - } - } - } - - if (authorized) - { - HttpServer.ServerStatistics.AddClient(clientHash); - - if (HttpMethod.Equals("GET")) - { - HttpServer.ServerStatistics.GetRequests++; - HandleGETRequest(); - } - else if (HttpMethod.Equals("POST")) - { - HttpServer.ServerStatistics.PostRequests++; - HandlePOSTRequest(); - } - } - else - { - if (Properties.Settings.Default.BanClients) - { - if (!BannedClients.ContainsKey(remoteIP)) BannedClients[remoteIP] = 0; - BannedClients[remoteIP]++; - if (!checkLogin) - { - Log.WriteLine(LogLevel.Warning, "IP address {0} is banned!", remoteIP); - WriteForbidden(); - } - } - if (checkLogin) - { - HttpServer.ServerStatistics.WrongLoginAttempts++; - WriteNotAuthorized(); - } - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, ".Process(object param) exception: {0}", e.Message); - WriteFailure(); - } - } - - try - { - if (OutputStream != null && OutputStream.BaseStream.CanWrite) - { - try - { - OutputStream.Flush(); - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, ".Process(object param): outputStream.Flush() exception: {0}", e.Message); - } - } - } - finally - { - Socket.Close(); - _inputStream = null; - OutputStream = null; - Socket = null; - } - } - - public bool ParseRequest() - { - String request = StreamReadLine(_inputStream); - if (string.IsNullOrEmpty(request)) return false; - string[] tokens = request.Split(' '); - if (tokens.Length != 3) return false; - HttpMethod = tokens[0].ToUpper(); - HttpUrl = tokens[1]; - HttpProtocolVersion = tokens[2]; - return true; - } - - public void ReadHeaders() - { - string line = string.Empty; - while ((line = StreamReadLine(_inputStream)) != null) - { - if (string.IsNullOrEmpty(line)) return; - - int separator = line.IndexOf(':'); - if (separator == -1) - { - throw new Exception("ReadHeaders(): invalid HTTP header line: " + line); - } - String name = line.Substring(0, separator); - int pos = separator + 1; - // strip spaces - while ((pos < line.Length) && (line[pos] == ' ')) pos++; - - string value = line.Substring(pos, line.Length - pos); - HttpHeaders[name] = value; - } - } - - public void HandleGETRequest() - { - Server.HandleGETRequest(this); - } - - private const int BUF_SIZE = 1024; - public void HandlePOSTRequest() - { - int content_len = 0; - MemoryStream memStream = null; - - try - { - memStream = new MemoryStream(); - if (this.HttpHeaders.ContainsKey("Content-Length")) - { - content_len = Convert.ToInt32(this.HttpHeaders["Content-Length"]); - if (content_len > MAX_POST_SIZE) - { - throw new Exception(String.Format("POST Content-Length({0}) too big for this simple server", content_len)); - } - byte[] buf = new byte[BUF_SIZE]; - int to_read = content_len; - while (to_read > 0) - { - int numread = this._inputStream.Read(buf, 0, Math.Min(BUF_SIZE, to_read)); - if (numread == 0) - { - if (to_read == 0) break; - else throw new Exception("Client disconnected during post"); - } - to_read -= numread; - memStream.Write(buf, 0, numread); - } - memStream.Seek(0, SeekOrigin.Begin); - } - using (StreamReader reader = new StreamReader(memStream)) - { - memStream = null; - Server.HandlePOSTRequest(this, reader); - } - } - finally - { - if (memStream != null) memStream.Dispose(); - } - } - - public void WriteSuccess(string contentType = "text/xml", bool isGZip = false) - { - try - { - OutputStream.Write("HTTP/1.1 200 OK\n"); - OutputStream.Write("Content-Type: " + contentType + "\n"); - if (isGZip) OutputStream.Write("Content-Encoding: gzip\n"); - OutputStream.Write("Connection: close\n\n"); - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, ".WriteSuccess() exception: {0}", e.Message); - } - } - - public void WriteFailure() - { - try - { - OutputStream.Write("HTTP/1.1 404 Bad request\n"); - OutputStream.Write("Connection: close\n\n"); - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, ".WriteFailure() exception: {0}", e.Message); - } - } - - public void WriteNotAuthorized() - { - try - { - OutputStream.Write("HTTP/1.1 401 Unauthorized\n"); - OutputStream.Write("WWW-Authenticate: Basic realm=TinyOPDS\n"); - OutputStream.Write("Connection: close\n\n"); - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, ".WriteNotAuthorized() exception: {0}", e.Message); - } - } - - public void WriteForbidden() - { - try - { - OutputStream.Write("HTTP/1.1 403 Forbidden\n"); - OutputStream.Write("Connection: close\n\n"); - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, ".WriteForbidden() exception: {0}", e.Message); - } - } - } - - /// - /// Server statistics class - /// - public class Statistics - { - public event EventHandler StatisticsUpdated; - private int _booksSent = 0; - private int _imagesSent = 0; - private int _getRequests = 0; - private int _postRequests = 0; - private int _successfulLoginAttempts = 0; - private int _wrongLoginAttempts = 0; - public int BooksSent { get { return _booksSent; } set { _booksSent = value; if (StatisticsUpdated != null) StatisticsUpdated(this, null); } } - public int ImagesSent { get { return _imagesSent; } set { _imagesSent = value; if (StatisticsUpdated != null) StatisticsUpdated(this, null); } } - public int GetRequests { get { return _getRequests; } set { _getRequests = value; if (StatisticsUpdated != null) StatisticsUpdated(this, null); } } - public int PostRequests { get { return _postRequests; } set { _postRequests = value; if (StatisticsUpdated != null) StatisticsUpdated(this, null); } } - public int SuccessfulLoginAttempts { get { return _successfulLoginAttempts; } set { _successfulLoginAttempts = value; if (StatisticsUpdated != null) StatisticsUpdated(this, null); } } - public int WrongLoginAttempts { get { return _wrongLoginAttempts; } set { _wrongLoginAttempts = value; if (StatisticsUpdated != null) StatisticsUpdated(this, null); } } - public int UniqueClientsCount { get { return _uniqueClients.Count; } } - public int BannedClientsCount { get { return HttpProcessor.BannedClients.Count(сlient => сlient.Value >= Properties.Settings.Default.WrongAttemptsCount); } } - public void AddClient(string newClient) { _uniqueClients[newClient] = true; } - private Dictionary _uniqueClients = new Dictionary(); - public void Clear() - { - _booksSent = _imagesSent = _getRequests = _postRequests = _successfulLoginAttempts = _wrongLoginAttempts = 0; - _uniqueClients.Clear(); - if (StatisticsUpdated != null) StatisticsUpdated(this, null); - } - } - - /// - /// Simple HTTP server - /// - public abstract class HttpServer - { - protected int _port; - protected int _timeout; - protected IPAddress _interfaceIP = IPAddress.Any; - TcpListener _listener; - internal bool _isActive = false; - public bool IsActive { get { return _isActive; } } - public Exception ServerException = null; - public AutoResetEvent ServerReady = null; - public static Statistics ServerStatistics = new Statistics(); - - public HttpServer(int Port, int Timeout = 10000) - { - _port = Port; - _timeout = Timeout; - ServerReady = new AutoResetEvent(false); - ServerStatistics.Clear(); - } - - public HttpServer(IPAddress InterfaceIP, int Port, int Timeout = 10000) - { - _interfaceIP = InterfaceIP; - _port = Port; - _timeout = Timeout; - ServerReady = new AutoResetEvent(false); - ServerStatistics.Clear(); - } - - ~HttpServer() - { - StopServer(); - } - - public virtual void StopServer() - { - _isActive = false; - if (_listener != null) - { - _listener.Stop(); - _listener = null; - } - if (ServerReady != null) - { - ServerReady.Dispose(); - ServerReady = null; - } - } - - /// - /// Server listener - /// - public void Listen() - { - HttpProcessor processor = null; - ServerException = null; - try - { - _listener = new TcpListener(_interfaceIP, _port); - _listener.Start(); - _isActive = true; - ServerReady.Set(); - while (_isActive) - { - if (_listener.Pending()) - { - TcpClient socket = _listener.AcceptTcpClient(); - socket.SendTimeout = socket.ReceiveTimeout = _timeout; - socket.SendBufferSize = 1024 * 1024; - socket.NoDelay = true; - processor = new HttpProcessor(socket, this); - ThreadPool.QueueUserWorkItem(new WaitCallback(processor.Process)); - } - else Thread.Sleep(10); - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, ".Listen() exception: {0}", e.Message); - ServerException = e; - _isActive = false; - ServerReady.Set(); - } - finally - { - if (processor != null) processor.Dispose(); - _isActive = false; - } - } - - /// - /// Abstract method to handle GET request - /// - /// - public abstract void HandleGETRequest(HttpProcessor processor); - - /// - /// Abstract method to handle POST request - /// - /// - /// - public abstract void HandlePOSTRequest(HttpProcessor processor, StreamReader inputData); - } -} diff --git a/releases/1.1/Server/OPDSServer.cs b/releases/1.1/Server/OPDSServer.cs deleted file mode 100644 index fd346af..0000000 --- a/releases/1.1/Server/OPDSServer.cs +++ /dev/null @@ -1,395 +0,0 @@ -/*********************************************************** - * This file is a part of TinyOPDS server project - * - * Copyright (c) 2013 SeNSSoFT - * - * This code is licensed under the Microsoft Public License, - * see http://tinyopds.codeplex.com/license for the details. - * - * This module defines OPDS HTTP server class - * - ************************************************************/ - -using System; -using System.IO; -using System.IO.Compression; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Net; - -using Ionic.Zip; -using TinyOPDS.OPDS; -using TinyOPDS.Data; - -namespace TinyOPDS.Server -{ - public class OPDSServer : HttpServer - { - public OPDSServer(IPAddress interfaceIP, int port, int timeout = 5000) : base(interfaceIP, port, timeout) { } - - /// - /// Dummy for POST requests - /// - /// - /// - public override void HandlePOSTRequest(HttpProcessor processor, StreamReader inputData) - { - Log.WriteLine(LogLevel.Warning, "HTTP POST request from {0}: {1} : NOT IMPLEMENTED", ((System.Net.IPEndPoint)processor.Socket.Client.RemoteEndPoint).Address, processor.HttpUrl); - } - - /// - /// POST requests handler - /// - /// - public override void HandleGETRequest(HttpProcessor processor) - { - Log.WriteLine("HTTP GET request from {0}: {1}", ((System.Net.IPEndPoint)processor.Socket.Client.RemoteEndPoint).Address, processor.HttpUrl); - try - { - // Parse request - string xml = string.Empty; - string request = processor.HttpUrl; - // Remove prefix if any - if (!string.IsNullOrEmpty(Properties.Settings.Default.RootPrefix)) - { - request = request.Replace(Properties.Settings.Default.RootPrefix, "/"); - } - - while (request.IndexOf("//") >= 0) request = request.Replace("//", "/"); - - string ext = Path.GetExtension(request); - string[] http_params = request.Split(new Char[] { '?', '=', '&' }); - - // User-agent check: some e-book readers can handle fb2 files (no conversion is needed) - string userAgent = processor.HttpHeaders["User-Agent"] as string; - bool acceptFB2 = Utils.DetectFB2Reader(userAgent); - - // Is it OPDS request? - if (string.IsNullOrEmpty(ext)) - { - try - { - // Is it root node requested? - if (request.Equals("/")) - { - xml = new RootCatalog().Catalog.ToString(); - } - else if (request.StartsWith("/authorsindex")) - { - int numChars = request.StartsWith("/authorsindex/") ? 14 : 13; - xml = new AuthorsCatalog().GetCatalog(request.Substring(numChars)).ToString(); - } - else if (request.StartsWith("/author/")) - { - xml = new BooksCatalog().GetCatalogByAuthor(request.Substring(8), acceptFB2).ToString(); - } - else if (request.StartsWith("/sequencesindex")) - { - int numChars = request.StartsWith("/sequencesindex/") ? 16 : 15; - xml = new SequencesCatalog().GetCatalog(request.Substring(numChars)).ToString(); - } - else if (request.Contains("/sequence/")) - { - xml = new BooksCatalog().GetCatalogBySequence(request.Substring(10), acceptFB2).ToString(); - } - else if (request.StartsWith("/genres")) - { - int numChars = request.Contains("/genres/") ? 8 : 7; - xml = new GenresCatalog().GetCatalog(request.Substring(numChars)).ToString(); - } - else if (request.StartsWith("/genre/")) - { - xml = new BooksCatalog().GetCatalogByGenre(request.Substring(7), acceptFB2).ToString(); - } - else if (request.StartsWith("/search")) - { - if (http_params[1].Equals("searchTerm")) - { - xml = new OpenSearch().Search(http_params[2], "", acceptFB2).ToString(); - } - else if (http_params[1].Equals("searchType")) - { - int pageNumber = 0; - if (http_params.Length > 6 && http_params[5].Equals("pageNumber")) - { - int.TryParse(http_params[6], out pageNumber); - } - xml = new OpenSearch().Search(http_params[4], http_params[2], acceptFB2, pageNumber).ToString(); - } - } - - if (string.IsNullOrEmpty(xml)) - { - processor.WriteFailure(); - return; - } - - // Modify and send xml back to the client app - xml = "\n" + xml.Insert(5, " xmlns=\"http://www.w3.org/2005/Atom\""); - - if (Properties.Settings.Default.UseAbsoluteUri) - { - try - { - string host = processor.HttpHeaders["Host"].ToString(); - xml = xml.Replace("href=\"", "href=\"http://" + host.UrlCombine(Properties.Settings.Default.RootPrefix)); - } - catch { } - } - -#if USE_GZIP_ENCODING - /// Unfortunately, current OPDS-enabled apps don't support this feature, even those that pretend to (like FBReader for Android) - - // Compress xml if compression supported - if (!processor.HttpHeaders.ContainsValue("gzip")) - { - - byte[] temp = Encoding.UTF8.GetBytes(xml); - using (MemoryStream inStream = new MemoryStream(temp)) - using (MemoryStream outStream = new MemoryStream()) - using (GZipStream gzipStream = new GZipStream(outStream, CompressionMode.Compress)) - { - inStream.CopyTo(gzipStream); - outStream.Position = 0; - processor.WriteSuccess("application/atom+xml;charset=utf=8",true); - outStream.CopyTo(processor.OutputStream.BaseStream); - } - } - else -#endif - { - processor.WriteSuccess("application/atom+xml;charset=utf-8"); - processor.OutputStream.Write(xml); - } - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "OPDS catalog exception {0}", e.Message); - } - return; - } - else if (request.Contains("opds-opensearch.xml")) - { - xml = new OpenSearch().OpenSearchDescription().ToString(); - xml = "\n" + xml.Insert(22, " xmlns=\"http://a9.com/-/spec/opensearch/1.1/\""); - - if (Properties.Settings.Default.UseAbsoluteUri) - { - try - { - string host = processor.HttpHeaders["Host"].ToString(); - xml = xml.Replace("href=\"", "href=\"http://" + host.UrlCombine(Properties.Settings.Default.RootPrefix)); - } - catch { } - } - - processor.WriteSuccess("application/atom+xml;charset=utf-8"); - processor.OutputStream.Write(xml); - return; - } - // fb2.zip book request - else if (request.Contains(".fb2.zip")) - { - MemoryStream memStream = null; - try - { - memStream = new MemoryStream(); - Book book = Library.GetBook(request.Substring(1, request.IndexOf('/', 1) - 1)); - - if (book.FilePath.ToLower().Contains(".zip@")) - { - string[] pathParts = book.FilePath.Split('@'); - using (ZipFile zipFile = new ZipFile(pathParts[0])) - { - ZipEntry entry = zipFile.Entries.First(e => e.FileName.Contains(pathParts[1])); - if (entry != null) entry.Extract(memStream); - } - } - else - { - using (FileStream stream = new FileStream(book.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - stream.CopyTo(memStream); - } - memStream.Position = 0; - - // Compress fb2 document to zip - using (ZipFile zip = new ZipFile()) - { - zip.AddEntry(Transliteration.Front(string.Format("{0}_{1}.fb2", book.Authors.First(), book.Title)), memStream); - using (MemoryStream outputStream = new MemoryStream()) - { - zip.Save(outputStream); - outputStream.Position = 0; - processor.WriteSuccess("application/fb2+zip"); - outputStream.CopyTo(processor.OutputStream.BaseStream); - } - } - HttpServer.ServerStatistics.BooksSent++; - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "FB2 file exception {0}", e.Message); - } - finally - { - processor.OutputStream.BaseStream.Flush(); - if (memStream != null) memStream.Dispose(); - } - return; - } - // epub book request - else if (ext.Contains(".epub")) - { - MemoryStream memStream = null; - try - { - memStream = new MemoryStream(); - Book book = Library.GetBook(request.Substring(1, request.IndexOf('/', 1) - 1)); - - if (book.FilePath.ToLower().Contains(".zip@")) - { - string[] pathParts = book.FilePath.Split('@'); - using (ZipFile zipFile = new ZipFile(pathParts[0])) - { - ZipEntry entry = zipFile.Entries.First(e => e.FileName.Contains(pathParts[1])); - if (entry != null) entry.Extract(memStream); - entry = null; - } - } - else - { - using (FileStream stream = new FileStream(book.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - stream.CopyTo(memStream); - } - memStream.Position = 0; - // At this moment, memStream has a copy of requested book - // For fb2, we need convert book to epub - if (book.BookType == BookType.FB2) - { - // No convertor found, return an error - if (string.IsNullOrEmpty(Properties.Settings.Default.ConvertorPath)) - { - Log.WriteLine(LogLevel.Error, "No FB2 to EPUB convertor found, file request can not be completed!"); - processor.WriteFailure(); - return; - } - - // Save fb2 book to the temp folder - string inFileName = Path.Combine(Path.GetTempPath(), book.ID + ".fb2"); - using (FileStream stream = new FileStream(inFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) - memStream.CopyTo(stream); - - // Run converter - string outFileName = Path.Combine(Path.GetTempPath(), book.ID + ".epub"); - string command = Path.Combine(Properties.Settings.Default.ConvertorPath, Utils.IsLinux ? "fb2toepub" : "Fb2ePub.exe"); - string arguments = string.Format(Utils.IsLinux ? "{0} {1}" : "\"{0}\" \"{1}\"", inFileName, outFileName); - - using (ProcessHelper converter = new ProcessHelper(command, arguments)) - { - converter.Run(); - - if (File.Exists(outFileName)) - { - memStream = new MemoryStream(); - using (FileStream fileStream = new FileStream(outFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) - fileStream.CopyTo(memStream); - - // Cleanup temp folder - try { File.Delete(inFileName); } - catch { } - try { File.Delete(outFileName); } - catch { } - } - else - { - string converterError = string.Empty; - foreach (string s in converter.ProcessOutput) converterError += s + " "; - Log.WriteLine(LogLevel.Error, "EPUB conversion error on file {0}. Error description: {1}", inFileName, converterError); - processor.WriteFailure(); - return; - } - } - } - - // At this moment, memStream has a copy of epub - processor.WriteSuccess("application/epub+zip"); - memStream.Position = 0; - memStream.CopyTo(processor.OutputStream.BaseStream); - HttpServer.ServerStatistics.BooksSent++; - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, "EPUB file exception {0}", e.Message); - } - finally - { - processor.OutputStream.BaseStream.Flush(); - if (memStream != null) memStream.Dispose(); - } - return; - } - // Cover image or thumbnail request - else if (ext.Contains(".jpeg")) - { - bool getCover = true; - string bookID = string.Empty; - if (request.Contains("/cover/")) - { - bookID = Path.GetFileNameWithoutExtension(request.Substring(request.IndexOf("/cover/") + 7)); - } - else if (request.Contains("/thumbnail/")) - { - bookID = Path.GetFileNameWithoutExtension(request.Substring(request.IndexOf("/thumbnail/") + 11)); - getCover = false; - } - - if (!string.IsNullOrEmpty(bookID)) - { - CoverImage image = null; - Book book = Library.GetBook(bookID); - - if (book != null) - { - if (ImagesCache.HasImage(bookID)) image = ImagesCache.GetImage(bookID); - else - { - image = new CoverImage(book); - if (image != null && image.HasImages) ImagesCache.Add(image); - } - - if (image != null && image.HasImages) - { - processor.WriteSuccess("image/jpeg"); - (getCover ? image.CoverImageStream : image.ThumbnailImageStream).CopyTo(processor.OutputStream.BaseStream); - processor.OutputStream.BaseStream.Flush(); - HttpServer.ServerStatistics.ImagesSent++; - return; - } - } - } - } - // favicon.ico request - else if (ext.Contains(".ico")) - { - string icon = Path.GetFileName(request); - Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("TinyOPDS.Icons." + icon); - if (stream != null && stream.Length > 0) - { - processor.WriteSuccess("image/x-icon"); - stream.CopyTo(processor.OutputStream.BaseStream); - processor.OutputStream.BaseStream.Flush(); - return; - } - } - processor.WriteFailure(); - } - catch (Exception e) - { - Log.WriteLine(LogLevel.Error, ".HandleGETRequest() exception {0}", e.Message); - processor.WriteFailure(); - } - } - } -} diff --git a/releases/1.1/TinyOPDS.csproj b/releases/1.1/TinyOPDS.csproj deleted file mode 100644 index 1f192c6..0000000 --- a/releases/1.1/TinyOPDS.csproj +++ /dev/null @@ -1,253 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {D4508020-1E2C-4D8E-B879-77D5C213E8EC} - WinExe - Properties - TinyOPDS - TinyOPDS - v4.0 - 512 - false - Client - Svn - Svn - Svn - SubversionScc - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - - - true - bin\Debug\ - DEBUG;TRACE - full - AnyCPU - bin\Debug\TinyOPDS.exe.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - true - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - true - false - - - bin\Release\ - TRACE - true - pdbonly - AnyCPU - bin\Release\TinyOPDS.exe.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - true - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - true - true - false - 4 - - - TinyOPDS.ico - - - true - bin\Debug\ - CODE_ANALYSIS;DEBUG;TRACE - full - AnyCPU - false - bin\Debug\TinyOPDS.exe.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - true - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - true - - - TinyOPDS.Program - - - false - - - - - - - LocalIntranet - - - false - - - Properties\app.manifest - - - - False - Libs\eBdb.EpubReader.dll - - - False - Libs\FB2Library.dll - - - False - Libs\Ionic.Zip.Reduced.dll - - - - - - - - - - - - - - - - - - Form - - - MainForm.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MainForm.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - SQL Server Compact 3.5 SP2 - true - - - False - Windows Installer 3.1 - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/releases/1.1/TinyOPDS.ico b/releases/1.1/TinyOPDS.ico deleted file mode 100644 index 901fcc4..0000000 Binary files a/releases/1.1/TinyOPDS.ico and /dev/null differ diff --git a/releases/1.1/TinyOPDS.png b/releases/1.1/TinyOPDS.png deleted file mode 100644 index 1681847..0000000 Binary files a/releases/1.1/TinyOPDS.png and /dev/null differ diff --git a/releases/1.1/TinyOPDS.sln b/releases/1.1/TinyOPDS.sln deleted file mode 100644 index 3a225a2..0000000 --- a/releases/1.1/TinyOPDS.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TinyOPDS", "TinyOPDS.csproj", "{D4508020-1E2C-4D8E-B879-77D5C213E8EC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TinyOPDSConsole", "..\TinyOPDSConsole\TinyOPDSConsole.csproj", "{5A92FA9B-B91C-48F4-9488-77103868D226}" -EndProject -Global - GlobalSection(SubversionScc) = preSolution - Svn-Managed = True - Manager = AnkhSVN - Subversion Support for Visual Studio - EndGlobalSection - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Full debug|Any CPU = Full debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D4508020-1E2C-4D8E-B879-77D5C213E8EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D4508020-1E2C-4D8E-B879-77D5C213E8EC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D4508020-1E2C-4D8E-B879-77D5C213E8EC}.Full debug|Any CPU.ActiveCfg = Full debug|Any CPU - {D4508020-1E2C-4D8E-B879-77D5C213E8EC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D4508020-1E2C-4D8E-B879-77D5C213E8EC}.Release|Any CPU.Build.0 = Release|Any CPU - {5A92FA9B-B91C-48F4-9488-77103868D226}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5A92FA9B-B91C-48F4-9488-77103868D226}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5A92FA9B-B91C-48F4-9488-77103868D226}.Full debug|Any CPU.ActiveCfg = Release|Any CPU - {5A92FA9B-B91C-48F4-9488-77103868D226}.Full debug|Any CPU.Build.0 = Release|Any CPU - {5A92FA9B-B91C-48F4-9488-77103868D226}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5A92FA9B-B91C-48F4-9488-77103868D226}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/releases/1.1/TinyOPDS.v11.suo b/releases/1.1/TinyOPDS.v11.suo deleted file mode 100644 index f28106c..0000000 Binary files a/releases/1.1/TinyOPDS.v11.suo and /dev/null differ diff --git a/releases/1.1/app.config b/releases/1.1/app.config deleted file mode 100644 index 9674f0e..0000000 --- a/releases/1.1/app.config +++ /dev/null @@ -1,88 +0,0 @@ - - - - -
- - - - - - - - - - - - - Моя домашняя библиотека - - - 8080 - - - False - - - False - - - False - - - - - - en - - - False - - - - - - False - - - - - - False - - - True - - - False - - - - - - False - - - 0 - - - False - - - 1 - - - 2013-01-01 - - - 5 - - - 0 - - - False - - - - diff --git a/releases/1.1/convertGenres.cs b/releases/1.1/convertGenres.cs deleted file mode 100644 index 17c0b2e..0000000 --- a/releases/1.1/convertGenres.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.IO; - -namespace convertGenres -{ - // Simple program to convert genres from text file to xml - public class Program - { - static bool firstTime = true; - - public static void Main(string[] args) - { - if (args.Length < 1) - { - Console.WriteLine("Usage: convertGenres file"); - return; - } - - if (File.Exists(args[0])) - { - using (StreamReader sr = new StreamReader(args[0])) - { - using (StreamWriter sw = new StreamWriter(Path.GetFileNameWithoutExtension(args[0]) + ".xml")) - { - sw.WriteLine("\n"); - - while (!sr.EndOfStream) - { - string s = sr.ReadLine().Replace("&", "&"); - - if (!s.Contains("codepage")) - { - // Is it multilingual file (en+ru)? - int lang_div = s.IndexOf((char)65533); - //Console.WriteLine("lang_div = {0}", lang_div); - - if (s[0] != ' ') - { - if (lang_div > 0) - { - string ru_name = s.Substring(0, lang_div - 1).Trim(); - string en_name = s.Substring(lang_div + 1).Trim(); - sw.WriteLine( (firstTime ? "" :"\t\n") + "\t"); - } - else sw.WriteLine("\t"); - firstTime = false; - } - else - { - int name_idx = s.IndexOf(' ', 2); - string subgenre = s.Substring(1, name_idx - 1); - - if (lang_div > 0) - { - string ru_name = s.Substring(name_idx + 1, lang_div - name_idx - 2).Trim(); - string en_name = s.Substring(lang_div + 1).Trim(); - sw.WriteLine("\t\t" + en_name + ""); - } - else - { - string name = s.Substring(name_idx + 1); - sw.WriteLine("\t\t" + name + ""); - } - } - } - } - - sw.WriteLine("\t\n"); - } - } - } - } - } -} \ No newline at end of file diff --git a/releases/1.1/donate.png b/releases/1.1/donate.png deleted file mode 100644 index 2cac793..0000000 Binary files a/releases/1.1/donate.png and /dev/null differ diff --git a/releases/1.1/genres.rus.txt b/releases/1.1/genres.rus.txt deleted file mode 100644 index 35d053f..0000000 --- a/releases/1.1/genres.rus.txt +++ /dev/null @@ -1,290 +0,0 @@ -UTF8 // codepage -Фантастика SF, Fantasy - sf_history Альтернативная история Alternative history - sf_action Боевая фантастика Action SF - sf_epic Эпическая фантастика Epic SF - sf_heroic Героическая фантастика Heroic SF - sf_detective Детективная фантастика Detective SF - sf_cyberpunk Киберпанк Cyberpunk - sf_space Космическая фантастика Space SF - sf_social Социальная фантастика Social SF - sf_horror Ужасы Horror - sf_humor Юмористическая фантастика Humor SF - sf_fantasy Фэнтези Fantasy - sf Научная фантастика Science Fiction - child_sf Детская фантастика Science Fiction for Kids - sf_fantasy_city Городское фэнтези Fantasy city - sf_postapocalyptic Постапокалипсис Postapocalyptic - love_sf Любовная фантастика Love SF - gothic_novel Готический роман Gothic novel - nsf Ненаучная фантастика Non Science Fiction - fairy_fantasy Сказочная фантастика Fairy SF - sf_etc Фантастика: прочее Other SF - sf_irony Ироническая фантастика Ironical SF - sf_fantasy_irony Ироническое фэнтези Ironyc female fantasy - sf_mystic Мистика Mystic - sf_space_opera Космоопера Space Opera - sf_stimpank Стимпанк Stimpank - sf_technofantasy Технофэнтези Technofantasy - popadanec Попаданцы popadanec - historical_fantasy Историческое фэнтези Historical fantasy - humor_fantasy Юмористическое фэнтези humor_fantasy -Детективы и Триллеры Detectives, Thrillers - sf_detective Детективная фантастика Detective SF - det_classic Классический детектив Classical Detective - det_police Полицейский детектив Police Stories - det_action Боевик Action - det_irony Иронический детектив Ironical Detective - det_history Исторический детектив Historical Detective - det_espionage Шпионский детектив Espionage Detective - det_crime Криминальный детектив Crime Detective - det_political Политический детектив Political Detective - det_maniac Маньяки Maniacs - det_hard Крутой детектив Hard-boiled Detective - thriller Триллер Thrillers - detective Детективы: прочее Detective - love_detective Любовные детективы Detective Romance - child_det Детские остросюжетные Detective for Kids - thriller_legal Юридический триллер Legal thriller - thriller_medical Медицинский триллер Medical thriller - thriller_techno Техно триллер Techno Thriller - det_cozy Дамский детективный роман Cozy Mysteries -Проза Prose - prose Проза Prose - prose_classic Классическая проза Classical Prose - prose_history Историческая проза Historical Prose - prose_contemporary Современная проза Contemporary Prose - prose_counter Контркультура Counterculture - prose_rus_classic Русская классическая проза Russian Classics - prose_su_classics Советская классическая проза Soviet Classics - prose_military О войне Military - aphorisms Афоризмы Aphorisms - essay Эссе, очерк, этюд, набросок Essay - story Новелла Story - great_story Повесть Great story - short_story Рассказ Short story - roman Роман Roman - extravaganza Феерия Extravaganza - epistolary_fiction Эпистолярная проза Epistolary - prose_epic Эпопея Epic - prose_magic Магический реализм Magic realism - sagas Семейный роман/Семейная сага Sagas - dissident Антисоветская литература Anti-Soviet fiction - prose_sentimental Сентиментальная проза prose_sentimental -Любовные романы Love - love_contemporary Современные любовные романы Contemporary Romance - love_history Исторические любовные романы Historical Romance - love_detective Любовные детективы Detective Romance - love_short Короткие любовные романы Short Romance - love_erotica Эротика Erotica - love О любви About love - love_sf Любовная фантастика Love SF - love_hard Порно Porno - det_cozy Дамский детективный роман Cozy Mysteries -Приключения Adventures - adv_western Вестерн Western - adv_history Исторические приключения History - adv_indian Приключения про индейцев Indians - adv_maritime Морские приключения Maritime Fiction - adv_geo Путешествия и география Travel & Geography - adv_animal Природа и животные Nature & Animals - adventure Приключения: прочее Misk Adventures - child_adv Детские приключения Adventures for Kids -Детское Children's - child_tale Сказка Fairy Tales - child_verse Детские стихи Verses for Kids - child_prose Детская проза Prose for Kids - child_sf Детская фантастика Science Fiction for Kids - child_det Детские остросюжетные Detective for Kids - child_adv Детские приключения Adventures for Kids - child_education Образовательная литература Education for Kids - children Детская литература: прочее For Kids: Misk - child_folklore Детский фольклор Child Folklore - prose_game Книга-игра Game book -Поэзия Poetry, Dramaturgy - child_verse Детские стихи Verses for Kids - poetry Поэзия: прочее Poetry - humor_verse Юмористические стихи Humor Verses - fable Басни Fable - vers_libre Верлибры Vers libre - visual_poetry Визуальная поэзия Visual Poetry - lyrics Лирика Lyrics - palindromes Палиндромы Palindromes - song_poetry Песенная поэзия Song Poetry - experimental_poetry Экспериментальная поэзия Experimental Poetry - epic_poetry Эпическая поэзия Epic Poetry - in_verse в стихах In verse -Старинное Antique - antique_ant Античная литература Antique Literature - antique_european Древнеевропейская литература Antique European Literature - antique_russian Древнерусская литература Antique Russian Literature - antique_east Древневосточная литература Antique East Literature - antique_myths Мифы. Легенды. Эпос Myths. Legends. Epos - antique Старинная литература: прочее Other Antique -Наука, Образование Science, Education - sci_history История History - sci_psychology Психология Psychology - sci_culture Культурология Cultural Science - sci_religion Религиоведение Religious Studies - sci_philosophy Философия Philosophy - sci_politics Политика Politics - sci_business Деловая литература Business - sci_juris Юриспруденция Jurisprudence - sci_linguistic Языкознание Linguistics - sci_medicine Медицина Medicine - sci_phys Физика Physics - sci_math Математика Mathematics - sci_chem Химия Chemistry - sci_biology Биология Biology - sci_tech Технические науки Technical - science Научная литература: прочее Misk Science, Education - sci_biochem Биохимия Biochemistry - sci_physchem Физическая химия Physical chemistry - sci_anachem Аналитическая химия Analitic Chemistry - sci_orgchem Органическая химия Organic Chemistry - sci_economy Экономика Economy - sci_state Государство и право State science - sci_biophys Биофизика Biophysics - sci_geo Геология и география Geology - sci_cosmos Астрономия и Космос Cosmos - sci_medicine_alternative Альтернативная медицина Alternative medicine - sci_philology Литературоведение Philology - sci_pedagogy Педагогика Pedagogy - sci_social_studies Обществознание Social studies - sci_ecology Экология Ecology - military_history Военная история Military History - sci_veterinary Ветеринария Veterinary - sci_zoo Зоология Zoology - sci_botany Ботаника Botany - sci_textbook Учебники Textbook - sci_crib Шпаргалки Cribs - sci_abstract Рефераты Abstract - foreign_language Иностранные языки Foreign languages - psy_childs Детская психология psy_childs - psy_theraphy Психотерапия и консультирование psy_theraphy - psy_sex_and_family Секс и семейная психология Sex and family -Компьютеры и Интернет Computers - comp_www Интернет Internet - comp_programming Программирование Programming - comp_hard Аппаратное обеспечение Hardware - comp_soft Программы Software - comp_db Базы данных Databases - comp_osnet ОС и Сети OS & Networking - computers Околокомпьютерная литература Computers: Misk - comp_dsp Цифровая обработка сигналов DSP -Справочная литература Reference - ref_encyc Энциклопедии Encyclopedias - ref_dict Словари Dictionaries - ref_ref Справочники Reference - ref_guide Руководства Guidebooks - reference Справочная литература Misk References - design Искусство и Дизайн Art, Design - geo_guides Путеводители Guides -Религия и духовность Religion - religion_rel Религия Religion - religion_esoterics Эзотерика Esoterics - religion_self Самосовершенствование Self-perfection - religion Религиозная литература: прочее Religion: Other - religion_budda Буддизм Buddha - religion_christianity Христианство Christianity - religion_orthodoxy Православие Orthodoxy - religion_catholicism Католицизм Catholicism - religion_protestantism Протестантизм Protestantism - religion_hinduism Индуизм Hinduism - religion_islam Ислам Islam - religion_judaism Иудаизм Judaism - astrology Астрология Astrology - palmistry Хиромантия Palmistry - religion_paganism Язычество Paganism -Юмор Humor - sf_humor Юмористическая фантастика Humor SF - humor_anecdote Анекдоты Anecdote - humor_prose Юмористическая проза Humor Prose - humor_verse Юмористические стихи Humor Verses - humor Юмор: прочее Misk Humor - comedy Комедия Comedy - humor_satire Сатира Satire -Домоводство (Дом и семья) Home, Family - home_cooking Кулинария Cooking - home_pets Домашние животные Pets - home_crafts Хобби и ремесла Hobbies & Crafts - home_entertain Развлечения Entertaining - home_health Здоровье Health - home_garden Сад и огород Garden - home_diy Сделай сам Do it yourself - home_sport Спорт Sports - home_sex Эротика, Секс Erotica, Sex - home Домоводство Home: Other - home_collecting Коллекционирование Collecting -Техника Technics - sci_tech Технические науки Technical - sci_transport Транспорт и авиация Transport - sci_metal Металлургия Metallurgy - sci_radio Радиоэлектроника Radio - sci_build Строительство и сопромат Building - auto_regulations Автомобили и ПДД Auto regulations - architecture_book Архитектура Architecture -Прочее Other - other Неотсортированное Other - notes Партитуры Notes - periodic Газеты и журналы Periodic - music Музыка Music - cine Кино Cine - theatre Театр Theatre - fanfiction Фанфик Fan fiction - unfinished Недописанное Unfinished - visual_arts Изобразительное искусство, фотография Visual Arts -Деловая литература Economy, Business - banking Банковское дело Banking - accounting Бухучет и аудит Accounting - global_economy Внешняя торговля Global Economy - paper_work Делопроизводство Paper Work - org_behavior Корпоративная культура Corporate Culture - personal_finance Личные финансы Personal Finance - small_business Малый бизнес Small Business - marketing Маркетинг, PR, реклама Marketing, PR, Adv - real_estate Недвижимость Real Estate - popular_business О бизнесе популярно Popular Business - industries Отраслевые издания Industries - job_hunting Поиск работы, карьера Job Hunting - ya Подростковая литература Young-adult fiction - management Управление, подбор персонала Management - stock Ценные бумаги, инвестиции Stock - economics Экономика Economics - trade Торговля Trade -Документальная литература Nonfiction - adv_geo Путешествия и география Travel & Geography - adv_animal Природа и животные Nature & Animals - nonf_biography Биографии и Мемуары Biography & Memoirs - nonf_publicism Публицистика Publicism - nonf_criticism Критика Criticism - nonfiction Документальная литература Misk Nonfiction - nonf_military Военная документалистика Military docs - sci_popular Научпоп Science popular -Драматургия Dramaturgy - dramaturgy Драматургия: прочее Dramaturgy - drama Драма Drama - screenplays Киносценарии Screenplays - comedy Комедия Comedy - mystery Мистерия Mystery - scenarios Сценарии Scenarios - tragedy Трагедия Tragedy - vaudeville Водевиль Vaudeville -Фольклор Folklore - humor_anecdote Анекдоты Anecdote - epic Былины Epic - child_folklore Детский фольклор Child Folklore - riddles Загадки Riddles - folk_songs Народные песни Folk Songs - folk_tale Народные сказки Folk tales - proverbs Пословицы, поговорки Proverbs - folklore Фольклор: прочее Folklore - limerick Частушки, прибаутки, потешки Limerick -Военное дело Military - prose_military О войне Military - nonf_military Военная документалистика Military docs - military_history Военная история Military History - military_weapon Военная техника и вооружение Weapon - military_arts Боевые искусства Military Arts - military_special Cпецслужбы Military special - military Военное дело: прочее Military diff --git a/releases/1.1/genres.xml b/releases/1.1/genres.xml deleted file mode 100644 index 4a481be..0000000 --- a/releases/1.1/genres.xml +++ /dev/null @@ -1,313 +0,0 @@ - - - - Alternative history - Action SF - Epic SF - Heroic SF - Detective SF - Cyberpunk - Space SF - Social SF - Horror - Humor SF - Fantasy - Science Fiction - Science Fiction for Kids - Fantasy city - Postapocalyptic - Love SF - Gothic novel - Non Science Fiction - Fairy SF - Other SF - Ironical SF - Ironyc female fantasy - Mystic - Space Opera - Stimpank - Technofantasy - popadanec - Historical fantasy - humor_fantasy - - - Detective SF - Classical Detective - Police Stories - Action - Ironical Detective - Historical Detective - Espionage Detective - Crime Detective - Political Detective - Maniacs - Hard-boiled Detective - Thrillers - Detective - Detective Romance - Detective for Kids - Legal thriller - Medical thriller - Techno Thriller - Cozy Mysteries - - - Prose - Classical Prose - Historical Prose - Contemporary Prose - Counterculture - Russian Classics - Soviet Classics - Military - Aphorisms - Essay - Story - Great story - Short story - Roman - Extravaganza - Epistolary - Epic - Magic realism - Sagas - Anti-Soviet fiction - prose_sentimental - - - Contemporary Romance - Historical Romance - Detective Romance - Short Romance - Erotica - About love - Love SF - Porno - Cozy Mysteries - - - Western - History - Indians - Maritime Fiction - Travel & Geography - Nature & Animals - Misk Adventures - Kids Adventures - - - Fairy Tales - Verses for Kids - Prose for Kids - Science Fiction for Kids - Detective for Kids - Kids Adventures - Education for Kids - For Kids: Misk - Child Folklore - Game book - - - Verses for Kids - Poetry - Humor Verses - Fable - Vers libre - Visual Poetry - Lyrics - Palindromes - Song Poetry - Experimental Poetry - Epic Poetry - In verse - - - Antique Literature - Antique European Literature - Antique Russian Literature - Antique East Literature - Myths. Legends. Epos - Other Antique - - - History - Psychology - Cultural Science - Religious Studies - Philosophy - Politics - Business - Jurisprudence - Linguistics - Medicine - Physics - Mathematics - Chemistry - Biology - Technical - Misk Science, Education - Biochemistry - Physical chemistry - Analitic Chemistry - Organic Chemistry - Economy - State science - Biophysics - Geology - Cosmos - Alternative medicine - Philology - Pedagogy - Social studies - Ecology - Military History - Veterinary - Zoology - Botany - Textbook - Cribs - Abstract - Foreign languages - psy_childs - psy_theraphy - Sex and family - - - Internet - Programming - Hardware - Software - Databases - OS & Networking - Computers: Misk - DSP - - - Encyclopedias - Dictionaries - Reference - Guidebooks - Misk References - Art, Design - Guides - - - Religion - Esoterics - Self-perfection - Religion: Other - Buddha - Christianity - Orthodoxy - Catholicism - Protestantism - Hinduism - Islam - Judaism - Astrology - Palmistry - Paganism - - - Humor SF - Anecdote - Humor Prose - Humor Verses - Misk Humor - Comedy - Satire - - - Cooking - Pets - Hobbies & Crafts - Entertaining - Health - Garden - Do it yourself - Sports - Erotica, Sex - Home: Other - Collecting - - - Technical - Transport - Metallurgy - Radio - Building - Auto regulations - Architecture - - - Other - Notes - Periodic - Music - Cine - Theatre - Fan fiction - Unfinished - Visual Arts - - - Banking - Accounting - Global Economy - Paper Work - Corporate Culture - Personal Finance - Small Business - Marketing, PR, Adv - Real Estate - Popular Business - Industries - Job Hunting - Young-adult fiction - Management - Stock - Economics - Trade - - - Travel & Geography - Nature & Animals - Biography & Memoirs - Publicism - Criticism - Misk Nonfiction - Military docs - Science popular - - - Dramaturgy - Drama - Screenplays - Comedy - Mystery - Scenarios - Tragedy - Vaudeville - - - Anecdote - Epic - Child Folklore - Riddles - Folk Songs - Folk tales - Proverbs - Folklore - Limerick - - - Military - Military docs - Military History - Weapon - Military Arts - Military special - Military - - diff --git a/releases/1.1/translation.xml b/releases/1.1/translation.xml deleted file mode 100644 index 263a9c5..0000000 --- a/releases/1.1/translation.xml +++ /dev/null @@ -1,438 +0,0 @@ - - - - English - Русский - - - - Path to books folder: - Путь к книжному каталогу: - - - Monitor library changes - Следить за каталогом - - - Duplicates: - Дубликаты: - - - STOPPED - ОСТАНОВЛЕН - - - Status: - Статус - - - 0 books/min - 0 книг/мин - - - {0} books/min - {0} книг/мин - - - Rate: - Скорость: - - - Elapsed time: - Прошло времени: - - - Start time: - Стартовал в: - - - Books in database: - Всего книг в базе: - - - Books found: - Найдено книг: - - - Books processed: - Обработано книг: - - - Invalid books: - Ошибочных книг: - - - Skipped books: - Пропущено книг: - - - Start scanning - Начать сканирование - - - Server name: - Название сервера: - - - Port: - Порт: - - - Start server - Стартовать сервер - - - SCANNING - СКАНИРУЮ - - - FINISHED - ЗАКОНЧИЛ - - - Stop scanning - Остановить сканирование - - - Stop server - Остановить сервер - - - Path to the ePub converter: - Путь к ePub конвертору: - - - GUI and OPDS language: - Язык программы и OPDS: - - - Close or minimize to tray - Скрывать в трей - - - Start minimized - Стартовать минимизированным - - - Start with Windows - Стартовать вместе с Windows - - - Save log to file - Сохранять лог в файл - - - Use UPnP - Использовать UPnP - - - Scanner settings - Настройки сканера - - - OPDS server settings - Настройки OPDS сервера - - - Miscellaneous - Разное - - - About program - О программе - - - Authentication - Авторизация - - - Exit - Выход - - - Forward port on router - Открыть порт на роутере - - - Absolute links - Абсолютные ссылки - - - OPDS root catalog prefix: - Префикс корневого каталога OPDS: - - - Local URL: - Локальный URL: - - - External URL: - Внешний URL: - - - Click here to download latest version of ePub converter - Кликните для закачки последней версии конвертера ePub - - - TinyOPDS server - TinyOPDS сервер - - - Project home page: - Домашняя страница: - - - Project license: - Лицензия проекта: - - - Special thanks: - Отдельное спасибо: - - - Database file name: - Файл базы данных: - - - Books by authors - Книги по авторам - - - Total authors on {0}: {1} - Всего авторов на {0}: {1} - - - Books: {0} - Книг: {0} - - - Books by author - Книги автора - - - By authors - По авторам - - - {0} books by {1} authors - {0} книг от {1} авторов - - - By series - По сериям - - - {0} books by {1} series - {0} книг в {1} сериях - - - By genres - По жанрам - - - Books grouped by genres - Книги, сгруппированные по жанрам - - - Book series - Книжные серии - - - Total series on {0}: {1} - Всего серий на {0}: {1} - - - {0} books in {1} - {0} книг в {1} - - - Books in genre «{0}» - Книги в жанре «{0}» - - - Hide window - Скрыть окно - - - Show window - Показать окно - - - Minimize window - Свернуть окно - - - Restore window - Показать окно - - - Can't find UPnP router, forwarding is not available - Не могу найти UPnP роутер, форвардинг не доступен - - - Invalid port value: value must be numeric and in range from 1 to 65535 - Неверный номер порта: значение должно быть в интервале от 1 до 65535 - - - Invalid port value. Default value 8080 will be used - Неверный номер порта. Будет использован номер 8080 - - - version {0}.{1} {2} - версия {0}.{1} {2} - - - Search authors - Поиск авторов - - - Search authors by name - Поиск авторов по имени - - - Search books - Поиск книг - - - Search books by title - Поиск книг по названию - - - Translation: - Перевод: - - - Year of publication: - Год публикации: - - - Format: - Формат: - - - Size: - Размер: - - - Series: - Серия: - - - All books by author {0} - Все книги автора {0} - - - All books by series {0} - Все книги серии {0} - - - Use HTTP basic authentication - Использовать базовую авторизацию HTTP - - - Remember authorized clients - Помнить авторизованных клиентов - - - Probably, port {0} is already in use. Please try different port value. - Вероятно, порт {0} уже используется. Попробуйте другое значение. - - - Log verbosity level - Детализация лог-файла - - - Info, warnings and errors - Информация, предупреждения и ошибки - - - Warnings and errors - Предупреждения и ошибки - - - Errors only - Только ошибки - - - Total requests: - Всего запросов: - - - Books sent: - Отдано книг: - - - Images sent: - Отдано картинок: - - - Unique clients: - Уникальных клиентов: - - - Successful logins: - Успешных входов: - - - Failed logins: - Неверных входов: - - - Banned clients: - Заблокировано: - - - Ban clients after - Блокировать клиентов после - - - failed attempts - неверных попыток - - - Check for update: - Проверять обновление: - - - Never - Никогда - - - Once a week - Раз в неделю - - - Once a month - Раз в месяц - - - TinyOPDS: update found - TinyOPDS: обнаружено обновление - - - Click here to download update v {0} - Кликните для загрузки обновления v {0} - - - New version {0} is available!\nWould you like to download now? - Новая версия [OK} доступна для загрузки.\nЖелаете загрузить сейчас? - - - - - - - - - - - - - - - - - - - - \ No newline at end of file