fetch feed name

This commit is contained in:
Athou
2013-03-30 20:51:51 +01:00
parent d8b8f6617a
commit 5a4d11c4de
8 changed files with 75 additions and 6 deletions

View File

@@ -32,7 +32,7 @@ public class FeedParser {
try { try {
SyndFeed rss = new SyndFeedInput().build(new StringReader(xml)); SyndFeed rss = new SyndFeedInput().build(new StringReader(xml));
feed.setTitle(rss.getTitle());
List<SyndEntry> items = rss.getEntries(); List<SyndEntry> items = rss.getEntries();
for (SyndEntry item : items) { for (SyndEntry item : items) {
FeedEntry entry = new FeedEntry(); FeedEntry entry = new FeedEntry();

View File

@@ -9,6 +9,7 @@ import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Temporal; import javax.persistence.Temporal;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.hibernate.annotations.Index; import org.hibernate.annotations.Index;
@@ -23,6 +24,9 @@ public class Feed extends AbstractModel {
@Index(name = "feed_index") @Index(name = "feed_index")
private String url; private String url;
@Transient
private String title;
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
private Date lastUpdated; private Date lastUpdated;
@@ -83,4 +87,12 @@ public class Feed extends AbstractModel {
this.subscriptions = subscriptions; this.subscriptions = subscriptions;
} }
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
} }

View File

@@ -66,12 +66,17 @@ public class JSONMessageBodyReaderWriter implements MessageBodyWriter<Object>,
OutputStream entityStream) throws IOException, OutputStream entityStream) throws IOException,
WebApplicationException { WebApplicationException {
httpHeaders.putSingle(HttpHeaders.CONTENT_TYPE, mediaType.toString() httpHeaders.putSingle(HttpHeaders.CONTENT_TYPE, mediaType.toString()
+ ";charset=UTF-8"); + ";charset=" + UTF_8);
httpHeaders.putSingle(HttpHeaders.CACHE_CONTROL, "no-cache"); httpHeaders.putSingle(HttpHeaders.CACHE_CONTROL, "no-cache");
httpHeaders.putSingle("Pragma", "no-cache"); httpHeaders.putSingle("Pragma", "no-cache");
OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8); if (type == String.class) {
getGson().toJson(t, type, writer); entityStream.write(t.toString().getBytes(UTF_8));
writer.flush(); } else {
OutputStreamWriter writer = new OutputStreamWriter(entityStream,
UTF_8);
getGson().toJson(t, type, writer);
writer.flush();
}
} }
@Override @Override

View File

@@ -31,6 +31,7 @@ import com.commafeed.backend.dao.FeedSubscriptionService;
import com.commafeed.backend.dao.UserRoleService; import com.commafeed.backend.dao.UserRoleService;
import com.commafeed.backend.dao.UserService; import com.commafeed.backend.dao.UserService;
import com.commafeed.backend.dao.UserSettingsService; import com.commafeed.backend.dao.UserSettingsService;
import com.commafeed.backend.feeds.FeedFetcher;
import com.commafeed.backend.feeds.OPMLImporter; import com.commafeed.backend.feeds.OPMLImporter;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole.Role; import com.commafeed.backend.model.UserRole.Role;
@@ -80,6 +81,9 @@ public abstract class AbstractREST {
@Inject @Inject
PasswordEncryptionService encryptionService; PasswordEncryptionService encryptionService;
@Inject
FeedFetcher feedFetcher;
@PostConstruct @PostConstruct
public void init() { public void init() {
CommaFeedApplication app = CommaFeedApplication.get(); CommaFeedApplication app = CommaFeedApplication.get();

View File

@@ -7,6 +7,7 @@ import javax.ws.rs.GET;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.Response.Status;
@@ -25,10 +26,26 @@ import com.commafeed.frontend.model.Category;
import com.commafeed.frontend.model.Subscription; import com.commafeed.frontend.model.Subscription;
import com.commafeed.frontend.model.SubscriptionRequest; import com.commafeed.frontend.model.SubscriptionRequest;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.sun.syndication.io.FeedException;
@Path("subscriptions") @Path("subscriptions")
public class SubscriptionsREST extends AbstractREST { public class SubscriptionsREST extends AbstractREST {
@GET
@Path("fetch")
public Feed fetchFeed(@QueryParam("url") String url) {
Preconditions.checkNotNull(url);
Feed feed = null;
try {
feed = feedFetcher.fetch(url);
} catch (FeedException e) {
throw new WebApplicationException(Response
.status(Status.INTERNAL_SERVER_ERROR)
.entity(e.getMessage()).build());
}
return feed;
}
@POST @POST
@Path("subscribe") @Path("subscribe")
public Response subscribe(SubscriptionRequest req) { public Response subscribe(SubscriptionRequest req) {

View File

@@ -21,7 +21,7 @@
<div class="control-group" ng-class="{error : !subscribeForm.url.$valid}"> <div class="control-group" ng-class="{error : !subscribeForm.url.$valid}">
<label class="control-label">Feed URL</label> <label class="control-label">Feed URL</label>
<div class="controls"> <div class="controls">
<input type="text" name="url" ng-model="sub.url" placeholder="http://example.com/feed" class="input-block-level" required></input> <input type="text" name="url" ng-model="sub.url" ng-blur="urlChanged()" placeholder="http://example.com/feed" class="input-block-level" required></input>
<span class="help-block" ng-show="!subscribeForm.url.$valid">Required</span> <span class="help-block" ng-show="!subscribeForm.url.$valid">Required</span>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,16 @@
var module = angular.module('commafeed.directives', []); var module = angular.module('commafeed.directives', []);
app.directive('ngBlur', function() {
return {
restrict: 'A',
link: function(scope, elm, attrs) {
elm.bind('blur', function() {
scope.$apply(attrs.ngBlur);
});
}
};
});
module.directive('scrollTo', function() { module.directive('scrollTo', function() {
return { return {
restrict : 'A', restrict : 'A',
@@ -46,6 +57,19 @@ module.directive('subscribe', function(SubscriptionService) {
$scope.close = function() { $scope.close = function() {
$scope.isOpen = false; $scope.isOpen = false;
}; };
$scope.urlChanged = function() {
if ($scope.sub.url && !$scope.sub.title) {
$scope.sub.title = 'Loading';
SubscriptionService.fetch({
url : $scope.sub.url
}, function(data) {
console.log(data)
$scope.sub.title = data.title;
});
}
};
$scope.save = function() { $scope.save = function() {
SubscriptionService.subscribe($scope.sub); SubscriptionService.subscribe($scope.sub);

View File

@@ -21,6 +21,12 @@ module.factory('SubscriptionService', [
return array; return array;
} }
var actions = { var actions = {
fetch : {
method : 'GET',
params : {
_method : 'fetch'
}
},
get : { get : {
method : 'GET', method : 'GET',
params : { params : {
@@ -58,6 +64,7 @@ module.factory('SubscriptionService', [
callback(data); callback(data);
}); });
}; };
s.fetch = res.fetch;
s.subscribe = function(sub, callback) { s.subscribe = function(sub, callback) {
res.subscribe(sub, function(data) { res.subscribe(sub, function(data) {
s.init(); s.init();