mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
bypass our server directly for feed favicons
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -365,7 +365,7 @@
|
|||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetGroups>app</targetGroups>
|
<targetGroups>app</targetGroups>
|
||||||
<options>indent,devel,noarg,quotmark</options>
|
<options>indent,devel,noarg,quotmark,laxcomma,laxbreak</options>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.commafeed.frontend.pages.DemoLoginPage;
|
import com.commafeed.frontend.pages.DemoLoginPage;
|
||||||
import com.commafeed.frontend.pages.FaviconPage;
|
|
||||||
import com.commafeed.frontend.pages.GoogleImportCallbackPage;
|
import com.commafeed.frontend.pages.GoogleImportCallbackPage;
|
||||||
import com.commafeed.frontend.pages.GoogleImportRedirectPage;
|
import com.commafeed.frontend.pages.GoogleImportRedirectPage;
|
||||||
import com.commafeed.frontend.pages.HomePage;
|
import com.commafeed.frontend.pages.HomePage;
|
||||||
@@ -69,7 +68,6 @@ public class CommaFeedApplication extends AuthenticatedWebApplication {
|
|||||||
mountPage("demo", DemoLoginPage.class);
|
mountPage("demo", DemoLoginPage.class);
|
||||||
mountPage("logout", LogoutPage.class);
|
mountPage("logout", LogoutPage.class);
|
||||||
mountPage("error", DisplayExceptionPage.class);
|
mountPage("error", DisplayExceptionPage.class);
|
||||||
mountPage("favicon", FaviconPage.class);
|
|
||||||
mountPage("google/import/redirect", GoogleImportRedirectPage.class);
|
mountPage("google/import/redirect", GoogleImportRedirectPage.class);
|
||||||
mountPage(GoogleImportCallbackPage.PAGE_PATH,
|
mountPage(GoogleImportCallbackPage.PAGE_PATH,
|
||||||
GoogleImportCallbackPage.class);
|
GoogleImportCallbackPage.class);
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
package com.commafeed.frontend.pages;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.apache.http.impl.cookie.DateUtils;
|
|
||||||
import org.apache.wicket.request.IRequestCycle;
|
|
||||||
import org.apache.wicket.request.IRequestHandler;
|
|
||||||
import org.apache.wicket.request.http.WebResponse;
|
|
||||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
|
||||||
import org.apache.wicket.util.time.Time;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.commafeed.backend.HttpGetter;
|
|
||||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
|
||||||
import com.commafeed.backend.StartupBean;
|
|
||||||
import com.commafeed.backend.model.UserRole.Role;
|
|
||||||
import com.commafeed.frontend.SecurityCheck;
|
|
||||||
import com.google.common.net.HttpHeaders;
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
@SecurityCheck(Role.USER)
|
|
||||||
public class FaviconPage extends BasePage {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory
|
|
||||||
.getLogger(FaviconPage.class);
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
HttpGetter getter;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
StartupBean startupBean;
|
|
||||||
|
|
||||||
public FaviconPage(PageParameters params) {
|
|
||||||
final String url = params.get("url").toString();
|
|
||||||
getRequestCycle().scheduleRequestHandlerAfterCurrent(
|
|
||||||
new IRequestHandler() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void respond(IRequestCycle requestCycle) {
|
|
||||||
WebResponse response = (WebResponse) requestCycle
|
|
||||||
.getResponse();
|
|
||||||
response.setLastModifiedTime(Time.millis(startupBean
|
|
||||||
.getStartupTime()));
|
|
||||||
response.setContentType("image/x-icon");
|
|
||||||
long expiresAfter = TimeUnit.DAYS.toMillis(7);
|
|
||||||
response.setHeader(
|
|
||||||
HttpHeaders.EXPIRES,
|
|
||||||
DateUtils.formatDate(new Date(startupBean
|
|
||||||
.getStartupTime() + expiresAfter)));
|
|
||||||
response.write(getImage(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void detach(IRequestCycle requestCycle) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] getImage(String url) {
|
|
||||||
byte[] img = null;
|
|
||||||
try {
|
|
||||||
if (StringUtils.isNotBlank(url)) {
|
|
||||||
int index = Math.max(url.length(), url.lastIndexOf("?"));
|
|
||||||
url = url.substring(0, index);
|
|
||||||
|
|
||||||
String iconUrl = "http://g.etfv.co/"
|
|
||||||
+ URLEncoder.encode(url, "UTF-8") + "?defaulticon=none";
|
|
||||||
HttpResult result = getter.getBinary(iconUrl);
|
|
||||||
if (result != null) {
|
|
||||||
img = result.getContent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
if (img == null) {
|
|
||||||
img = getDefaultIcon();
|
|
||||||
}
|
|
||||||
return img;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] getDefaultIcon() {
|
|
||||||
byte[] bytes = null;
|
|
||||||
InputStream is = null;
|
|
||||||
try {
|
|
||||||
is = getClass().getResourceAsStream("/favicon.gif");
|
|
||||||
bytes = IOUtils.toByteArray(is);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error(e.getMessage(), e);
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(is);
|
|
||||||
}
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 238 B After Width: | Height: | Size: 238 B |
@@ -7,7 +7,25 @@ module.directive('favicon', function() {
|
|||||||
url : '='
|
url : '='
|
||||||
},
|
},
|
||||||
replace : true,
|
replace : true,
|
||||||
template : '<img ng-src="favicon?url={{url}}" class="favicon"></img>'
|
template : '<img ng-src="{{iconUrl()}}" class="favicon" onError="this.src=\'images/default_favicon.gif\'"></img>',
|
||||||
|
controller : function($scope) {
|
||||||
|
$scope.iconUrl = function() {
|
||||||
|
var url = $scope.url;
|
||||||
|
|
||||||
|
var current = window.location.href;
|
||||||
|
var baseUrl = current.substring(0, current.lastIndexOf('#'));
|
||||||
|
var defaultIcon = baseUrl + 'images/default_favicon.gif';
|
||||||
|
if (!url) {
|
||||||
|
return defaultIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = Math.max(url.length, url.lastIndexOf('?'));
|
||||||
|
var iconUrl = 'http://g.etfv.co/';
|
||||||
|
iconUrl += encodeURIComponent(url.substring(0, index));
|
||||||
|
iconUrl += '?defaulticon=none';
|
||||||
|
return iconUrl;
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -82,133 +100,144 @@ module.directive('category', [ function() {
|
|||||||
restrict : 'E',
|
restrict : 'E',
|
||||||
replace : true,
|
replace : true,
|
||||||
templateUrl : 'directives/category.html',
|
templateUrl : 'directives/category.html',
|
||||||
controller : ['$scope', '$state', '$dialog', 'FeedService',
|
controller : [
|
||||||
'CategoryService', 'SettingsService', function($scope, $state, $dialog, FeedService,
|
'$scope',
|
||||||
CategoryService, SettingsService) {
|
'$state',
|
||||||
$scope.settingsService = SettingsService;
|
'$dialog',
|
||||||
$scope.unsubscribe = function(subscription) {
|
'FeedService',
|
||||||
var title = 'Unsubscribe';
|
'CategoryService',
|
||||||
var msg = 'Unsubscribe from ' + subscription.name + ' ?';
|
'SettingsService',
|
||||||
var btns = [ {
|
function($scope, $state, $dialog, FeedService, CategoryService,
|
||||||
result : 'cancel',
|
SettingsService) {
|
||||||
label : 'Cancel'
|
$scope.settingsService = SettingsService;
|
||||||
}, {
|
$scope.unsubscribe = function(subscription) {
|
||||||
result : 'ok',
|
var title = 'Unsubscribe';
|
||||||
label : 'OK',
|
var msg = 'Unsubscribe from ' + subscription.name
|
||||||
cssClass : 'btn-primary'
|
+ ' ?';
|
||||||
} ];
|
var btns = [ {
|
||||||
|
result : 'cancel',
|
||||||
|
label : 'Cancel'
|
||||||
|
}, {
|
||||||
|
result : 'ok',
|
||||||
|
label : 'OK',
|
||||||
|
cssClass : 'btn-primary'
|
||||||
|
} ];
|
||||||
|
|
||||||
$dialog.messageBox(title, msg, btns).open().then(
|
$dialog.messageBox(title, msg, btns).open().then(
|
||||||
function(result) {
|
function(result) {
|
||||||
if (result == 'ok') {
|
if (result == 'ok') {
|
||||||
var data = {
|
var data = {
|
||||||
id : subscription.id
|
id : subscription.id
|
||||||
};
|
};
|
||||||
FeedService.unsubscribe(data, function() {
|
FeedService.unsubscribe(data,
|
||||||
CategoryService.init();
|
function() {
|
||||||
|
CategoryService.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
$scope.formatCategoryName = function(category) {
|
||||||
|
var count = $scope.unreadCount({
|
||||||
|
category : category
|
||||||
});
|
});
|
||||||
};
|
var label = category.name;
|
||||||
|
if (count > 0) {
|
||||||
|
label = label + ' (' + count + ')';
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
};
|
||||||
|
|
||||||
$scope.formatCategoryName = function(category) {
|
$scope.formatFeedName = function(feed) {
|
||||||
var count = $scope.unreadCount({
|
var label = feed.name;
|
||||||
category : category
|
if (feed.unread > 0) {
|
||||||
});
|
label = label + ' (' + feed.unread + ')';
|
||||||
var label = category.name;
|
}
|
||||||
if (count > 0) {
|
return label;
|
||||||
label = label + ' (' + count + ')';
|
};
|
||||||
}
|
|
||||||
return label;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.formatFeedName = function(feed) {
|
$scope.feedClicked = function(id) {
|
||||||
var label = feed.name;
|
if ($scope.selectedType == 'feed'
|
||||||
if (feed.unread > 0) {
|
&& id == $scope.selectedId) {
|
||||||
label = label + ' (' + feed.unread + ')';
|
$scope.$emit('emitReload');
|
||||||
}
|
} else {
|
||||||
return label;
|
$state.transitionTo('feeds.view', {
|
||||||
};
|
_type : 'feed',
|
||||||
|
_id : id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$scope.feedClicked = function(id) {
|
$scope.categoryClicked = function(id) {
|
||||||
if ($scope.selectedType == 'feed' && id == $scope.selectedId) {
|
if ($scope.selectedType == 'category'
|
||||||
$scope.$emit('emitReload');
|
&& id == $scope.selectedId) {
|
||||||
} else {
|
$scope.$emit('emitReload');
|
||||||
$state.transitionTo('feeds.view', {
|
} else {
|
||||||
_type : 'feed',
|
$state.transitionTo('feeds.view', {
|
||||||
_id : id
|
_type : 'category',
|
||||||
});
|
_id : id
|
||||||
}
|
});
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$scope.categoryClicked = function(id) {
|
$scope.renameFeed = function(feed) {
|
||||||
if ($scope.selectedType == 'category' && id == $scope.selectedId) {
|
var name = window.prompt('Rename feed : ', feed.name);
|
||||||
$scope.$emit('emitReload');
|
if (name && name != feed.name) {
|
||||||
} else {
|
feed.name = name;
|
||||||
$state.transitionTo('feeds.view', {
|
FeedService.rename({
|
||||||
_type : 'category',
|
id : feed.id,
|
||||||
_id : id
|
name : name
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.renameFeed = function(feed) {
|
$scope.renameCategory = function(category) {
|
||||||
var name = window.prompt('Rename feed : ', feed.name);
|
var name = window.prompt('Rename category: ',
|
||||||
if (name && name != feed.name) {
|
category.name);
|
||||||
feed.name = name;
|
if (name && name != category.name) {
|
||||||
FeedService.rename({
|
category.name = name;
|
||||||
id : feed.id,
|
CategoryService.rename({
|
||||||
name : name
|
id : category.id,
|
||||||
});
|
name : name
|
||||||
}
|
});
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$scope.renameCategory = function(category) {
|
$scope.deleteCategory = function(category) {
|
||||||
var name = window.prompt('Rename category: ', category.name);
|
var title = 'Delete category';
|
||||||
if (name && name != category.name) {
|
var msg = 'Delete category ' + category.name + ' ?';
|
||||||
category.name = name;
|
var btns = [ {
|
||||||
CategoryService.rename({
|
result : 'cancel',
|
||||||
id : category.id,
|
label : 'Cancel'
|
||||||
name : name
|
}, {
|
||||||
});
|
result : 'ok',
|
||||||
}
|
label : 'OK',
|
||||||
};
|
cssClass : 'btn-primary'
|
||||||
|
} ];
|
||||||
|
|
||||||
$scope.deleteCategory = function(category) {
|
$dialog.messageBox(title, msg, btns).open().then(
|
||||||
var title = 'Delete category';
|
function(result) {
|
||||||
var msg = 'Delete category ' + category.name + ' ?';
|
if (result == 'ok') {
|
||||||
var btns = [ {
|
CategoryService.remove({
|
||||||
result : 'cancel',
|
id : category.id
|
||||||
label : 'Cancel'
|
}, function() {
|
||||||
}, {
|
CategoryService.init();
|
||||||
result : 'ok',
|
});
|
||||||
label : 'OK',
|
}
|
||||||
cssClass : 'btn-primary'
|
|
||||||
} ];
|
|
||||||
|
|
||||||
$dialog.messageBox(title, msg, btns).open().then(
|
|
||||||
function(result) {
|
|
||||||
if (result == 'ok') {
|
|
||||||
CategoryService.remove({
|
|
||||||
id : category.id
|
|
||||||
}, function() {
|
|
||||||
CategoryService.init();
|
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.toggleCategory = function(category) {
|
$scope.toggleCategory = function(category) {
|
||||||
category.expanded = !category.expanded;
|
category.expanded = !category.expanded;
|
||||||
if (category.id == 'all') {
|
if (category.id == 'all') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CategoryService.collapse({
|
CategoryService.collapse({
|
||||||
id : category.id,
|
id : category.id,
|
||||||
collapse : !category.expanded
|
collapse : !category.expanded
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}]
|
} ]
|
||||||
};
|
};
|
||||||
} ]);
|
} ]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user