use of me.perrycate.groupmeutils.data.Message in project groupme-utils by TheGuyWithTheFace.
the class MessageIterator method next.
@Override
public Message next() {
Message current = currentMessages[remainingMessages - 1];
remainingMessages--;
if (remainingMessages == 0) {
currentMessages = loadMessages();
remainingMessages = currentMessages.length;
}
return current;
}
use of me.perrycate.groupmeutils.data.Message in project groupme-utils by TheGuyWithTheFace.
the class Dumper method writeChunk.
// */
/**
* Writes messages to specified chunk. (A chunk is just a short text file
* containing 100 or less messages in text format.)
*/
private void writeChunk(Message[] messages, ChunkStorage storage) {
int length = messages.length;
try (ByteArrayOutputStream chunk = new ByteArrayOutputStream()) {
// concatenate each message into a series of bytes in a chunk
for (int i = length - 1; i >= 0; i--) {
Message message = messages[i];
String text = format(message) + '\n';
byte[] textInBytes = text.getBytes(Charset.forName(ENCODING));
chunk.write(textInBytes);
}
// Write chunk to storage
storage.addFirst(chunk.toByteArray());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
use of me.perrycate.groupmeutils.data.Message in project groupme-utils by TheGuyWithTheFace.
the class Dumper method append.
// */
/**
* Scans the groupme for any new messages ocurring after the last message in
* inputFile, and appends new messages to the bottom.
*
* This method assumes that inputFile is the result of a previous
* dumpFromTop or appendFromTop call, and thus maintains the same output
* format.
*
*/
public int append(File sourceFile) {
// TODO we could in fact share more code with dump if we only
// made note of the last message in the group, but then got messages in
// the same order as dump() (bottom-up) and just stop when we reach the
// message Id we made note of. The downside is that if people add to
// the chat while append() is running, these messages won't be added.
// On the other hand though, this would eliminate the concern of the
// message count being innacurate for the same reason, so maybe that's
// a good thing?
FileReader r;
try {
r = new FileReader(sourceFile);
} catch (FileNotFoundException e) {
System.err.println("FATAL: Could not find file " + sourceFile + "!");
return -1;
}
// Find the last message in the file. Ideally there is a faster way to
// do this other than reading through it line by line from the top, but
// I have not found it yet.
// TODO there certainly must be, especially now that we don't have to
// copy things into new file, we just need to get the last line in file.
String lastLine = "";
String tmp = "";
try (BufferedReader reader = new BufferedReader(r)) {
tmp = reader.readLine();
while (tmp != null) {
lastLine = tmp;
tmp = reader.readLine();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
// TODO if no id found, should tell that to the user.
// get ID of last message in file
String firstMessageId = readIdFromLine(lastLine);
// Append new messages to group, storing messages in file chunks to
// avoid keeping them all in memory.
ChunkStorage storage = new ChunkStorage();
GroupMessages messages = groupme.getMessagesAfter(groupId, firstMessageId);
int nrOfMessages = messages.getMessages().length;
while (messages.getMessages().length > 0) {
// Have to reverse message order since getMessagesAfter's order is
// opposite to getMessagesBefore. Inconvenient, but I'm trying to
// keep it consistent with GroupMe's API for now, for better or
// worse.
List<Message> m = Arrays.asList(messages.getMessages());
// WARNING/TODO/NOTE: fixing the "GroupMessages not being
// defensively
// copied bug" will require change here, since the current code is
// working around messages being reversed.
Collections.reverse(m);
writeChunk(m.toArray(new Message[0]), storage);
// Remember, we reversed the array
firstMessageId = messages.getMessage(0).getId();
// Different from dump(): this gets Messages AFTER messageId
messages = groupme.getMessagesAfter(groupId, firstMessageId);
}
// Concatenate each chunk into a single log
try (OutputStream o = Files.newOutputStream(sourceFile.toPath(), StandardOpenOption.APPEND, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
BufferedOutputStream output = new BufferedOutputStream(o)) {
while (storage.size() != 0) {
// Different from dump(): this removes from the first, not last
output.write(storage.removeLast());
}
storage.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return nrOfMessages;
}
use of me.perrycate.groupmeutils.data.Message in project groupme-utils by TheGuyWithTheFace.
the class Stats method write.
public void write() {
// Create header
HashMap<String, String> entries = new HashMap<>();
for (Member m : group.getMembers()) {
entries.put(getPostsKey(m.getUserId()), "Posts by " + m.getNickname());
}
// Groupme has a quirk where meta messages ("so and so left, joined,
// etc") are reported by a user with ID system, but system is not
// listed as a user.
entries.put(getPostsKey("system"), "System posts");
writer.addRow(entries);
// Collect data
MessageIterator messages = api.getAllMessages(group.getId());
Message currentMessage = messages.next();
LocalDate day = LocalDateTime.ofInstant(currentMessage.getCreatedAt(), this.timeZone).toLocalDate();
HashMap<String, Integer> data = new HashMap<>();
while (messages.hasNext()) {
currentMessage = messages.next();
// Start new day if necessary
LocalDate currentDay = LocalDateTime.ofInstant(currentMessage.getCreatedAt(), this.timeZone).toLocalDate();
long daysElapsed = ChronoUnit.DAYS.between(day, currentDay);
if (daysElapsed != 0) {
// Finish writing previous day
writer.addRow(data);
// If multiple days elapsed, write empty rows
data = new HashMap<>();
for (int i = 0; i < daysElapsed - 1; i++) {
writer.addRow(data);
}
// Start new day
data = new HashMap<>();
day = currentDay;
}
// Add data for this message
incrementPosts(currentMessage.getUserId(), data);
if (currentMessage.getFavoritedBy() != null)
incrementLikes(currentMessage.getFavoritedBy(), data);
}
// Add final row
writer.addRow(data);
// Write and finish
writer.writeTo(outputFile, false);
System.out.println("Finished!");
}
use of me.perrycate.groupmeutils.data.Message in project groupme-utils by TheGuyWithTheFace.
the class GroupMessagesDeserializer method deserialize.
public GroupMessages deserialize(JsonElement jsonElement, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject response = getResponse(jsonElement).getAsJsonObject();
JsonArray messagesJson = response.get("messages").getAsJsonArray();
int count = response.get("count").getAsInt();
// different from count!
int numMessages = messagesJson.size();
Message[] messages = new Message[numMessages];
// Deserialize each message, add to array
for (int i = 0; i < numMessages; i++) {
JsonElement elem = messagesJson.get(i);
// leave actual deserialization to MessageDeserializer
messages[i] = context.deserialize(elem, Message.class);
}
return new GroupMessages(count, messages);
}
Aggregations