예제 #1
0
        void ProcessDbMessage(DbMessage record)
        {
            // Does the message exist yet?
            var message = this.GetMessageById(record.MessageId, nullIfMissing: true);

            bool messageIsNew = message == null;

            var eventCollector = new YamsterModelEventCollector();

            if (messageIsNew)
            {
                message = new YamsterMessage(record.MessageId, this);
                this.messagesById.Add(record.MessageId, message);
                eventCollector.NotifyAfterAdd(message);
                message.SetDbMessage(record, eventCollector);

                // For now we assume that messages cannot move between threads
                var           threadId = message.ThreadId;
                YamsterThread thread   = GetThreadById(threadId, nullIfMissing: true);
                if (thread == null)
                {
                    thread = new YamsterThread(threadId, message.Group, this);
                    threadsById.Add(threadId, thread);
                    eventCollector.NotifyAfterAdd(thread);
                    message.Group.AddThread(thread, eventCollector);

                    thread.AddMessage(message, eventCollector);

                    FixupUnresolvedObjectsForThread(thread, message, eventCollector);
                }
                else
                {
                    thread.AddMessage(message, eventCollector);
                }
            }
            else
            {
                message.SetDbMessage(record, eventCollector);
            }

            // Was there an unresolved message that we can process now?
            DbMessageState unresolvedMessageState;

            if (this.unresolvedMessageStatesById.TryGetValue(record.MessageId, out unresolvedMessageState))
            {
                this.unresolvedMessageStatesById.Remove(record.MessageId);
                ProcessDbMessageState(unresolvedMessageState, eventCollector);
            }

            if (messageIsNew)
            {
                CheckForListenedMessage(message, eventCollector);
            }

            eventCollector.FireEvents();
        }
예제 #2
0
        internal YamsterMessage(long messageId, YamsterCache yamsterCache)
            : base(yamsterCache)
        {
            this.messageId = messageId;
            this.dbMessage = new DbMessage()
            {
                MessageId    = messageId,
                ChangeNumber = 0
            };

            this.dbMessageState = new DbMessageState()
            {
                MessageId    = messageId,
                ChangeNumber = 0
            };
        }
