Skip to content
Permalink
Browse files

#499 Add SENT note's state, when the new note was sent to the server,…

… but not loaded yet.
  • Loading branch information...
yvolk committed May 19, 2019
1 parent 7f95ee6 commit 5cb643b959121408359ffd456ce35dea085d985d
@@ -655,4 +655,45 @@ private AActivity newLoadedNote(Actor accountActor, Actor author, String content
note.via = "AndStatus";
return activity1;
}

@Test
public void sendingNoteActivityPub() {
MyAccount ma = demoData.getMyAccount(demoData.activityPubTestAccountName);
DataUpdater di = new DataUpdater(ma);
Actor accountActor = ma.getActor();
String content = "My note from ActivityPub " + demoData.testRunUid;

AActivity activity0 = AActivity.newPartialNote(accountActor, accountActor, "",
System.currentTimeMillis(), DownloadStatus.SENDING);
activity0.getNote().setContentPosted(content);

AActivity activity1 = di.onActivity(activity0);
Note note1 = activity1.getNote();
assertTrue("Note should be added " + activity1, note1.noteId != 0);
assertTrue("Activity should be added " + activity1, activity1.getId() != 0);
assertEquals("Note " + note1, DownloadStatus.SENDING, note1.getStatus());

// Response from a server
AActivity activity2 = AActivity.from(accountActor, ActivityType.CREATE);
activity2.setId(activity1.getId());
activity2.setTimelinePosition("https://" + demoData.activityPubMainHost + "/activities/" + MyLog.uniqueCurrentTimeMS());
activity2.setUpdatedDate(MyLog.uniqueCurrentTimeMS());

// No content in the response, just oid of the note
Note note2 = Note.fromOriginAndOid(accountActor.origin,
"https://" + demoData.activityPubMainHost + "/objects/" + MyLog.uniqueCurrentTimeMS(),
DownloadStatus.UNKNOWN);
activity2.setNote(note2);

// This is what is done in org.andstatus.app.service.CommandExecutorOther.updateNote to link the notes
activity2.setId(activity1.getId());
activity2.getNote().noteId = note1.noteId;

AActivity activity3 = di.onActivity(activity2);
Note note3 = activity3.getNote();
assertEquals("The same note should be updated " + activity3, note1.noteId, note3.noteId);
assertEquals("Note oid " + activity3, note2.oid, MyQuery.idToOid(OidEnum.NOTE_OID, note3.noteId, 0));
assertTrue("Activity should be added " + activity3, activity3.getId() != 0);
assertEquals("Note " + note3, DownloadStatus.SENT, note3.getStatus());
}
}
@@ -59,7 +59,7 @@
private static final String TAG_ASYNC = TAG + "Async";
private static final String HTTP = "http://";

public final String testRunUid = String.valueOf(System.currentTimeMillis());
public final String testRunUid = MyLog.uniqueDateTimeFormatted();
public final AtomicInteger conversationIterationCounter = new AtomicInteger(0);

public final String t131tUsername = "t131t";
@@ -155,29 +155,36 @@ private void updateNote1(@NonNull AActivity activity, int recursing) {
note.noteId = MyQuery.oidToId(OidEnum.NOTE_OID, note.origin.getId(), note.oid);
}

final long updatedDateStored;
final DownloadStatus statusStored;
if (note.noteId != 0) {
statusStored = DownloadStatus.load(
MyQuery.noteIdToLongColumnValue(NoteTable.NOTE_STATUS, note.noteId));
updatedDateStored = MyQuery.noteIdToLongColumnValue(NoteTable.UPDATED_DATE, note.noteId);
} else {
updatedDateStored = 0;
statusStored = DownloadStatus.ABSENT;
}

/*
* Is the row first time retrieved from a Social Network?
* Note can already exist in this these cases:
* 1. There was only "a stub" stored (without a sent date and a body)
* 2. Note was "unsent"
* 1. There was only "a stub" stored (without a sent date and content)
* 2. Note was "unsent" i.e. it had content, but didn't have oid
*/
boolean isFirstTimeLoaded1 = note.getStatus() == DownloadStatus.LOADED || note.noteId == 0;
boolean isDraftUpdated = !isFirstTimeLoaded1
&& (note.getStatus() == DownloadStatus.SENDING || note.getStatus() == DownloadStatus.DRAFT);

