refactored everything and moved the project into a Maven project, that can be built easily, and removed a json call that was deprecated
This commit is contained in:
parent
b0e6f33b87
commit
a3f4c5688a
30
.gitignore
vendored
30
.gitignore
vendored
@ -1,27 +1,3 @@
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
/twitter_techsupportgore_bot/nbproject/private/
|
||||
/twitter_techsupportgore_bot/build/
|
||||
/twitter_techsupportgore_bot/dist/
|
||||
*.sqlite
|
||||
*.iml
|
||||
.idea/
|
||||
target/
|
@ -1,23 +1,25 @@
|
||||
################################################################################
|
||||
# REDDIT SETTINGS #
|
||||
################################################################################
|
||||
subreddit=techsupportgore
|
||||
delay=30
|
||||
sqlite_db_name=techsupportgore_twitterbot
|
||||
clear_database=N
|
||||
reddit_posts_limit=1
|
||||
reddit_posts_sorting_order=new
|
||||
|
||||
################################################################################
|
||||
# MISCELLANEOUS SETTINGS #
|
||||
################################################################################
|
||||
working_directory=data
|
||||
max_text_length=280
|
||||
|
||||
################################################################################
|
||||
# TWITTER API SETTINGS #
|
||||
################################################################################
|
||||
twitterAPI_consumerKey=
|
||||
twitterAPI_consumerSecret=
|
||||
twitterAPI_accessToken=
|
||||
twitterAPI_accessSecret=
|
||||
################################################################################
|
||||
# REDDIT SETTINGS #
|
||||
################################################################################
|
||||
# What comes after /r/ (ex: softwaregore)
|
||||
subreddit=
|
||||
# delay (in seconds) between two scans. (ex: 60)
|
||||
delay=
|
||||
sqlite_db_name=
|
||||
clear_database=
|
||||
reddit_posts_limit=
|
||||
reddit_posts_sorting_order=
|
||||
|
||||
################################################################################
|
||||
# MISCELLANEOUS SETTINGS #
|
||||
################################################################################
|
||||
working_directory=
|
||||
max_text_length=
|
||||
|
||||
################################################################################
|
||||
# TWITTER API SETTINGS #
|
||||
################################################################################
|
||||
twitterAPI_consumerKey=
|
||||
twitterAPI_consumerSecret=
|
||||
twitterAPI_accessToken=
|
||||
twitterAPI_accessSecret=
|
68
pom.xml
Normal file
68
pom.xml
Normal file
@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>RedditReposterBot</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- Build an executable JAR -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>lib/</classpathPrefix>
|
||||
<mainClass>xyz.vallat.louis.RedditReposterBot</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<!-- bind to the packaging phase -->
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.twitter4j</groupId>
|
||||
<artifactId>twitter4j-core</artifactId>
|
||||
<version>4.0.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.30.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -1,73 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="RedditReposterBot" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project RedditReposterBot.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="RedditReposterBot-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
@ -1,4 +0,0 @@
|
||||
#Tue, 06 Aug 2019 11:12:49 +0200
|
||||
|
||||
|
||||
C\:\\Users\\louis\\Documents\\GitHub\\twitter_techsupportgore_bot\\reddit_reposter_bot=
|
32
reddit_reposter_bot/dist/README.TXT
vendored
32
reddit_reposter_bot/dist/README.TXT
vendored
@ -1,32 +0,0 @@
|
||||
========================
|
||||
BUILD OUTPUT DESCRIPTION
|
||||
========================
|
||||
|
||||
When you build an Java application project that has a main class, the IDE
|
||||
automatically copies all of the JAR
|
||||
files on the projects classpath to your projects dist/lib folder. The IDE
|
||||
also adds each of the JAR files to the Class-Path element in the application
|
||||
JAR files manifest file (MANIFEST.MF).
|
||||
|
||||
To run the project from the command line, go to the dist folder and
|
||||
type the following:
|
||||
|
||||
java -jar "RedditReposterBot.jar"
|
||||
|
||||
To distribute this project, zip up the dist folder (including the lib folder)
|
||||
and distribute the ZIP file.
|
||||
|
||||
Notes:
|
||||
|
||||
* If two JAR files on the project classpath have the same name, only the first
|
||||
JAR file is copied to the lib folder.
|
||||
* Only JAR files are copied to the lib folder.
|
||||
If the classpath contains other types of files or folders, these files (folders)
|
||||
are not copied.
|
||||
* If a library on the projects classpath also has a Class-Path element
|
||||
specified in the manifest,the content of the Class-Path element has to be on
|
||||
the projects runtime path.
|
||||
* To set a main class in a standard Java project, right-click the project node
|
||||
in the Projects window and choose Properties. Then click Run and enter the
|
||||
class name in the Main Class field. Alternatively, you can manually type the
|
||||
class name in the manifest Main-Class element.
|
@ -1,3 +0,0 @@
|
||||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +0,0 @@
|
||||
build.xml.data.CRC32=9dc9f11e
|
||||
build.xml.script.CRC32=293f3476
|
||||
build.xml.stylesheet.CRC32=8064a381@1.80.1.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=9dc9f11e
|
||||
nbproject/build-impl.xml.script.CRC32=69003ede
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48
|
@ -1,9 +0,0 @@
|
||||
application.args=helo
|
||||
#
|
||||
#Mon Apr 22 18:09:19 CEST 2019
|
||||
javac.debug=true
|
||||
javadoc.preview=true
|
||||
do.depend=false
|
||||
do.jar=true
|
||||
compile.on.save=false
|
||||
user.properties.file=C\:\\Users\\louis\\AppData\\Roaming\\NetBeans\\8.2\\build.properties
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
||||
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
|
||||
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
|
||||
<group/>
|
||||
</open-files>
|
||||
</project-private>
|
Binary file not shown.
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
|
||||
<properties>
|
||||
<comment/>
|
||||
<entry key="ACTIVATED_FEATURES">#org.netbeans.modules.profiler.v2.features.MonitorFeature@#org.netbeans.modules.profiler.v2.features.ThreadsFeature@#org.netbeans.modules.profiler.v2.features.SQLFeature@</entry>
|
||||
<entry key="SINGLE_FEATURE">false</entry>
|
||||
</properties>
|
@ -1,85 +0,0 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
application.title=RedditReposterBot
|
||||
application.vendor=louis
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/RedditReposterBot.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
endorsed.classpath=
|
||||
excludes=
|
||||
file.reference.gson-2.8.5.jar=C:\\Users\\louis\\Documents\\libraries\\Java\\gson-2.8.5.jar
|
||||
file.reference.kotlin-runtime.jar=nulllib\\kotlin-runtime.jar
|
||||
file.reference.sqlite-jdbc-3.23.1.jar=C:\\Users\\louis\\Documents\\libraries\\Java\\sqlite-jdbc-3.23.1.jar
|
||||
file.reference.twitter4j-core-4.0.7.jar=C:\\Users\\louis\\Documents\\libraries\\Java\\twitter4j-core-4.0.7.jar
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=\
|
||||
${file.reference.gson-2.8.5.jar}:\
|
||||
${file.reference.twitter4j-core-4.0.7.jar}:\
|
||||
${file.reference.sqlite-jdbc-3.23.1.jar}
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=-Xlint:unchecked
|
||||
javac.deprecation=false
|
||||
javac.external.vm=true
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.8
|
||||
javac.target=1.8
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
kotlinc.classpath=${file.reference.kotlin-runtime.jar}
|
||||
main.class=RedditReposterBot.RedditReposterBot
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=false
|
||||
platform.active=default_platform
|
||||
project.license=gpl30
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>RedditReposterBot</name>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
212
reddit_reposter_bot/src/RedditReposterBot/ConfigFileReader.java → src/main/java/xyz.vallat.louis/ConfigFileReader.java
Normal file → Executable file
212
reddit_reposter_bot/src/RedditReposterBot/ConfigFileReader.java → src/main/java/xyz.vallat.louis/ConfigFileReader.java
Normal file → Executable file
@ -1,106 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot;
|
||||
|
||||
import RedditReposterBot.exceptions.NoSuchFile;
|
||||
import RedditReposterBot.exceptions.NotSufficientRights;
|
||||
import RedditReposterBot.exceptions.NoSuchProperty;
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A config file reader.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public final class ConfigFileReader {
|
||||
|
||||
/**
|
||||
* The config file name.
|
||||
*/
|
||||
private static String CONFIGFILE = "settings.conf";
|
||||
|
||||
/**
|
||||
* The properties object.
|
||||
*/
|
||||
private final Properties prop = new Properties();
|
||||
|
||||
/**
|
||||
* Create a new config file reader that automatically reads the config file.
|
||||
*
|
||||
* @throws NoSuchFile
|
||||
* @throws NotSufficientRights
|
||||
*/
|
||||
public ConfigFileReader() throws NoSuchFile, NotSufficientRights {
|
||||
readConfigFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new config file reader that automatically reads the config file,
|
||||
* precising the config file name.
|
||||
*
|
||||
* @param conf the cnfig file path name.
|
||||
* @throws NoSuchFile
|
||||
* @throws NotSufficientRights
|
||||
*/
|
||||
public ConfigFileReader(String conf) throws NoSuchFile, NotSufficientRights {
|
||||
CONFIGFILE = conf;
|
||||
readConfigFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the config file.
|
||||
*
|
||||
* @throws RedditReposterBot.exceptions.NoSuchFile
|
||||
* @throws RedditReposterBot.exceptions.NotSufficientRights
|
||||
*/
|
||||
public void readConfigFile() throws NoSuchFile, NotSufficientRights {
|
||||
if (!new File(CONFIGFILE).exists()) {
|
||||
throw new NoSuchFile(
|
||||
"[!] The config file " + CONFIGFILE + " doesn't exists.");
|
||||
} else if (!new File(CONFIGFILE).canRead()) {
|
||||
throw new NotSufficientRights(
|
||||
"[!] Can't read the config file " + CONFIGFILE + ".");
|
||||
}
|
||||
try {
|
||||
prop.load(new FileInputStream(new File(CONFIGFILE)));
|
||||
} catch (IOException ex) {
|
||||
System.out.println(
|
||||
"[!] Error on loading the config file.");
|
||||
System.out.println("[!] " + ex.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property for an id.
|
||||
*
|
||||
* @param id the property id.
|
||||
* @return the properties.
|
||||
* @throws RedditReposterBot.exceptions.NoSuchProperty
|
||||
*/
|
||||
public String getProperties(String id) throws NoSuchProperty {
|
||||
if (!this.prop.containsKey(id)) {
|
||||
throw new NoSuchProperty(
|
||||
"[!] The property " + id + " is not defined in the config "
|
||||
+ "file. Define it in " + CONFIGFILE + " and try again.");
|
||||
}
|
||||
return this.prop.getProperty(id);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis;
|
||||
|
||||
import xyz.vallat.louis.exceptions.NoSuchFile;
|
||||
import xyz.vallat.louis.exceptions.NotSufficientRights;
|
||||
import xyz.vallat.louis.exceptions.NoSuchProperty;
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A config file reader.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public final class ConfigFileReader {
|
||||
|
||||
/**
|
||||
* The config file name.
|
||||
*/
|
||||
private static String CONFIGFILE = "data/settings.conf";
|
||||
|
||||
/**
|
||||
* The properties object.
|
||||
*/
|
||||
private final Properties prop = new Properties();
|
||||
|
||||
/**
|
||||
* Create a new config file reader that automatically reads the config file.
|
||||
*
|
||||
* @throws NoSuchFile
|
||||
* @throws NotSufficientRights
|
||||
*/
|
||||
public ConfigFileReader() throws NoSuchFile, NotSufficientRights {
|
||||
readConfigFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new config file reader that automatically reads the config file,
|
||||
* precising the config file name.
|
||||
*
|
||||
* @param conf the cnfig file path name.
|
||||
* @throws NoSuchFile
|
||||
* @throws NotSufficientRights
|
||||
*/
|
||||
public ConfigFileReader(String conf) throws NoSuchFile, NotSufficientRights {
|
||||
CONFIGFILE = conf;
|
||||
readConfigFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the config file.
|
||||
*
|
||||
* @throws RedditReposterBot.exceptions.NoSuchFile
|
||||
* @throws RedditReposterBot.exceptions.NotSufficientRights
|
||||
*/
|
||||
public void readConfigFile() throws NoSuchFile, NotSufficientRights {
|
||||
if (!new File(CONFIGFILE).exists()) {
|
||||
throw new NoSuchFile(
|
||||
"[!] The config file " + CONFIGFILE + " doesn't exists.");
|
||||
} else if (!new File(CONFIGFILE).canRead()) {
|
||||
throw new NotSufficientRights(
|
||||
"[!] Can't read the config file " + CONFIGFILE + ".");
|
||||
}
|
||||
try {
|
||||
prop.load(new FileInputStream(new File(CONFIGFILE)));
|
||||
} catch (IOException ex) {
|
||||
System.out.println(
|
||||
"[!] Error on loading the config file.");
|
||||
System.out.println("[!] " + ex.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property for an id.
|
||||
*
|
||||
* @param id the property id.
|
||||
* @return the properties.
|
||||
* @throws RedditReposterBot.exceptions.NoSuchProperty
|
||||
*/
|
||||
public String getProperties(String id) throws NoSuchProperty {
|
||||
if (!this.prop.containsKey(id)) {
|
||||
throw new NoSuchProperty(
|
||||
"[!] The property " + id + " is not defined in the config "
|
||||
+ "file. Define it in " + CONFIGFILE + " and try again.");
|
||||
}
|
||||
return this.prop.getProperty(id);
|
||||
}
|
||||
}
|
882
reddit_reposter_bot/src/RedditReposterBot/Hypervisor.java → src/main/java/xyz.vallat.louis/Hypervisor.java
Normal file → Executable file
882
reddit_reposter_bot/src/RedditReposterBot/Hypervisor.java → src/main/java/xyz.vallat.louis/Hypervisor.java
Normal file → Executable file
@ -1,441 +1,441 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot;
|
||||
|
||||
import RedditReposterBot.socialMediaHandler.SocialMediaPoster;
|
||||
import RedditReposterBot.redditHandler.RedditExtractor;
|
||||
import RedditReposterBot.exceptions.NoSuchFile;
|
||||
import RedditReposterBot.exceptions.NoSuchOrder;
|
||||
import RedditReposterBot.exceptions.NotSufficientRights;
|
||||
import RedditReposterBot.exceptions.NoSuchProperty;
|
||||
import RedditReposterBot.redditHandler.RedditPost;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Singleton Hypervisor. This is the object that does everything. So we want it
|
||||
* to be unique. That's why it's a singleton.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class Hypervisor {
|
||||
|
||||
/**
|
||||
* Working folder.
|
||||
*/
|
||||
private String workingDirectory;
|
||||
|
||||
/**
|
||||
* SQLITE database for saving the already parsed posts.
|
||||
*/
|
||||
private final String sqliteDatabase;
|
||||
|
||||
/**
|
||||
* SQLITE table name.
|
||||
*/
|
||||
private final String tableName;
|
||||
|
||||
/**
|
||||
* Delay between two scans, in seconds.
|
||||
*/
|
||||
private final int delay;
|
||||
|
||||
/**
|
||||
* Minimum of all the social medias text size.
|
||||
*/
|
||||
private final int maxLength;
|
||||
|
||||
/**
|
||||
* Subreddit to extract info from.
|
||||
*/
|
||||
private final String subreddit;
|
||||
|
||||
/**
|
||||
* The singleton.
|
||||
*/
|
||||
private static Hypervisor SINGLETON = null;
|
||||
|
||||
/**
|
||||
* All the social medias to post our reddit content.
|
||||
*/
|
||||
private final ArrayList<SocialMediaPoster> socialMedias;
|
||||
|
||||
/**
|
||||
* Connection to the SQLITE database.
|
||||
*/
|
||||
private Connection connexion;
|
||||
|
||||
/**
|
||||
* RedditExtractor.
|
||||
*/
|
||||
private final RedditExtractor myRedditExtractor;
|
||||
|
||||
/**
|
||||
* Private constructor so nobody except this obect can build this object.
|
||||
*/
|
||||
private Hypervisor()
|
||||
throws NotSufficientRights, ClassNotFoundException,
|
||||
SQLException, IOException, NoSuchFile, NoSuchProperty, NoSuchOrder {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
System.out.println("[+] Creating Hypervisor.");
|
||||
ConfigFileReader reader = new ConfigFileReader();
|
||||
this.subreddit = reader.getProperties("subreddit");
|
||||
this.tableName = reader.getProperties("subreddit");
|
||||
this.delay = Integer.valueOf(reader.getProperties("delay"));
|
||||
this.sqliteDatabase = reader.getProperties("sqlite_db_name");
|
||||
this.socialMedias = new ArrayList<>();
|
||||
this.workingDirectory = reader.getProperties("working_directory");
|
||||
setupTheBotDirectory();
|
||||
this.connexion = DriverManager.getConnection("jdbc:sqlite:"
|
||||
+ this.workingDirectory + File.separator
|
||||
+ this.sqliteDatabase);
|
||||
this.myRedditExtractor = new RedditExtractor(subreddit);
|
||||
if ("Y".equals(reader.getProperties("clear_database"))) {
|
||||
clearDatabase();
|
||||
}
|
||||
this.maxLength = Integer.valueOf(reader.getProperties("max_text_length"));
|
||||
load();
|
||||
this.connexion.close();
|
||||
System.out.println("[+] Hypervisor created successfully.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Singleton Hypervisor instance.
|
||||
*
|
||||
* @return the instance.
|
||||
*
|
||||
* @throws java.lang.ClassNotFoundException
|
||||
* @throws RedditReposterBot.exceptions.NotSufficientRights
|
||||
* @throws java.sql.SQLException
|
||||
* @throws java.io.IOException
|
||||
* @throws RedditReposterBot.exceptions.NoSuchFile
|
||||
* @throws RedditReposterBot.exceptions.NoSuchProperty
|
||||
* @throws RedditReposterBot.exceptions.NoSuchOrder
|
||||
*/
|
||||
public static Hypervisor getSingleton()
|
||||
throws ClassNotFoundException, NotSufficientRights,
|
||||
SQLException, IOException, NoSuchFile, NoSuchProperty, NoSuchOrder {
|
||||
if (SINGLETON == null) {
|
||||
SINGLETON = new Hypervisor();
|
||||
}
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main loop for the program. This is where everything happens.
|
||||
*
|
||||
* @throws java.lang.ClassNotFoundException
|
||||
* @throws java.sql.SQLException
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public void run()
|
||||
throws ClassNotFoundException, SQLException,
|
||||
InterruptedException {
|
||||
System.out.println("[+] Hypervisor is now running.");
|
||||
for (;;) {
|
||||
this.connexion = DriverManager.getConnection("jdbc:sqlite:"
|
||||
+ this.workingDirectory + File.separator
|
||||
+ this.sqliteDatabase);
|
||||
for (RedditPost post : myRedditExtractor.getRedditPosts()) {
|
||||
computeRedditPost(post);
|
||||
}
|
||||
this.connexion.close();
|
||||
System.out.println(
|
||||
"[*] Hypervisor is waiting for "
|
||||
+ this.delay + " seconds.");
|
||||
Thread.sleep(this.delay * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all the reddit posts from the database.
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void load() throws ClassNotFoundException, SQLException {
|
||||
createTable();
|
||||
PreparedStatement recherche = this.connexion.prepareStatement(
|
||||
"SELECT COUNT(id) AS cpt FROM " + this.tableName + ";");
|
||||
try (ResultSet res = recherche.executeQuery()) {
|
||||
res.next();
|
||||
System.out.println("[*] " + res.getInt("cpt") + " posts in database.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the database by dropping it.
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void clearDatabase() throws ClassNotFoundException, SQLException {
|
||||
System.out.println("[*] Clearing the database.");
|
||||
PreparedStatement stmt = connexion.prepareStatement(""
|
||||
+ "DROP TABLE IF EXISTS " + this.tableName + ";"
|
||||
);
|
||||
stmt.execute();
|
||||
createTable();
|
||||
System.out.println("[*] The database has been cleared successfully.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a given reddit post to the database.
|
||||
*
|
||||
* @param current a given reddit post to add to the database
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void addRedditPostToDatabase(RedditPost current)
|
||||
throws ClassNotFoundException, SQLException {
|
||||
createTable();
|
||||
if (!isInDatabase(current.getPostId())) {
|
||||
PreparedStatement ajout = this.connexion.prepareStatement(
|
||||
"INSERT INTO " + this.tableName
|
||||
+ "("
|
||||
+ "postType, "
|
||||
+ "postId, "
|
||||
+ "title, "
|
||||
+ "quarantine, "
|
||||
+ "score, "
|
||||
+ "postHint, "
|
||||
+ "crosspostable, "
|
||||
+ "over18, "
|
||||
+ "author, "
|
||||
+ "permalink, "
|
||||
+ "spoiler, "
|
||||
+ "url, "
|
||||
+ "shared"
|
||||
+ ") "
|
||||
+ "VALUES "
|
||||
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"
|
||||
);
|
||||
ajout.setString(1,
|
||||
current.isImage() ? "image"
|
||||
: current.isLink() ? "link"
|
||||
: current.isText() ? "text"
|
||||
: "video");
|
||||
ajout.setString(2, current.getPostId());
|
||||
ajout.setString(3, current.getTitle());
|
||||
ajout.setBoolean(4, current.isQuarantine());
|
||||
ajout.setDouble(5, current.getScore());
|
||||
ajout.setString(6, current.getPostHint());
|
||||
ajout.setBoolean(7, current.isCrosspostable());
|
||||
ajout.setBoolean(8, current.isOver18());
|
||||
ajout.setString(9, current.getAuthor());
|
||||
ajout.setString(10, current.getPermalink());
|
||||
ajout.setBoolean(11, current.isSpoiler());
|
||||
ajout.setString(12, current.getUrl());
|
||||
ajout.setBoolean(13, true);
|
||||
ajout.execute();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a post is in database.
|
||||
*
|
||||
* @param postId the post id
|
||||
* @return if the post is in the database
|
||||
*
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
private boolean isInDatabase(String postId)
|
||||
throws SQLException, ClassNotFoundException {
|
||||
PreparedStatement recherche = this.connexion.prepareStatement(
|
||||
"SELECT * FROM " + this.tableName + " "
|
||||
+ "WHERE postId = '" + postId + "'");
|
||||
try (ResultSet resultats = recherche.executeQuery()) {
|
||||
return resultats.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create our working table if it doesn't exists yet.
|
||||
*
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
private void createTable() throws SQLException, ClassNotFoundException {
|
||||
PreparedStatement stmt = connexion.prepareStatement(""
|
||||
+ "CREATE TABLE IF NOT EXISTS " + this.tableName + " "
|
||||
+ "("
|
||||
+ "id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||
+ "postType TEXT, "
|
||||
+ "postId TEXT UNIQUE, "
|
||||
+ "title TEXT, "
|
||||
+ "quarantine BOOLEAN, "
|
||||
+ "score DOUBLE, "
|
||||
+ "postHint TEXT, "
|
||||
+ "crosspostable BOOLEAN, "
|
||||
+ "over18 BOOLEAN, "
|
||||
+ "author TEXT, "
|
||||
+ "permalink TEXT, "
|
||||
+ "spoiler BOOLEAN, "
|
||||
+ "url TEXT, "
|
||||
+ "shared BOOLEAN"
|
||||
+ ");"
|
||||
);
|
||||
stmt.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a given reddit post.
|
||||
*
|
||||
* @param r the reddit post to compute.
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void computeRedditPost(RedditPost r)
|
||||
throws SQLException, ClassNotFoundException {
|
||||
if (!isInDatabase(r.getPostId()) && !r.isQuarantine() && r.hasMediaUrl()) {
|
||||
System.out.println(
|
||||
"[*] Computing the post \"" + r.getTitle() + "\"");
|
||||
addRedditPostToDatabase(r);
|
||||
String fileName = saveImage(r.getUrl());
|
||||
socialMedias.forEach((s) -> {
|
||||
long postRef = s.postImage(
|
||||
formatPost(r.getTitle()), fileName);
|
||||
if (postRef != 0 && postRef != -1) {
|
||||
s.replyText(formatPost("from /u/" + r.getAuthor() + " "
|
||||
+ "on /r/" + this.subreddit + " "
|
||||
+ "at link : https://www.reddit.com"
|
||||
+ r.getPermalink()), postRef);
|
||||
}
|
||||
});
|
||||
deleteFile(fileName);
|
||||
System.out.println("[+] Post \""
|
||||
+ r.getTitle()
|
||||
+ "\" has been shared successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a given text for being posted on the different social networks.
|
||||
*
|
||||
* @param text the text to format
|
||||
* @return the formatted text
|
||||
*/
|
||||
private String formatPost(String text) {
|
||||
return text.length() >= this.maxLength
|
||||
? text.substring(0, this.maxLength - 4) + "..."
|
||||
: text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Image from URL. Modified version of the code that can be found at
|
||||
* https://www.programcreek.com/2012/12/download-image-from-url-in-java/
|
||||
*
|
||||
* @param imageUrl the image URL.
|
||||
*/
|
||||
private String saveImage(String imageUrl) {
|
||||
System.out.println("[+] Dowloading image " + imageUrl + ".");
|
||||
try {
|
||||
URL url = new URL(imageUrl);
|
||||
String fileName = url.getFile();
|
||||
String destName = workingDirectory + fileName.substring(
|
||||
fileName.lastIndexOf("/"), fileName.lastIndexOf("?"));
|
||||
InputStream is = url.openStream();
|
||||
OutputStream os = new FileOutputStream(destName);
|
||||
|
||||
byte[] b = new byte[2048];
|
||||
int length;
|
||||
|
||||
while ((length = is.read(b)) != -1) {
|
||||
os.write(b, 0, length);
|
||||
}
|
||||
is.close();
|
||||
os.close();
|
||||
|
||||
System.out.println(
|
||||
"[+] Image " + destName + " dowloaded successfully.");
|
||||
return destName;
|
||||
} catch (IOException ex) {
|
||||
System.err.println("[!] IOException : " + ex.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file.
|
||||
*
|
||||
* @param filePath the path to the file we want to delete.
|
||||
*/
|
||||
private void deleteFile(String filePath) {
|
||||
File f = new File(filePath);
|
||||
f.delete();
|
||||
System.out.println("[*] File " + filePath + " deleted.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set working directory.
|
||||
*
|
||||
* @param tempDir the path to the working directory.
|
||||
* @throws RedditReposterBot.exceptions.NotSufficientRights
|
||||
*/
|
||||
public void setWorkDir(String tempDir) throws NotSufficientRights {
|
||||
this.workingDirectory = tempDir;
|
||||
setupTheBotDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the working directory.
|
||||
*
|
||||
* @return the working directory path.
|
||||
*/
|
||||
public String getWorkDir() {
|
||||
return workingDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the bot.
|
||||
*
|
||||
* @throws NotSufficientRights
|
||||
*/
|
||||
private void setupTheBotDirectory() throws NotSufficientRights {
|
||||
File f = new File(workingDirectory);
|
||||
f.mkdir();
|
||||
if (!f.canRead() || !f.canWrite()) {
|
||||
throw new NotSufficientRights(
|
||||
"[!] This program does not have the sufficient "
|
||||
+ "rights on the folder \"" + workingDirectory + "\".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a social media to post content to.
|
||||
*
|
||||
* @param s the social media
|
||||
*/
|
||||
public void addSocialMedia(SocialMediaPoster s) {
|
||||
this.socialMedias.add(s);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis;
|
||||
|
||||
import xyz.vallat.louis.socialMediaHandler.SocialMediaPoster;
|
||||
import xyz.vallat.louis.redditHandler.RedditExtractor;
|
||||
import xyz.vallat.louis.exceptions.NoSuchFile;
|
||||
import xyz.vallat.louis.exceptions.NoSuchOrder;
|
||||
import xyz.vallat.louis.exceptions.NotSufficientRights;
|
||||
import xyz.vallat.louis.exceptions.NoSuchProperty;
|
||||
import xyz.vallat.louis.redditHandler.RedditPost;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Singleton Hypervisor. This is the object that does everything. So we want it
|
||||
* to be unique. That's why it's a singleton.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class Hypervisor {
|
||||
|
||||
/**
|
||||
* Working folder.
|
||||
*/
|
||||
private String workingDirectory;
|
||||
|
||||
/**
|
||||
* SQLITE database for saving the already parsed posts.
|
||||
*/
|
||||
private final String sqliteDatabase;
|
||||
|
||||
/**
|
||||
* SQLITE table name.
|
||||
*/
|
||||
private final String tableName;
|
||||
|
||||
/**
|
||||
* Delay between two scans, in seconds.
|
||||
*/
|
||||
private final int delay;
|
||||
|
||||
/**
|
||||
* Minimum of all the social medias text size.
|
||||
*/
|
||||
private final int maxLength;
|
||||
|
||||
/**
|
||||
* Subreddit to extract info from.
|
||||
*/
|
||||
private final String subreddit;
|
||||
|
||||
/**
|
||||
* The singleton.
|
||||
*/
|
||||
private static Hypervisor SINGLETON = null;
|
||||
|
||||
/**
|
||||
* All the social medias to post our reddit content.
|
||||
*/
|
||||
private final ArrayList<SocialMediaPoster> socialMedias;
|
||||
|
||||
/**
|
||||
* Connection to the SQLITE database.
|
||||
*/
|
||||
private Connection connexion;
|
||||
|
||||
/**
|
||||
* RedditExtractor.
|
||||
*/
|
||||
private final RedditExtractor myRedditExtractor;
|
||||
|
||||
/**
|
||||
* Private constructor so nobody except this obect can build this object.
|
||||
*/
|
||||
private Hypervisor()
|
||||
throws NotSufficientRights, ClassNotFoundException,
|
||||
SQLException, IOException, NoSuchFile, NoSuchProperty, NoSuchOrder {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
System.out.println("[+] Creating Hypervisor.");
|
||||
ConfigFileReader reader = new ConfigFileReader();
|
||||
this.subreddit = reader.getProperties("subreddit");
|
||||
this.tableName = reader.getProperties("subreddit");
|
||||
this.delay = Integer.valueOf(reader.getProperties("delay"));
|
||||
this.sqliteDatabase = reader.getProperties("sqlite_db_name");
|
||||
this.socialMedias = new ArrayList<>();
|
||||
this.workingDirectory = reader.getProperties("working_directory");
|
||||
setupTheBotDirectory();
|
||||
this.connexion = DriverManager.getConnection("jdbc:sqlite:"
|
||||
+ this.workingDirectory + File.separator
|
||||
+ this.sqliteDatabase);
|
||||
this.myRedditExtractor = new RedditExtractor(subreddit);
|
||||
if ("Y".equals(reader.getProperties("clear_database"))) {
|
||||
clearDatabase();
|
||||
}
|
||||
this.maxLength = Integer.valueOf(reader.getProperties("max_text_length"));
|
||||
load();
|
||||
this.connexion.close();
|
||||
System.out.println("[+] Hypervisor created successfully.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Singleton Hypervisor instance.
|
||||
*
|
||||
* @return the instance.
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws NotSufficientRights
|
||||
* @throws SQLException
|
||||
* @throws IOException
|
||||
* @throws NoSuchFile
|
||||
* @throws NoSuchProperty
|
||||
* @throws NoSuchOrder
|
||||
*/
|
||||
public static Hypervisor getSingleton()
|
||||
throws ClassNotFoundException, NotSufficientRights,
|
||||
SQLException, IOException, NoSuchFile, NoSuchProperty, NoSuchOrder {
|
||||
if (SINGLETON == null) {
|
||||
SINGLETON = new Hypervisor();
|
||||
}
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main loop for the program. This is where everything happens.
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void run()
|
||||
throws ClassNotFoundException, SQLException,
|
||||
InterruptedException {
|
||||
System.out.println("[+] Hypervisor is now running.");
|
||||
for (;;) {
|
||||
this.connexion = DriverManager.getConnection("jdbc:sqlite:"
|
||||
+ this.workingDirectory + File.separator
|
||||
+ this.sqliteDatabase);
|
||||
for (RedditPost post : myRedditExtractor.getRedditPosts()) {
|
||||
computeRedditPost(post);
|
||||
}
|
||||
this.connexion.close();
|
||||
System.out.println(
|
||||
"[*] Hypervisor is waiting for "
|
||||
+ this.delay + " seconds.");
|
||||
Thread.sleep(this.delay * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all the reddit posts from the database.
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void load() throws ClassNotFoundException, SQLException {
|
||||
createTable();
|
||||
PreparedStatement recherche = this.connexion.prepareStatement(
|
||||
"SELECT COUNT(id) AS cpt FROM " + this.tableName + ";");
|
||||
try (ResultSet res = recherche.executeQuery()) {
|
||||
res.next();
|
||||
System.out.println("[*] " + res.getInt("cpt") + " posts in database.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the database by dropping it.
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void clearDatabase() throws ClassNotFoundException, SQLException {
|
||||
System.out.println("[*] Clearing the database.");
|
||||
PreparedStatement stmt = connexion.prepareStatement(""
|
||||
+ "DROP TABLE IF EXISTS " + this.tableName + ";"
|
||||
);
|
||||
stmt.execute();
|
||||
createTable();
|
||||
System.out.println("[*] The database has been cleared successfully.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a given reddit post to the database.
|
||||
*
|
||||
* @param current a given reddit post to add to the database
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void addRedditPostToDatabase(RedditPost current)
|
||||
throws ClassNotFoundException, SQLException {
|
||||
createTable();
|
||||
if (!isInDatabase(current.getPostId())) {
|
||||
PreparedStatement ajout = this.connexion.prepareStatement(
|
||||
"INSERT INTO " + this.tableName
|
||||
+ "("
|
||||
+ "postType, "
|
||||
+ "postId, "
|
||||
+ "title, "
|
||||
+ "quarantine, "
|
||||
+ "score, "
|
||||
+ "postHint, "
|
||||
+ "crosspostable, "
|
||||
+ "over18, "
|
||||
+ "author, "
|
||||
+ "permalink, "
|
||||
+ "spoiler, "
|
||||
+ "url, "
|
||||
+ "shared"
|
||||
+ ") "
|
||||
+ "VALUES "
|
||||
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"
|
||||
);
|
||||
ajout.setString(1,
|
||||
current.isImage() ? "image"
|
||||
: current.isLink() ? "link"
|
||||
: current.isText() ? "text"
|
||||
: "video");
|
||||
ajout.setString(2, current.getPostId());
|
||||
ajout.setString(3, current.getTitle());
|
||||
ajout.setBoolean(4, current.isQuarantine());
|
||||
ajout.setDouble(5, current.getScore());
|
||||
ajout.setString(6, current.getPostHint());
|
||||
ajout.setBoolean(7, current.isCrosspostable());
|
||||
ajout.setBoolean(8, current.isOver18());
|
||||
ajout.setString(9, current.getAuthor());
|
||||
ajout.setString(10, current.getPermalink());
|
||||
ajout.setBoolean(11, current.isSpoiler());
|
||||
ajout.setString(12, current.getUrl());
|
||||
ajout.setBoolean(13, true);
|
||||
ajout.execute();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a post is in database.
|
||||
*
|
||||
* @param postId the post id
|
||||
* @return if the post is in the database
|
||||
*
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
private boolean isInDatabase(String postId)
|
||||
throws SQLException, ClassNotFoundException {
|
||||
PreparedStatement recherche = this.connexion.prepareStatement(
|
||||
"SELECT * FROM " + this.tableName + " "
|
||||
+ "WHERE postId = '" + postId + "'");
|
||||
try (ResultSet resultats = recherche.executeQuery()) {
|
||||
return resultats.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create our working table if it doesn't exists yet.
|
||||
*
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
private void createTable() throws SQLException, ClassNotFoundException {
|
||||
PreparedStatement stmt = connexion.prepareStatement(""
|
||||
+ "CREATE TABLE IF NOT EXISTS " + this.tableName + " "
|
||||
+ "("
|
||||
+ "id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||
+ "postType TEXT, "
|
||||
+ "postId TEXT UNIQUE, "
|
||||
+ "title TEXT, "
|
||||
+ "quarantine BOOLEAN, "
|
||||
+ "score DOUBLE, "
|
||||
+ "postHint TEXT, "
|
||||
+ "crosspostable BOOLEAN, "
|
||||
+ "over18 BOOLEAN, "
|
||||
+ "author TEXT, "
|
||||
+ "permalink TEXT, "
|
||||
+ "spoiler BOOLEAN, "
|
||||
+ "url TEXT, "
|
||||
+ "shared BOOLEAN"
|
||||
+ ");"
|
||||
);
|
||||
stmt.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a given reddit post.
|
||||
*
|
||||
* @param r the reddit post to compute.
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void computeRedditPost(RedditPost r)
|
||||
throws SQLException, ClassNotFoundException {
|
||||
if (!isInDatabase(r.getPostId()) && !r.isQuarantine() && r.hasMediaUrl()) {
|
||||
System.out.println(
|
||||
"[*] Computing the post \"" + r.getTitle() + "\"");
|
||||
addRedditPostToDatabase(r);
|
||||
String fileName = saveImage(r.getUrl());
|
||||
socialMedias.forEach((s) -> {
|
||||
long postRef = s.postImage(
|
||||
formatPost(r.getTitle()), fileName);
|
||||
if (postRef != 0 && postRef != -1) {
|
||||
s.replyText(formatPost("from /u/" + r.getAuthor() + " "
|
||||
+ "on /r/" + this.subreddit + " "
|
||||
+ "at link : https://www.reddit.com"
|
||||
+ r.getPermalink()), postRef);
|
||||
}
|
||||
});
|
||||
deleteFile(fileName);
|
||||
System.out.println("[+] Post \""
|
||||
+ r.getTitle()
|
||||
+ "\" has been shared successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a given text for being posted on the different social networks.
|
||||
*
|
||||
* @param text the text to format
|
||||
* @return the formatted text
|
||||
*/
|
||||
private String formatPost(String text) {
|
||||
return text.length() >= this.maxLength
|
||||
? text.substring(0, this.maxLength - 4) + "..."
|
||||
: text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Image from URL. Modified version of the code that can be found at
|
||||
* https://www.programcreek.com/2012/12/download-image-from-url-in-java/
|
||||
*
|
||||
* @param imageUrl the image URL.
|
||||
*/
|
||||
private String saveImage(String imageUrl) {
|
||||
System.out.println("[+] Dowloading image " + imageUrl + ".");
|
||||
try {
|
||||
URL url = new URL(imageUrl);
|
||||
String fileName = url.getFile();
|
||||
String destName = workingDirectory + fileName.substring(
|
||||
fileName.lastIndexOf("/"), fileName.lastIndexOf("?"));
|
||||
InputStream is = url.openStream();
|
||||
OutputStream os = new FileOutputStream(destName);
|
||||
|
||||
byte[] b = new byte[2048];
|
||||
int length;
|
||||
|
||||
while ((length = is.read(b)) != -1) {
|
||||
os.write(b, 0, length);
|
||||
}
|
||||
is.close();
|
||||
os.close();
|
||||
|
||||
System.out.println(
|
||||
"[+] Image " + destName + " dowloaded successfully.");
|
||||
return destName;
|
||||
} catch (IOException ex) {
|
||||
System.err.println("[!] IOException : " + ex.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file.
|
||||
*
|
||||
* @param filePath the path to the file we want to delete.
|
||||
*/
|
||||
private void deleteFile(String filePath) {
|
||||
File f = new File(filePath);
|
||||
f.delete();
|
||||
System.out.println("[*] File " + filePath + " deleted.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set working directory.
|
||||
*
|
||||
* @param tempDir the path to the working directory.
|
||||
* @throws NotSufficientRights
|
||||
*/
|
||||
public void setWorkDir(String tempDir) throws NotSufficientRights {
|
||||
this.workingDirectory = tempDir;
|
||||
setupTheBotDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the working directory.
|
||||
*
|
||||
* @return the working directory path.
|
||||
*/
|
||||
public String getWorkDir() {
|
||||
return workingDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the bot.
|
||||
*
|
||||
* @throws NotSufficientRights
|
||||
*/
|
||||
private void setupTheBotDirectory() throws NotSufficientRights {
|
||||
File f = new File(workingDirectory);
|
||||
f.mkdir();
|
||||
if (!f.canRead() || !f.canWrite()) {
|
||||
throw new NotSufficientRights(
|
||||
"[!] This program does not have the sufficient "
|
||||
+ "rights on the folder \"" + workingDirectory + "\".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a social media to post content to.
|
||||
*
|
||||
* @param s the social media
|
||||
*/
|
||||
public void addSocialMedia(SocialMediaPoster s) {
|
||||
this.socialMedias.add(s);
|
||||
}
|
||||
}
|
136
reddit_reposter_bot/src/RedditReposterBot/RedditReposterBot.java → src/main/java/xyz.vallat.louis/RedditReposterBot.java
Normal file → Executable file
136
reddit_reposter_bot/src/RedditReposterBot/RedditReposterBot.java → src/main/java/xyz.vallat.louis/RedditReposterBot.java
Normal file → Executable file
@ -1,68 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot;
|
||||
|
||||
import RedditReposterBot.socialMediaHandler.TwitterBot;
|
||||
import RedditReposterBot.exceptions.NoSuchFile;
|
||||
import RedditReposterBot.exceptions.NoSuchOrder;
|
||||
import RedditReposterBot.exceptions.NoSuchProperty;
|
||||
import RedditReposterBot.exceptions.NotSufficientRights;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* This is where everything begins.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class RedditReposterBot {
|
||||
|
||||
/**
|
||||
* Version of the application.
|
||||
*/
|
||||
private static final String VERSION = "1.0.1";
|
||||
|
||||
/**
|
||||
* Launch the Hypervisor.
|
||||
*
|
||||
* @param args command line arguments
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws NotSufficientRights
|
||||
* @throws SQLException
|
||||
* @throws IOException
|
||||
* @throws InterruptedException
|
||||
* @throws NoSuchFile
|
||||
* @throws NoSuchProperty
|
||||
* @throws NoSuchOrder
|
||||
*/
|
||||
public static void main(String[] args) throws
|
||||
ClassNotFoundException,
|
||||
NotSufficientRights,
|
||||
SQLException,
|
||||
IOException,
|
||||
InterruptedException,
|
||||
NoSuchFile,
|
||||
NoSuchProperty,
|
||||
NoSuchOrder {
|
||||
|
||||
System.out.println("[*] App version " + VERSION);
|
||||
Hypervisor master = Hypervisor.getSingleton();
|
||||
master.addSocialMedia(new TwitterBot());
|
||||
master.run();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis;
|
||||
|
||||
import xyz.vallat.louis.socialMediaHandler.TwitterBot;
|
||||
import xyz.vallat.louis.exceptions.NoSuchFile;
|
||||
import xyz.vallat.louis.exceptions.NoSuchOrder;
|
||||
import xyz.vallat.louis.exceptions.NoSuchProperty;
|
||||
import xyz.vallat.louis.exceptions.NotSufficientRights;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* This is where everything begins.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class RedditReposterBot {
|
||||
|
||||
/**
|
||||
* Version of the application.
|
||||
*/
|
||||
private static final String VERSION = "1.0.1";
|
||||
|
||||
/**
|
||||
* Launch the Hypervisor.
|
||||
*
|
||||
* @param args command line arguments
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
* @throws NotSufficientRights
|
||||
* @throws SQLException
|
||||
* @throws IOException
|
||||
* @throws InterruptedException
|
||||
* @throws NoSuchFile
|
||||
* @throws NoSuchProperty
|
||||
* @throws NoSuchOrder
|
||||
*/
|
||||
public static void main(String[] args) throws
|
||||
ClassNotFoundException,
|
||||
NotSufficientRights,
|
||||
SQLException,
|
||||
IOException,
|
||||
InterruptedException,
|
||||
NoSuchFile,
|
||||
NoSuchProperty,
|
||||
NoSuchOrder {
|
||||
|
||||
System.out.println("[*] App version " + VERSION);
|
||||
Hypervisor master = Hypervisor.getSingleton();
|
||||
master.addSocialMedia(new TwitterBot());
|
||||
master.run();
|
||||
}
|
||||
}
|
82
reddit_reposter_bot/src/RedditReposterBot/exceptions/NoSuchFile.java → src/main/java/xyz.vallat.louis/exceptions/NoSuchFile.java
Normal file → Executable file
82
reddit_reposter_bot/src/RedditReposterBot/exceptions/NoSuchFile.java → src/main/java/xyz.vallat.louis/exceptions/NoSuchFile.java
Normal file → Executable file
@ -1,41 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.exceptions;
|
||||
|
||||
/**
|
||||
* Exception throwable when there are no file at a given path.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class NoSuchFile extends Exception {
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>NoSuchFile</code> without detail message.
|
||||
*/
|
||||
public NoSuchFile() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>NoSuchFile</code> with the specified
|
||||
* detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public NoSuchFile(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.exceptions;
|
||||
|
||||
/**
|
||||
* Exception throwable when there are no file at a given path.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class NoSuchFile extends Exception {
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>NoSuchFile</code> without detail message.
|
||||
*/
|
||||
public NoSuchFile() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>NoSuchFile</code> with the specified
|
||||
* detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public NoSuchFile(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
84
reddit_reposter_bot/src/RedditReposterBot/exceptions/NoSuchOrder.java → src/main/java/xyz.vallat.louis/exceptions/NoSuchOrder.java
Normal file → Executable file
84
reddit_reposter_bot/src/RedditReposterBot/exceptions/NoSuchOrder.java → src/main/java/xyz.vallat.louis/exceptions/NoSuchOrder.java
Normal file → Executable file
@ -1,42 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.exceptions;
|
||||
|
||||
/**
|
||||
* Exception throwable when a sort order isn't a correct one.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class NoSuchOrder extends Exception {
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>NoSuchOrder</code> without detail
|
||||
* message.
|
||||
*/
|
||||
public NoSuchOrder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>NoSuchOrder</code> with the specified
|
||||
* detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public NoSuchOrder(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.exceptions;
|
||||
|
||||
/**
|
||||
* Exception throwable when a sort order isn't a correct one.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class NoSuchOrder extends Exception {
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>NoSuchOrder</code> without detail
|
||||
* message.
|
||||
*/
|
||||
public NoSuchOrder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>NoSuchOrder</code> with the specified
|
||||
* detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public NoSuchOrder(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
@ -1,43 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.exceptions;
|
||||
|
||||
/**
|
||||
* Exception throwable when there are no property in the config file for a given
|
||||
* setting name/id.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class NoSuchProperty extends Exception {
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>NoSuchProperty</code> without detail
|
||||
* message.
|
||||
*/
|
||||
public NoSuchProperty() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>NoSuchProperty</code> with the specified
|
||||
* detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public NoSuchProperty(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.exceptions;
|
||||
|
||||
/**
|
||||
* Exception throwable when there are no property in the config file for a given
|
||||
* setting name/id.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class NoSuchProperty extends Exception {
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>NoSuchProperty</code> without detail
|
||||
* message.
|
||||
*/
|
||||
public NoSuchProperty() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>NoSuchProperty</code> with the specified
|
||||
* detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public NoSuchProperty(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
@ -1,42 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.exceptions;
|
||||
|
||||
/**
|
||||
* Exception throwable when the rights on a folder or a file aren't sufficient.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class NotSufficientRights extends Exception {
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>NotSufficientRights</code> without detail
|
||||
* message.
|
||||
*/
|
||||
public NotSufficientRights() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>NotSufficientRights</code> with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public NotSufficientRights(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.exceptions;
|
||||
|
||||
/**
|
||||
* Exception throwable when the rights on a folder or a file aren't sufficient.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class NotSufficientRights extends Exception {
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>NotSufficientRights</code> without detail
|
||||
* message.
|
||||
*/
|
||||
public NotSufficientRights() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>NotSufficientRights</code> with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public NotSufficientRights(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
@ -1,232 +1,229 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.redditHandler;
|
||||
|
||||
import RedditReposterBot.exceptions.NoSuchFile;
|
||||
import RedditReposterBot.exceptions.NoSuchOrder;
|
||||
import RedditReposterBot.exceptions.NoSuchProperty;
|
||||
import RedditReposterBot.exceptions.NotSufficientRights;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Reddit extractor object.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public final class RedditExtractor {
|
||||
|
||||
/**
|
||||
* Subreddit to extract infos from.
|
||||
*/
|
||||
private final SubReddit sub;
|
||||
|
||||
/**
|
||||
* Main Constructor.
|
||||
*
|
||||
* @param subreddit Subreddit name. Just after /r/
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RedditReposterBot.exceptions.NoSuchProperty
|
||||
* @throws RedditReposterBot.exceptions.NoSuchFile
|
||||
* @throws RedditReposterBot.exceptions.NotSufficientRights
|
||||
* @throws NoSuchOrder
|
||||
*/
|
||||
public RedditExtractor(String subreddit)
|
||||
throws IOException, NoSuchProperty, NoSuchFile,
|
||||
NotSufficientRights, NoSuchOrder {
|
||||
if (!doesSubredditExists(subreddit)) {
|
||||
throw new MalformedURLException("This subreddit ("
|
||||
+ subreddit + ") does not exist.");
|
||||
} else {
|
||||
this.sub = new SubReddit(subreddit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a subreddit exists.
|
||||
*
|
||||
* @param subredditName
|
||||
* @return if a subreddit exists
|
||||
*/
|
||||
public boolean doesSubredditExists(String subredditName) {
|
||||
System.out.println("[*] Checking if subreddit /r/" + subredditName
|
||||
+ " exists.");
|
||||
return ((new JsonParser()
|
||||
.parse(getJsonFromURL(""
|
||||
+ "https://www.reddit.com/api/search_reddit_names.json"
|
||||
+ "?query=" + subredditName + "&exact=true"))
|
||||
.getAsJsonObject().get("names").getAsJsonArray()
|
||||
.size()) >= 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the subreddit JSON response.
|
||||
*
|
||||
* @return the JSON from the REDDIT API.
|
||||
*/
|
||||
public String getSubredditJson() {
|
||||
return getJsonFromURL(this.sub.getJsonURL());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get JSON from URL.
|
||||
*
|
||||
* @param URL the JSON url.
|
||||
* @return the JSON data as a String from the given URL.
|
||||
*/
|
||||
public String getJsonFromURL(String URL) {
|
||||
try {
|
||||
System.out.println("[+] Obtaining JSON from URL " + URL + ".");
|
||||
HttpURLConnection con;
|
||||
URL myurl = new URL(URL);
|
||||
con = (HttpURLConnection) myurl.openConnection();
|
||||
try {
|
||||
con.setRequestMethod("GET");
|
||||
con.setRequestProperty("User-Agent", "Mozilla 5.0 (Windows; U; "
|
||||
+ "Windows NT 5.1; en-US; rv:1.8.0.11) ");
|
||||
StringBuilder response;
|
||||
try (BufferedReader in = new BufferedReader(
|
||||
new InputStreamReader(con.getInputStream()))) {
|
||||
String line;
|
||||
response = new StringBuilder();
|
||||
while ((line = in.readLine()) != null) {
|
||||
response.append(line);
|
||||
response.append(System.lineSeparator());
|
||||
}
|
||||
return response.toString();
|
||||
}
|
||||
} finally {
|
||||
con.disconnect();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("[!] IOException: " + e.getMessage());
|
||||
System.out.println("[!] Retrying...");
|
||||
return getJsonFromURL(URL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Reddit's subreddit posts.
|
||||
*
|
||||
* @return a treeset of all the reddit posts parsed.
|
||||
*/
|
||||
public HashSet<RedditPost> getRedditPosts() {
|
||||
try {
|
||||
HashSet<RedditPost> set = new HashSet<>();
|
||||
String jsonResponse = getSubredditJson();
|
||||
JsonObject objet = new JsonParser().parse(jsonResponse)
|
||||
.getAsJsonObject();
|
||||
JsonObject data = new JsonParser().parse(objet.get("data")
|
||||
.toString()).getAsJsonObject();
|
||||
JsonArray children = new JsonParser().parse(data.get("children")
|
||||
.toString()).getAsJsonArray();
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
try {
|
||||
JsonObject child = new JsonParser().parse(children.get(i)
|
||||
.toString()).getAsJsonObject();
|
||||
JsonObject childData = new JsonParser().parse(child.get("data")
|
||||
.toString()).getAsJsonObject();
|
||||
if (childData.get("id").toString() != null
|
||||
&& !childData.get("quarantine").getAsBoolean()
|
||||
&& childData.get("url").getAsString() != null) {
|
||||
String id = childData.get("id").toString();
|
||||
String title = childData.get("title") != null
|
||||
? childData.get("title").toString()
|
||||
: this.sub.getName();
|
||||
title = title
|
||||
.replace("\"", "")
|
||||
.replace("\\", "\"")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("&", "&");
|
||||
String author = childData.get("author") != null
|
||||
? childData.get("author").toString()
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("&", "&") : "anonymous";
|
||||
author = author.replace("\"", "");
|
||||
boolean quarantine = childData.get("quarantine")
|
||||
.getAsBoolean();
|
||||
double score = childData.get("score").getAsDouble();
|
||||
String postHint = childData.get("post_hint").getAsString();
|
||||
boolean crosspostable = !childData.get("is_crosspostable")
|
||||
.getAsBoolean();
|
||||
boolean over18 = childData.get("over_18").getAsBoolean();
|
||||
String url;
|
||||
try {
|
||||
JsonObject preview = new JsonParser().parse(childData
|
||||
.get("preview").toString()).getAsJsonObject();
|
||||
JsonArray previewImages = new JsonParser().parse(preview
|
||||
.get("images").toString()).getAsJsonArray();
|
||||
JsonObject source = new JsonParser().parse(previewImages
|
||||
.get(0).toString()).getAsJsonObject();
|
||||
JsonObject urlSrc = new JsonParser().parse(source
|
||||
.get("source").toString()).getAsJsonObject();
|
||||
url = urlSrc.get("url").toString().replace("&", "&")
|
||||
.replace("\"", "");
|
||||
} catch (NullPointerException n) {
|
||||
url = childData.get("url").getAsString();
|
||||
}
|
||||
String permalink = childData.get("permalink").getAsString();
|
||||
boolean spoiler = childData.get("spoiler").getAsBoolean();
|
||||
|
||||
if (postHint.contains("video")) {
|
||||
set.add(new RedditPostVideo(
|
||||
id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author,
|
||||
permalink, spoiler, url));
|
||||
} else if ("link".equals(postHint)) {
|
||||
set.add(new RedditPostLink(
|
||||
id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author,
|
||||
permalink, spoiler, url));
|
||||
} else if ("text".equals(postHint)) {
|
||||
set.add(new RedditPostText(
|
||||
id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author,
|
||||
permalink, spoiler, url));
|
||||
} else if ("image".equals(postHint)) {
|
||||
set.add(new RedditPostImage(
|
||||
id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author,
|
||||
permalink, spoiler, url));
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
System.out.println(
|
||||
"[*] There were a problem while parsing. "
|
||||
+ "Continuing");
|
||||
}
|
||||
}
|
||||
return set;
|
||||
} catch (JsonSyntaxException e) {
|
||||
System.err.println("[!] JsonSyntaxException: " + e.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.redditHandler;
|
||||
|
||||
import com.google.gson.*;
|
||||
import xyz.vallat.louis.exceptions.NoSuchFile;
|
||||
import xyz.vallat.louis.exceptions.NoSuchOrder;
|
||||
import xyz.vallat.louis.exceptions.NoSuchProperty;
|
||||
import xyz.vallat.louis.exceptions.NotSufficientRights;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Reddit extractor object.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public final class RedditExtractor {
|
||||
|
||||
/**
|
||||
* Subreddit to extract infos from.
|
||||
*/
|
||||
private final SubReddit sub;
|
||||
|
||||
/**
|
||||
* Main Constructor.
|
||||
*
|
||||
* @param subreddit Subreddit name. Just after /r/
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws NoSuchProperty
|
||||
* @throws NoSuchFile
|
||||
* @throws NotSufficientRights
|
||||
* @throws NoSuchOrder
|
||||
*/
|
||||
public RedditExtractor(String subreddit)
|
||||
throws IOException, NoSuchProperty, NoSuchFile,
|
||||
NotSufficientRights, NoSuchOrder {
|
||||
if (!doesSubredditExists(subreddit)) {
|
||||
throw new MalformedURLException("This subreddit ("
|
||||
+ subreddit + ") does not exist.");
|
||||
} else {
|
||||
this.sub = new SubReddit(subreddit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a subreddit exists.
|
||||
*
|
||||
* @param subredditName
|
||||
* @return if a subreddit exists
|
||||
*/
|
||||
public boolean doesSubredditExists(String subredditName) {
|
||||
System.out.println("[*] Checking if subreddit /r/" + subredditName
|
||||
+ " exists.");
|
||||
return ((JsonParser.parseString(getJsonFromURL(""
|
||||
+ "https://www.reddit.com/api/search_reddit_names.json"
|
||||
+ "?query=" + subredditName + "&exact=true")).getAsJsonObject()
|
||||
.get("names").getAsJsonArray()
|
||||
.size()) >= 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the subreddit JSON response.
|
||||
*
|
||||
* @return the JSON from the REDDIT API.
|
||||
*/
|
||||
public String getSubredditJson() {
|
||||
return getJsonFromURL(this.sub.getJsonURL());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get JSON from URL.
|
||||
*
|
||||
* @param URL the JSON url.
|
||||
* @return the JSON data as a String from the given URL.
|
||||
*/
|
||||
public String getJsonFromURL(String URL) {
|
||||
try {
|
||||
System.out.println("[+] Obtaining JSON from URL " + URL + ".");
|
||||
HttpURLConnection con;
|
||||
URL myurl = new URL(URL);
|
||||
con = (HttpURLConnection) myurl.openConnection();
|
||||
try {
|
||||
con.setRequestMethod("GET");
|
||||
con.setRequestProperty("User-Agent", "Mozilla 5.0 (Windows; U; "
|
||||
+ "Windows NT 5.1; en-US; rv:1.8.0.11) ");
|
||||
StringBuilder response;
|
||||
try (BufferedReader in = new BufferedReader(
|
||||
new InputStreamReader(con.getInputStream()))) {
|
||||
String line;
|
||||
response = new StringBuilder();
|
||||
while ((line = in.readLine()) != null) {
|
||||
response.append(line);
|
||||
response.append(System.lineSeparator());
|
||||
}
|
||||
return response.toString();
|
||||
}
|
||||
} finally {
|
||||
con.disconnect();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("[!] IOException: " + e.getMessage());
|
||||
System.out.println("[!] Retrying...");
|
||||
return getJsonFromURL(URL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Reddit's subreddit posts.
|
||||
*
|
||||
* @return a treeset of all the reddit posts parsed.
|
||||
*/
|
||||
public HashSet<RedditPost> getRedditPosts() {
|
||||
try {
|
||||
HashSet<RedditPost> set = new HashSet<>();
|
||||
String jsonResponse = getSubredditJson();
|
||||
JsonObject objet = JsonParser.parseString(jsonResponse)
|
||||
.getAsJsonObject();
|
||||
JsonObject data = JsonParser.parseString(objet.get("data")
|
||||
.toString()).getAsJsonObject();
|
||||
JsonArray children = JsonParser.parseString(data.get("children")
|
||||
.toString()).getAsJsonArray();
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
try {
|
||||
JsonObject child = JsonParser.parseString(children.get(i)
|
||||
.toString()).getAsJsonObject();
|
||||
JsonObject childData = JsonParser.parseString(child.get("data")
|
||||
.toString()).getAsJsonObject();
|
||||
if (childData.get("id").toString() != null
|
||||
&& !childData.get("quarantine").getAsBoolean()
|
||||
&& childData.get("url").getAsString() != null) {
|
||||
String id = childData.get("id").toString();
|
||||
String title = childData.get("title") != null
|
||||
? childData.get("title").toString()
|
||||
: this.sub.getName();
|
||||
title = title
|
||||
.replace("\"", "")
|
||||
.replace("\\", "\"")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("&", "&");
|
||||
String author = childData.get("author") != null
|
||||
? childData.get("author").toString()
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("&", "&") : "anonymous";
|
||||
author = author.replace("\"", "");
|
||||
boolean quarantine = childData.get("quarantine")
|
||||
.getAsBoolean();
|
||||
double score = childData.get("score").getAsDouble();
|
||||
String postHint = childData.get("post_hint").getAsString();
|
||||
boolean crosspostable = !childData.get("is_crosspostable")
|
||||
.getAsBoolean();
|
||||
boolean over18 = childData.get("over_18").getAsBoolean();
|
||||
String url;
|
||||
try {
|
||||
JsonObject preview = JsonParser.parseString(childData
|
||||
.get("preview").toString()).getAsJsonObject();
|
||||
JsonArray previewImages = JsonParser.parseString(preview
|
||||
.get("images").toString()).getAsJsonArray();
|
||||
JsonObject source = JsonParser.parseString(previewImages
|
||||
.get(0).toString()).getAsJsonObject();
|
||||
JsonObject urlSrc = JsonParser.parseString(source
|
||||
.get("source").toString()).getAsJsonObject();
|
||||
url = urlSrc.get("url").toString().replace("&", "&")
|
||||
.replace("\"", "");
|
||||
} catch (NullPointerException n) {
|
||||
url = childData.get("url").getAsString();
|
||||
}
|
||||
String permalink = childData.get("permalink").getAsString();
|
||||
boolean spoiler = childData.get("spoiler").getAsBoolean();
|
||||
|
||||
if (postHint.contains("video")) {
|
||||
set.add(new RedditPostVideo(
|
||||
id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author,
|
||||
permalink, spoiler, url));
|
||||
} else if ("link".equals(postHint)) {
|
||||
set.add(new RedditPostLink(
|
||||
id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author,
|
||||
permalink, spoiler, url));
|
||||
} else if ("text".equals(postHint)) {
|
||||
set.add(new RedditPostText(
|
||||
id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author,
|
||||
permalink, spoiler, url));
|
||||
} else if ("image".equals(postHint)) {
|
||||
set.add(new RedditPostImage(
|
||||
id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author,
|
||||
permalink, spoiler, url));
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
System.out.println(
|
||||
"[*] There were a problem while parsing. "
|
||||
+ "Continuing");
|
||||
}
|
||||
}
|
||||
return set;
|
||||
} catch (JsonSyntaxException e) {
|
||||
System.err.println("[!] JsonSyntaxException: " + e.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
530
reddit_reposter_bot/src/RedditReposterBot/redditHandler/RedditPost.java → src/main/java/xyz.vallat.louis/redditHandler/RedditPost.java
Normal file → Executable file
530
reddit_reposter_bot/src/RedditReposterBot/redditHandler/RedditPost.java → src/main/java/xyz.vallat.louis/redditHandler/RedditPost.java
Normal file → Executable file
@ -1,265 +1,265 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.redditHandler;
|
||||
|
||||
/**
|
||||
* This is an abstract class to define all RedditPosts.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public abstract class RedditPost {
|
||||
|
||||
/**
|
||||
* Post's id.
|
||||
*/
|
||||
protected String postId;
|
||||
|
||||
/**
|
||||
* Post's title.
|
||||
*/
|
||||
protected String title;
|
||||
|
||||
/**
|
||||
* Is the post in quarantine?
|
||||
*/
|
||||
protected boolean quarantine;
|
||||
|
||||
/**
|
||||
* Post's score.
|
||||
*/
|
||||
protected double score;
|
||||
|
||||
/**
|
||||
* Post's hint.
|
||||
*/
|
||||
protected String postHint;
|
||||
|
||||
/**
|
||||
* Is this post crosspostable?
|
||||
*/
|
||||
protected boolean crosspostable;
|
||||
|
||||
/**
|
||||
* Is this post NSFW?
|
||||
*/
|
||||
protected boolean over18;
|
||||
|
||||
/**
|
||||
* Post's author.
|
||||
*/
|
||||
protected String author;
|
||||
|
||||
/**
|
||||
* Post's permalink.
|
||||
*/
|
||||
protected String permalink;
|
||||
|
||||
/**
|
||||
* Is this post a spoiler?
|
||||
*/
|
||||
protected boolean spoiler;
|
||||
|
||||
/**
|
||||
* Post's media url.
|
||||
*/
|
||||
protected String url;
|
||||
|
||||
/**
|
||||
* Main constructor for a Reddit post.
|
||||
*
|
||||
* @param id post's id
|
||||
* @param title post's title
|
||||
* @param quarantine is this post in quarantine?
|
||||
* @param score post's score
|
||||
* @param postHint post's hint
|
||||
* @param crosspostable is post crosspostable?
|
||||
* @param over18 is post NSFW?
|
||||
* @param author post's author
|
||||
* @param permalink post's permalink
|
||||
* @param spoiler is this post a spoiler?
|
||||
* @param url post's media url
|
||||
*/
|
||||
public RedditPost(String id, String title, boolean quarantine, double score,
|
||||
String postHint, boolean crosspostable, boolean over18,
|
||||
String author, String permalink, boolean spoiler, String url) {
|
||||
this.postId = id;
|
||||
this.title = title;
|
||||
this.quarantine = quarantine;
|
||||
this.score = score;
|
||||
this.postHint = postHint;
|
||||
this.crosspostable = crosspostable;
|
||||
this.over18 = over18;
|
||||
this.author = author;
|
||||
this.permalink = permalink;
|
||||
this.spoiler = spoiler;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's URL.
|
||||
*
|
||||
* @return the post's media URL.
|
||||
*/
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Media URL is correct.
|
||||
*
|
||||
* @return if the URL is correct.
|
||||
*/
|
||||
public boolean hasMediaUrl() {
|
||||
return url.contains(".jpg") || url.contains(".png");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's title.
|
||||
*
|
||||
* @return post's title.
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this post in quarantine?
|
||||
*
|
||||
* @return if the post is in quarantine.
|
||||
*/
|
||||
public boolean isQuarantine() {
|
||||
return quarantine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set quarantine state for the post.
|
||||
*
|
||||
* @param state the state to apply.
|
||||
*/
|
||||
public void setQuarantineState(boolean state) {
|
||||
this.quarantine = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's score.
|
||||
*
|
||||
* @return last known post's score.
|
||||
*/
|
||||
public double getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update post's score.
|
||||
*
|
||||
* @param newScore the new score.
|
||||
*/
|
||||
public void updateScore(double newScore) {
|
||||
this.score = newScore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's hint.
|
||||
*
|
||||
* @return post's hint.
|
||||
*/
|
||||
public String getPostHint() {
|
||||
return postHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this post crosspostable?
|
||||
*
|
||||
* @return if the post is crosspostable.
|
||||
*/
|
||||
public boolean isCrosspostable() {
|
||||
return crosspostable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this post NSFW?
|
||||
*
|
||||
* @return if the post is Not Safe For Work.
|
||||
*/
|
||||
public boolean isOver18() {
|
||||
return over18;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's author.
|
||||
*
|
||||
* @return post's author.
|
||||
*/
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's permalink.
|
||||
*
|
||||
* @return the post's permalink.
|
||||
*/
|
||||
public String getPermalink() {
|
||||
return permalink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this post a spoiler?
|
||||
*
|
||||
* @return if the post is a spoiler.
|
||||
*/
|
||||
public boolean isSpoiler() {
|
||||
return spoiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's id.
|
||||
*
|
||||
* @return post's id.
|
||||
*/
|
||||
public String getPostId() {
|
||||
return postId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this post an image?
|
||||
*
|
||||
* @return if the post is an image.
|
||||
*/
|
||||
public abstract boolean isImage();
|
||||
|
||||
/**
|
||||
* Is this post a text?
|
||||
*
|
||||
* @return if the post is a text.
|
||||
*/
|
||||
public abstract boolean isText();
|
||||
|
||||
/**
|
||||
* Is this post a video?
|
||||
*
|
||||
* @return if the post is a video.
|
||||
*/
|
||||
public abstract boolean isVideo();
|
||||
|
||||
/**
|
||||
* Is this post a link?
|
||||
*
|
||||
* @return if the post is a link.
|
||||
*/
|
||||
public abstract boolean isLink();
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.redditHandler;
|
||||
|
||||
/**
|
||||
* This is an abstract class to define all RedditPosts.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public abstract class RedditPost {
|
||||
|
||||
/**
|
||||
* Post's id.
|
||||
*/
|
||||
protected String postId;
|
||||
|
||||
/**
|
||||
* Post's title.
|
||||
*/
|
||||
protected String title;
|
||||
|
||||
/**
|
||||
* Is the post in quarantine?
|
||||
*/
|
||||
protected boolean quarantine;
|
||||
|
||||
/**
|
||||
* Post's score.
|
||||
*/
|
||||
protected double score;
|
||||
|
||||
/**
|
||||
* Post's hint.
|
||||
*/
|
||||
protected String postHint;
|
||||
|
||||
/**
|
||||
* Is this post crosspostable?
|
||||
*/
|
||||
protected boolean crosspostable;
|
||||
|
||||
/**
|
||||
* Is this post NSFW?
|
||||
*/
|
||||
protected boolean over18;
|
||||
|
||||
/**
|
||||
* Post's author.
|
||||
*/
|
||||
protected String author;
|
||||
|
||||
/**
|
||||
* Post's permalink.
|
||||
*/
|
||||
protected String permalink;
|
||||
|
||||
/**
|
||||
* Is this post a spoiler?
|
||||
*/
|
||||
protected boolean spoiler;
|
||||
|
||||
/**
|
||||
* Post's media url.
|
||||
*/
|
||||
protected String url;
|
||||
|
||||
/**
|
||||
* Main constructor for a Reddit post.
|
||||
*
|
||||
* @param id post's id
|
||||
* @param title post's title
|
||||
* @param quarantine is this post in quarantine?
|
||||
* @param score post's score
|
||||
* @param postHint post's hint
|
||||
* @param crosspostable is post crosspostable?
|
||||
* @param over18 is post NSFW?
|
||||
* @param author post's author
|
||||
* @param permalink post's permalink
|
||||
* @param spoiler is this post a spoiler?
|
||||
* @param url post's media url
|
||||
*/
|
||||
public RedditPost(String id, String title, boolean quarantine, double score,
|
||||
String postHint, boolean crosspostable, boolean over18,
|
||||
String author, String permalink, boolean spoiler, String url) {
|
||||
this.postId = id;
|
||||
this.title = title;
|
||||
this.quarantine = quarantine;
|
||||
this.score = score;
|
||||
this.postHint = postHint;
|
||||
this.crosspostable = crosspostable;
|
||||
this.over18 = over18;
|
||||
this.author = author;
|
||||
this.permalink = permalink;
|
||||
this.spoiler = spoiler;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's URL.
|
||||
*
|
||||
* @return the post's media URL.
|
||||
*/
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Media URL is correct.
|
||||
*
|
||||
* @return if the URL is correct.
|
||||
*/
|
||||
public boolean hasMediaUrl() {
|
||||
return url.contains(".jpg") || url.contains(".png");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's title.
|
||||
*
|
||||
* @return post's title.
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this post in quarantine?
|
||||
*
|
||||
* @return if the post is in quarantine.
|
||||
*/
|
||||
public boolean isQuarantine() {
|
||||
return quarantine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set quarantine state for the post.
|
||||
*
|
||||
* @param state the state to apply.
|
||||
*/
|
||||
public void setQuarantineState(boolean state) {
|
||||
this.quarantine = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's score.
|
||||
*
|
||||
* @return last known post's score.
|
||||
*/
|
||||
public double getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update post's score.
|
||||
*
|
||||
* @param newScore the new score.
|
||||
*/
|
||||
public void updateScore(double newScore) {
|
||||
this.score = newScore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's hint.
|
||||
*
|
||||
* @return post's hint.
|
||||
*/
|
||||
public String getPostHint() {
|
||||
return postHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this post crosspostable?
|
||||
*
|
||||
* @return if the post is crosspostable.
|
||||
*/
|
||||
public boolean isCrosspostable() {
|
||||
return crosspostable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this post NSFW?
|
||||
*
|
||||
* @return if the post is Not Safe For Work.
|
||||
*/
|
||||
public boolean isOver18() {
|
||||
return over18;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's author.
|
||||
*
|
||||
* @return post's author.
|
||||
*/
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's permalink.
|
||||
*
|
||||
* @return the post's permalink.
|
||||
*/
|
||||
public String getPermalink() {
|
||||
return permalink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this post a spoiler?
|
||||
*
|
||||
* @return if the post is a spoiler.
|
||||
*/
|
||||
public boolean isSpoiler() {
|
||||
return spoiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post's id.
|
||||
*
|
||||
* @return post's id.
|
||||
*/
|
||||
public String getPostId() {
|
||||
return postId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this post an image?
|
||||
*
|
||||
* @return if the post is an image.
|
||||
*/
|
||||
public abstract boolean isImage();
|
||||
|
||||
/**
|
||||
* Is this post a text?
|
||||
*
|
||||
* @return if the post is a text.
|
||||
*/
|
||||
public abstract boolean isText();
|
||||
|
||||
/**
|
||||
* Is this post a video?
|
||||
*
|
||||
* @return if the post is a video.
|
||||
*/
|
||||
public abstract boolean isVideo();
|
||||
|
||||
/**
|
||||
* Is this post a link?
|
||||
*
|
||||
* @return if the post is a link.
|
||||
*/
|
||||
public abstract boolean isLink();
|
||||
}
|
@ -1,53 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.redditHandler;
|
||||
|
||||
/**
|
||||
* Reddit image post object representation.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class RedditPostImage extends RedditPost {
|
||||
|
||||
public RedditPostImage(String id, String title, boolean quarantine,
|
||||
double score, String postHint, boolean crosspostable,
|
||||
boolean over18, String author, String permalink,
|
||||
boolean spoiler, String url) {
|
||||
super(id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author, permalink, spoiler, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isText() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLink() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.redditHandler;
|
||||
|
||||
/**
|
||||
* Reddit image post object representation.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class RedditPostImage extends RedditPost {
|
||||
|
||||
public RedditPostImage(String id, String title, boolean quarantine,
|
||||
double score, String postHint, boolean crosspostable,
|
||||
boolean over18, String author, String permalink,
|
||||
boolean spoiler, String url) {
|
||||
super(id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author, permalink, spoiler, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isText() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLink() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,54 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.redditHandler;
|
||||
|
||||
/**
|
||||
* Reddit link post object representation.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class RedditPostLink extends RedditPost {
|
||||
|
||||
public RedditPostLink(String id, String title, boolean quarantine,
|
||||
double score, String postHint, boolean crosspostable,
|
||||
boolean over18, String author, String permalink,
|
||||
boolean spoiler, String url) {
|
||||
super(id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author, permalink, spoiler, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isText() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLink() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.redditHandler;
|
||||
|
||||
/**
|
||||
* Reddit link post object representation.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class RedditPostLink extends RedditPost {
|
||||
|
||||
public RedditPostLink(String id, String title, boolean quarantine,
|
||||
double score, String postHint, boolean crosspostable,
|
||||
boolean over18, String author, String permalink,
|
||||
boolean spoiler, String url) {
|
||||
super(id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author, permalink, spoiler, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isText() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLink() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.redditHandler;
|
||||
|
||||
/**
|
||||
* Reddit text post object representation.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class RedditPostText extends RedditPost {
|
||||
|
||||
public RedditPostText(String id, String title, boolean quarantine,
|
||||
double score, String postHint, boolean crosspostable,
|
||||
boolean over18, String author, String permalink,
|
||||
boolean spoiler, String url) {
|
||||
super(id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author, permalink, spoiler, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isText() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLink() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.redditHandler;
|
||||
|
||||
/**
|
||||
* Reddit text post object representation.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class RedditPostText extends RedditPost {
|
||||
|
||||
public RedditPostText(String id, String title, boolean quarantine,
|
||||
double score, String postHint, boolean crosspostable,
|
||||
boolean over18, String author, String permalink,
|
||||
boolean spoiler, String url) {
|
||||
super(id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author, permalink, spoiler, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isText() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLink() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,54 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.redditHandler;
|
||||
|
||||
/**
|
||||
* Reddit video post object representation.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class RedditPostVideo extends RedditPost {
|
||||
|
||||
public RedditPostVideo(String id, String title, boolean quarantine,
|
||||
double score, String postHint, boolean crosspostable,
|
||||
boolean over18, String author, String permalink,
|
||||
boolean spoiler, String url) {
|
||||
super(id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author, permalink, spoiler, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isText() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideo() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLink() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.redditHandler;
|
||||
|
||||
/**
|
||||
* Reddit video post object representation.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public class RedditPostVideo extends RedditPost {
|
||||
|
||||
public RedditPostVideo(String id, String title, boolean quarantine,
|
||||
double score, String postHint, boolean crosspostable,
|
||||
boolean over18, String author, String permalink,
|
||||
boolean spoiler, String url) {
|
||||
super(id, title, quarantine, score, postHint,
|
||||
crosspostable, over18, author, permalink, spoiler, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isText() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideo() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLink() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
296
reddit_reposter_bot/src/RedditReposterBot/redditHandler/SubReddit.java → src/main/java/xyz.vallat.louis/redditHandler/SubReddit.java
Normal file → Executable file
296
reddit_reposter_bot/src/RedditReposterBot/redditHandler/SubReddit.java → src/main/java/xyz.vallat.louis/redditHandler/SubReddit.java
Normal file → Executable file
@ -1,148 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.redditHandler;
|
||||
|
||||
import RedditReposterBot.ConfigFileReader;
|
||||
import RedditReposterBot.exceptions.NoSuchFile;
|
||||
import RedditReposterBot.exceptions.NoSuchOrder;
|
||||
import RedditReposterBot.exceptions.NoSuchProperty;
|
||||
import RedditReposterBot.exceptions.NotSufficientRights;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A subreddit.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public final class SubReddit {
|
||||
|
||||
/**
|
||||
* Subreddit's name.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Subreddit's URL.
|
||||
*/
|
||||
private final String url;
|
||||
|
||||
/**
|
||||
* Subreddit's JSON URL.
|
||||
*/
|
||||
private final String jsonURL;
|
||||
|
||||
/**
|
||||
* Dist limit for the JSON api call.
|
||||
*/
|
||||
private int limit;
|
||||
|
||||
/**
|
||||
* Order for the JSON (by default, new).
|
||||
*/
|
||||
private String order;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param name subreddit's name
|
||||
*
|
||||
* @throws RedditReposterBot.exceptions.NoSuchProperty
|
||||
* @throws RedditReposterBot.exceptions.NoSuchFile
|
||||
* @throws RedditReposterBot.exceptions.NotSufficientRights
|
||||
* @throws RedditReposterBot.exceptions.NoSuchOrder
|
||||
*/
|
||||
public SubReddit(String name) throws NoSuchProperty, NoSuchFile,
|
||||
NotSufficientRights, NoSuchOrder {
|
||||
this.name = name;
|
||||
ConfigFileReader reader = new ConfigFileReader();
|
||||
setLimit(Integer.valueOf(reader.getProperties("reddit_posts_limit")));
|
||||
setOrder(reader.getProperties("reddit_posts_sorting_order"));
|
||||
this.url = "https://www.reddit.com/r/" + name + "/";
|
||||
this.jsonURL
|
||||
= this.url.substring(0, this.url.length()) + order + ".json";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set subreddit dist limit for parsing JSON file.
|
||||
*
|
||||
* @param limit the limit between 1 and 100.
|
||||
*/
|
||||
public void setLimit(int limit) {
|
||||
if (limit < 1 || limit > 100) {
|
||||
throw new IllegalArgumentException(
|
||||
"Limit should be between 1 and 100, and it was"
|
||||
+ limit + ".");
|
||||
} else {
|
||||
this.limit = limit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order for the subreddit.
|
||||
*
|
||||
* @param order an order to set
|
||||
*
|
||||
* @throws NoSuchOrder
|
||||
*/
|
||||
public void setOrder(String order) throws NoSuchOrder {
|
||||
String[] availableOrders
|
||||
= {"new", "hot", "best", "controversial", "top", "rising"};
|
||||
if (!Arrays.asList(availableOrders).contains(order)) {
|
||||
throw new NoSuchOrder("This order " + order
|
||||
+ "isn't allowed. Orders allowed are: "
|
||||
+ Arrays.toString(availableOrders));
|
||||
} else {
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subreddit dist limit.
|
||||
*
|
||||
* @return the limit.
|
||||
*/
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
*
|
||||
* @return the name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url.
|
||||
*
|
||||
* @return the subreddit's url.
|
||||
*/
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JSON URL.
|
||||
*
|
||||
* @return the subreddit's JSON URL.
|
||||
*/
|
||||
public String getJsonURL() {
|
||||
return jsonURL + "?limit=" + limit;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.redditHandler;
|
||||
|
||||
import xyz.vallat.louis.ConfigFileReader;
|
||||
import xyz.vallat.louis.exceptions.NoSuchFile;
|
||||
import xyz.vallat.louis.exceptions.NoSuchOrder;
|
||||
import xyz.vallat.louis.exceptions.NoSuchProperty;
|
||||
import xyz.vallat.louis.exceptions.NotSufficientRights;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A subreddit.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public final class SubReddit {
|
||||
|
||||
/**
|
||||
* Subreddit's name.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Subreddit's URL.
|
||||
*/
|
||||
private final String url;
|
||||
|
||||
/**
|
||||
* Subreddit's JSON URL.
|
||||
*/
|
||||
private final String jsonURL;
|
||||
|
||||
/**
|
||||
* Dist limit for the JSON api call.
|
||||
*/
|
||||
private int limit;
|
||||
|
||||
/**
|
||||
* Order for the JSON (by default, new).
|
||||
*/
|
||||
private String order;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param name subreddit's name
|
||||
*
|
||||
* @throws NoSuchProperty
|
||||
* @throws NoSuchFile
|
||||
* @throws NotSufficientRights
|
||||
* @throws NoSuchOrder
|
||||
*/
|
||||
public SubReddit(String name) throws NoSuchProperty, NoSuchFile,
|
||||
NotSufficientRights, NoSuchOrder {
|
||||
this.name = name;
|
||||
ConfigFileReader reader = new ConfigFileReader();
|
||||
setLimit(Integer.valueOf(reader.getProperties("reddit_posts_limit")));
|
||||
setOrder(reader.getProperties("reddit_posts_sorting_order"));
|
||||
this.url = "https://www.reddit.com/r/" + name + "/";
|
||||
this.jsonURL
|
||||
= this.url.substring(0, this.url.length()) + order + ".json";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set subreddit dist limit for parsing JSON file.
|
||||
*
|
||||
* @param limit the limit between 1 and 100.
|
||||
*/
|
||||
public void setLimit(int limit) {
|
||||
if (limit < 1 || limit > 100) {
|
||||
throw new IllegalArgumentException(
|
||||
"Limit should be between 1 and 100, and it was"
|
||||
+ limit + ".");
|
||||
} else {
|
||||
this.limit = limit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order for the subreddit.
|
||||
*
|
||||
* @param order an order to set
|
||||
*
|
||||
* @throws NoSuchOrder
|
||||
*/
|
||||
public void setOrder(String order) throws NoSuchOrder {
|
||||
String[] availableOrders
|
||||
= {"new", "hot", "best", "controversial", "top", "rising"};
|
||||
if (!Arrays.asList(availableOrders).contains(order)) {
|
||||
throw new NoSuchOrder("This order " + order
|
||||
+ "isn't allowed. Orders allowed are: "
|
||||
+ Arrays.toString(availableOrders));
|
||||
} else {
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subreddit dist limit.
|
||||
*
|
||||
* @return the limit.
|
||||
*/
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
*
|
||||
* @return the name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url.
|
||||
*
|
||||
* @return the subreddit's url.
|
||||
*/
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JSON URL.
|
||||
*
|
||||
* @return the subreddit's JSON URL.
|
||||
*/
|
||||
public String getJsonURL() {
|
||||
return jsonURL + "?limit=" + limit;
|
||||
}
|
||||
}
|
@ -1,35 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.socialMediaHandler;
|
||||
|
||||
/**
|
||||
* Interface to specify what methods should social media posters implement.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public interface SocialMediaPoster {
|
||||
|
||||
public String getSocialMediaName();
|
||||
|
||||
public long postText(String text);
|
||||
|
||||
public long postImage(String imagePath);
|
||||
|
||||
public long postImage(String text, String imagePath);
|
||||
|
||||
public long replyText(String text, long tweetId);
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.socialMediaHandler;
|
||||
|
||||
/**
|
||||
* Interface to specify what methods should social media posters implement.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public interface SocialMediaPoster {
|
||||
|
||||
public String getSocialMediaName();
|
||||
|
||||
public long postText(String text);
|
||||
|
||||
public long postImage(String imagePath);
|
||||
|
||||
public long postImage(String text, String imagePath);
|
||||
|
||||
public long replyText(String text, long tweetId);
|
||||
}
|
@ -1,205 +1,205 @@
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package RedditReposterBot.socialMediaHandler;
|
||||
|
||||
import RedditReposterBot.exceptions.NotSufficientRights;
|
||||
import RedditReposterBot.exceptions.NoSuchProperty;
|
||||
import RedditReposterBot.ConfigFileReader;
|
||||
import RedditReposterBot.exceptions.NoSuchFile;
|
||||
import java.io.File;
|
||||
import twitter4j.StatusUpdate;
|
||||
import twitter4j.Twitter;
|
||||
import twitter4j.TwitterException;
|
||||
import twitter4j.TwitterFactory;
|
||||
import twitter4j.conf.ConfigurationBuilder;
|
||||
|
||||
/**
|
||||
* Twutter Bot object.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public final class TwitterBot implements SocialMediaPoster {
|
||||
|
||||
/**
|
||||
* The twitter link.
|
||||
*/
|
||||
private final Twitter twitter;
|
||||
|
||||
/**
|
||||
* The Twitter API consumer key.
|
||||
*/
|
||||
private final String consumerKey;
|
||||
|
||||
/**
|
||||
* The Twitter API consumer secret.
|
||||
*/
|
||||
private final String consumerSecret;
|
||||
|
||||
/**
|
||||
* The Twitter API access token.
|
||||
*/
|
||||
private final String accessToken;
|
||||
|
||||
/**
|
||||
* The Twitter API access secret.
|
||||
*/
|
||||
private final String accessSecret;
|
||||
|
||||
/**
|
||||
* Main constructor for the Twitter Bot.
|
||||
*
|
||||
* @throws RedditReposterBot.exceptions.NoSuchFile
|
||||
* @throws RedditReposterBot.exceptions.NotSufficientRights
|
||||
* @throws RedditReposterBot.exceptions.NoSuchProperty
|
||||
*/
|
||||
public TwitterBot() throws NoSuchFile, NotSufficientRights, NoSuchProperty {
|
||||
ConfigFileReader reader = new ConfigFileReader();
|
||||
this.consumerKey = reader.getProperties("twitterAPI_consumerKey");
|
||||
this.consumerSecret = reader.getProperties("twitterAPI_consumerSecret");
|
||||
this.accessToken = reader.getProperties("twitterAPI_accessToken");
|
||||
this.accessSecret = reader.getProperties("twitterAPI_accessSecret");
|
||||
|
||||
ConfigurationBuilder cb = new ConfigurationBuilder();
|
||||
cb.setDebugEnabled(true)
|
||||
.setOAuthConsumerKey(consumerKey)
|
||||
.setOAuthConsumerSecret(consumerSecret)
|
||||
.setOAuthAccessToken(accessToken)
|
||||
.setOAuthAccessTokenSecret(accessSecret);
|
||||
|
||||
TwitterFactory factory = new TwitterFactory(cb.build());
|
||||
this.twitter = factory.getInstance();
|
||||
|
||||
showScreenName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the bot's screen name.
|
||||
*/
|
||||
public void showScreenName() {
|
||||
try {
|
||||
System.out.println("[+] Connected as user @"
|
||||
+ this.twitter.getScreenName()
|
||||
+ " on " + getSocialMediaName() + ".");
|
||||
} catch (TwitterException te) {
|
||||
System.err.println("[!] TwitterException: " + te.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tweet a text.
|
||||
*
|
||||
* @param text the text to tweet.
|
||||
* @return the tweet's id.
|
||||
*/
|
||||
@Override
|
||||
public long postText(String text) {
|
||||
try {
|
||||
System.out.println("[+] Tweeting \"" + text + "\".");
|
||||
return twitter.updateStatus(text).getId();
|
||||
} catch (TwitterException te) {
|
||||
System.err.println("[!] TwitterException: " + te.getMessage());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tweet an image.
|
||||
*
|
||||
* @param imagePath the path to the image.
|
||||
* @return the tweet's id.
|
||||
*/
|
||||
@Override
|
||||
public long postImage(String imagePath) {
|
||||
System.out.println("[+] Tweeting image.");
|
||||
File file = new File(imagePath);
|
||||
|
||||
StatusUpdate status = new StatusUpdate("");
|
||||
status.setMedia(file);
|
||||
try {
|
||||
return twitter.updateStatus(status).getId();
|
||||
} catch (TwitterException te) {
|
||||
System.err.println("[!] TwitterException: " + te.getMessage());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post an image with some text.
|
||||
*
|
||||
* @param text image's caption.
|
||||
* @param imagePath path to the image.
|
||||
* @return the tweet's id.
|
||||
*/
|
||||
@Override
|
||||
public long postImage(String text, String imagePath) {
|
||||
System.out.println("[+] Tweeting image with caption \"" + text + "\".");
|
||||
File file = new File(imagePath);
|
||||
|
||||
StatusUpdate status = new StatusUpdate(text);
|
||||
status.setMedia(file);
|
||||
try {
|
||||
return twitter.updateStatus(status).getId();
|
||||
} catch (TwitterException te) {
|
||||
System.err.println("[!] TwitterException: " + te.getMessage());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the social media name.
|
||||
*
|
||||
* @return the social media name.
|
||||
*/
|
||||
@Override
|
||||
public String getSocialMediaName() {
|
||||
return "Twitter";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the screen name.
|
||||
*
|
||||
* @return the user's screen name.
|
||||
*
|
||||
* @throws TwitterException
|
||||
*/
|
||||
public String getScreenName() throws TwitterException {
|
||||
return this.twitter.getScreenName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reply to a tweet.
|
||||
*
|
||||
* @param text the text to tweet.
|
||||
* @param tweetId the tweet id.
|
||||
* @return the reply's id.
|
||||
*/
|
||||
@Override
|
||||
public long replyText(String text, long tweetId) {
|
||||
System.out.println("[+] Replying \"" + text + "\" to tweet "
|
||||
+ tweetId + ".");
|
||||
StatusUpdate statusReply = new StatusUpdate(text);
|
||||
statusReply.setInReplyToStatusId(tweetId);
|
||||
try {
|
||||
twitter.updateStatus(statusReply);
|
||||
} catch (TwitterException ex) {
|
||||
System.err.println("TwitterException: " + ex.getMessage());
|
||||
}
|
||||
return statusReply.getInReplyToStatusId();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2019 louis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package xyz.vallat.louis.socialMediaHandler;
|
||||
|
||||
import xyz.vallat.louis.exceptions.NotSufficientRights;
|
||||
import xyz.vallat.louis.exceptions.NoSuchProperty;
|
||||
import xyz.vallat.louis.ConfigFileReader;
|
||||
import xyz.vallat.louis.exceptions.NoSuchFile;
|
||||
import java.io.File;
|
||||
import twitter4j.StatusUpdate;
|
||||
import twitter4j.Twitter;
|
||||
import twitter4j.TwitterException;
|
||||
import twitter4j.TwitterFactory;
|
||||
import twitter4j.conf.ConfigurationBuilder;
|
||||
|
||||
/**
|
||||
* Twutter Bot object.
|
||||
*
|
||||
* @author louis
|
||||
*/
|
||||
public final class TwitterBot implements SocialMediaPoster {
|
||||
|
||||
/**
|
||||
* The twitter link.
|
||||
*/
|
||||
private final Twitter twitter;
|
||||
|
||||
/**
|
||||
* The Twitter API consumer key.
|
||||
*/
|
||||
private final String consumerKey;
|
||||
|
||||
/**
|
||||
* The Twitter API consumer secret.
|
||||
*/
|
||||
private final String consumerSecret;
|
||||
|
||||
/**
|
||||
* The Twitter API access token.
|
||||
*/
|
||||
private final String accessToken;
|
||||
|
||||
/**
|
||||
* The Twitter API access secret.
|
||||
*/
|
||||
private final String accessSecret;
|
||||
|
||||
/**
|
||||
* Main constructor for the Twitter Bot.
|
||||
*
|
||||
* @throws RedditReposterBot.exceptions.NoSuchFile
|
||||
* @throws RedditReposterBot.exceptions.NotSufficientRights
|
||||
* @throws RedditReposterBot.exceptions.NoSuchProperty
|
||||
*/
|
||||
public TwitterBot() throws NoSuchFile, NotSufficientRights, NoSuchProperty {
|
||||
ConfigFileReader reader = new ConfigFileReader();
|
||||
this.consumerKey = reader.getProperties("twitterAPI_consumerKey");
|
||||
this.consumerSecret = reader.getProperties("twitterAPI_consumerSecret");
|
||||
this.accessToken = reader.getProperties("twitterAPI_accessToken");
|
||||
this.accessSecret = reader.getProperties("twitterAPI_accessSecret");
|
||||
|
||||
ConfigurationBuilder cb = new ConfigurationBuilder();
|
||||
cb.setDebugEnabled(true)
|
||||
.setOAuthConsumerKey(consumerKey)
|
||||
.setOAuthConsumerSecret(consumerSecret)
|
||||
.setOAuthAccessToken(accessToken)
|
||||
.setOAuthAccessTokenSecret(accessSecret);
|
||||
|
||||
TwitterFactory factory = new TwitterFactory(cb.build());
|
||||
this.twitter = factory.getInstance();
|
||||
|
||||
showScreenName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the bot's screen name.
|
||||
*/
|
||||
public void showScreenName() {
|
||||
try {
|
||||
System.out.println("[+] Connected as user @"
|
||||
+ this.twitter.getScreenName()
|
||||
+ " on " + getSocialMediaName() + ".");
|
||||
} catch (TwitterException te) {
|
||||
System.err.println("[!] TwitterException: " + te.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tweet a text.
|
||||
*
|
||||
* @param text the text to tweet.
|
||||
* @return the tweet's id.
|
||||
*/
|
||||
@Override
|
||||
public long postText(String text) {
|
||||
try {
|
||||
System.out.println("[+] Tweeting \"" + text + "\".");
|
||||
return twitter.updateStatus(text).getId();
|
||||
} catch (TwitterException te) {
|
||||
System.err.println("[!] TwitterException: " + te.getMessage());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tweet an image.
|
||||
*
|
||||
* @param imagePath the path to the image.
|
||||
* @return the tweet's id.
|
||||
*/
|
||||
@Override
|
||||
public long postImage(String imagePath) {
|
||||
System.out.println("[+] Tweeting image.");
|
||||
File file = new File(imagePath);
|
||||
|
||||
StatusUpdate status = new StatusUpdate("");
|
||||
status.setMedia(file);
|
||||
try {
|
||||
return twitter.updateStatus(status).getId();
|
||||
} catch (TwitterException te) {
|
||||
System.err.println("[!] TwitterException: " + te.getMessage());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post an image with some text.
|
||||
*
|
||||
* @param text image's caption.
|
||||
* @param imagePath path to the image.
|
||||
* @return the tweet's id.
|
||||
*/
|
||||
@Override
|
||||
public long postImage(String text, String imagePath) {
|
||||
System.out.println("[+] Tweeting image with caption \"" + text + "\".");
|
||||
File file = new File(imagePath);
|
||||
|
||||
StatusUpdate status = new StatusUpdate(text);
|
||||
status.setMedia(file);
|
||||
try {
|
||||
return twitter.updateStatus(status).getId();
|
||||
} catch (TwitterException te) {
|
||||
System.err.println("[!] TwitterException: " + te.getMessage());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the social media name.
|
||||
*
|
||||
* @return the social media name.
|
||||
*/
|
||||
@Override
|
||||
public String getSocialMediaName() {
|
||||
return "Twitter";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the screen name.
|
||||
*
|
||||
* @return the user's screen name.
|
||||
*
|
||||
* @throws TwitterException
|
||||
*/
|
||||
public String getScreenName() throws TwitterException {
|
||||
return this.twitter.getScreenName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reply to a tweet.
|
||||
*
|
||||
* @param text the text to tweet.
|
||||
* @param tweetId the tweet id.
|
||||
* @return the reply's id.
|
||||
*/
|
||||
@Override
|
||||
public long replyText(String text, long tweetId) {
|
||||
System.out.println("[+] Replying \"" + text + "\" to tweet "
|
||||
+ tweetId + ".");
|
||||
StatusUpdate statusReply = new StatusUpdate(text);
|
||||
statusReply.setInReplyToStatusId(tweetId);
|
||||
try {
|
||||
twitter.updateStatus(statusReply);
|
||||
} catch (TwitterException ex) {
|
||||
System.err.println("TwitterException: " + ex.getMessage());
|
||||
}
|
||||
return statusReply.getInReplyToStatusId();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user