aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--juick-server-web/src/main/java/com/juick/server/component/UserUpdatedEvent.java23
-rw-r--r--juick-www/src/main/java/com/juick/service/CloudflareCache.java56
-rw-r--r--juick-www/src/main/java/com/juick/service/cloudflare/FilesPayload.java20
-rw-r--r--juick-www/src/main/java/com/juick/www/configuration/WwwAppConfiguration.java5
-rw-r--r--juick-www/src/main/java/com/juick/www/controllers/Settings.java12
5 files changed, 110 insertions, 6 deletions
diff --git a/juick-server-web/src/main/java/com/juick/server/component/UserUpdatedEvent.java b/juick-server-web/src/main/java/com/juick/server/component/UserUpdatedEvent.java
new file mode 100644
index 00000000..059aeefd
--- /dev/null
+++ b/juick-server-web/src/main/java/com/juick/server/component/UserUpdatedEvent.java
@@ -0,0 +1,23 @@
+package com.juick.server.component;
+
+import com.juick.User;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.lang.NonNull;
+
+public class UserUpdatedEvent extends ApplicationEvent {
+ private User user;
+ /**
+ * Generated when user is updated (avatar changed, etc).
+ *
+ * @param source the object on which the event initially occurred (never {@code null})
+ * @param user updated user
+ */
+ public UserUpdatedEvent(@NonNull Object source, User user) {
+ super(source);
+ this.user = user;
+ }
+
+ public User getUser() {
+ return user;
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/service/CloudflareCache.java b/juick-www/src/main/java/com/juick/service/CloudflareCache.java
new file mode 100644
index 00000000..00e1f684
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/service/CloudflareCache.java
@@ -0,0 +1,56 @@
+package com.juick.service;
+
+import com.juick.service.cloudflare.FilesPayload;
+import com.juick.User;
+import com.juick.server.component.UserUpdatedEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationListener;
+import org.springframework.http.*;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class CloudflareCache implements ApplicationListener<UserUpdatedEvent> {
+ private static final Logger logger = LoggerFactory.getLogger(CloudflareCache.class);
+ @Value("${cloudflare_auth_email}")
+ private String authEmail;
+ @Value("${cloudflare_api_key}")
+ private String apiKey;
+ @Value("${cloudflare_zone_id}")
+ private String zoneId;
+ private final static String baseUri = "https://api.cloudflare.com/client/v4";
+ @Override
+ public void onApplicationEvent(UserUpdatedEvent event) {
+ User user = event.getUser();
+ logger.debug("Purging Cloudflare cache for {} avatar", user.getName());
+ UriComponents uriComponents = UriComponentsBuilder.fromUriString("{baseUri}/zones/{zoneId}/purge_cache")
+ .buildAndExpand(baseUri, zoneId);
+ HttpHeaders httpHeaders = new HttpHeaders();
+ httpHeaders.add("X-Auth-Email", authEmail);
+ httpHeaders.add("X-Auth-Key", apiKey);
+ httpHeaders.setContentType(MediaType.APPLICATION_JSON);
+ FilesPayload payload = new FilesPayload();
+ payload.setFiles(Arrays.asList(
+ String.format("http://i.juick.com/a/%d.png", user.getUid()),
+ String.format("http://i.juick.com/as/%d.png", user.getUid()),
+ String.format("http://i.juick.com/a/%d.jpg", user.getUid()),
+ String.format("http://i.juick.com/as/%d.jpg", user.getUid()),
+ String.format("https://i.juick.com/a/%d.png", user.getUid()),
+ String.format("https://i.juick.com/as/%d.png", user.getUid()),
+ String.format("https://i.juick.com/a/%d.jpg", user.getUid()),
+ String.format("https://i.juick.com/as/%d.jpg", user.getUid())
+ ));
+ RestTemplate api = new RestTemplate();
+ api.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
+ ResponseEntity<String> response = api.exchange(uriComponents.toUri(),
+ HttpMethod.DELETE,
+ new HttpEntity<>(payload, httpHeaders), String.class);
+ logger.info("Cloudflare response: {}", response.getBody());
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/service/cloudflare/FilesPayload.java b/juick-www/src/main/java/com/juick/service/cloudflare/FilesPayload.java
new file mode 100644
index 00000000..35d9e72f
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/service/cloudflare/FilesPayload.java
@@ -0,0 +1,20 @@
+package com.juick.service.cloudflare;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FilesPayload {
+ private List<String> files;
+
+ public FilesPayload() {
+ files = new ArrayList<>();
+ }
+
+ public List<String> getFiles() {
+ return files;
+ }
+
+ public void setFiles(List<String> files) {
+ this.files = files;
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/configuration/WwwAppConfiguration.java b/juick-www/src/main/java/com/juick/www/configuration/WwwAppConfiguration.java
index d79ae636..205c0627 100644
--- a/juick-www/src/main/java/com/juick/www/configuration/WwwAppConfiguration.java
+++ b/juick-www/src/main/java/com/juick/www/configuration/WwwAppConfiguration.java
@@ -19,6 +19,7 @@ package com.juick.www.configuration;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.juick.service.CloudflareCache;
import com.juick.service.TagService;
import com.juick.service.UserService;
import com.juick.www.HelpService;
@@ -93,5 +94,9 @@ public class WwwAppConfiguration {
})
.build();
}
+ @Bean
+ public CloudflareCache cloudflareCache() {
+ return new CloudflareCache();
+ }
}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/Settings.java b/juick-www/src/main/java/com/juick/www/controllers/Settings.java
index db60acba..64775aec 100644
--- a/juick-www/src/main/java/com/juick/www/controllers/Settings.java
+++ b/juick-www/src/main/java/com/juick/www/controllers/Settings.java
@@ -16,19 +16,16 @@
*/
package com.juick.www.controllers;
+import com.juick.server.component.UserUpdatedEvent;
import com.juick.server.helpers.NotifyOpts;
import com.juick.server.helpers.UserInfo;
-import com.juick.server.util.HashUtils;
+import com.juick.server.util.*;
import com.juick.service.*;
-import com.juick.server.util.HttpBadRequestException;
-import com.juick.server.util.HttpUtils;
-import com.juick.server.util.ImageUtils;
-import com.juick.server.util.UserUtils;
-import com.juick.www.WebApp;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
@@ -77,6 +74,8 @@ public class Settings {
private EmailService emailService;
@Inject
private TelegramService telegramService;
+ @Inject
+ private ApplicationEventPublisher applicationEventPublisher;
@GetMapping("/settings")
protected String doGet(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws IOException {
@@ -164,6 +163,7 @@ public class Settings {
ImageUtils.saveAvatar(avatarTmpPath, visitor.getUid(), tmpDir, imgDir);
}
if (userService.updateUserInfo(visitor, info)) {
+ applicationEventPublisher.publishEvent(new UserUpdatedEvent(this, visitor));
result = String.format("<p>Your info is updated.</p><p><a href='/%s/'>Back to blog</a>.</p>", visitor.getName());
}
break;