Initial commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
/bin/
|
||||
/access_token.txt
|
||||
/consumer_keys.txt
|
||||
/info.txt
|
||||
/.classpath
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>PrimeDate</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,11 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
Binary file not shown.
@@ -0,0 +1,55 @@
|
||||
package fr.klemek.primedate;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* Main process to be launched
|
||||
* @author Kleme
|
||||
*/
|
||||
public abstract class MainProcess {
|
||||
|
||||
private final static SimpleDateFormat date2num = new SimpleDateFormat("yyyyMMddHHmm");
|
||||
private final static SimpleDateFormat sdf = new SimpleDateFormat("MMMM d, yyyy 'at' HH:mm", Locale.ENGLISH);
|
||||
private final static NumberFormat nf = NumberFormat.getNumberInstance(Locale.ENGLISH);
|
||||
|
||||
private static void checkTime() {
|
||||
try {
|
||||
Calendar currentTime = Calendar.getInstance();
|
||||
currentTime.add(Calendar.MILLISECOND, -currentTime.getTimeZone().getOffset(currentTime.getTimeInMillis()));
|
||||
|
||||
long currentTimeValue = Long.parseLong(date2num.format(currentTime.getTime()));
|
||||
|
||||
if (PrimeCalculator.isPrime(currentTimeValue)) {
|
||||
String msg = String.format("Hi, the date is %s GMT and %s is a prime number",
|
||||
sdf.format(currentTime.getTime()), nf.format(currentTimeValue));
|
||||
TwitterClient.tweet(msg);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
if(args.length < 1) {
|
||||
System.out.println("Argument 1 must be a file containing customer keys");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
if(TwitterClient.setUpTwitter(args[0])) {
|
||||
Timer timer = new Timer();
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
checkTime();
|
||||
}
|
||||
}, 0, 1 * 60 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package fr.klemek.primedate;
|
||||
|
||||
/**
|
||||
* Calculate and check prime numbers
|
||||
* @author Kleme
|
||||
*/
|
||||
public abstract class PrimeCalculator {
|
||||
|
||||
// http://compoasso.free.fr/primelistweb/page/prime/eratosthene_en.php
|
||||
|
||||
private static final long MAX = 1000000L; // 1 000 000
|
||||
private static final long SQRT_MAX = (long) Math.sqrt(MAX) + 1;
|
||||
private static final int MEMORY_SIZE = (int) (MAX >> 4);
|
||||
private static final int BLOCK_MAX = (int) (1 << 4);
|
||||
|
||||
private static boolean computed = false;
|
||||
private static byte[] primes = new byte[MEMORY_SIZE];
|
||||
|
||||
/**
|
||||
* Get stored bit for number i
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
private static boolean getBit(long i) {
|
||||
byte block = primes[(int) (i >> 4)];
|
||||
byte mask = (byte) (1 << ((i >> 1) & 7));
|
||||
return ((block & mask) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set stored bit for number i
|
||||
* @param i
|
||||
*/
|
||||
private static void setBit(long i) {
|
||||
int index = (int) (i >> 4);
|
||||
byte block = primes[index];
|
||||
byte mask = (byte) (1 << ((i >> 1) & 7));
|
||||
primes[index] = (byte) (block | mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes first million numbers, (takes ~25 ms)
|
||||
*/
|
||||
private static void computeList() {
|
||||
for (long i = 3; i < SQRT_MAX; i += 2)
|
||||
if (!getBit(i)) {
|
||||
long j = (i * i);
|
||||
while (j < MAX) {
|
||||
setBit(j);
|
||||
j += (2 * i);
|
||||
}
|
||||
}
|
||||
computed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Next prime stored
|
||||
* @param p
|
||||
* @return
|
||||
*/
|
||||
private static int nextPrime(int p) {
|
||||
p++;
|
||||
while (getBit(p))
|
||||
p++;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a number is prime by calculating its block
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
private static boolean isPrimeByBlock(long number) {
|
||||
long start = number - number % BLOCK_MAX;
|
||||
long end = start + BLOCK_MAX;
|
||||
long endSqrt = (long) Math.sqrt(end) + 1;
|
||||
|
||||
byte block = 0;
|
||||
int p = 3;
|
||||
while (p < endSqrt) {
|
||||
p = nextPrime(p);
|
||||
|
||||
long j = p - (start % p);
|
||||
j += ((j & 1) == 0 ? p : 0);
|
||||
|
||||
long p2 = p * 2;
|
||||
while (j < BLOCK_MAX) {
|
||||
block |= (1 << ((j >> 1) & 7));
|
||||
j += p2;
|
||||
}
|
||||
}
|
||||
byte mask = (byte) (1 << ((number >> 1) & 7));
|
||||
|
||||
return !((block & mask) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a number is prime (max 1 000 000 000 000)
|
||||
*
|
||||
* @param number
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean isPrime(long number) throws Exception {
|
||||
if (number <= 0 || Math.sqrt(number) > MAX)
|
||||
throw new Exception("Number out of range");
|
||||
if (number <= 2)
|
||||
return true;
|
||||
if ((number & 1) == 0)
|
||||
return false;
|
||||
if (!computed)
|
||||
computeList();
|
||||
if (number < MAX)
|
||||
return !getBit(number);
|
||||
return isPrimeByBlock(number);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package fr.klemek.primedate;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import twitter4j.Twitter;
|
||||
import twitter4j.TwitterException;
|
||||
import twitter4j.TwitterFactory;
|
||||
import twitter4j.auth.AccessToken;
|
||||
import twitter4j.auth.RequestToken;
|
||||
import twitter4j.conf.ConfigurationBuilder;
|
||||
|
||||
/**
|
||||
* Contains the useful functions to connect to twitter
|
||||
* @author Kleme
|
||||
*/
|
||||
public abstract class TwitterClient {
|
||||
|
||||
//http://twitter4j.org/en/code-examples.html
|
||||
|
||||
private final static String ACCESS_TOKEN_FILE = "access_token.txt";
|
||||
|
||||
private static Twitter twitter;
|
||||
|
||||
/**
|
||||
* Load keys and tokens to connect to the correct twitter account
|
||||
* @param keyFile the file containing the customer keys
|
||||
* @return
|
||||
*/
|
||||
public static boolean setUpTwitter(String keyFile) {
|
||||
try {
|
||||
File consumer_file = new File(keyFile);
|
||||
if(!consumer_file.exists()) {
|
||||
System.out.println("Invalid consumer key file");
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] consumer_key = loadConsumerKey(keyFile);
|
||||
|
||||
if(consumer_key.length < 2) {
|
||||
System.out.println("Invalid consumer key file");
|
||||
return false;
|
||||
}
|
||||
|
||||
File token_file = new File(ACCESS_TOKEN_FILE);
|
||||
|
||||
if(!token_file.exists()) {
|
||||
twitter = TwitterFactory.getSingleton();
|
||||
twitter.setOAuthConsumer(consumer_key[0], consumer_key[1]);
|
||||
RequestToken requestToken = twitter.getOAuthRequestToken();
|
||||
AccessToken accessToken = null;
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
|
||||
while (null == accessToken) {
|
||||
System.out.println("Open the following URL and grant access to your account:");
|
||||
System.out.println(requestToken.getAuthorizationURL());
|
||||
System.out.print("Enter the PIN(if available) or just hit enter.[PIN]:");
|
||||
String pin;
|
||||
|
||||
pin = br.readLine();
|
||||
if (pin.length() > 0) {
|
||||
accessToken = twitter.getOAuthAccessToken(requestToken, pin);
|
||||
} else {
|
||||
accessToken = twitter.getOAuthAccessToken();
|
||||
}
|
||||
}
|
||||
// persist to the accessToken for future reference.
|
||||
storeAccessToken(accessToken);
|
||||
}else {
|
||||
/*TwitterFactory factory = new TwitterFactory();
|
||||
|
||||
twitter = factory.getInstance();
|
||||
twitter.setOAuthConsumer(consumer_key[0], consumer_key[1]);
|
||||
twitter.setOAuthAccessToken(accessToken);*/
|
||||
AccessToken accessToken = loadAccessToken();
|
||||
ConfigurationBuilder cb = new ConfigurationBuilder();
|
||||
cb.setDebugEnabled(true)
|
||||
.setOAuthConsumerKey(consumer_key[0])
|
||||
.setOAuthConsumerSecret(consumer_key[1])
|
||||
.setOAuthAccessToken(accessToken.getToken())
|
||||
.setOAuthAccessTokenSecret(accessToken.getTokenSecret());
|
||||
TwitterFactory tf = new TwitterFactory(cb.build());
|
||||
twitter = tf.getInstance();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} catch (TwitterException te) {
|
||||
if (401 == te.getStatusCode()) {
|
||||
System.out.println("Unable to get the access token.");
|
||||
} else {
|
||||
te.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the access tokens into the constant file
|
||||
* @param accessToken
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void storeAccessToken(AccessToken accessToken) throws IOException {
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
File file = new File(ACCESS_TOKEN_FILE);
|
||||
file.createNewFile();
|
||||
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
|
||||
bw.write(accessToken.getToken());
|
||||
bw.newLine();
|
||||
bw.write(accessToken.getTokenSecret());
|
||||
}finally {
|
||||
bw.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the access tokens from the constant file
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private static AccessToken loadAccessToken() throws IOException {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
File file = new File(ACCESS_TOKEN_FILE);
|
||||
br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
|
||||
String token = br.readLine();
|
||||
String tokenSecret = br.readLine();
|
||||
return new AccessToken(token, tokenSecret);
|
||||
}finally {
|
||||
br.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the consumer keys from the given file
|
||||
* @param file_name
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private static String[] loadConsumerKey(String file_name) throws IOException{
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
ArrayList<String> file_lines = new ArrayList<>();
|
||||
File file = new File(file_name);
|
||||
br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
|
||||
String line;
|
||||
while((line = br.readLine()) != null) {
|
||||
file_lines.add(line);
|
||||
}
|
||||
return file_lines.toArray(new String[0]);
|
||||
}finally {
|
||||
br.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the status of the twitter account
|
||||
* @param msg
|
||||
*/
|
||||
public static void tweet(String msg) {
|
||||
try {
|
||||
twitter.updateStatus(msg);
|
||||
System.out.println("Tweeted : "+msg);
|
||||
} catch (TwitterException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user