Improved review statistics management (#2910).

This commit is contained in:
Christian P. MOMON 2018-05-17 09:17:27 +02:00
parent 29babf478b
commit 7a443487f3
4 changed files with 176 additions and 18 deletions

View File

@ -1,6 +1,6 @@
/** /**
* Copyright (C) 2011-2013,2017 Nicolas Vinot <aeris@imirhil.fr> * Copyright (C) 2011-2013,2017 Nicolas Vinot <aeris@imirhil.fr>
* Copyright (C) 2017 Christian Pierre MOMON <cmomon@april.org> * Copyright (C) 2017-2018 Christian Pierre MOMON <cmomon@april.org>
* *
* This file is part of (April) Hebdobot. * This file is part of (April) Hebdobot.
* *
@ -24,6 +24,7 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Collection; import java.util.Collection;
import java.util.Locale; import java.util.Locale;
@ -75,6 +76,7 @@ public class Hebdobot extends PircBot
private String channel; private String channel;
private File reviewDirectory; private File reviewDirectory;
private String reviewFileSuffix; private String reviewFileSuffix;
private LocalTime reviewWaitTime;
private Review review; private Review review;
private IdenticaSettings identicaSettings; private IdenticaSettings identicaSettings;
private PastebinSettings pastebinSettings; private PastebinSettings pastebinSettings;
@ -101,8 +103,7 @@ public class Hebdobot extends PircBot
* @param reviewFileSuffix * @param reviewFileSuffix
* the review file suffix * the review file suffix
*/ */
public Hebdobot(final String host, final int port, final String name, final String channel, final File homeDirectory, final File reviewDirectory, public Hebdobot(final String host, final int port, final String name, final String channel, final File homeDirectory, final File reviewDirectory)
final String reviewFileSuffix)
{ {
this.homeDirectory = homeDirectory; this.homeDirectory = homeDirectory;
this.host = host; this.host = host;
@ -110,7 +111,8 @@ public class Hebdobot extends PircBot
this.channel = channel; this.channel = channel;
this.setName(name); this.setName(name);
this.reviewDirectory = reviewDirectory; this.reviewDirectory = reviewDirectory;
this.reviewFileSuffix = reviewFileSuffix; this.reviewFileSuffix = null;
this.reviewWaitTime = null;
this.review = null; this.review = null;
this.identicaSettings = new IdenticaSettings(); this.identicaSettings = new IdenticaSettings();
@ -181,6 +183,21 @@ public class Hebdobot extends PircBot
return this.pastebinSettings; return this.pastebinSettings;
} }
public File getReviewDirectory()
{
return this.reviewDirectory;
}
public String getReviewFileSuffix()
{
return this.reviewFileSuffix;
}
public LocalTime getReviewWaitTime()
{
return this.reviewWaitTime;
}
/** /**
* Gets the twitter settings. * Gets the twitter settings.
* *
@ -575,6 +592,34 @@ public class Hebdobot extends PircBot
// Date command. // Date command.
sendMessage(LocalDateTime.now().format(DateTimeFormatter.ofPattern("EEEE dd MMMM yyyy kk'h'mm", Locale.FRENCH))); sendMessage(LocalDateTime.now().format(DateTimeFormatter.ofPattern("EEEE dd MMMM yyyy kk'h'mm", Locale.FRENCH)));
} }
else if (StringsUtils.equalsAnyIgnoreCase(text, "!stats"))
{
logger.info("!stats caught.");
// Display statistics. This feature has to not break
// Hebdobot.
try
{
File reviewDataFile = new File(this.reviewDirectory, "reviewstats.csv");
if (reviewDataFile.exists())
{
ReviewDatas datas = ReviewDatasFile.load(reviewDataFile);
datas.clean();
sendMessage("% " + ReviewStatsReporter.reportUserCountBoard(datas));
sendMessage("% " + ReviewStatsReporter.reportDurationBoard(datas));
}
else
{
logger.warn("Statistic file not found [{}]", reviewDataFile.getAbsolutePath());
sendMessage("% Fichier de statistiques absent.");
}
}
catch (Exception exception)
{
logger.warn("Exception during statistics work.", exception);
sendMessage("% Impossible d'afficher des statistiques.");
}
}
else if (text.startsWith("!")) else if (text.startsWith("!"))
{ {
logger.info("!??? caught."); logger.info("!??? caught.");
@ -722,4 +767,14 @@ public class Hebdobot extends PircBot
{ {
this.homeDirectory = homeDirectory; this.homeDirectory = homeDirectory;
} }
public void setReviewFileSuffix(final String reviewFileSuffix)
{
this.reviewFileSuffix = reviewFileSuffix;
}
public void setReviewWaitTime(final LocalTime reviewWaitTime)
{
this.reviewWaitTime = reviewWaitTime;
}
} }

View File

@ -24,9 +24,9 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -34,6 +34,9 @@ import org.april.hebdobot.HebdobotException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import fr.devinsy.util.strings.StringList;
import fr.devinsy.util.strings.StringsUtils;
/** /**
* The Class StatsFile. * The Class StatsFile.
*/ */
@ -60,13 +63,14 @@ public class ReviewDatasFile
*/ */
public static void append(final File file, final ReviewData stat) throws HebdobotException public static void append(final File file, final ReviewData stat) throws HebdobotException
{ {
RandomAccessFile out = null;
try try
{ {
out = new RandomAccessFile(file, "rw"); String line = String.format("%s\t%d\t%d\n", stat.getDate().format(DateTimeFormatter.ofPattern("yyyyMMdd-hh'h'mm")), stat.getUserCount(),
out.seek(out.length()); stat.getDuration());
out.writeUTF(String.format("%s\t%d\t%d\n", stat.getDate(), stat.getUserCount(), stat.getDuration())); StringList lines = StringsUtils.load(file);
lines.add(line);
StringsUtils.save(file, lines);
} }
catch (FileNotFoundException exception) catch (FileNotFoundException exception)
{ {
@ -79,10 +83,6 @@ public class ReviewDatasFile
logger.error("IO error: " + exception.getMessage(), exception); logger.error("IO error: " + exception.getMessage(), exception);
throw new HebdobotException("IO Error appending file [" + file + "]"); throw new HebdobotException("IO Error appending file [" + file + "]");
} }
finally
{
IOUtils.closeQuietly(out);
}
} }
/** /**

View File

@ -18,6 +18,9 @@
*/ */
package org.april.hebdobot.model.stats; package org.april.hebdobot.model.stats;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -102,6 +105,16 @@ public class ReviewStatsReporter
IntegerStat stat = board.get(currentDuration); IntegerStat stat = board.get(currentDuration);
int total = board.getCountSum(); int total = board.getCountSum();
/*
logger.debug("1 {}", stat.getValue());
logger.debug("2 {}", board.getPositionOf(stat.getValue()));
logger.debug("3 {}", board.getMinValue());
logger.debug("4 {}", board.getAverage());
logger.debug("5 {}", board.getMaxValue());
logger.debug("6 {}", stat.getCount());
*/
result = String.format( result = String.format(
"Statistiques sur la durée de la revue (%d mn) : position %d (min=%d mn,moy=%.1f mn,max=%d mn), fréquence %d/%d (%.0f %%)", "Statistiques sur la durée de la revue (%d mn) : position %d (min=%d mn,moy=%.1f mn,max=%d mn), fréquence %d/%d (%.0f %%)",
stat.getValue(), board.getPositionOf(stat.getValue()), board.getMinValue(), board.getAverage(), board.getMaxValue(), stat.getCount(), stat.getValue(), board.getPositionOf(stat.getValue()), board.getMinValue(), board.getAverage(), board.getMaxValue(), stat.getCount(),
@ -111,6 +124,28 @@ public class ReviewStatsReporter
return result; return result;
} }
/**
* Report duration board.
*
* @param datas
* the datas
* @return the string
*/
public static String reportDurationBoard(final ReviewDatas datas)
{
String result;
IntegerBoard board = new IntegerBoard();
for (ReviewData data : datas)
{
board.add(data.getDuration());
}
result = "Tableau des durées (mn) : " + board.toString();
//
return result;
}
/** /**
* Report new max. * Report new max.
* *
@ -135,7 +170,8 @@ public class ReviewStatsReporter
result = "Nouveau record de participation."; result = "Nouveau record de participation.";
} }
result = String.format("%s Dernier record %d, le %s.", result, last.getUserCount(), last.getDate().toString()); String lastRecordDate = last.getDate().format(DateTimeFormatter.ofPattern("EEEE dd MMMM yyyy", Locale.FRENCH));
result = String.format("%s Dernier record %d, le %s.", result, last.getUserCount(), lastRecordDate);
// //
return result; return result;
@ -170,4 +206,26 @@ public class ReviewStatsReporter
// //
return result; return result;
} }
/**
* Report user count board.
*
* @param datas
* the datas
* @return the string
*/
public static String reportUserCountBoard(final ReviewDatas datas)
{
String result;
IntegerBoard board = new IntegerBoard();
for (ReviewData data : datas)
{
board.add(data.getDuration());
}
result = "Tableau du nombre de participants : " + board.toString();
//
return result;
}
} }

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2017 Christian Pierre MOMON <cmomon@april.org> * Copyright (C) 2017-2018 Christian Pierre MOMON <cmomon@april.org>
* *
* This file is part of (April) Hebdobot. * This file is part of (April) Hebdobot.
* *
@ -18,6 +18,8 @@
*/ */
package org.april.hebdobot.twitter; package org.april.hebdobot.twitter;
import java.io.File;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -26,6 +28,7 @@ import twitter4j.Status;
import twitter4j.Twitter; import twitter4j.Twitter;
import twitter4j.TwitterException; import twitter4j.TwitterException;
import twitter4j.TwitterFactory; import twitter4j.TwitterFactory;
import twitter4j.UploadedMedia;
import twitter4j.conf.ConfigurationBuilder; import twitter4j.conf.ConfigurationBuilder;
/** /**
@ -87,11 +90,14 @@ public class TwitterClient
* @throws TwitterException * @throws TwitterException
* the twitter exception * the twitter exception
*/ */
public void tweet(final String message) throws TwitterException public Status tweet(final String message) throws TwitterException
{ {
Status result;
if (StringUtils.isBlank(message)) if (StringUtils.isBlank(message))
{ {
logger.info("Empty message => tweet aborted."); logger.info("Empty message => tweet aborted.");
result = null;
} }
else else
{ {
@ -104,8 +110,47 @@ public class TwitterClient
Twitter twitter = new TwitterFactory(config.build()).getInstance(); Twitter twitter = new TwitterFactory(config.build()).getInstance();
Status status = twitter.updateStatus(message); result = twitter.updateStatus(message);
logger.info("Tweet result [" + status.getText() + "]."); logger.info("Tweet result [" + result.getText() + "].");
} }
//
return result;
}
public Status tweet(final String message, final File image) throws TwitterException
{
Status result;
if (StringUtils.isBlank(message))
{
logger.info("Empty message => tweet aborted.");
result = null;
}
else
{
ConfigurationBuilder config = new ConfigurationBuilder();
config.setDebugEnabled(true);
config.setOAuthConsumerKey(this.consumerKey);
config.setOAuthConsumerSecret(this.consumerSecret);
config.setOAuthAccessToken(this.accessToken);
config.setOAuthAccessTokenSecret(this.accessTokenSecret);
Twitter twitter = new TwitterFactory(config.build()).getInstance();
result = twitter.updateStatus("Test 1");
UploadedMedia um = twitter.uploadMedia(new File("/home/cpm/C/Hebdobot/TestConf/revue-hebdomadaire.png"));
result = twitter.updateStatus("Test 2");
result = twitter.updateStatus("Test 3");
logger.info("Tweet result [" + result.getText() + "].");
}
// if ((imageFile != null) && (imageFile.exists()))
// {
// twitter
// }
//
return result;
} }
} }