/// <summary> /// 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 /// </summary> /// <param name="subjects"></param> /// <returns></returns> private List <string> LookupGenres(List <string> subjects) { List <string> genres = new List <string>(); if (subjects == null || subjects.Count < 1) { genres.Add("prose"); } else { foreach (string subj in subjects) { var genre = LibraryFactory.GetLibrary().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); }
private Model.Statements TranslateLibrary(SQLTranslationContext context, String localName, Library library) { var result = new Model.Statements(); if (!translatedLibraries.ContainsKey(library.Name)) { context.StartArtifact(localName); try { // Libraries foreach (LibraryRef libraryRef in library.Libraries) { TranslateLibrary(context, libraryRef.Name, LibraryFactory.ResolveLibrary(libraryRef, null)); } // TODO: CodeSystems // TODO: ValueSets // TODO: Parameters // ExpressionDefs foreach (ExpressionDef expressionDef in library.Expressions) { result.Add(TranslateExpressionDef(context, localName, expressionDef)); } // TODO: Functions } finally { context.EndArtifact(); } } return(result); }
public Watcher(string path = "") { DirectoryToWatch = path; _booksManager = new BackgroundWorker(); _booksManager.DoWork += _booksManager_DoWork; _scanner = new FileScanner(false); _scanner.OnBookFound += (object s, BookFoundEventArgs be) => { if (LibraryFactory.GetLibrary().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 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 <Genre> libGenres = LibraryFactory.GetLibrary().Genres; List <Genre> genres = null; // Is it top level (main genres)? if (string.IsNullOrEmpty(searchPattern)) { genres = (from g in LibraryFactory.GetLibrary().FB2Genres from sg in g.Subgenres where libGenres.Contains(sg) select g).Distinct().ToList(); } // Is it a second level (subgenres)? else { Genre genre = LibraryFactory.GetLibrary().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); }
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 (LibraryFactory.GetLibrary().IsChanged) { LibraryFactory.GetLibrary().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 libraryPath_Validated(object sender, EventArgs e) { if (!string.IsNullOrEmpty(Properties.Settings.Default.LibraryPath) && !LibraryFactory.GetLibrary().LibraryPath.Equals(Properties.Settings.Default.LibraryPath) && Directory.Exists(Properties.Settings.Default.LibraryPath)) { if (LibraryFactory.GetLibrary().IsChanged) { LibraryFactory.GetLibrary().Save(); } LibraryFactory.GetLibrary().LibraryPath = Properties.Settings.Default.LibraryPath; booksInDB.Text = string.Format("{0} fb2: {1} epub: {2}", 0, 0, 0); if (Settings.Default.LibraryKind == 0) { databaseFileName.Text = Utils.CreateGuid(Utils.IsoOidNamespace, Properties.Settings.Default.LibraryPath).ToString() + ".db"; } _watcher.IsEnabled = false; // Reload library LibraryFactory.GetLibrary().LoadAsync(); } else { libraryPath.Undo(); } }
public void DeleteItem(int id) { LibraryFactory item = libItems.FindAll(x => x.GetId() == id)[0]; libItems.RemoveAll(x => x.GetId() == id); database.Remove(item); }
/// <summary> /// Book manager thread /// </summary> /// <param name="sender"></param> /// <param name="e"></param> 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 (LibraryFactory.GetLibrary().Delete(fileName)) { if (OnBookDeleted != null) { OnBookDeleted(this, new BookDeletedEventArgs(fileName)); } } _deletedBooks.Remove(fileName); } // Get some rest for UI else { Thread.Sleep(100); } } }
public LibraryFactory GetEntryData() { LibraryFactory movie = LibraryFactory.GetLibrary(LibraryType.Movie, id, info.GetMovieGenre()); ((Movie)movie).SetEntry(new Entry { Description = info.GetMovieDescription(), Name = info.GetMovieName(), Release = info.GetMovieReleaseDate(), Poster = info.GetMoviePoster(), Cast = info.GetMovieCast(), Rating = info.GetMovieRating() }); return(movie); }
public LibraryFactory GetEntryData() { List <LibraryFactory> data = new List <LibraryFactory>(); LibraryFactory series = LibraryFactory.GetLibrary(LibraryType.Series, id, info.GetTVGenre()); ((Series)series).Name = info.GetTVName(); ((Series)series).Description = info.GetTVDescription(); ((Series)series).Rating = info.GetTVRating(); ((Series)series).ReleaseDate = info.GetTVReleaseDate(); ((Series)series).Poster = info.GetTVPoster(); foreach (Season s in info.getTVSeasons()) { ((Series)series).AddSeason(s); } return(series); }
protected void OnAddLibrary(Object sender, EventArgs e) { ((PageBase)Page).CheckRight(NSurveyRights.ManageLibrary, true); if (txtLibName.Text.Length == 0) { ((PageBase)Page).ShowErrorMessage(MessageLabel, ((PageBase)Page).GetPageResource("MissingLibraryNameMessage")); MessageLabel.Visible = true; return; } LibraryData libraryData = new LibraryData(); LibraryData.LibrariesRow library = libraryData.Libraries.NewLibrariesRow(); library.LibraryId = _libraryId; library.LibraryName = txtLibName.Text; library.Description = txtLibDescr.Text; // library.DefaultLanguageCode = ddlDefaultLang.SelectedValue; // new MultiLanguage().UpdateSurveyLanguage(LibraryId, ddlDefaultLang.SelectedValue, true, Constants.Constants.EntityLibrary); libraryData.Libraries.Rows.Add(library); if (LibraryEditMode) { LibraryFactory.Create().UpdateLibrary(libraryData); var ml = new MultiLanguage(); // Reset all other default items foreach (ListItem item in this.ddlDefaultLang.Items) { new MultiLanguage().UpdateSurveyLanguage(LibraryId, item.Value, item.Selected, Constants.Constants.EntityLibrary); } } else { LibraryFactory.Create().AddLibrary(libraryData); new MultiLanguage().UpdateSurveyLanguage(libraryData.Libraries[0].LibraryId, System.Globalization.CultureInfo.CurrentCulture.Name, true, Constants.Constants.EntityLibrary); txtLibName.Text = string.Empty; txtLibDescr.Text = string.Empty; } ((PageBase)Page).ShowNormalMessage(MessageLabel, ((PageBase)Page).GetPageResource("UpdatedLibraryNameMessage")); MessageLabel.Visible = true; UINavigator.NavigateToLibraryDirectory(0, 0, 0); FillData(); }
private void internalUpdateInfo(bool IsScanFinished) { booksInDB.Text = string.Format("{0} fb2: {1} epub: {2}", LibraryFactory.GetLibrary().Count, LibraryFactory.GetLibrary().FB2Count, LibraryFactory.GetLibrary().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"); } }
void scanner_OnBookFound(object sender, BookFoundEventArgs e) { if (LibraryFactory.GetLibrary().Add(e.Book)) { if (e.Book.BookType == BookType.FB2) { _fb2Count++; } else { _epubCount++; } } else { _duplicates++; } if (LibraryFactory.GetLibrary().Count % 500 == 0) { LibraryFactory.GetLibrary().Save(); } UpdateInfo(); }
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 += (_, __) => { LibraryFactory.GetLibrary().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(); LibraryFactory.GetLibrary().Save(); UpdateInfo(true); scannerButton.Text = Localizer.Text("Start scanning"); Log.WriteLine("Directory scanner stopped"); } }
public IActionResult Fb2zip(string fname1, string fname2) { string fname = fname1 + "/" + fname2; if (fname2.Contains(".fb2.zip")) { MemoryStream memStream = null; memStream = new MemoryStream(); Book book = LibraryFactory.GetLibrary().GetBook(fname); if (book.FilePath.ToLower().Contains(".zip@")) { string[] pathParts = book.FilePath.Split('@'); using ZipArchive zipArchive = ZipFile.OpenRead(pathParts[0]); var entry = zipArchive.Entries.First(e => e.Name.Contains(pathParts[1])); if (entry != null) { entry.Open().CopyTo(memStream); } } else { using (FileStream stream = new FileStream(book.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) stream.CopyTo(memStream); } memStream.Position = 0; var outputStream = new MemoryStream(); var filename = Transliteration.Front($"{book.Authors.First()}_{book.Title}.fb2"); using (ZipArchive zipArchive = new ZipArchive(outputStream, ZipArchiveMode.Create, true)) { var entry = zipArchive.CreateEntry(filename); using (var z = entry.Open()) { memStream.WriteTo(z); } } outputStream.Seek(0, SeekOrigin.Begin); return(File(outputStream, "application/fb2+zip", filename + ".zip")); } //else if (fname.Contains(".jpeg")) //{ // bool getCover = true; // string bookID = string.Empty; // var request = Request.Path.Value; // 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 = LibraryFactory.GetLibrary().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) // { // return File(getCover ? image.CoverImageStream : image.ThumbnailImageStream, "image/jpeg"); // } // } // return NoContent(); // } // return NoContent(); //} //else if (fname.Contains(".ico")) //{ // var request = Request.Path.Value; // string icon = Path.GetFileName(request); // //Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("TinyOPDSCore.Icons." + icon); // Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("TinyOPDS"); // if (stream != null && stream.Length > 0) // { // return File(stream, "image/x-icon"); // } // return NoContent(); //} else { return(NoContent()); } }
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 sequence names starting with searchPattern List <string> Sequences = (from s in LibraryFactory.GetLibrary().Sequences where s.StartsWith(searchPattern) && s.Length > searchPattern.Length + 1 select s).ToList(); if (Sequences.Count > threshold) { Dictionary <string, int> 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 <string, int> 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 <string> sequences = (from s in Sequences where s.StartsWith(searchPattern) select s).ToList(); // Add catalog entries foreach (string sequence in sequences) { var seriesCount = LibraryFactory.GetLibrary().GetBooksBySequenceCount(sequence); 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); }
/// <summary> /// Scan zip file /// </summary> 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 (LibraryFactory.GetLibrary().Contains(ZipFileName.Substring(LibraryFactory.GetLibrary().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; } } }
/// <summary> /// POST requests handler /// </summary> /// <param name="p"></param> 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) || !new string[] { ".ico", ".jpeg", ".epub", ".zip", ".xml" }.Contains(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 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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 = LibraryFactory.GetLibrary().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 = LibraryFactory.GetLibrary().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 = LibraryFactory.GetLibrary().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(); } }
/// <summary> /// Return a library object that reflects the database library /// </summary> /// <param name="answerTypeId">Id of the library you need</param> /// <returns>An Library data object with the current database values</returns> public LibraryData GetLibraryById(int libraryId) { return(LibraryFactory.Create().GetLibraryById(libraryId)); }
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; } LibraryFactory.GetLibrary().LibraryPath = Properties.Settings.Default.LibraryPath; LibraryFactory.GetLibrary().LibraryLoaded += MainForm_LibraryLoaded; // Create file watcher _watcher = new Watcher(LibraryFactory.GetLibrary().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; if (Settings.Default.LibraryKind == 1) { MainForm_LibraryLoaded(null, null); useWatcher.Enabled = false; scannerButton.Enabled = 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; }
public string GetEpisodePosterName(LibraryFactory item, int season, int episode) { string file = item.GetCardInfo()[0] + "-_-S" + season.ToString() + "-_-E" + episode.ToString(); return(GetPosterName(file)); }
public void OnDeleteLibrary(Object sender, EventArgs e) { ((PageBase)Page).CheckRight(NSurveyRights.ManageLibrary, true); LibraryFactory.Create().DeleteLibrary(_libraryId); UINavigator.NavigateToLibraryDirectory(((PageBase)Page).getSurveyId(), ((PageBase)Page).MenuIndex, 0); }
/// <summary> /// /// </summary> /// <param name="fileName"></param> public void ScanFile(string fullName) { Book book = null; string ext = Path.GetExtension(fullName).ToLower(); // Process accepted files try { if (LibraryFactory.GetLibrary().Contains(fullName.Substring(LibraryFactory.GetLibrary().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)); } } }
/// <summary> /// /// </summary> /// <param name="searchPattern"></param> /// <param name="threshold"></param> /// <returns></returns> 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 <string> Authors = LibraryFactory.GetLibrary().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 <string> transAuthors = LibraryFactory.GetLibrary().GetAuthorsByName(translit, isOpenSearch); if (transAuthors.Count > 0) { Authors.AddRange(transAuthors); } } } if (Authors.Count > threshold) { Dictionary <string, int> 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 <string, int> 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 = LibraryFactory.GetLibrary().GetBooksByAuthorCount(author); 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); }
public void AddItem(LibraryFactory item) { database.Add(item); libItems.Add(item); }
public List <LibraryFactory> GetAll() { List <LibraryFactory> lib = new List <LibraryFactory>(); using (SQLiteConnection cnn = new SQLiteConnection(LoadConnectionString())) { cnn.Open(); SQLiteCommand commandMovie = new SQLiteCommand("SELECT * FROM Movie", cnn); SQLiteDataReader readerMovie = commandMovie.ExecuteReader(); while (readerMovie.Read()) { int entryId = readerMovie.GetInt32(0); List <Cast> casts = new List <Cast>(); SQLiteCommand commandEntryCast = new SQLiteCommand("SELECT * FROM Entry_Cast WHERE entry_id = @entryid", cnn); commandEntryCast.Parameters.AddWithValue("@entryid", entryId); SQLiteDataReader readerEntryCast = commandEntryCast.ExecuteReader(); while (readerEntryCast.Read()) { int castId = readerEntryCast.GetInt32(1); Cast cast = new Cast(); SQLiteCommand commandCast = new SQLiteCommand("SELECT * FROM Cast WHERE cast_id = @castId", cnn); commandCast.Parameters.AddWithValue("@castId", castId); SQLiteDataReader readerCast = commandCast.ExecuteReader(); while (readerCast.Read()) { cast.Firstname = readerCast.GetString(1); cast.Role = readerCast.GetString(4); } casts.Add(cast); } LibraryFactory movie = LibraryFactory.GetLibrary(LibraryType.Movie, readerMovie.GetInt32(2), readerMovie.GetString(1)); SQLiteCommand commandEntry = new SQLiteCommand("SELECT * FROM Entry WHERE entry_id = @entryid", cnn); commandEntry.Parameters.AddWithValue("@entryid", entryId); SQLiteDataReader readerEntry = commandEntry.ExecuteReader(); while (readerEntry.Read()) { Entry entry = new Entry() { Name = readerEntry.GetString(1), Description = readerEntry.GetString(2), Release = readerEntry.GetDateTime(3), Poster = readerEntry.GetString(4), Cast = casts }; ((Movie)movie).SetEntry(entry); } lib.Add(movie); } SQLiteCommand commandSeries = new SQLiteCommand("SELECT * FROM Series", cnn); SQLiteDataReader readerSeries = commandSeries.ExecuteReader(); while (readerSeries.Read()) { LibraryFactory series = LibraryFactory.GetLibrary(LibraryType.Series, readerSeries.GetInt32(0), readerSeries.GetString(3)); ((Series)series).Description = readerSeries.GetString(2); ((Series)series).Poster = readerSeries.GetString(4); ((Series)series).Name = readerSeries.GetString(1); SQLiteCommand commandSeason = new SQLiteCommand("SELECT * FROM Season WHERE series_id = @seriesid ORDER BY season_id ASC", cnn); commandSeason.Parameters.AddWithValue("@seriesid", readerSeries.GetInt32(0)); SQLiteDataReader readerSeason = commandSeason.ExecuteReader(); while (readerSeason.Read()) { Season season = new Season(readerSeason.GetString(2), readerSeason.GetString(3)); SQLiteCommand commandEntrySeason = new SQLiteCommand("SELECT * FROM Entry_Season WHERE season_id = @seasonid ORDER BY 'index' ASC", cnn); commandEntrySeason.Parameters.AddWithValue("@seasonid", readerSeason.GetInt32(0)); SQLiteDataReader readerEntrySeason = commandEntrySeason.ExecuteReader(); while (readerEntrySeason.Read()) { int entryId = readerEntrySeason.GetInt32(0); List <Cast> casts = new List <Cast>(); SQLiteCommand commandEntryCast = new SQLiteCommand("SELECT * FROM Entry_Cast WHERE entry_id = @entryid", cnn); commandEntryCast.Parameters.AddWithValue("@entryid", entryId); SQLiteDataReader readerEntryCast = commandEntryCast.ExecuteReader(); while (readerEntryCast.Read()) { int castId = readerEntryCast.GetInt32(1); Cast cast = new Cast(); SQLiteCommand commandCast = new SQLiteCommand("SELECT * FROM Cast WHERE cast_id = @castId", cnn); commandCast.Parameters.AddWithValue("@castId", castId); SQLiteDataReader readerCast = commandCast.ExecuteReader(); while (readerCast.Read()) { cast.Firstname = readerCast.GetString(1); cast.Role = readerCast.GetString(4); } casts.Add(cast); } SQLiteCommand commandEntry = new SQLiteCommand("SELECT * FROM Entry WHERE entry_id = @entryid", cnn); commandEntry.Parameters.AddWithValue("@entryid", entryId); SQLiteDataReader readerEntry = commandEntry.ExecuteReader(); while (readerEntry.Read()) { Entry entry = new Entry() { Name = readerEntry.GetString(1), Description = readerEntry.GetString(2), Release = readerEntry.GetDateTime(3), Poster = readerEntry.GetString(4), Cast = casts }; season.AddEpisode(entry); } } ((Series)series).AddSeason(season); } lib.Add(series); } } return(lib); }
public string GetSeasonPosterName(LibraryFactory item, int index) { string file = item.GetCardInfo()[0] + "-_-" + "S" + index.ToString(); return(GetPosterName(file)); }
/// <summary> /// Returns all available libraries /// </summary> public LibraryData GetLibraries() { return(LibraryFactory.Create().GetLibraries()); }
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 <string> authors = new List <string>(); List <Book> titles = new List <Book>(); if (string.IsNullOrEmpty(searchType)) { string transSearchPattern = Transliteration.Back(searchPattern, TransliterationType.GOST); authors = LibraryFactory.GetLibrary().GetAuthorsByName(searchPattern, true); if (authors.Count == 0 && !string.IsNullOrEmpty(transSearchPattern)) { authors = LibraryFactory.GetLibrary().GetAuthorsByName(transSearchPattern, true); } titles = LibraryFactory.GetLibrary().GetBooksByTitle(searchPattern); if (titles.Count == 0 && !string.IsNullOrEmpty(transSearchPattern)) { titles = LibraryFactory.GetLibrary().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); }
private void MainForm_LibraryLoaded(object sender, EventArgs e) { UpdateInfo(); _watcher.DirectoryToWatch = LibraryFactory.GetLibrary().LibraryPath; _watcher.IsEnabled = Properties.Settings.Default.WatchLibrary; }