예제 #3
0
        void ReadCsvFiles()
        {
            using (var csvReader = new CsvReader(Path.Combine(this.FolderPath, "Networks.csv")))
            {
                int col_Id  = csvReader.GetColumnIndex("id");
                int col_Url = csvReader.GetColumnIndex("url");

                while (csvReader.ReadNextLine())
                {
                    csvReader.WrapExceptions(() =>
                    {
                        networkId  = long.Parse(csvReader[col_Id]);
                        networkUrl = csvReader[col_Url];
                    });
                }
            }

            using (var csvReader = new CsvReader(Path.Combine(this.FolderPath, "Groups.csv")))
            {
                int col_Id          = csvReader.GetColumnIndex("id");
                int col_Name        = csvReader.GetColumnIndex("name");
                int col_Description = csvReader.GetColumnIndex("description");
                int col_Private     = csvReader.GetColumnIndex("private");
                int col_Deleted     = csvReader.GetColumnIndex("deleted");

                while (csvReader.ReadNextLine())
                {
                    DbGroup group     = new DbGroup();
                    bool    isDeleted = false;
                    csvReader.WrapExceptions(() =>
                    {
                        group.GroupId          = long.Parse(csvReader[col_Id]);
                        group.GroupName        = csvReader[col_Name];
                        group.GroupDescription = csvReader[col_Description];

                        // TODO: How to recognize DbGroupPrivacy.Restricted?
                        bool isPrivate = bool.Parse(csvReader[col_Private]);
                        group.Privacy  = isPrivate ? DbGroupPrivacy.Private : DbGroupPrivacy.Public;

                        group.WebUrl = networkUrl + "/#/threads/inGroup?type=in_group&feedId=" + group.GroupId;

                        // TODO: How to obtain MugshotUrl?

                        isDeleted = bool.Parse(csvReader[col_Deleted]);
                    });

                    groupsById.Add(group.GroupId, group);

                    if (isDeleted)
                    {
                        deletedGroups.Add(group.GroupId);
                    }
                }
            }

            using (var csvReader = new CsvReader(Path.Combine(this.FolderPath, "Users.csv")))
            {
                int col_Id       = csvReader.GetColumnIndex("id");
                int col_Name     = csvReader.GetColumnIndex("name");
                int col_JobTitle = csvReader.GetColumnIndex("job_title");
                int col_Email    = csvReader.GetColumnIndex("email");
                int col_State    = csvReader.GetColumnIndex("state");

                while (csvReader.ReadNextLine())
                {
                    DbUser user      = new DbUser();
                    bool   isDeleted = false;
                    csvReader.WrapExceptions(() =>
                    {
                        user.UserId = long.Parse(csvReader[col_Id]);
                        // TODO: Is there a way to obtain the correct alias?
                        user.Alias    = csvReader[col_Email].Replace('@', '_');
                        user.Email    = csvReader[col_Email];
                        user.FullName = csvReader[col_Name];
                        user.JobTitle = csvReader[col_JobTitle];

                        // TODO: We need the alias to calculate user.WebUrl

                        // TODO: user.MugshotUrl

                        isDeleted = csvReader[col_State].Trim().ToUpper() == "SOFT_DELETE";
                    });

                    usersById.Add(user.UserId, user);

                    if (isDeleted)
                    {
                        deletedUsers.Add(user.UserId);
                    }
                }
            }

            using (var csvReader = new CsvReader(Path.Combine(this.FolderPath, "Messages.csv")))
            {
                int col_Id             = csvReader.GetColumnIndex("id");
                int col_GroupId        = csvReader.GetColumnIndex("group_id");
                int col_ThreadId       = csvReader.GetColumnIndex("thread_id");
                int col_ConversationId = csvReader.GetColumnIndex("conversation_id");

                int col_InPrivateGroup        = csvReader.GetColumnIndex("in_private_group");
                int col_InPrivateConversation = csvReader.GetColumnIndex("in_private_conversation");
                int col_Participants          = csvReader.GetColumnIndex("participants");

                int col_CreatedAt   = csvReader.GetColumnIndex("created_at");
                int col_SenderId    = csvReader.GetColumnIndex("sender_id");
                int col_RepliedToId = csvReader.GetColumnIndex("replied_to_id");
                int col_Body        = csvReader.GetColumnIndex("body");
                int col_DeletedAt   = csvReader.GetColumnIndex("deleted_at");

                while (csvReader.ReadNextLine())
                {
                    DbMessage message   = new DbMessage();
                    bool      isDeleted = false;
                    csvReader.WrapExceptions(() =>
                    {
                        message.MessageId = long.Parse(csvReader[col_Id]);
                        message.GroupId   = ParseLongWithDefault(csvReader[col_GroupId], YamsterGroup.AllCompanyGroupId);
                        message.ThreadId  = long.Parse(csvReader[col_ThreadId]);

                        bool inPrivateGroup        = bool.Parse(csvReader[col_InPrivateGroup]);
                        bool inPrivateConversation = bool.Parse(csvReader[col_InPrivateConversation]);

                        if (inPrivateConversation)
                        {
                            // This is apparently broken
                            // long conversationId = ParseLongWithDefault(csvReader[col_ConversationId], 0);
                            long conversationId = message.ThreadId;

                            DbConversation conversation;
                            if (!conversationsById.TryGetValue(conversationId, out conversation))
                            {
                                conversation = new DbConversation();
                                conversation.ConversationId = conversationId;
                                ParseParticipants(conversation.ParticipantUserIds, csvReader[col_Participants]);
                                conversationsById.Add(conversationId, conversation);
                            }

                            message.ConversationId = conversationId;
                            message.GroupId        = YamsterGroup.ConversationsGroupId;
                        }

                        message.CreatedDate        = DateTime.Parse(csvReader[col_CreatedAt]);
                        message.SenderUserId       = long.Parse(csvReader[col_SenderId]);
                        message.MessageIdRepliedTo = ParseLongWithDefault(csvReader[col_RepliedToId], 0);

                        // TODO: Likes?

                        // TODO: Parse message.NotifiedUserIds from "CC" line
                        message.Body   = csvReader[col_Body];
                        message.WebUrl = networkUrl + "/messages/" + message.MessageId;

                        // TODO: Attachments?

                        message.MessageType = DbMessageType.Update;

                        isDeleted = !string.IsNullOrWhiteSpace(csvReader[col_DeletedAt]);
                    });

                    messagesById.Add(message.MessageId, message);

                    if (isDeleted)
                    {
                        deletedMessages.Add(message.MessageId);
                    }
                    else
                    {
                        if (message.ConversationId != 0)
                        {
                            notDeletedConversations.Add(message.ConversationId);
                        }
                    }
                }
            }
        }
