mirror of
				https://github.com/Kareadita/Kavita.git
				synced 2025-11-03 19:17:05 -05:00 
			
		
		
		
	OPDS Fix (#737)
* Removed the Nothing here message when feeds are empty to conform to spec. * Don't show toast on new series added when user is reading * I forgot to add unique Ids to each feed, thus breaking Panels integration.
This commit is contained in:
		
							parent
							
								
									cbf095c3a1
								
							
						
					
					
						commit
						69246d80fb
					
				@ -17,6 +17,7 @@ using API.Interfaces.Services;
 | 
				
			|||||||
using API.Services;
 | 
					using API.Services;
 | 
				
			||||||
using Kavita.Common;
 | 
					using Kavita.Common;
 | 
				
			||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
 | 
					using Microsoft.Extensions.Logging;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace API.Controllers
 | 
					namespace API.Controllers
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -48,7 +49,6 @@ namespace API.Controllers
 | 
				
			|||||||
            _cacheService = cacheService;
 | 
					            _cacheService = cacheService;
 | 
				
			||||||
            _readerService = readerService;
 | 
					            _readerService = readerService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
            _xmlSerializer = new XmlSerializer(typeof(Feed));
 | 
					            _xmlSerializer = new XmlSerializer(typeof(Feed));
 | 
				
			||||||
            _xmlOpenSearchSerializer = new XmlSerializer(typeof(OpenSearchDescription));
 | 
					            _xmlOpenSearchSerializer = new XmlSerializer(typeof(OpenSearchDescription));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -62,7 +62,7 @@ namespace API.Controllers
 | 
				
			|||||||
            if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds)
 | 
					            if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds)
 | 
				
			||||||
                return BadRequest("OPDS is not enabled on this server");
 | 
					                return BadRequest("OPDS is not enabled on this server");
 | 
				
			||||||
            var feed = CreateFeed("Kavita", string.Empty, apiKey);
 | 
					            var feed = CreateFeed("Kavita", string.Empty, apiKey);
 | 
				
			||||||
            feed.Id = "root";
 | 
					            SetFeedId(feed, "root");
 | 
				
			||||||
            feed.Entries.Add(new FeedEntry()
 | 
					            feed.Entries.Add(new FeedEntry()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Id = "inProgress",
 | 
					                Id = "inProgress",
 | 
				
			||||||
@ -140,9 +140,8 @@ namespace API.Controllers
 | 
				
			|||||||
                return BadRequest("OPDS is not enabled on this server");
 | 
					                return BadRequest("OPDS is not enabled on this server");
 | 
				
			||||||
            var userId = await GetUser(apiKey);
 | 
					            var userId = await GetUser(apiKey);
 | 
				
			||||||
            var libraries = await _unitOfWork.LibraryRepository.GetLibrariesForUserIdAsync(userId);
 | 
					            var libraries = await _unitOfWork.LibraryRepository.GetLibrariesForUserIdAsync(userId);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            var feed = CreateFeed("All Libraries", $"{apiKey}/libraries", apiKey);
 | 
					            var feed = CreateFeed("All Libraries", $"{apiKey}/libraries", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, "libraries");
 | 
				
			||||||
            foreach (var library in libraries)
 | 
					            foreach (var library in libraries)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                feed.Entries.Add(new FeedEntry()
 | 
					                feed.Entries.Add(new FeedEntry()
 | 
				
			||||||
@ -181,7 +180,7 @@ namespace API.Controllers
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var feed = CreateFeed("All Collections", $"{apiKey}/collections", apiKey);
 | 
					            var feed = CreateFeed("All Collections", $"{apiKey}/collections", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, "collections");
 | 
				
			||||||
            foreach (var tag in tags)
 | 
					            foreach (var tag in tags)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                feed.Entries.Add(new FeedEntry()
 | 
					                feed.Entries.Add(new FeedEntry()
 | 
				
			||||||
@ -198,15 +197,6 @@ namespace API.Controllers
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (tags.Count == 0)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                feed.Entries.Add(new FeedEntry()
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Id = "0",
 | 
					 | 
				
			||||||
                    Title = "Nothing here",
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return CreateXmlResult(SerializeXml(feed));
 | 
					            return CreateXmlResult(SerializeXml(feed));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -244,6 +234,7 @@ namespace API.Controllers
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var feed = CreateFeed(tag.Title + " Collection", $"{apiKey}/collections/{collectionId}", apiKey);
 | 
					            var feed = CreateFeed(tag.Title + " Collection", $"{apiKey}/collections/{collectionId}", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, $"collections-{collectionId}");
 | 
				
			||||||
            AddPagination(feed, series, $"{Prefix}{apiKey}/collections/{collectionId}");
 | 
					            AddPagination(feed, series, $"{Prefix}{apiKey}/collections/{collectionId}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var seriesDto in series)
 | 
					            foreach (var seriesDto in series)
 | 
				
			||||||
@ -270,7 +261,7 @@ namespace API.Controllers
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var feed = CreateFeed("All Reading Lists", $"{apiKey}/reading-list", apiKey);
 | 
					            var feed = CreateFeed("All Reading Lists", $"{apiKey}/reading-list", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, "reading-list");
 | 
				
			||||||
            foreach (var readingListDto in readingLists)
 | 
					            foreach (var readingListDto in readingLists)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                feed.Entries.Add(new FeedEntry()
 | 
					                feed.Entries.Add(new FeedEntry()
 | 
				
			||||||
@ -305,6 +296,7 @@ namespace API.Controllers
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var feed = CreateFeed(readingList.Title + " Reading List", $"{apiKey}/reading-list/{readingListId}", apiKey);
 | 
					            var feed = CreateFeed(readingList.Title + " Reading List", $"{apiKey}/reading-list/{readingListId}", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, $"reading-list-{readingListId}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var items = (await _unitOfWork.ReadingListRepository.GetReadingListItemDtosByIdAsync(readingListId, userId)).ToList();
 | 
					            var items = (await _unitOfWork.ReadingListRepository.GetReadingListItemDtosByIdAsync(readingListId, userId)).ToList();
 | 
				
			||||||
            foreach (var item in items)
 | 
					            foreach (var item in items)
 | 
				
			||||||
@ -321,17 +313,6 @@ namespace API.Controllers
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (items.Count == 0)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                feed.Entries.Add(new FeedEntry()
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Id = "0",
 | 
					 | 
				
			||||||
                    Title = "Nothing here",
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return CreateXmlResult(SerializeXml(feed));
 | 
					            return CreateXmlResult(SerializeXml(feed));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -357,6 +338,7 @@ namespace API.Controllers
 | 
				
			|||||||
            }, _filterDto);
 | 
					            }, _filterDto);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var feed = CreateFeed(library.Name, $"{apiKey}/libraries/{libraryId}", apiKey);
 | 
					            var feed = CreateFeed(library.Name, $"{apiKey}/libraries/{libraryId}", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, $"library-{library.Name}");
 | 
				
			||||||
            AddPagination(feed, series, $"{Prefix}{apiKey}/libraries/{libraryId}");
 | 
					            AddPagination(feed, series, $"{Prefix}{apiKey}/libraries/{libraryId}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var seriesDto in series)
 | 
					            foreach (var seriesDto in series)
 | 
				
			||||||
@ -381,6 +363,7 @@ namespace API.Controllers
 | 
				
			|||||||
            }, _filterDto);
 | 
					            }, _filterDto);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var feed = CreateFeed("Recently Added", $"{apiKey}/recently-added", apiKey);
 | 
					            var feed = CreateFeed("Recently Added", $"{apiKey}/recently-added", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, "recently-added");
 | 
				
			||||||
            AddPagination(feed, recentlyAdded, $"{Prefix}{apiKey}/recently-added");
 | 
					            AddPagination(feed, recentlyAdded, $"{Prefix}{apiKey}/recently-added");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var seriesDto in recentlyAdded)
 | 
					            foreach (var seriesDto in recentlyAdded)
 | 
				
			||||||
@ -388,16 +371,6 @@ namespace API.Controllers
 | 
				
			|||||||
                feed.Entries.Add(CreateSeries(seriesDto, apiKey));
 | 
					                feed.Entries.Add(CreateSeries(seriesDto, apiKey));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (recentlyAdded.Count == 0)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                feed.Entries.Add(new FeedEntry()
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Id = "0",
 | 
					 | 
				
			||||||
                    Title = "Nothing here",
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return CreateXmlResult(SerializeXml(feed));
 | 
					            return CreateXmlResult(SerializeXml(feed));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -421,6 +394,7 @@ namespace API.Controllers
 | 
				
			|||||||
            Response.AddPaginationHeader(pagedList.CurrentPage, pagedList.PageSize, pagedList.TotalCount, pagedList.TotalPages);
 | 
					            Response.AddPaginationHeader(pagedList.CurrentPage, pagedList.PageSize, pagedList.TotalCount, pagedList.TotalPages);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var feed = CreateFeed("In Progress", $"{apiKey}/in-progress", apiKey);
 | 
					            var feed = CreateFeed("In Progress", $"{apiKey}/in-progress", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, "in-progress");
 | 
				
			||||||
            AddPagination(feed, pagedList, $"{Prefix}{apiKey}/in-progress");
 | 
					            AddPagination(feed, pagedList, $"{Prefix}{apiKey}/in-progress");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var seriesDto in pagedList)
 | 
					            foreach (var seriesDto in pagedList)
 | 
				
			||||||
@ -428,15 +402,6 @@ namespace API.Controllers
 | 
				
			|||||||
                feed.Entries.Add(CreateSeries(seriesDto, apiKey));
 | 
					                feed.Entries.Add(CreateSeries(seriesDto, apiKey));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (pagedList.Count == 0)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                feed.Entries.Add(new FeedEntry()
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Id = "0",
 | 
					 | 
				
			||||||
                    Title = "Nothing here",
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return CreateXmlResult(SerializeXml(feed));
 | 
					            return CreateXmlResult(SerializeXml(feed));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -460,7 +425,7 @@ namespace API.Controllers
 | 
				
			|||||||
            var series = await _unitOfWork.SeriesRepository.SearchSeries(libraries.Select(l => l.Id).ToArray(), query);
 | 
					            var series = await _unitOfWork.SeriesRepository.SearchSeries(libraries.Select(l => l.Id).ToArray(), query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var feed = CreateFeed(query, $"{apiKey}/series?query=" + query, apiKey);
 | 
					            var feed = CreateFeed(query, $"{apiKey}/series?query=" + query, apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, "search-series");
 | 
				
			||||||
            foreach (var seriesDto in series)
 | 
					            foreach (var seriesDto in series)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                feed.Entries.Add(CreateSeries(seriesDto, apiKey));
 | 
					                feed.Entries.Add(CreateSeries(seriesDto, apiKey));
 | 
				
			||||||
@ -469,6 +434,11 @@ namespace API.Controllers
 | 
				
			|||||||
            return CreateXmlResult(SerializeXml(feed));
 | 
					            return CreateXmlResult(SerializeXml(feed));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static void SetFeedId(Feed feed, string id)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            feed.Id = id;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [HttpGet("{apiKey}/search")]
 | 
					        [HttpGet("{apiKey}/search")]
 | 
				
			||||||
        [Produces("application/xml")]
 | 
					        [Produces("application/xml")]
 | 
				
			||||||
        public async Task<IActionResult> GetSearchDescriptor(string apiKey)
 | 
					        public async Task<IActionResult> GetSearchDescriptor(string apiKey)
 | 
				
			||||||
@ -502,6 +472,7 @@ namespace API.Controllers
 | 
				
			|||||||
            var series = await _unitOfWork.SeriesRepository.GetSeriesDtoByIdAsync(seriesId, userId);
 | 
					            var series = await _unitOfWork.SeriesRepository.GetSeriesDtoByIdAsync(seriesId, userId);
 | 
				
			||||||
            var volumes = await _unitOfWork.VolumeRepository.GetVolumesDtoAsync(seriesId, userId);
 | 
					            var volumes = await _unitOfWork.VolumeRepository.GetVolumesDtoAsync(seriesId, userId);
 | 
				
			||||||
            var feed = CreateFeed(series.Name + " - Volumes", $"{apiKey}/series/{series.Id}", apiKey);
 | 
					            var feed = CreateFeed(series.Name + " - Volumes", $"{apiKey}/series/{series.Id}", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, $"series-{series.Id}");
 | 
				
			||||||
            feed.Links.Add(CreateLink(FeedLinkRelation.Image, FeedLinkType.Image, $"/api/image/series-cover?seriesId={seriesId}"));
 | 
					            feed.Links.Add(CreateLink(FeedLinkRelation.Image, FeedLinkType.Image, $"/api/image/series-cover?seriesId={seriesId}"));
 | 
				
			||||||
            foreach (var volumeDto in volumes)
 | 
					            foreach (var volumeDto in volumes)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@ -525,6 +496,7 @@ namespace API.Controllers
 | 
				
			|||||||
                    _chapterSortComparer);
 | 
					                    _chapterSortComparer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var feed = CreateFeed(series.Name + " - Volume " + volume.Name + " - Chapters ", $"{apiKey}/series/{seriesId}/volume/{volumeId}", apiKey);
 | 
					            var feed = CreateFeed(series.Name + " - Volume " + volume.Name + " - Chapters ", $"{apiKey}/series/{seriesId}/volume/{volumeId}", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, $"series-{series.Id}-volume-{volume.Id}-chapters");
 | 
				
			||||||
            foreach (var chapter in chapters)
 | 
					            foreach (var chapter in chapters)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                feed.Entries.Add(new FeedEntry()
 | 
					                feed.Entries.Add(new FeedEntry()
 | 
				
			||||||
@ -555,6 +527,7 @@ namespace API.Controllers
 | 
				
			|||||||
            var files = await _unitOfWork.ChapterRepository.GetFilesForChapterAsync(chapterId);
 | 
					            var files = await _unitOfWork.ChapterRepository.GetFilesForChapterAsync(chapterId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var feed = CreateFeed(series.Name + " - Volume " + volume.Name + " - Chapters ", $"{apiKey}/series/{seriesId}/volume/{volumeId}/chapter/{chapterId}", apiKey);
 | 
					            var feed = CreateFeed(series.Name + " - Volume " + volume.Name + " - Chapters ", $"{apiKey}/series/{seriesId}/volume/{volumeId}/chapter/{chapterId}", apiKey);
 | 
				
			||||||
 | 
					            SetFeedId(feed, $"series-{series.Id}-volume-{volume.Id}-chapter-{chapter.Id}-files");
 | 
				
			||||||
            foreach (var mangaFile in files)
 | 
					            foreach (var mangaFile in files)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                feed.Entries.Add(CreateChapter(seriesId, volumeId, chapterId, mangaFile, series, volume, chapter, apiKey));
 | 
					                feed.Entries.Add(CreateChapter(seriesId, volumeId, chapterId, mangaFile, series, volume, chapter, apiKey));
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
import { EventEmitter, Injectable } from '@angular/core';
 | 
					import { EventEmitter, Injectable } from '@angular/core';
 | 
				
			||||||
 | 
					import { Router } from '@angular/router';
 | 
				
			||||||
import { HubConnection, HubConnectionBuilder } from '@microsoft/signalr';
 | 
					import { HubConnection, HubConnectionBuilder } from '@microsoft/signalr';
 | 
				
			||||||
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 | 
					import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 | 
				
			||||||
import { ToastrService } from 'ngx-toastr';
 | 
					import { ToastrService } from 'ngx-toastr';
 | 
				
			||||||
@ -49,7 +50,7 @@ export class MessageHubService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  isAdmin: boolean = false;
 | 
					  isAdmin: boolean = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(private modalService: NgbModal, private toastr: ToastrService) {
 | 
					  constructor(private modalService: NgbModal, private toastr: ToastrService, private router: Router) {
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -111,7 +112,8 @@ export class MessageHubService {
 | 
				
			|||||||
        payload: resp.body
 | 
					        payload: resp.body
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      this.seriesAdded.emit(resp.body);
 | 
					      this.seriesAdded.emit(resp.body);
 | 
				
			||||||
      if (this.isAdmin) {
 | 
					      // Don't show the toast when user has reader open
 | 
				
			||||||
 | 
					      if (this.isAdmin && this.router.url.match(/\d+\/manga|book\/\d+/gi) !== null) {
 | 
				
			||||||
        this.toastr.info('Series ' + (resp.body as SeriesAddedEvent).seriesName + ' added');
 | 
					        this.toastr.info('Series ' + (resp.body as SeriesAddedEvent).seriesName + ' added');
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user