long updatedDateStored = 0;
if (note.noteId != 0) {
DownloadStatus statusStored = DownloadStatus.load(
MyQuery.noteIdToLongColumnValue(NoteTable.NOTE_STATUS, note.noteId));
updatedDateStored = MyQuery.noteIdToLongColumnValue(NoteTable.UPDATED_DATE, note.noteId);
if (isFirstTimeLoaded1) {
isFirstTimeLoaded1 = statusStored != DownloadStatus.LOADED;
}
final boolean isFirstTimeLoaded = (note.getStatus() == DownloadStatus.LOADED || note.noteId == 0) &&
statusStored != DownloadStatus.LOADED;
boolean isFirstTimeSent = !isFirstTimeLoaded && note.noteId != 0 &&
StringUtils.nonEmptyNonTemp(note.oid) &&
statusStored.isUnsentDraft() &&
StringUtils.isEmptyOrTemp(MyQuery.idToOid(OidEnum.NOTE_OID, note.noteId, 0));
if (note.getStatus() == DownloadStatus.UNKNOWN && isFirstTimeSent) {
note.setStatus(DownloadStatus.SENT);
}
boolean isFirstTimeLoaded = isFirstTimeLoaded1;
boolean isDraftUpdated = !isFirstTimeLoaded && !isFirstTimeSent && note.getStatus().isUnsentDraft();

boolean isNewerThanInDatabase = note.getUpdatedDate() > updatedDateStored;
if (!isFirstTimeLoaded && !isDraftUpdated && !isNewerThanInDatabase) {
if (!isFirstTimeLoaded && !isFirstTimeSent && !isDraftUpdated && !isNewerThanInDatabase) {
MyLog.v("Note", () -> "Skipped note as not younger " + note);
return;
}
@@ -188,12 +195,16 @@ private void updateNote1(@NonNull AActivity activity, int recursing) {
values.put(NoteTable.INS_DATE, MyLog.uniqueCurrentTimeMS());
}
values.put(NoteTable.NOTE_STATUS, note.getStatus().save());
values.put(NoteTable.UPDATED_DATE, note.getUpdatedDate());
if (isNewerThanInDatabase) {
values.put(NoteTable.UPDATED_DATE, note.getUpdatedDate());
}

if (activity.getAuthor().actorId != 0) {
values.put(NoteTable.AUTHOR_ID, activity.getAuthor().actorId);
}
values.put(NoteTable.NOTE_OID, note.oid);
if (nonEmptyOid(note.oid)) {
values.put(NoteTable.NOTE_OID, note.oid);
}
values.put(NoteTable.ORIGIN_ID, note.origin.getId());
if (nonEmptyOid(note.conversationOid)) {
values.put(NoteTable.CONVERSATION_OID, note.conversationOid);
@@ -224,7 +235,7 @@ private void updateNote1(@NonNull AActivity activity, int recursing) {
if (note.lookupConversationId() != 0) {
values.put(NoteTable.CONVERSATION_ID, note.getConversationId());
}
if (shouldSaveAttachments(isFirstTimeLoaded, isDraftUpdated)) {
if (note.getStatus().mayUpdateContent() && shouldSaveAttachments(isFirstTimeLoaded, isDraftUpdated)) {
values.put(NoteTable.ATTACHMENTS_COUNT, note.attachments.size());
}

@@ -233,6 +244,7 @@ private void updateNote1(@NonNull AActivity activity, int recursing) {
+ ":" + note.getStatus()
+ (isFirstTimeLoaded ? " new;" : "")
+ (isDraftUpdated ? " draft updated;" : "")
+ (isFirstTimeSent ? " just sent;" : "")
+ (isNewerThanInDatabase ? " newer, updated at " + new Date(note.getUpdatedDate()) + ";"
: "") );
}
@@ -256,18 +268,20 @@ private void updateNote1(@NonNull AActivity activity, int recursing) {
execContext.getContext().getContentResolver().update(msgUri, values, null, null);
MyLog.v("Note", () -> "Updated " + note);
}
note.audience().save(execContext.getMyContext(), note.origin, note.noteId, note.getPublic(), false);
if (note.getStatus().mayUpdateContent()) {
note.audience().save(execContext.getMyContext(), note.origin, note.noteId, note.getPublic(), false);

if (shouldSaveAttachments(isFirstTimeLoaded, isDraftUpdated)) {
note.attachments.save(execContext, note.noteId);
}
if (shouldSaveAttachments(isFirstTimeLoaded, isDraftUpdated)) {
note.attachments.save(execContext, note.noteId);
}

if (keywordsFilter.matchedAny(note.getContentToSearch())) {
activity.setNotified(TriState.FALSE);
} else {
if (note.getStatus() == DownloadStatus.LOADED) {
execContext.getResult().incrementDownloadedCount();
execContext.getResult().incrementNewCount();
if (keywordsFilter.matchedAny(note.getContentToSearch())) {
activity.setNotified(TriState.FALSE);
} else {
if (note.getStatus() == DownloadStatus.LOADED) {
execContext.getResult().incrementDownloadedCount();
execContext.getResult().incrementNewCount();
}
}
}
} catch (Exception e) {
@@ -27,6 +27,7 @@
HARD_ERROR(5, 0),
ABSENT(6, 0),
SENDING(7, R.string.download_status_unsent),
SENT(11, R.string.sent),
DRAFT(8, R.string.download_status_draft),
DELETED(9, 0),
NEEDS_UPDATE(10, 0),
@@ -77,4 +78,35 @@ private static boolean mayBeSent(DownloadStatus status) {
return false;
}
}

public boolean isUnsentDraft() {
switch (this) {
case SENDING:
case DRAFT:
return true;
default:
return false;
}
}

public boolean mayUpdateContent() {
switch (this) {
case SENDING:
case DRAFT:
case LOADED:
return true;
default:
return false;
}
}

public boolean isPresentAtServer() {
switch (this) {
case SENT:
case LOADED:
return true;
default:
return false;
}
}
}
@@ -29,6 +29,7 @@
import org.andstatus.app.util.I18n;
import org.andstatus.app.util.MyHtml;
import org.andstatus.app.util.MyLog;
import org.andstatus.app.util.StringUtils;
import org.andstatus.app.util.TriState;

import androidx.annotation.NonNull;
@@ -43,6 +44,7 @@
@NonNull
public final Origin origin;
public final long noteId;
public String noteOid = "";
public final DownloadStatus status;
public final Actor author;
public final Actor actor;
@@ -64,6 +66,7 @@ public NoteForAnyAccount(MyContext myContext, long activityId, long noteId) {
String sql = "SELECT " + NoteTable.NOTE_STATUS + ", "
+ NoteTable.CONTENT + ", "
+ NoteTable.AUTHOR_ID + ","
+ NoteTable.NOTE_OID + ", "
+ NoteTable.PUBLIC
+ " FROM " + NoteTable.TABLE_NAME
+ " WHERE " + NoteTable._ID + "=" + noteId;
@@ -72,6 +75,7 @@ public NoteForAnyAccount(MyContext myContext, long activityId, long noteId) {
statusLoc = DownloadStatus.load(DbUtils.getLong(cursor, NoteTable.NOTE_STATUS));
content = DbUtils.getString(cursor, NoteTable.CONTENT);
authorId = DbUtils.getLong(cursor, NoteTable.AUTHOR_ID);
noteOid = DbUtils.getString(cursor, NoteTable.NOTE_OID);
isPublicLoc = DbUtils.getTriState(cursor, NoteTable.PUBLIC);
}
} catch (Exception e) {
@@ -100,4 +104,8 @@ public boolean isLoaded() {
public String getBodyTrimmed() {
return I18n.trimTextAt(MyHtml.htmlToCompactPlainText(content), 80).toString();
}

public boolean isPresentAtServer() {
return status.isPresentAtServer() || StringUtils.nonEmptyNonTemp(noteOid);
}
}
@@ -173,7 +173,7 @@ private boolean isHtmlContentAllowed() {
public static boolean mayBeEdited(OriginType originType, DownloadStatus downloadStatus) {
if (originType == null || downloadStatus == null) return false;
return downloadStatus == DownloadStatus.DRAFT || downloadStatus.mayBeSent() ||
(downloadStatus == DownloadStatus.LOADED && originType.allowEditing());
(downloadStatus.isPresentAtServer() && originType.allowEditing());
}

private String evalContentToSearch() {
@@ -225,7 +225,7 @@ private void createContextMenu(ContextMenu menu, View v, BaseNoteViewItem viewIt
}

if (accountToNote.isAuthorSucceededMyAccount()) {
if (noteForAnyAccount.isLoaded()) {
if (noteForAnyAccount.isPresentAtServer()) {
if (!accountToNote.reblogged && getActingAccount().getConnection()
.hasApiEndpoint(Connection.ApiRoutineEnum.DELETE_NOTE)) {
NoteContextMenuItem.DELETE_NOTE.addTo(menu, order++,
@@ -254,7 +254,9 @@ private void createContextMenu(ContextMenu menu, View v, BaseNoteViewItem viewIt
break;
}
}
NoteContextMenuItem.GET_NOTE.addTo(menu, order, R.string.get_message);
if (noteForAnyAccount.isPresentAtServer()) {
NoteContextMenuItem.GET_NOTE.addTo(menu, order, R.string.get_message);
}
} catch (Exception e) {
MyLog.e(this, method, e);
}

0 comments on commit 5cb643b

Please sign in to comment.
You can’t perform that action at this time.