mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
support for media thumbnail and description as a backup for missing content (#800)
This commit is contained in:
5
pom.xml
5
pom.xml
@@ -418,6 +418,11 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.rometools</groupId>
|
||||
<artifactId>rome-modules</artifactId>
|
||||
<version>${rome.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.rometools</groupId>
|
||||
<artifactId>rome-opml</artifactId>
|
||||
|
||||
@@ -1,271 +1,279 @@
|
||||
.main-content {
|
||||
margin-left: 250px;
|
||||
padding-left: 15px;
|
||||
margin-left: 250px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.full-screen .main-content {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.entryList {
|
||||
padding-top: 50px;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
/* entry list*/
|
||||
.entrylist-header {
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.entrylist-header h3 {
|
||||
margin: 0;
|
||||
line-height: 40px;
|
||||
margin: 0;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.entrylist-header a {
|
||||
color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.expanded .entry-header,.expanded .entry-body-content {
|
||||
padding-left: 25px;
|
||||
padding-right: 25px;
|
||||
.expanded .entry-header,
|
||||
.expanded .entry-body-content {
|
||||
padding-left: 25px;
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.expanded .entry-header {
|
||||
max-width: 650px;
|
||||
max-width: 650px;
|
||||
}
|
||||
|
||||
.full-screen .expanded .entry-header {
|
||||
max-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.rtl .entry-header,.rtl .entry-body-content,.rtl.entry-name {
|
||||
direction: rtl;
|
||||
.rtl .entry-header,
|
||||
.rtl .entry-body-content,
|
||||
.rtl.entry-name {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.rtl ul,.rtl ol {
|
||||
padding: 0;
|
||||
margin: 0 25px 10px 0px;
|
||||
.rtl ul,
|
||||
.rtl ol {
|
||||
padding: 0;
|
||||
margin: 0 25px 10px 0px;
|
||||
}
|
||||
|
||||
#feed-accordion .entry {
|
||||
border-bottom: 1px solid #CCCCCC;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
}
|
||||
|
||||
#feed-accordion .no-entries {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
margin-top: 80px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
margin-top: 80px;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-heading {
|
||||
background-color: #ebebeb;
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
|
||||
#feed-accordion .unread .entry-heading:hover {
|
||||
background-color: #ebebeb;
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
|
||||
#feed-accordion .unread .entry-heading {
|
||||
background-color: #fff;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
#feed-accordion .current.closed .entry-heading {
|
||||
background-color: #ffc;
|
||||
background-color: #ffc;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-heading-link {
|
||||
color: black;
|
||||
height: 32px;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
padding: 6px 0px;
|
||||
color: black;
|
||||
height: 32px;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
padding: 6px 0px;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-heading .feed-name {
|
||||
color: #555;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
position: absolute;
|
||||
width: 145px;
|
||||
text-overflow: ellipsis;
|
||||
color: #555;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
position: absolute;
|
||||
width: 145px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-heading .entry-name {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-right: 150px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-right: 150px;
|
||||
}
|
||||
|
||||
#feed-accordion .unread .entry-heading .entry-name {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-heading .shrink {
|
||||
margin-left: 150px;
|
||||
margin-left: 150px;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-heading .entry-date {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 45px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 45px;
|
||||
}
|
||||
|
||||
#feed-accordion a.entry-heading-link:hover {
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-external-link {
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
margin-top: -25px;
|
||||
color: black;
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
margin-top: -25px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-external-link:hover {
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-body .entry-title {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 130%;
|
||||
font-weight: bold;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 130%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-body .entry-subtitle {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-body-content {
|
||||
max-width: 650px;
|
||||
color: black;
|
||||
padding-bottom: 10px;
|
||||
#feed-accordion .entry-body-content {
|
||||
max-width: 650px;
|
||||
color: black;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.full-screen #feed-accordion .entry-body-content {
|
||||
max-width: 100%;
|
||||
.full-screen #feed-accordion .entry-body-content {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-enclosure {
|
||||
clear: both;
|
||||
padding-top: 10px;
|
||||
clear: both;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-media-description {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-buttons {
|
||||
clear: both;
|
||||
background-color: #fafafa;
|
||||
padding: 3px 0px;
|
||||
border-top: 1px solid #ebebeb;
|
||||
clear: both;
|
||||
background-color: #fafafa;
|
||||
padding: 3px 0px;
|
||||
border-top: 1px solid #ebebeb;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-buttons .checkbox.inline {
|
||||
padding-top: 0px;
|
||||
margin-left: 5px;
|
||||
padding-top: 0px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-buttons .keep-unread label {
|
||||
display: inline;
|
||||
font-weight: inherit;
|
||||
display: inline;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
#feed-accordion .share-buttons a {
|
||||
color: #333333;
|
||||
padding-left: 5px;
|
||||
color: #333333;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#feed-accordion .share-buttons a:hover {
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#feed-accordion .tags-panel {
|
||||
margin-left: 30px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
#feed-accordion .tags-panel .label{
|
||||
margin-left: 5px;
|
||||
#feed-accordion .tags-panel .label {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-field input {
|
||||
padding: 2px
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#feed-accordion .tag-input {
|
||||
margin: 0 0 0 5px;
|
||||
padding: 0;
|
||||
width: 200px;
|
||||
margin: 0 0 0 5px;
|
||||
padding: 0;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#feed-accordion .entry-buttons label {
|
||||
margin-bottom: 0px;
|
||||
font-size: 12px;
|
||||
margin-bottom: 0px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#feed-accordion a.mark-up-to {
|
||||
color: #333333;
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
color: #333333;
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
}
|
||||
|
||||
#feed-accordion a.mark-up-to:hover {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#feed-accordion .star {
|
||||
text-decoration: none;
|
||||
padding: 0px 5px;
|
||||
text-decoration: none;
|
||||
padding: 0px 5px;
|
||||
}
|
||||
|
||||
#feed-accordion .icon-star-yellow {
|
||||
color: gold;
|
||||
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
|
||||
color: gold;
|
||||
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
|
||||
}
|
||||
|
||||
#feed-accordion .icon-star-empty {
|
||||
color: #555;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
#feed-accordion.expanded .entry {
|
||||
margin-bottom: 40px;
|
||||
border: 1px solid #ddd;
|
||||
box-shadow: 0 0 4px #e3e5eb;
|
||||
margin-bottom: 40px;
|
||||
border: 1px solid #ddd;
|
||||
box-shadow: 0 0 4px #e3e5eb;
|
||||
}
|
||||
|
||||
#feed-accordion.expanded .current {
|
||||
border-left: 1px solid rgb(77, 144, 240);
|
||||
border-left: 1px solid rgb(77, 144, 240);
|
||||
}
|
||||
|
||||
#feed-accordion .current.entry-font-size-0 {
|
||||
font-size: 14px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#feed-accordion .current.entry-font-size-1 {
|
||||
font-size: 15px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
#feed-accordion .current.entry-font-size-2 {
|
||||
font-size: 16px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#feed-accordion .current.entry-font-size-3 {
|
||||
font-size: 17px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
#feed-accordion .current.entry-font-size-4 {
|
||||
font-size: 18px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
#feed-accordion .current.entry-font-size-5 {
|
||||
font-size: 19px;
|
||||
font-size: 19px;
|
||||
}
|
||||
|
||||
#feed-accordion .highlight-search {
|
||||
background-color: rgba(255, 255, 140, 0.5);
|
||||
color: #333;
|
||||
}
|
||||
background-color: rgba(255, 255, 140, 0.5);
|
||||
color: #333;
|
||||
}
|
||||
|
||||
@@ -101,20 +101,26 @@
|
||||
></div>
|
||||
<div
|
||||
class="entry-enclosure"
|
||||
ng-if="entry.enclosureType && (entry.enclosureUrl && entry.content && entry.content.indexOf(entry.enclosureUrl) == -1)"
|
||||
ng-if="entry.enclosureType && entry.enclosureUrl && (!entry.content || entry.content.indexOf(entry.enclosureUrl) == -1)"
|
||||
>
|
||||
<video controls ng-if="entry.enclosureType && entry.enclosureType.indexOf('video') == 0">
|
||||
<video controls ng-if="entry.enclosureType.indexOf('video') == 0">
|
||||
<source ng-src="{{entry.enclosureUrl | trustUrl}}" type="{{entry.enclosureType}}" />
|
||||
</video>
|
||||
<audio controls ng-if="entry.enclosureType && entry.enclosureType.indexOf('audio') == 0">
|
||||
<audio controls ng-if="entry.enclosureType.indexOf('audio') == 0">
|
||||
<source ng-src="{{entry.enclosureUrl | trustUrl}}" type="{{entry.enclosureType}}" />
|
||||
</audio>
|
||||
<div ng-if="entry.enclosureType && entry.enclosureType.indexOf('image') == 0">
|
||||
<div ng-if="entry.enclosureType.indexOf('image') == 0">
|
||||
<img ng-src="{{entry.enclosureUrl | trustUrl}}" />
|
||||
</div>
|
||||
<a ng-href="{{entry.enclosureUrl | trustUrl}}" target="_blank" ng-if="entry.enclosureType" download>
|
||||
{{ 'global.download' | translate }}
|
||||
</a>
|
||||
<a ng-href="{{entry.enclosureUrl | trustUrl}}" target="_blank" download> {{ 'global.download' | translate }} </a>
|
||||
</div>
|
||||
<div class="entry-media" ng-if="!entry.content && entry.mediaThumbnailUrl">
|
||||
<img
|
||||
ng-src="{{entry.mediaThumbnailUrl | trustUrl}}"
|
||||
ng-attr-width="{{entry.mediaThumbnailWidth}}"
|
||||
ng-attr-height="{{entry.mediaThumbnailHeight}}"
|
||||
/>
|
||||
<div ng-if="entry.mediaDescription" class="entry-media-description">{{entry.mediaDescription}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry-buttons form-inline">
|
||||
|
||||
@@ -10,9 +10,7 @@ import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jdom2.Element;
|
||||
import org.jdom2.Namespace;
|
||||
@@ -22,6 +20,13 @@ import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
import com.commafeed.backend.model.FeedEntryContent;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.rometools.modules.mediarss.MediaEntryModule;
|
||||
import com.rometools.modules.mediarss.MediaModule;
|
||||
import com.rometools.modules.mediarss.types.MediaGroup;
|
||||
import com.rometools.modules.mediarss.types.Metadata;
|
||||
import com.rometools.modules.mediarss.types.Thumbnail;
|
||||
import com.rometools.rome.feed.synd.SyndCategory;
|
||||
import com.rometools.rome.feed.synd.SyndContent;
|
||||
import com.rometools.rome.feed.synd.SyndEnclosure;
|
||||
import com.rometools.rome.feed.synd.SyndEntry;
|
||||
import com.rometools.rome.feed.synd.SyndFeed;
|
||||
@@ -30,6 +35,10 @@ import com.rometools.rome.feed.synd.SyndLinkImpl;
|
||||
import com.rometools.rome.io.FeedException;
|
||||
import com.rometools.rome.io.SyndFeedInput;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
@@ -86,15 +95,28 @@ public class FeedParser {
|
||||
|
||||
FeedEntryContent content = new FeedEntryContent();
|
||||
content.setContent(getContent(item));
|
||||
content.setCategories(FeedUtils.truncate(
|
||||
item.getCategories().stream().map(c -> c.getName()).collect(Collectors.joining(", ")), 4096));
|
||||
content.setCategories(FeedUtils
|
||||
.truncate(item.getCategories().stream().map(SyndCategory::getName).collect(Collectors.joining(", ")), 4096));
|
||||
content.setTitle(getTitle(item));
|
||||
content.setAuthor(StringUtils.trimToNull(item.getAuthor()));
|
||||
|
||||
SyndEnclosure enclosure = Iterables.getFirst(item.getEnclosures(), null);
|
||||
if (enclosure != null) {
|
||||
content.setEnclosureUrl(FeedUtils.truncate(enclosure.getUrl(), 2048));
|
||||
content.setEnclosureType(enclosure.getType());
|
||||
}
|
||||
|
||||
MediaEntryModule module = (MediaEntryModule) item.getModule(MediaModule.URI);
|
||||
if (module != null) {
|
||||
Media media = getMedia(module);
|
||||
if (media != null) {
|
||||
content.setMediaDescription(media.getDescription());
|
||||
content.setMediaThumbnailUrl(FeedUtils.truncate(media.getThumbnailUrl(), 2048));
|
||||
content.setMediaThumbnailWidth(media.getThumbnailWidth());
|
||||
content.setMediaThumbnailHeight(media.getThumbnailHeight());
|
||||
}
|
||||
}
|
||||
|
||||
entry.setContent(content);
|
||||
|
||||
entries.add(entry);
|
||||
@@ -166,7 +188,7 @@ public class FeedParser {
|
||||
if (item.getContents().isEmpty()) {
|
||||
content = item.getDescription() == null ? null : item.getDescription().getValue();
|
||||
} else {
|
||||
content = item.getContents().stream().map(c -> c.getValue()).collect(Collectors.joining(System.lineSeparator()));
|
||||
content = item.getContents().stream().map(SyndContent::getValue).collect(Collectors.joining(System.lineSeparator()));
|
||||
}
|
||||
return StringUtils.trimToNull(content);
|
||||
}
|
||||
@@ -184,6 +206,41 @@ public class FeedParser {
|
||||
return StringUtils.trimToNull(title);
|
||||
}
|
||||
|
||||
private Media getMedia(MediaEntryModule module) {
|
||||
Media media = getMedia(module.getMetadata());
|
||||
if (media == null && ArrayUtils.isNotEmpty(module.getMediaGroups())) {
|
||||
MediaGroup group = module.getMediaGroups()[0];
|
||||
media = getMedia(group.getMetadata());
|
||||
}
|
||||
|
||||
return media;
|
||||
}
|
||||
|
||||
private Media getMedia(Metadata metadata) {
|
||||
if (metadata == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Media media = new Media();
|
||||
media.setDescription(metadata.getDescription());
|
||||
|
||||
if (ArrayUtils.isNotEmpty(metadata.getThumbnail())) {
|
||||
Thumbnail thumbnail = metadata.getThumbnail()[0];
|
||||
media.setThumbnailWidth(thumbnail.getWidth());
|
||||
media.setThumbnailHeight(thumbnail.getHeight());
|
||||
|
||||
if (thumbnail.getUrl() != null) {
|
||||
media.setThumbnailUrl(thumbnail.getUrl().toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (media.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return media;
|
||||
}
|
||||
|
||||
private String findHub(SyndFeed feed) {
|
||||
for (SyndLink l : feed.getLinks()) {
|
||||
if ("hub".equalsIgnoreCase(l.getRel())) {
|
||||
@@ -204,4 +261,16 @@ public class FeedParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class Media {
|
||||
private String description;
|
||||
private String thumbnailUrl;
|
||||
private Integer thumbnailWidth;
|
||||
private Integer thumbnailHeight;
|
||||
|
||||
public boolean isEmpty() {
|
||||
return description == null && thumbnailUrl == null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +43,17 @@ public class FeedEntryContent extends AbstractModel {
|
||||
@Column(length = 255)
|
||||
private String enclosureType;
|
||||
|
||||
@Lob
|
||||
@Column(length = Integer.MAX_VALUE)
|
||||
@Type(type = "org.hibernate.type.TextType")
|
||||
private String mediaDescription;
|
||||
|
||||
@Column(length = 2048)
|
||||
private String mediaThumbnailUrl;
|
||||
|
||||
private Integer mediaThumbnailWidth;
|
||||
private Integer mediaThumbnailHeight;
|
||||
|
||||
@Column(length = 4096)
|
||||
private String categories;
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ package com.commafeed.backend.service;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -12,6 +10,8 @@ import com.commafeed.backend.dao.FeedEntryContentDAO;
|
||||
import com.commafeed.backend.feed.FeedUtils;
|
||||
import com.commafeed.backend.model.FeedEntryContent;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class FeedEntryContentService {
|
||||
@@ -35,6 +35,7 @@ public class FeedEntryContentService {
|
||||
content.setAuthor(FeedUtils.truncate(FeedUtils.handleContent(content.getAuthor(), baseUrl, true), 128));
|
||||
content.setTitle(FeedUtils.truncate(FeedUtils.handleContent(content.getTitle(), baseUrl, true), 2048));
|
||||
content.setContent(FeedUtils.handleContent(content.getContent(), baseUrl, false));
|
||||
content.setMediaDescription(FeedUtils.handleContent(content.getMediaDescription(), baseUrl, false));
|
||||
result = content;
|
||||
feedEntryContentDAO.saveOrUpdate(result);
|
||||
} else {
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.commafeed.backend.feed.FeedUtils;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
import com.commafeed.backend.model.FeedEntryContent;
|
||||
import com.commafeed.backend.model.FeedEntryStatus;
|
||||
import com.commafeed.backend.model.FeedEntryTag;
|
||||
import com.commafeed.backend.model.FeedSubscription;
|
||||
import com.rometools.rome.feed.synd.SyndContent;
|
||||
import com.rometools.rome.feed.synd.SyndContentImpl;
|
||||
@@ -49,17 +50,25 @@ public class Entry implements Serializable {
|
||||
entry.setFeedUrl(sub.getFeed().getUrl());
|
||||
entry.setFeedLink(sub.getFeed().getLink());
|
||||
entry.setIconUrl(FeedUtils.getFaviconUrl(sub, publicUrl));
|
||||
entry.setTags(status.getTags().stream().map(t -> t.getName()).collect(Collectors.toList()));
|
||||
entry.setTags(status.getTags().stream().map(FeedEntryTag::getName).collect(Collectors.toList()));
|
||||
|
||||
if (content != null) {
|
||||
entry.setRtl(FeedUtils.isRTL(feedEntry));
|
||||
entry.setTitle(content.getTitle());
|
||||
entry.setContent(proxyImages ? FeedUtils.proxyImages(content.getContent(), publicUrl) : content.getContent());
|
||||
entry.setAuthor(content.getAuthor());
|
||||
|
||||
entry.setEnclosureType(content.getEnclosureType());
|
||||
entry.setEnclosureUrl(proxyImages && StringUtils.contains(content.getEnclosureType(), "image")
|
||||
? FeedUtils.proxyImage(content.getEnclosureUrl(), publicUrl)
|
||||
: content.getEnclosureUrl());
|
||||
|
||||
entry.setMediaDescription(content.getMediaDescription());
|
||||
entry.setMediaThumbnailUrl(
|
||||
proxyImages ? FeedUtils.proxyImage(content.getMediaThumbnailUrl(), publicUrl) : content.getMediaThumbnailUrl());
|
||||
entry.setMediaThumbnailWidth(content.getMediaThumbnailWidth());
|
||||
entry.setMediaThumbnailHeight(content.getMediaThumbnailHeight());
|
||||
|
||||
entry.setCategories(content.getCategories());
|
||||
}
|
||||
|
||||
@@ -116,6 +125,18 @@ public class Entry implements Serializable {
|
||||
@ApiModelProperty(value = "entry enclosure mime type, if any")
|
||||
private String enclosureType;
|
||||
|
||||
@ApiModelProperty(value = "entry media description, if any")
|
||||
private String mediaDescription;
|
||||
|
||||
@ApiModelProperty(value = "entry media thumbnail url, if any")
|
||||
private String mediaThumbnailUrl;
|
||||
|
||||
@ApiModelProperty(value = "entry media thumbnail width, if any")
|
||||
private Integer mediaThumbnailWidth;
|
||||
|
||||
@ApiModelProperty(value = "entry media thumbnail height, if any")
|
||||
private Integer mediaThumbnailHeight;
|
||||
|
||||
@ApiModelProperty(value = "entry publication date", dataType = "number", required = true)
|
||||
private Date date;
|
||||
|
||||
|
||||
@@ -8,4 +8,19 @@
|
||||
<dropColumn tableName="USERSETTINGS" columnName="readability" />
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="add-content-media" author="athou">
|
||||
<addColumn tableName="FEEDENTRYCONTENTS">
|
||||
<column name="mediaDescription" type="CLOB" />
|
||||
</addColumn>
|
||||
<addColumn tableName="FEEDENTRYCONTENTS">
|
||||
<column name="mediaThumbnailUrl" type="VARCHAR(2048)" />
|
||||
</addColumn>
|
||||
<addColumn tableName="FEEDENTRYCONTENTS">
|
||||
<column name="mediaThumbnailWidth" type="INT" />
|
||||
</addColumn>
|
||||
<addColumn tableName="FEEDENTRYCONTENTS">
|
||||
<column name="mediaThumbnailHeight" type="INT" />
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
||||
Reference in New Issue
Block a user