├── gpn.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── src └── main │ ├── resources │ ├── twitter4j.properties.example │ └── logback.xml │ └── java │ └── de │ └── cccs │ └── filterretweeter │ ├── Filter.java │ ├── filters │ ├── FilterAlreadyRetweeted.java │ ├── FilterUsernames.java │ └── FilterBlockedUsers.java │ ├── FilterRetweeter.java │ └── Retweeter.java ├── .gitignore ├── README.md ├── gradlew.bat └── gradlew /gpn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cccs/filterretweeter/master/gpn.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cccs/filterretweeter/master/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/twitter4j.properties.example: -------------------------------------------------------------------------------- 1 | debug=false 2 | includeRTs=true 3 | includeMyRetweet=false 4 | oauth.consumerKey= 5 | oauth.consumerSecret= 6 | oauth.accessToken= 7 | oauth.accessTokenSecret= 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.cache 2 | /.classpath 3 | /.project 4 | /.settings 5 | target 6 | /project/target 7 | /.idea 8 | /.idea_modules 9 | *.iml 10 | bin 11 | /.gradle 12 | build 13 | /src/main/resources/twitter4j.properties 14 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Apr 17 11:56:39 CEST 2014 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-all.zip 7 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/de/cccs/filterretweeter/Filter.java: -------------------------------------------------------------------------------- 1 | package de.cccs.filterretweeter; 2 | 3 | import twitter4j.Status; 4 | 5 | 6 | public interface Filter { 7 | /** 8 | * Checks if the filter matches 9 | * @param status the tweet to be matched 10 | * @return true if the tweet is to be filtered (i.e. removed) 11 | */ 12 | public boolean filterTweet(Status status); 13 | 14 | /** 15 | * Notifies the filter that a status has been processed (i.e. retweeted) 16 | * @param status the status that passed all filters 17 | */ 18 | public void notify(Status status); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/de/cccs/filterretweeter/filters/FilterAlreadyRetweeted.java: -------------------------------------------------------------------------------- 1 | package de.cccs.filterretweeter.filters; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import twitter4j.Status; 7 | import de.cccs.filterretweeter.Filter; 8 | 9 | 10 | public class FilterAlreadyRetweeted implements Filter { 11 | protected List retweetedIds = new ArrayList(); 12 | 13 | @Override 14 | public boolean filterTweet(Status status) { 15 | return retweetedIds.contains(status.getId()); 16 | } 17 | 18 | @Override 19 | public void notify(Status status) { 20 | retweetedIds.add(status.getId()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/de/cccs/filterretweeter/filters/FilterUsernames.java: -------------------------------------------------------------------------------- 1 | package de.cccs.filterretweeter.filters; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.regex.Pattern; 6 | 7 | import twitter4j.Status; 8 | import de.cccs.filterretweeter.Filter; 9 | 10 | 11 | public class FilterUsernames implements Filter { 12 | final List patterns; 13 | 14 | public FilterUsernames(String... names) { 15 | patterns = new ArrayList(names.length); 16 | for (String name: names) { 17 | patterns.add(Pattern.compile("^" + name + "$", Pattern.CASE_INSENSITIVE)); 18 | } 19 | } 20 | 21 | @Override 22 | public boolean filterTweet(Status status) { 23 | for (Pattern pattern: patterns) { 24 | if (pattern.matcher(status.getUser().getScreenName()).find()) { 25 | return true; 26 | } 27 | } 28 | return false; 29 | } 30 | 31 | @Override 32 | public void notify(Status status) { 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Filter Retweeter 2 | 3 | Twitter-Bot, um Twitter-Suchergebnisse zu filtern und anschließend zu 4 | retweeten. 5 | 6 | ## Konfiguration 7 | 8 | Die Datei `src/main/resources/twitter4j.properties.example` nach 9 | `src/main/resources/twitter4j.properties` kopieren und bearbeiten. 10 | Die entsprechenden Schlüssel erhält man, indem man sich mit dem 11 | Ziel-Twitter-Account auf der 12 | [Twitter-Entwickler-Seite](https://dev.twitter.com/apps) anmeldet und 13 | eine neue Anwendung anlegt. 14 | 15 | ## Installation 16 | 17 | Mittels 18 | 19 | ./gradlew installApp 20 | 21 | wird die Anwendung übersetzt und im Verzeichnis `build/install` samt 22 | Startskript abgelegt. 23 | 24 | ## Ideen 25 | 26 | Erweiterungsmöglichkeiten? Gibt es viele! 27 | 28 | * Konfiguration der Filter in Config-Datei, die bei Änderung neu 29 | eingelesen wird 30 | * Verbesserte Ausgabe: Unterscheide zwischen „planmäßig gefilterten“ 31 | Tweets (z.B. die, die vom Bot schon retweetet wurden) und 32 | „böswilligen/unpassenden“ (z.B. von Accounts, die ein Filterkriterium 33 | für einen anderen Kontext verwenden), um so das Greifen der 34 | Filterkonfiguration besser prüfen zu können 35 | * Adaptive Poll-Zeite und Query-Länge: Je nach Anzahl der neuen Tweets 36 | die Poll-Zeit (und ggfs. Query-Länge) anpassen, um das Risiko des 37 | API-Limits zu reduzieren 38 | * ... 39 | 40 | ## Lizenz 41 | 42 | Geschrieben von Stefan Schlott. Das Programm steht unter der [GPL 43 | v2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html). 44 | 45 | -------------------------------------------------------------------------------- /src/main/java/de/cccs/filterretweeter/filters/FilterBlockedUsers.java: -------------------------------------------------------------------------------- 1 | package de.cccs.filterretweeter.filters; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import twitter4j.Status; 11 | import twitter4j.Twitter; 12 | import twitter4j.TwitterException; 13 | import de.cccs.filterretweeter.Filter; 14 | 15 | 16 | public class FilterBlockedUsers implements Filter { 17 | final static Logger logger = LoggerFactory.getLogger(FilterBlockedUsers.class); 18 | public final int INTERVAL = 15; // Update every 15 mins 19 | final Twitter twitter; 20 | List blockedIDs = new ArrayList(); 21 | Date lastUpdate = null; 22 | 23 | public FilterBlockedUsers(Twitter twitter) { 24 | this.twitter = twitter; 25 | } 26 | 27 | void updateBlockList() { 28 | Date now = new Date(); 29 | if (lastUpdate == null || (lastUpdate.getTime() + 60 * INTERVAL) < now.getTime()) { 30 | try { 31 | long ids[] = twitter.getBlocksIDs().getIDs(); 32 | blockedIDs = new ArrayList(ids.length); 33 | for (long id : ids) { 34 | blockedIDs.add(id); 35 | } 36 | } catch (TwitterException e) { 37 | logger.warn("Unable to get block list", e); 38 | } 39 | lastUpdate = now; 40 | } 41 | } 42 | 43 | @Override 44 | public boolean filterTweet(Status status) { 45 | updateBlockList(); 46 | return blockedIDs.contains(status.getUser().getId()); 47 | } 48 | 49 | @Override 50 | public void notify(Status status) { 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/de/cccs/filterretweeter/FilterRetweeter.java: -------------------------------------------------------------------------------- 1 | package de.cccs.filterretweeter; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import twitter4j.*; 7 | import de.cccs.filterretweeter.filters.FilterAlreadyRetweeted; 8 | import de.cccs.filterretweeter.filters.FilterBlockedUsers; 9 | import de.cccs.filterretweeter.filters.FilterUsernames; 10 | 11 | 12 | public class FilterRetweeter { 13 | static final int DELAY = 5; 14 | 15 | public static void main(String[] args) { 16 | System.out.println("Filter Retweeter"); 17 | 18 | Twitter twitter = TwitterFactory.getSingleton(); 19 | try { 20 | System.out.println("Logged in as " + twitter.getAccountSettings().getScreenName()); 21 | } catch (Exception e) { 22 | System.out.println("Unable to log in: " + e); 23 | System.exit(1); 24 | } 25 | TwitterStreamFactory streamFactory = new TwitterStreamFactory(); 26 | 27 | List filterList = new ArrayList(); 28 | filterList.add(new FilterAlreadyRetweeted()); 29 | filterList.add(new FilterBlockedUsers(twitter)); 30 | filterList.add(new FilterUsernames("conferencecat\\d*", "confere\\d*", "gpncat\\d*", "gpnation")); 31 | 32 | List retweeters = new ArrayList(); 33 | retweeters.add(new Retweeter(twitter, streamFactory, filterList, "#eh14")); 34 | retweeters.add(new Retweeter(twitter, streamFactory, filterList, "#eh2014")); 35 | retweeters.add(new Retweeter(twitter, streamFactory, filterList, "#easterhegg")); 36 | 37 | // Fallback: Do search 38 | while(true) { 39 | System.out.println("Checking for tweets..."); 40 | for (Retweeter r: retweeters) { 41 | r.runSearch(); 42 | } 43 | System.out.println("Checking done. Sleeping " + DELAY + " minutes..."); 44 | try { 45 | Thread.sleep(1000*60*DELAY); 46 | } catch (InterruptedException e) { } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /src/main/java/de/cccs/filterretweeter/Retweeter.java: -------------------------------------------------------------------------------- 1 | package de.cccs.filterretweeter; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import twitter4j.*; 10 | 11 | 12 | public class Retweeter implements StatusListener { 13 | final static Logger logger = LoggerFactory.getLogger(Retweeter.class); 14 | final Twitter twitter; 15 | List filters; 16 | final Query query; 17 | final TwitterStream stream; 18 | private Date lastUpdate = new Date(); 19 | 20 | 21 | public Retweeter(Twitter twitter, TwitterStreamFactory streamFactory, List filters, String query) { 22 | this.twitter = twitter; 23 | this.filters = filters; 24 | this.query = new Query(query).count(30); 25 | // Setup stream 26 | stream = streamFactory.getInstance(); 27 | FilterQuery filter = new FilterQuery(); 28 | filter.track(new String[] { query }); 29 | stream.addListener(this); 30 | stream.filter(filter); 31 | } 32 | 33 | /** 34 | * Check a single tweet against filters. 35 | * If filters pass, retweet and update filters. 36 | * 37 | * @param twitter 38 | * @param status 39 | * @param filters 40 | * @throws TwitterException 41 | */ 42 | public void checkRetweet(Twitter twitter, Status status, List filters) { 43 | // Check if tweet should be filtered 44 | for (Filter filter : filters) { 45 | if (filter.filterTweet(status)) { 46 | logger.info("--- Skipping tweet @" + status.getUser().getScreenName() + ":" + status.getText()); 47 | return; 48 | } 49 | } 50 | // Do retweet 51 | logger.info("+++ Retweeting @" + status.getUser().getScreenName() + ":" + status.getText()); 52 | try { 53 | twitter.retweetStatus(status.getId()); 54 | } catch (TwitterException e) { 55 | logger.warn("Unable to retweet status (skipping it): " + e); 56 | } 57 | // Notify filters 58 | for (Filter filter : filters) { 59 | filter.notify(status); 60 | } 61 | } 62 | 63 | 64 | /** 65 | * Process tweets which are newer than the last run and are no retweets by themselves. 66 | */ 67 | protected void processStatus(Status status) { 68 | if (!status.isRetweet() && !status.isRetweetedByMe() /*&& lastUpdate.before(status.getCreatedAt())*/) { 69 | checkRetweet(twitter, status, filters); 70 | } 71 | } 72 | 73 | 74 | /** 75 | * Do a single run: Do query, iterate over all results, process them 76 | */ 77 | public void runSearch() { 78 | QueryResult result; 79 | try { 80 | result = twitter.search(query); 81 | } catch (TwitterException e) { 82 | logger.warn("Problem with search: ", e); 83 | return; 84 | } 85 | List tweets = result.getTweets(); 86 | logger.info("Query " + query.getQuery() + " returned " + tweets.size() + " tweets"); 87 | for (Status status : tweets) { 88 | processStatus(status); 89 | } 90 | lastUpdate = new Date(); 91 | } 92 | 93 | 94 | @Override 95 | public void onStatus(Status status) { 96 | processStatus(status); 97 | } 98 | 99 | @Override 100 | public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) { 101 | } 102 | 103 | @Override 104 | public void onTrackLimitationNotice(int numberOfLimitedStatuses) { 105 | } 106 | 107 | @Override 108 | public void onScrubGeo(long userId, long upToStatusId) { 109 | } 110 | 111 | @Override 112 | public void onStallWarning(StallWarning warning) { 113 | } 114 | 115 | @Override 116 | public void onException(Exception ex) { 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | --------------------------------------------------------------------------------