From d47bdfaf13b3eda524f3c606b4bf7e60435cda26 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Fri, 11 Nov 2016 13:23:07 +0300 Subject: initial filetransfer bot --- juick-xmpp-ft/build.gradle | 37 +++++++ .../java/com/juick/components/XMPPFTServer.java | 51 ++++++++++ .../configuration/FileTransferConfiguration.java | 107 +++++++++++++++++++++ .../configuration/FileTransferInitializer.java | 33 +++++++ .../components/controllers/StatusController.java | 30 ++++++ settings.gradle | 2 +- 6 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 juick-xmpp-ft/build.gradle create mode 100644 juick-xmpp-ft/src/main/java/com/juick/components/XMPPFTServer.java create mode 100644 juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferConfiguration.java create mode 100644 juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferInitializer.java create mode 100644 juick-xmpp-ft/src/main/java/com/juick/components/controllers/StatusController.java diff --git a/juick-xmpp-ft/build.gradle b/juick-xmpp-ft/build.gradle new file mode 100644 index 00000000..508075f3 --- /dev/null +++ b/juick-xmpp-ft/build.gradle @@ -0,0 +1,37 @@ +apply plugin: 'java' +apply plugin: 'war' +apply plugin: 'org.akhikhl.gretty' +apply plugin: 'com.github.ben-manes.versions' + +repositories { + mavenCentral() +} + +def springFrameworkVersion = '4.3.4.RELEASE' +def jacksonVersion = '2.8.4' +def slf4jVersion = '1.7.21' + +dependencies { + compile project(':juick-core') + compile "org.slf4j:slf4j-api:${slf4jVersion}" + compile "org.springframework:spring-webmvc:${springFrameworkVersion}" + compile "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}" + compile "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}" + compile "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${jacksonVersion}" + compile 'javax.inject:javax.inject:1' + compile 'org.apache.httpcomponents:httpclient:4.5.2' + compile 'org.apache.commons:commons-dbcp2:2.1.1' + compile 'com.mitchellbosecke:pebble-spring4:2.2.3' + compile 'rocks.xmpp:xmpp-core-client:0.7.2' + compile 'rocks.xmpp:xmpp-extensions-client:0.7.2' + providedRuntime 'mysql:mysql-connector-java:5.1.39' +} + +compileJava.options.encoding = 'UTF-8' + +gretty { + httpPort = 8080 + contextPath = '' + servletContainer = 'tomcat8' +} + diff --git a/juick-xmpp-ft/src/main/java/com/juick/components/XMPPFTServer.java b/juick-xmpp-ft/src/main/java/com/juick/components/XMPPFTServer.java new file mode 100644 index 00000000..bf8e0298 --- /dev/null +++ b/juick-xmpp-ft/src/main/java/com/juick/components/XMPPFTServer.java @@ -0,0 +1,51 @@ +package com.juick.components; + +import org.apache.commons.lang3.math.NumberUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.env.Environment; +import rocks.xmpp.extensions.component.accept.ExternalComponent; +import rocks.xmpp.extensions.filetransfer.FileTransfer; +import rocks.xmpp.extensions.filetransfer.FileTransferManager; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * Created by vitalyster on 11.11.2016. + */ +public class XMPPFTServer { + private static final Logger logger = LoggerFactory.getLogger(XMPPFTServer.class); + + public XMPPFTServer(Environment env) { + ExternalComponent component = ExternalComponent.create(env.getProperty("component_name", "files"), + env.getProperty("component_password", "secret"), env.getProperty("component_host", "localhost"), + NumberUtils.toInt(env.getProperty("component_port", "5347"), 5347)); + String tmpDir = env.getProperty("upload_tmp_dir", "/tmp"); + FileTransferManager fileTransferManager = component.getManager(FileTransferManager.class); + fileTransferManager.addFileTransferOfferListener(e -> { + try { + String mime = e.getMimeType(); + List allowedTypes = new ArrayList() {{ add("image/png"); add("image/jpeg"); }}; + if (allowedTypes.contains(mime)) { + FileTransfer ft = e.accept(Paths.get(tmpDir, e.getName())).get(); + ft.addFileTransferStatusListener(st -> { + logger.debug(String.format("%s: received %d of %d", e.getName(), st.getBytesTransferred(), e.getSize())); + if (ft.isDone()) { + logger.info("transfer completed"); + } + }); + ft.transfer(); + logger.info("transfer started"); + } else { + e.reject(); + } + } catch (IOException | InterruptedException | ExecutionException e1) { + logger.error("ft error", e1); + } + }); + } +} diff --git a/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferConfiguration.java b/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferConfiguration.java new file mode 100644 index 00000000..de47ddc9 --- /dev/null +++ b/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferConfiguration.java @@ -0,0 +1,107 @@ +package com.juick.components.configuration; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import com.juick.components.XMPPFTServer; +import com.mitchellbosecke.pebble.PebbleEngine; +import com.mitchellbosecke.pebble.loader.Loader; +import com.mitchellbosecke.pebble.loader.ServletLoader; +import com.mitchellbosecke.pebble.spring4.PebbleViewResolver; +import com.mitchellbosecke.pebble.spring4.extension.SpringExtension; +import org.apache.commons.dbcp2.BasicDataSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; + +import javax.inject.Inject; +import javax.servlet.ServletContext; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Created by vitalyster on 28.06.2016. + */ +@Configuration +@ComponentScan(basePackages = {"com.juick"}) +@PropertySource(value = "classpath:juick.conf", ignoreResourceNotFound = true) +public class FileTransferConfiguration extends WebMvcConfigurationSupport { + @Inject + Environment env; + @Inject + ExecutorService service; + + @Bean + JdbcTemplate jdbc() { + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(env.getProperty("datasource_driver", "com.mysql.jdbc.Driver")); + dataSource.setUrl(env.getProperty("datasource_url")); + return new JdbcTemplate(dataSource); + } + @Inject + private ServletContext servletContext; + + @Bean + public Loader templateLoader(){ + return new ServletLoader(servletContext); + } + + @Bean + public SpringExtension springExtension() { + return new SpringExtension(); + } + + @Bean + public PebbleEngine pebbleEngine() { + return new PebbleEngine.Builder() + .loader(this.templateLoader()) + .extension(springExtension()) + .build(); + } + + @Bean + public ViewResolver viewResolver() { + PebbleViewResolver viewResolver = new PebbleViewResolver(); + viewResolver.setPrefix("/WEB-INF/templates/"); + viewResolver.setSuffix(".html"); + viewResolver.setPebbleEngine(pebbleEngine()); + return viewResolver; + } + @Bean + public XMPPFTServer xmpp() { + return new XMPPFTServer(env); + } + @Bean + public ExecutorService service() { + return Executors.newCachedThreadPool(); + } + + @Override + protected void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.setOrder(0); + registry.addResourceHandler("/scripts.js").addResourceLocations("/"); + registry.addResourceHandler("/style.css").addResourceLocations("/"); + } + + @Override + protected void configureMessageConverters(List> converters) { + Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder() + .serializationInclusion(JsonInclude.Include.NON_DEFAULT) + .serializationInclusion(JsonInclude.Include.NON_NULL) + .serializationInclusion(JsonInclude.Include.NON_ABSENT) + .serializationInclusion(JsonInclude.Include.NON_EMPTY); + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(builder.build()); + converter.getObjectMapper().registerModule(new Jdk8Module()); + converters.add(converter); + super.configureMessageConverters(converters); + } +} diff --git a/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferInitializer.java b/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferInitializer.java new file mode 100644 index 00000000..db514e21 --- /dev/null +++ b/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferInitializer.java @@ -0,0 +1,33 @@ +package com.juick.components.configuration; +import org.springframework.web.filter.CharacterEncodingFilter; +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; + +import javax.servlet.Filter; + +/** + * Created by vt on 09/02/16. + */ +public class FileTransferInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { + @Override + protected Class[] getRootConfigClasses() { + return new Class[] {FileTransferConfiguration.class}; + } + + @Override + protected Class[] getServletConfigClasses() { + return null; + } + + @Override + protected String[] getServletMappings() { + return new String[] { + "/" + }; + } + @Override + protected Filter[] getServletFilters() { + CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); + characterEncodingFilter.setEncoding("UTF-8"); + return new Filter[] { characterEncodingFilter}; + } +} diff --git a/juick-xmpp-ft/src/main/java/com/juick/components/controllers/StatusController.java b/juick-xmpp-ft/src/main/java/com/juick/components/controllers/StatusController.java new file mode 100644 index 00000000..16a8aeb4 --- /dev/null +++ b/juick-xmpp-ft/src/main/java/com/juick/components/controllers/StatusController.java @@ -0,0 +1,30 @@ +package com.juick.components.controllers; + +import com.juick.components.XMPPFTServer; +import com.juick.server.helpers.Status; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.inject.Inject; + +/** + * Created by vitalyster on 24.10.2016. + */ +@Controller +@ResponseBody +public class StatusController { + @Inject + XMPPFTServer xmpp; + + @RequestMapping(method = RequestMethod.GET, value = "/", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + public Status status() { + if (xmpp != null) { + String status = "OK"; + return new Status(status); + } + return new Status("Error"); + } +} diff --git a/settings.gradle b/settings.gradle index 8c4b604f..78a7c7de 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':deps:com.juick.xmpp', ':juick-core', ':juick-api', ':juick-www', ':juick-rss', ':juick-ws', ':juick-demo', ':juick-notifications', ':juick-crosspost', ':juick-xmpp' +include ':deps:com.juick.xmpp', ':juick-core', ':juick-api', ':juick-www', ':juick-rss', ':juick-ws', ':juick-demo', ':juick-notifications', ':juick-crosspost', ':juick-xmpp', ':juick-xmpp-ft' -- cgit v1.2.3