예제 #4
0
        void UpdateMessage(DbArchiveMessageRecord archiveMessage)
        {
            JsonMessage message = SQLiteJsonConverter.LoadFromJson <JsonMessage>(archiveMessage.Json);

            DbMessage coreMessage = new DbMessage();

            coreMessage.LastFetchedUtc = archiveMessage.LastFetchedUtc;
            coreMessage.MessageId      = message.Id;

            coreMessage.GroupId            = archiveMessage.GroupId;
            coreMessage.ThreadId           = message.ThreadId;
            coreMessage.ConversationId     = message.ConversationId;
            coreMessage.CreatedDate        = message.Created;
            coreMessage.SenderUserId       = message.SenderId;
            coreMessage.MessageIdRepliedTo = message.RepliedToId ?? 0;

            coreMessage.LikingUserIds.AssignFrom(message.Likes.Users.Select(x => x.UserId));
            foreach (var likingUser in message.Likes.Users)
            {
                // We don't get a proper UserReference for liking users, but we do get
                // some basic information.  Write this to the Users table *only* if there
                // is not already some real data there.
                DbUser coreUser = new DbUser();
                coreUser.LastFetchedUtc = archiveMessage.LastFetchedUtc;
                coreUser.UserId         = likingUser.UserId;
                coreUser.FullName       = likingUser.FullName ?? "";
                coreUser.JobTitle       = "";
                coreUser.WebUrl         = ""; // we could infer this from likingUser.Alias
                coreUser.MugshotUrl     = "";

                // Ignore = only write if there isn't already an existing record
                Users.InsertRecord(coreUser, SQLiteConflictResolution.Ignore);
            }

            coreMessage.LikesCount = message.Likes.Count;
            coreMessage.NotifiedUserIds.AssignFrom(message.NotifiedUserIds ?? new long[0]);
            coreMessage.Body   = message.Body.Plain ?? "";
            coreMessage.WebUrl = message.Permalink ?? "";

            var firstImageAttachment = message.Attachments.Where(x => x.AttachmentType == "image").FirstOrDefault();

            if (firstImageAttachment != null)
            {
                coreMessage.AttachmentFilename          = firstImageAttachment.Name;
                coreMessage.AttachmentWebUrl            = firstImageAttachment.WebUrl;
                coreMessage.AttachmentScaledUrlTemplate = firstImageAttachment.ScaledUrlTemplate;
                coreMessage.AttachmentWidth             = firstImageAttachment.Width ?? 0;
                coreMessage.AttachmentHeight            = firstImageAttachment.Height ?? 0;
            }


            if (!Enum.TryParse(message.MessageType, true, out coreMessage.MessageType))
            {
                coreMessage.MessageType = DbMessageType.Unknown;
            }

            Messages.InsertRecord(coreMessage, SQLiteConflictResolution.Replace);

            DbMessageState messageState = new DbMessageState()
            {
                MessageId = archiveMessage.Id
            };

            MessageStates.InsertRecord(messageState, SQLiteConflictResolution.Ignore);

            // Ensure that every message has a corresponding DbThreadState for its thread
            DbThreadState threadState = new DbThreadState()
            {
                ThreadId = coreMessage.ThreadId
            };

            ThreadStates.InsertRecord(threadState, SQLiteConflictResolution.Ignore);
        }
예제 #5
0
        internal void SetDbMessage(DbMessage newValue, YamsterModelEventCollector eventCollector)
        {
            if (newValue == null)
            {
                throw new ArgumentNullException("DbMessage");
            }
            if (newValue.MessageId != messageId)
            {
                throw new ArgumentException("Cannot change ID");
            }

            var oldValue = this.dbMessage;

            this.dbMessage         = newValue;
            this.cachedPreviewText = null;

            this.group      = this.YamsterCache.FetchGroupById(this.dbMessage.GroupId, eventCollector);
            this.senderUser = this.YamsterCache.FetchUserById(this.dbMessage.SenderUserId, eventCollector);

            this.messageRepliedTo = null;
            if (this.dbMessage.MessageIdRepliedTo != 0
                // The Yammer UI doesn't show "in reply to" when messageRepliedTo is the threadstarter.
                // TODO: What does it do if the threadstarter's MessageId != ThreadId?
                && this.dbMessage.MessageIdRepliedTo != this.dbMessage.ThreadId)
            {
                this.YamsterCache.ListenForMessageById(
                    this.dbMessage.MessageIdRepliedTo,
                    this,
                    eventCollector,
                    delegate(YamsterMessage listenedMessage, YamsterModelEventCollector ec)
                {
                    if (listenedMessage.MessageId == this.dbMessage.MessageIdRepliedTo)
                    {
                        this.messageRepliedTo = listenedMessage;
                        ec.NotifyAfterUpdate(this);
                    }
                }
                    );
            }

            int oldlikingUsersCount = likingUsers.Count;

            likingUsers.Clear();
            foreach (long userId in this.dbMessage.LikingUserIds)
            {
                var user = this.YamsterCache.FetchUserById(userId, eventCollector);
                likingUsers.AddUser(user);
            }

            if (this.thread != null)
            {
                int totalLikesCountDelta = newValue.LikesCount - oldValue.LikesCount;
                if (totalLikesCountDelta != 0)
                {
                    this.thread.NotifyTotalLikesChanged(totalLikesCountDelta, eventCollector);
                }
            }

            notifiedUsers.Clear();
            foreach (long userId in this.dbMessage.NotifiedUserIds)
            {
                var user = this.YamsterCache.FetchUserById(userId, eventCollector);
                notifiedUsers.AddUser(user);
            }

            UpdateLoadedStatus();

            eventCollector.NotifyAfterUpdate(this);
        }