mirror of
https://github.com/MarginaliaSearch/MarginaliaSearch.git
synced 2025-02-23 13:09:00 +00:00
(search) Add experimental OPML-export function for feed subscriptions
This commit is contained in:
parent
ab5c30ad51
commit
84f55b84ff
@ -1,6 +1,7 @@
|
||||
package nu.marginalia.search;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.jooby.Jooby;
|
||||
import io.prometheus.client.Counter;
|
||||
import io.prometheus.client.Histogram;
|
||||
import nu.marginalia.WebsiteUrl;
|
||||
@ -18,6 +19,7 @@ public class SearchService extends JoobyService {
|
||||
|
||||
private final WebsiteUrl websiteUrl;
|
||||
private final StaticResources staticResources;
|
||||
private final SearchSiteSubscriptionService siteSubscriptionService;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SearchService.class);
|
||||
private static final Histogram wmsa_search_service_request_time = Histogram.build()
|
||||
@ -38,6 +40,7 @@ public class SearchService extends JoobyService {
|
||||
StaticResources staticResources,
|
||||
SearchFrontPageService frontPageService,
|
||||
SearchAddToCrawlQueueService addToCrawlQueueService,
|
||||
SearchSiteSubscriptionService siteSubscriptionService,
|
||||
SearchSiteInfoService siteInfoService,
|
||||
SearchCrosstalkService crosstalkService,
|
||||
SearchBrowseService searchBrowseService,
|
||||
@ -57,6 +60,14 @@ public class SearchService extends JoobyService {
|
||||
this.websiteUrl = websiteUrl;
|
||||
this.staticResources = staticResources;
|
||||
|
||||
this.siteSubscriptionService = siteSubscriptionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startJooby(Jooby jooby) {
|
||||
super.startJooby(jooby);
|
||||
|
||||
jooby.get("/export-opml", siteSubscriptionService::exportOpml);
|
||||
}
|
||||
//
|
||||
// SearchServiceMetrics.get("/search", searchQueryService::pathSearch);
|
||||
|
@ -4,6 +4,8 @@ import com.google.inject.Inject;
|
||||
import io.jooby.Context;
|
||||
import io.jooby.Cookie;
|
||||
import io.jooby.Value;
|
||||
import nu.marginalia.api.feeds.FeedsClient;
|
||||
import nu.marginalia.api.feeds.RpcFeed;
|
||||
import nu.marginalia.db.DbDomainQueries;
|
||||
import nu.marginalia.model.EdgeDomain;
|
||||
import org.slf4j.Logger;
|
||||
@ -12,19 +14,25 @@ import org.slf4j.LoggerFactory;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Base64;
|
||||
import java.util.HashSet;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class SearchSiteSubscriptionService {
|
||||
private final DbDomainQueries dbDomainQueries;
|
||||
private final FeedsClient feedsClient;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SearchSiteSubscriptionService.class);
|
||||
|
||||
@Inject
|
||||
public SearchSiteSubscriptionService(DbDomainQueries dbDomainQueries) {
|
||||
public SearchSiteSubscriptionService(DbDomainQueries dbDomainQueries, FeedsClient feedsClient) {
|
||||
this.dbDomainQueries = dbDomainQueries;
|
||||
this.feedsClient = feedsClient;
|
||||
}
|
||||
|
||||
public HashSet<Integer> getSubscriptions(Context context) {
|
||||
@ -90,4 +98,32 @@ public class SearchSiteSubscriptionService {
|
||||
|
||||
putSubscriptions(context, subscriptions);
|
||||
}
|
||||
|
||||
public Object exportOpml(Context ctx) throws ExecutionException, InterruptedException {
|
||||
ctx.setResponseType("text/xml.opml");
|
||||
ctx.setResponseHeader("Content-Disposition", "attachment; filename=feeds.opml");
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
|
||||
sb.append("<opml version=\"2.0\">\n");
|
||||
sb.append("<!-- This is an OPM file that can be imported into many feed readers. See https://opml.org/ for spec. -->\n");
|
||||
sb.append("<head>\n");
|
||||
sb.append("<title>Marginalia Subscriptions</title>\n");
|
||||
sb.append("<dateCreated>").append(LocalDateTime.now().atOffset(ZoneOffset.UTC).format(DateTimeFormatter.RFC_1123_DATE_TIME)).append("</dateCreated>\n");
|
||||
sb.append("</head>\n");
|
||||
|
||||
sb.append("<body>\n");
|
||||
for (int domainId : getSubscriptions(ctx)) {
|
||||
RpcFeed feed = feedsClient.getFeed(domainId).get();
|
||||
sb.append("<outline title=\"")
|
||||
.append(feed.getDomain())
|
||||
.append("\" htmlUrl=\"")
|
||||
.append(new EdgeDomain(feed.getDomain()).toRootUrlHttps().toString())
|
||||
.append("\" xmlUrl=\"").append(feed.getFeedUrl()).append("\"/>\n");
|
||||
}
|
||||
sb.append("</body>\n");
|
||||
sb.append("</opml>");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,14 @@
|
||||
</div>
|
||||
@else
|
||||
<div class="max-w-7xl mx-auto flex flex-col space-y-4 fill-w m-4">
|
||||
<div class="my-4 text-black dark:text-white font-serif text-xl mx-8">Subscriptions</div>
|
||||
<div class="my-4 text-black dark:text-white font-serif text-xl mx-8 place-items-baseline flex">
|
||||
Subscriptions
|
||||
<div class="grow"></div>
|
||||
<a class="text-sm font-sans" href="/export-opml">
|
||||
<i class="fas fa-download mr-2"></i>
|
||||
Export as OPML
|
||||
</a>
|
||||
</div>
|
||||
@for (NewsItemCluster cluster : model.news())
|
||||
!{NewsItem item = cluster.first();}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user