コード例 #1
0
        /// <summary>
        /// Mark this conversation as read or unread on the server.
        /// </summary>
        private void MarkReadConversation()
        {
            if (CIX.Online)
            {
                try
                {
                    string         url            = string.Format("personalmessage/{0}/{1}/toggleread", RemoteID, UnreadCount > 0);
                    HttpWebRequest request        = APIRequest.Get(url, APIRequest.APIFormat.XML);
                    string         responseString = APIRequest.ReadResponseString(request);

                    // Any non-exception response should treat the action as having completed. The two
                    // possible outcomes are either the message is marked read or the ID is invalid.
                    // The latter case cannot be re-tried so don't repeat the action.
                    Flags &= ~InboxConversationFlags.MarkRead;
                    lock (CIX.DBLock)
                    {
                        CIX.DB.Update(this);
                    }
                    if (responseString == "Success")
                    {
                        LogFile.WriteLine("Conversation {0} marked as read on server", RemoteID);
                    }
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("InboxConversation.MarkReadConversation", e);
                }
            }
        }
コード例 #2
0
ファイル: Mugshot.cs プロジェクト: cixonline/cixreader
        /// <summary>
        /// Sync the user's mugshot as stored in the database with the server.
        /// </summary>
        public void Sync()
        {
            if (CIX.Online && Username == CIX.Username)
            {
                LogFile.WriteLine("Uploading mugshot for {0} to server", Username);
                using (Image img = System.Drawing.Image.FromStream(new MemoryStream(Image)))
                {
                    try
                    {
                        HttpWebRequest request        = APIRequest.Post("user/setmugshot", APIRequest.APIFormat.XML, img);
                        string         responseString = APIRequest.ReadResponseString(request);

                        if (responseString == "Success")
                        {
                            LogFile.WriteLine("Mugshot successfully uploaded");
                            Pending      = false;
                            CreationTime = DateTime.Now;
                            lock (CIX.DBLock)
                            {
                                CIX.DB.Update(this);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        CIX.ReportServerExceptions("Mugshot.Sync", e);
                        Pending = true;
                        lock (CIX.DBLock)
                        {
                            CIX.DB.Update(this);
                        }
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Post a reply message to the server. The ConversationID field of the message must be set to
        /// a valid conversation ID for the thread to which the reply is being posted.
        /// </summary>
        /// <param name="message">The draft InboxMessage to be posted</param>
        private void Reply(InboxMessage message)
        {
            bool hasError = false;

            try {
                PMessageReply reply = new PMessageReply
                {
                    Body  = message.Body.EscapeXml(),
                    ConID = RemoteID
                };

                WebRequest request   = APIRequest.Post("personalmessage/reply", APIRequest.APIFormat.XML, reply);
                Stream     objStream = APIRequest.ReadResponse(request);
                if (objStream != null)
                {
                    using (TextReader reader = new StreamReader(objStream))
                    {
                        XmlDocument doc = new XmlDocument {
                            InnerXml = reader.ReadLine()
                        };

                        if (doc.DocumentElement != null)
                        {
                            string responseString = doc.DocumentElement.InnerText;
                            int    messageID;

                            if (int.TryParse(responseString, out messageID))
                            {
                                message.RemoteID = messageID;
                                lock (CIX.DBLock)
                                {
                                    CIX.DB.Update(message);
                                }
                                LogFile.WriteLine("Reply {0} posted to server and updated locally", message.RemoteID);
                            }
                            else
                            {
                                hasError = true;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                CIX.ReportServerExceptions("InboxConversation.Reply", e);
                hasError = true;
            }

            if (hasError)
            {
                Flags |= InboxConversationFlags.Error;
                lock (CIX.DBLock)
                {
                    CIX.DB.Update(this);
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Refresh this profile from the server.
        /// </summary>
        public void Refresh()
        {
            if (CIX.Online)
            {
                LogFile.WriteLine("Profile for {0} requested from server", Username);

                try
                {
                    // First get the basic profile information
                    string         profileUrl = Username == CIX.Username ? "user/profile" : "user/" + Username + "/profile";
                    HttpWebRequest request    = APIRequest.Get(profileUrl, APIRequest.APIFormat.XML);
                    Stream         objStream  = APIRequest.ReadResponse(request);
                    if (objStream != null)
                    {
                        using (XmlReader reader = XmlReader.Create(objStream))
                        {
                            XmlSerializer serializer = new XmlSerializer(typeof(ProfileSmall));
                            ProfileSmall  profileSet = (ProfileSmall)serializer.Deserialize(reader);

                            Location     = profileSet.Location;
                            FullName     = profileSet.Fname + " " + profileSet.Sname;
                            EMailAddress = profileSet.Email;
                            LastOn       = DateTime.Parse(profileSet.LastOn);
                            Sex          = profileSet.Sex;
                            Flags        = (NotificationFlags)profileSet.Flags;
                            lock (CIX.DBLock)
                            {
                                CIX.DB.Update(this);
                            }
                            LogFile.WriteLine("Profile for {0} updated from server", Username);
                        }
                    }

                    request = APIRequest.Get("user/" + Username + "/resume", APIRequest.APIFormat.XML);
                    string resumeText = APIRequest.ReadResponseString(request);

                    if (!string.IsNullOrEmpty(resumeText) && CIX.DB != null)
                    {
                        About = resumeText.UnescapeXml();
                        lock (CIX.DBLock)
                        {
                            CIX.DB.Update(this);
                        }

                        LogFile.WriteLine("Resume for {0} updated from server", Username);

                        CIX.ProfileCollection.NotifyProfileUpdated(this);
                    }
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("Profile.Refresh", e);
                }
                Debug.Flush();
            }
        }
コード例 #5
0
ファイル: Account.cs プロジェクト: cixonline/cixreader
        private void Account_Load(object sender, EventArgs e)
        {
            CIX.ProfileCollection.ProfileUpdated += OnProfileUpdated;
            CIX.MugshotUpdated += OnMugshotUpdated;

            CIX.FolderCollection.AccountUpdated += OnAccountUpdated;
            CIX.RefreshUserAccount();

            RefreshAccount(Profile.ProfileForUser(CIX.Username), true);
            CIX.ProfileCollection.Get(CIX.Username).Refresh();
        }
コード例 #6
0
 /// <summary>
 /// Contains the thread where inbox interactions with the server are contained. Events
 /// are fired from within the thread to the UI handler to indicate changes.
 /// </summary>
 internal void Sync()
 {
     try
     {
         PostMessages();
         Refresh();
     }
     catch (Exception e)
     {
         CIX.ReportServerExceptions("ConversationCollection.Sync", e);
     }
 }
コード例 #7
0
ファイル: Mugshot.cs プロジェクト: cixonline/cixreader
        /// <summary>
        /// Execution task to retrieve a mugshot for the specified username from the server.
        /// </summary>
        public void Refresh()
        {
            if (CIX.Online)
            {
                LogFile.WriteLine("Mugshot for {0} requested from server", Username);

                try
                {
                    HttpWebRequest  request  = APIRequest.Get("user/" + Username + "/mugshot", APIRequest.APIFormat.XML);
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                    Stream responseStream = response.GetResponseStream();
                    if (responseStream != null)
                    {
                        byte[] imageBytes;

                        using (BinaryReader reader = new BinaryReader(responseStream))
                        {
                            imageBytes = reader.ReadBytes((int)response.ContentLength);
                        }

                        // Crop the user mugshot and scale it down so we're only storing a centered
                        // square of the required dimensions.
                        TypeConverter tc           = TypeDescriptor.GetConverter(typeof(Image));
                        Image         mugshotImage = (Image)tc.ConvertFrom(imageBytes);

                        mugshotImage = mugshotImage.ResizeImage(MaxMugshotWidth, MaxMugshotHeight);

                        ImageConverter converter = new ImageConverter();
                        imageBytes = (byte[])converter.ConvertTo(mugshotImage, typeof(byte[]));

                        Image        = imageBytes;
                        CreationTime = DateTime.Now;

                        lock (CIX.DBLock)
                        {
                            CIX.DB.Update(this);
                        }

                        Cache[Username] = this;

                        LogFile.WriteLine("Mugshot for {0} updated from server", Username);
                        CIX.NotifyMugshotUpdated(this);
                    }
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("Mugshot.Refresh", e);
                }
                Debug.Flush();
            }
        }
コード例 #8
0
ファイル: WelcomeView.cs プロジェクト: cixonline/cixreader
 /// <summary>
 /// Display this view with the specified folder and options
 /// </summary>
 public override bool ViewFromFolder(FolderBase folder, Address address, FolderOptions flags)
 {
     if (_welcomePage == null)
     {
         FillCanvas();
     }
     if (CIX.Online)
     {
         CIX.RefreshOnlineUsers();
         FolderCollection.RefreshInterestingThreads();
     }
     return(true);
 }
コード例 #9
0
ファイル: Mugshot.cs プロジェクト: cixonline/cixreader
        /// <summary>
        /// Set the mugshot for the current user. First change in the database and if we
        /// have network access, change on the server. If there's no network access we
        /// mark this as needing updating in the configuration.
        /// </summary>
        /// <param name="newMugshot">An image specifying the new mugshot</param>
        public void Update(Image newMugshot)
        {
            // Make sure the input image is the maximum size allowed
            newMugshot = newMugshot.ResizeImage(MaxMugshotWidth, MaxMugshotHeight);

            ImageConverter converter = new ImageConverter();

            Mugshot mugshot = CIX.DB.Table <Mugshot>().SingleOrDefault(c => c.Username == CIX.Username);

            if (mugshot != null)
            {
                mugshot.Image        = (byte[])converter.ConvertTo(newMugshot, typeof(byte[]));
                mugshot.CreationTime = DateTime.Now;

                lock (CIX.DBLock)
                {
                    CIX.DB.Update(mugshot);
                }
            }
            else
            {
                mugshot = new Mugshot
                {
                    Username     = CIX.Username,
                    CreationTime = DateTime.Now,
                    Image        = (byte[])converter.ConvertTo(newMugshot, typeof(byte[]))
                };

                lock (CIX.DBLock)
                {
                    CIX.DB.Insert(mugshot);
                }
            }

            Cache.Remove(CIX.Username);
            _realImage = null;

            if (!CIX.Online)
            {
                Pending = true;
                lock (CIX.DBLock)
                {
                    CIX.DB.Update(mugshot);
                }
            }
            else
            {
                mugshot.Sync();
            }
            CIX.NotifyMugshotUpdated(mugshot);
        }
コード例 #10
0
        /// <summary>
        /// Synchronise moderators list changes with the server
        /// </summary>
        private void SyncModerators()
        {
            Thread t = new Thread(() =>
            {
                try
                {
                    string encodedForumName = FolderCollection.EncodeForumName(Name);
                    foreach (string part in AddedModerators)
                    {
                        string url            = string.Format("moderator/{0}/{1}/modadd", encodedForumName, part);
                        HttpWebRequest getUrl = APIRequest.Get(url, APIRequest.APIFormat.XML);
                        string responseString = APIRequest.ReadResponseString(getUrl);

                        if (responseString == "Success")
                        {
                            LogFile.WriteLine("Moderator {0} successfully added to {1}", part, Name);
                        }
                    }
                    foreach (string part in RemovedModerators)
                    {
                        string url            = string.Format("moderator/{0}/{1}/modrem", encodedForumName, part);
                        HttpWebRequest getUrl = APIRequest.Get(url, APIRequest.APIFormat.XML);
                        string responseString = APIRequest.ReadResponseString(getUrl);

                        if (responseString == "Success")
                        {
                            LogFile.WriteLine("Moderator {0} successfully removed from {1}", part, Name);
                        }
                    }

                    // Clear out the current moderators lists to force a refresh from the server
                    AddedMods   = string.Empty;
                    RemovedMods = string.Empty;
                    Mods        = string.Empty;
                    lock (CIX.DBLock)
                    {
                        CIX.DB.Update(this);
                    }

                    // Notify interested parties that the moderators list has changed
                    CIX.DirectoryCollection.NotifyModeratorsUpdated(this);
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("DirForum.SyncModerators", e);
                }
            });

            t.Start();
        }
コード例 #11
0
        /// <summary>
        /// Handle the Login button and cache the username and password entered. If the
        /// Remember option was checked, save the username in the global settings.
        /// </summary>
        private void fldOK_Click(object sender, EventArgs e)
        {
            if (Username != null && fldUsername.Text != Username)
            {
                fldError.Visible = true;
                return;
            }

            if (Password != null && fldPassword.Text != Password)
            {
                fldError.Visible = true;
                return;
            }

            // Authenticate online if possible
            // Disabling the buttons is symbolic anyway. Just to show something is happening.
            fldOK.Enabled     = false;
            fldCancel.Enabled = false;
            CIX.AuthenticateResponse success = CIX.Authenticate(fldUsername.Text, fldPassword.Text);
            fldOK.Enabled     = true;
            fldCancel.Enabled = true;

            if (success == CIX.AuthenticateResponse.Unconnected)
            {
                MessageBox.Show(Properties.Resources.NoConnection, Properties.Resources.AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (success == CIX.AuthenticateResponse.Inactivated)
            {
                fldError.Text    = Properties.Resources.InactivatedAccount;
                fldError.Visible = true;
                return;
            }

            if (success == CIX.AuthenticateResponse.Failure)
            {
                fldError.Text    = Properties.Resources.BadUsernameOrPassword;
                fldError.Visible = true;
                return;
            }

            Username = fldUsername.Text;
            Password = fldPassword.Text;

            Settings.CurrentUser.SetString("LastUser", Username);

            DialogResult = DialogResult.OK;
            Close();
        }
コード例 #12
0
ファイル: CIXMessage.cs プロジェクト: cixonline/cixreader
        /// <summary>
        /// Post this message to the server
        /// </summary>
        private void PostMessage()
        {
            CIX.FolderCollection.NotifyMessagePostStarted(this);
            PostPending = false;
            try
            {
                Folder      folder      = Topic;
                PostMessage postMessage = new PostMessage
                {
                    Body       = Body.FixQuotes(),
                    Forum      = folder.ParentFolder.Name,
                    Topic      = folder.Name,
                    WrapColumn = "0",
                    MarkRead   = "1",
                    MsgID      = CommentID.ToString(CultureInfo.InvariantCulture)
                };

                HttpWebRequest postUrl        = APIRequest.Post("forums/post", APIRequest.APIFormat.XML, postMessage);
                string         responseString = APIRequest.ReadResponseString(postUrl);

                int newRemoteID;
                if (int.TryParse(responseString, out newRemoteID))
                {
                    RemoteID = newRemoteID;
                    Date     = DateTime.UtcNow.UTCToGMTBST();
                    lock (CIX.DBLock)
                    {
                        CIX.DB.Update(this);
                    }
                    if (CommentID == 0)
                    {
                        LogFile.WriteLine("Posted new thread \"{0}\" as message {1}", Body.FirstLine(), RemoteID);
                    }
                    else
                    {
                        LogFile.WriteLine("Posted new reply to message {0} as message {1}", CommentID, RemoteID);
                    }
                    CIX.FolderCollection.NotifyMessageChanged(this);
                }
                else
                {
                    LogFile.WriteLine("Failed to post message {0} : {1}", ID, responseString);
                }
            }
            catch (Exception e)
            {
                CIX.ReportServerExceptions("CIXMessage.PostMessage", e);
            }
            CIX.FolderCollection.NotifyMessagePostCompleted(this);
        }
コード例 #13
0
        /// <summary>
        /// Refresh this topic from the server
        /// </summary>
        internal void InternalRefresh()
        {
            if (CIX.Online & !_isFolderRefreshing)
            {
                _isFolderRefreshing = true;
                CIX.FolderCollection.NotifyTopicUpdateStarted(this);

                try
                {
                    // When refreshing, get the last 30 days worth unless the topic is empty in which
                    // case we get everything. The assumption is that if any changes occur with the
                    // read/unread status on the server then 30 days back is enough to sync those
                    // with the local database.
                    DateTime latestReply = new DateTime(1900, 1, 1);
                    if (Messages.Count > 0)
                    {
                        latestReply = DateTime.Now.Subtract(new TimeSpan(30, 0, 0, 0));
                    }

                    // First clear the flag so we don't over-refresh
                    RefreshRequired = false;

                    Folder forum = ParentFolder;
                    int    countOfNewMessages = 0;

                    string urlFormat = string.Format("forums/{0}/{1}/allmessages", FolderCollection.EncodeForumName(forum.Name), Name);

                    HttpWebRequest request = APIRequest.GetWithQuery(urlFormat, APIRequest.APIFormat.XML, "maxresults=5000&since=" + latestReply.ToString("yyyy-MM-dd HH:mm:ss"));
                    using (Stream objStream = APIRequest.ReadResponse(request))
                    {
                        if (objStream != null)
                        {
                            countOfNewMessages = FolderCollection.AddMessages(objStream, ref latestReply, false, false);
                        }
                    }
                    if (countOfNewMessages > 0)
                    {
                        LogFile.WriteLine("{0}/{1} refreshed with {2} new messages", forum.Name, Name, countOfNewMessages);
                    }
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("Folder.Refresh", this, e);
                }

                CIX.FolderCollection.NotifyTopicUpdateCompleted(this);
                _isFolderRefreshing = false;
            }
        }
コード例 #14
0
        /// <summary>
        /// Do a fixup scan of the messages in the folder and make a request to
        /// retrieve any missing ones.
        /// </summary>
        public void Fixup()
        {
            List <Range> listOfRanges  = new List <Range>();
            int          lastMessageID = 0;

            foreach (CIXMessage message in _allMessages.OrderedMessages)
            {
                if (!message.IsPseudo && message.RemoteID != lastMessageID + 1)
                {
                    Range newRange = new Range
                    {
                        TopicName = Name,
                        ForumName = ParentFolder.Name,
                        Start     = lastMessageID + 1,
                        End       = message.RemoteID - 1
                    };
                    listOfRanges.Add(newRange);
                }
                lastMessageID = message.RemoteID;
            }
            if (listOfRanges.Count > 0)
            {
                Thread t = new Thread(() =>
                {
                    try
                    {
                        HttpWebRequest wrGeturl = APIRequest.Post("forums/messagerange", APIRequest.APIFormat.XML, listOfRanges);
                        Stream objStream        = APIRequest.ReadResponse(wrGeturl);
                        if (objStream != null)
                        {
                            DateTime sinceDate = CIX.LastSyncDate;
                            int newMessages    = FolderCollection.AddMessages(objStream, ref sinceDate, true, true);

                            if (newMessages > 0)
                            {
                                LogFile.WriteLine("{0}/{1} refreshed with {2} new messages", ParentFolder.Name, Name, newMessages);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        CIX.ReportServerExceptions("Folder.Fixup", e);
                    }
                });
                t.Start();
            }
        }
コード例 #15
0
        /// <summary>
        /// Sync this profile with the server.
        /// </summary>
        public void Sync()
        {
            if (CIX.Online && Username == CIX.Username)
            {
                string[] splitName = FullName.Split(new[] { ' ' }, 2);

                LogFile.WriteLine("Uploading profile for {0} to server", CIX.Username);

                ProfileSet newProfileSmall = new ProfileSet
                {
                    Fname    = splitName[0],
                    Sname    = (splitName.Length > 1) ? splitName[1] : string.Empty,
                    Location = Location,
                    Email    = EMailAddress,
                    Flags    = (int)Flags,
                    Sex      = Sex
                };

                try
                {
                    HttpWebRequest request        = APIRequest.Post("user/setprofile", APIRequest.APIFormat.XML, newProfileSmall);
                    string         responseString = APIRequest.ReadResponseString(request);

                    if (responseString == "Success")
                    {
                        Pending = false;
                        LogFile.WriteLine("Profile successfully uploaded");
                    }

                    request        = APIRequest.Post("user/setresume", APIRequest.APIFormat.XML, About);
                    responseString = APIRequest.ReadResponseString(request);

                    if (responseString == "True")
                    {
                        Pending = false;
                        LogFile.WriteLine("Resume successfully uploaded");
                    }
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("Profile.Sync", e);
                }
            }
        }
コード例 #16
0
        /// <summary>
        /// Refresh the list of moderators
        /// </summary>
        private void RefreshModerators()
        {
            Thread t = new Thread(() =>
            {
                try
                {
                    List <string> moderators = new List <string>();

                    LogFile.WriteLine("Updating list of moderators for {0}", Name);

                    string urlFormat = string.Format("forums/{0}/moderators", FolderCollection.EncodeForumName(Name));

                    HttpWebRequest wrGeturl = APIRequest.GetWithQuery(urlFormat, APIRequest.APIFormat.XML, "maxresults=10000");
                    Stream objStream        = APIRequest.ReadResponse(wrGeturl);
                    if (objStream != null)
                    {
                        using (XmlReader reader = XmlReader.Create(objStream))
                        {
                            XmlSerializer serializer = new XmlSerializer(typeof(ForumMods));
                            ForumMods allModerators  = (ForumMods)serializer.Deserialize(reader);

                            moderators.AddRange(allModerators.Mods.Select(mod => mod.Name));

                            Mods = string.Join(",", moderators);

                            LogFile.WriteLine("List of moderators for {0} updated", Name);

                            lock (CIX.DBLock)
                            {
                                CIX.DB.Update(this);
                            }
                        }
                    }
                    CIX.DirectoryCollection.NotifyModeratorsUpdated(this);
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("DirForum.Moderators", e);
                }
                isModeratorsRefreshing = 0;
            });

            t.Start();
        }
コード例 #17
0
        /// <summary>
        /// Retrieve an entire conversation. Any new messages are added to the message set and
        /// an event is fired.
        /// </summary>
        /// <param name="root">The root message to which this conversation belongs</param>
        /// <param name="latestMesssageDate">Ref to a DateTime that is set to the date of the
        /// most recent message in this conversation</param>
        /// <returns>The number of messages retrieved</returns>
        private static int GetConversation(InboxConversation root, ref DateTime latestMesssageDate)
        {
            int countOfRead = 0;

            try
            {
                HttpWebRequest request   = APIRequest.Get("personalmessage/" + root.RemoteID + "/message", APIRequest.APIFormat.XML);
                Stream         objStream = APIRequest.ReadResponse(request);
                if (objStream != null)
                {
                    using (XmlReader reader = XmlReader.Create(objStream))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(PMessageSet));
                        PMessageSet   inboxSet   = (PMessageSet)serializer.Deserialize(reader);

                        foreach (CIXInboxMessage message in inboxSet.PMessages)
                        {
                            if (!root.Messages.Contains(message.MessageID))
                            {
                                InboxMessage newMessage = new InboxMessage
                                {
                                    ConversationID = root.ID,
                                    RemoteID       = message.MessageID,
                                    Body           = message.Body,
                                    Date           = DateTime.Parse(message.Date),
                                    Author         = message.Sender
                                };
                                root.Messages.AddInternal(newMessage);
                                if (newMessage.Date > latestMesssageDate)
                                {
                                    latestMesssageDate = newMessage.Date;
                                }
                                ++countOfRead;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                CIX.ReportServerExceptions("ConversationCollection.GetConversation", e);
            }
            return(countOfRead);
        }
コード例 #18
0
        /// <summary>
        /// Join the specified forum.
        /// </summary>
        private void InternalJoin()
        {
            try
            {
                LogFile.WriteLine("Joining forum {0}", Name);

                HttpWebRequest request = APIRequest.GetWithQuery("forums/" + FolderCollection.EncodeForumName(Name) + "/join", APIRequest.APIFormat.XML, "mark=true");

                string responseString = APIRequest.ReadResponseString(request);
                if (responseString == "Success")
                {
                    LogFile.WriteLine("Successfully joined forum {0}", Name);

                    Folder folder = CIX.FolderCollection.Get(-1, Name);
                    if (folder == null)
                    {
                        folder = new Folder {
                            Name = Name, Flags = FolderFlags.Recent, ParentID = -1
                        };
                        CIX.FolderCollection.Add(folder);
                    }

                    folder.Flags &= ~FolderFlags.Resigned;
                    lock (CIX.DBLock)
                    {
                        CIX.DB.Update(folder);
                    }

                    CIX.DirectoryCollection.NotifyForumJoined(folder);

                    CIX.FolderCollection.Refresh(false);
                }
                JoinPending = false;
                lock (CIX.DBLock)
                {
                    CIX.DB.Update(this);
                }
            }
            catch (Exception e)
            {
                CIX.ReportServerExceptions("DirForum.Join", e);
            }
        }
コード例 #19
0
ファイル: CIXMessage.cs プロジェクト: cixonline/cixreader
        /// <summary>
        /// Withdraw this message from the server.
        /// </summary>
        private void WithdrawMessage()
        {
            try
            {
                LogFile.WriteLine("Withdrawing message {0}", RemoteID);

                Folder         topic     = Topic;
                Folder         forum     = topic.ParentFolder;
                string         urlFormat = string.Format("forums/{0}/{1}/{2}/withdraw", FolderCollection.EncodeForumName(forum.Name), topic.Name, RemoteID);
                HttpWebRequest request   = APIRequest.Get(urlFormat, APIRequest.APIFormat.XML);

                // Don't try and withdraw again because this was an error.
                WithdrawPending = false;
                lock (CIX.DBLock)
                {
                    CIX.DB.Update(this);
                }
                string responseString = APIRequest.ReadResponseString(request);

                if (responseString == "Success")
                {
                    LogFile.WriteLine("Successfully withdrawn message {0}", RemoteID);

                    // Replace the message text with the one that we'd get from the server
                    // and save us a round-trip.
                    Body = IsMine ? Resources.WithdrawnByAuthor : Resources.WithdrawnByModerator;
                    lock (CIX.DBLock)
                    {
                        CIX.DB.Update(this);
                    }
                    CIX.FolderCollection.NotifyMessageChanged(this);
                }
                else
                {
                    LogFile.WriteLine("Error withdrawing message. Response is: {1}", forum.Name, responseString);
                }
            }
            catch (Exception e)
            {
                CIX.ReportServerExceptions("CIXMessage.WithdrawMessage", e);
            }
        }
コード例 #20
0
 /// <summary>
 /// Synchronise the profile collection, updating any changes to the local
 /// profile and resume that was made offline to the server.
 /// </summary>
 public void Sync()
 {
     try
     {
         Profile selfProfile = Profile.ProfileForUser(CIX.Username);
         if (selfProfile.Pending)
         {
             selfProfile.Sync();
         }
         Mugshot selfMugshot = Mugshot.MugshotForUser(CIX.Username, false);
         if (selfMugshot.Pending)
         {
             selfMugshot.Sync();
         }
     }
     catch (Exception e)
     {
         CIX.ReportServerExceptions("ProfileCollection.Sync", e);
     }
 }
コード例 #21
0
        /// <summary>
        /// Request admittance to this forum
        /// </summary>
        public void RequestAdmittance()
        {
            if (CIX.Online)
            {
                Thread t = new Thread(() =>
                {
                    try
                    {
                        StringBuilder textTemplate = new StringBuilder(Resources.AdmissionRequestTemplate1);
                        textTemplate.Replace("$username$", CIX.Username);
                        textTemplate.Replace("$forum$", Name);

                        StringBuilder htmlTemplate = new StringBuilder(Resources.AdmissionRequestTemplate);
                        htmlTemplate.Replace("$username$", CIX.Username);
                        htmlTemplate.Replace("$forum$", Name);

                        SendMail sendMail = new SendMail
                        {
                            Text = textTemplate.ToString(),
                            HTML = htmlTemplate.ToString()
                        };

                        LogFile.WriteLine("Requesting admission to forum {0}", Name);

                        string url             = string.Format("moderator/{0}/sendmessage", Name);
                        HttpWebRequest postUrl = APIRequest.Post(url, APIRequest.APIFormat.XML, sendMail);
                        string responseString  = APIRequest.ReadResponseString(postUrl);

                        if (responseString == "Success")
                        {
                            LogFile.WriteLine("Successfully sent admittance request for forum {0}", Name);
                        }
                    }
                    catch (Exception e)
                    {
                        CIX.ReportServerExceptions("DirForum.RequestAdmittance", e);
                    }
                });
                t.Start();
            }
        }
コード例 #22
0
        /// <summary>
        /// Sync forum details with the server.
        /// </summary>
        private void SyncDetails()
        {
            Thread t = new Thread(() =>
            {
                try
                {
                    LogFile.WriteLine("Updating forum {0} to server", Name);
                    Forum newForum = new Forum
                    {
                        Title       = Title,
                        Name        = Name,
                        Description = Desc,
                        Category    = Cat,
                        SubCategory = Sub,
                        Type        = Type
                    };

                    HttpWebRequest postUrl = APIRequest.Post("moderator/forumupdate", APIRequest.APIFormat.XML, newForum);
                    string responseString  = APIRequest.ReadResponseString(postUrl);

                    if (responseString == "Success")
                    {
                        LogFile.WriteLine("Forum {0} successfully updated", Name);

                        DetailsPending = false;
                        lock (CIX.DBLock)
                        {
                            CIX.DB.Update(this);
                        }
                    }
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("DirForum.SyncDetails", e);
                }
            });

            t.Start();
        }
コード例 #23
0
        /// <summary>
        /// Delete this conversation from the server.
        /// </summary>
        private void DeleteConversation()
        {
            if (CIX.Online)
            {
                try
                {
                    // If draft, then just delete
                    if (RemoteID == 0)
                    {
                        CIX.ConversationCollection.Remove(this);
                        return;
                    }

                    HttpWebRequest request        = APIRequest.Get("personalmessage/inbox/" + RemoteID + "/rem", APIRequest.APIFormat.XML);
                    string         responseString = APIRequest.ReadResponseString(request);
                    if (responseString == "Success")
                    {
                        LogFile.WriteLine("Conversation {0} deleted from inbox", RemoteID);
                        CIX.ConversationCollection.Remove(this);
                    }

                    request        = APIRequest.Get("personalmessage/outbox/" + RemoteID + "/rem", APIRequest.APIFormat.XML);
                    responseString = APIRequest.ReadResponseString(request);

                    if (responseString == "Success")
                    {
                        LogFile.WriteLine("Conversation {0} deleted from outbox", RemoteID);
                        CIX.ConversationCollection.Remove(this);
                    }
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("InboxConversation.DeleteConversations", e);
                }
            }
        }
コード例 #24
0
 private void SyncProgress_Shown(object sender, System.EventArgs e)
 {
     CIX.RefreshStatusEnded += SyncProgress_Completed;
     CIX.RunAllTasks();
 }
コード例 #25
0
        /// <summary>
        /// Resign this folder on the server.
        /// </summary>
        private void ResignFolder()
        {
            if (!CIX.Online)
            {
                ResignPending = true;
                lock (CIX.DBLock)
                {
                    CIX.DB.Update(this);
                }
                return;
            }

            try
            {
                string url;
                if (IsRootFolder)
                {
                    LogFile.WriteLine("Resigning forum {0}", Name);
                    url = "forums/" + FolderCollection.EncodeForumName(Name) + "/resign";
                }
                else
                {
                    Folder forum = ParentFolder;
                    LogFile.WriteLine("Resigning topic {0}/{1}", forum.Name, Name);
                    url = "forums/" + FolderCollection.EncodeForumName(forum.Name) + "/" + FolderCollection.EncodeForumName(Name) + "/resigntopic";
                }

                HttpWebRequest request = APIRequest.Get(url, APIRequest.APIFormat.XML);

                string responseString = APIRequest.ReadResponseString(request);
                if (responseString == "Success")
                {
                    LogFile.WriteLine("Successfully resigned from {0}", Name);

                    CIX.FolderCollection.NotifyFolderUpdated(this);
                }
                else
                {
                    LogFile.WriteLine("Error resigning {0}. Response is: {1}", Name, responseString);
                }

                if (DeletePending)
                {
                    DeletePending = false;
                    Delete(false);
                    return;
                }

                // Whatever happens, clear the pending action so we don't keep trying to
                // resign the forum repeatedly.
                ResignPending = false;
                Flags        |= FolderFlags.Resigned;
                lock (CIX.DBLock)
                {
                    CIX.DB.Update(this);
                }
            }
            catch (Exception e)
            {
                CIX.ReportServerExceptions("Folder.ResignFolder", this, e);
            }
        }
コード例 #26
0
        /// <summary>
        /// Sync this conversation with the server.
        /// </summary>
        public void Sync()
        {
            if (Flags.HasFlag(InboxConversationFlags.Deleted))
            {
                DeleteConversation();
                return;
            }
            if (Flags.HasFlag(InboxConversationFlags.MarkRead))
            {
                MarkReadConversation();
            }

            if (Flags.HasFlag(InboxConversationFlags.Error))
            {
                return;
            }

            int conversationID = RemoteID;

            foreach (InboxMessage message in Messages)
            {
                if (message.IsDraft)
                {
                    if (conversationID > 0)
                    {
                        Reply(message);
                    }
                    else
                    {
                        bool hasError = false;

                        try
                        {
                            PMessageAdd newMessage = new PMessageAdd
                            {
                                Body      = message.Body.EscapeXml(),
                                Recipient = message.Author,
                                Subject   = Subject
                            };

                            WebRequest request   = APIRequest.Post("personalmessage/add", APIRequest.APIFormat.XML, newMessage);
                            Stream     objStream = APIRequest.ReadResponse(request);
                            if (objStream != null)
                            {
                                using (TextReader reader = new StreamReader(objStream))
                                {
                                    XmlDocument doc = new XmlDocument {
                                        InnerXml = reader.ReadLine()
                                    };

                                    if (doc.DocumentElement != null)
                                    {
                                        string   responseString = doc.DocumentElement.InnerText;
                                        string[] splitStrings   = responseString.Split(',');

                                        if (splitStrings.Length == 2)
                                        {
                                            int messageID;

                                            if (int.TryParse(splitStrings[0], out conversationID) &&
                                                int.TryParse(splitStrings[1], out messageID))
                                            {
                                                lock (CIX.DBLock)
                                                {
                                                    RemoteID = conversationID;
                                                    CIX.DB.Update(this);

                                                    message.RemoteID = messageID;
                                                    CIX.DB.Update(message);
                                                }
                                                LogFile.WriteLine("New message {0} in conversation {1} posted to server and updated locally", message.RemoteID, RemoteID);
                                            }
                                        }
                                        else
                                        {
                                            hasError = true;
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            CIX.ReportServerExceptions("InboxConversation.Sync", e);
                            hasError = true;
                        }

                        // Flag if we hit an error
                        if (hasError)
                        {
                            Flags |= InboxConversationFlags.Error;
                            lock (CIX.DBLock)
                            {
                                CIX.DB.Update(this);
                            }
                        }
                    }
                }
            }
        }
コード例 #27
0
        /// <summary>
        /// Refresh the details of the forum, including title and description.
        /// </summary>
        /// <param name="forumName">The forum name</param>
        public void RefreshForum(string forumName)
        {
            Thread t = new Thread(() =>
            {
                DirForum forum = null;
                try
                {
                    string encodedForumName = FolderCollection.EncodeForumName(forumName);
                    LogFile.WriteLine("Updating directory for {0}", forumName);

                    HttpWebRequest wrGeturl = APIRequest.Get("forums/" + encodedForumName + "/details", APIRequest.APIFormat.XML);
                    Stream objStream        = APIRequest.ReadResponse(wrGeturl);
                    if (objStream != null)
                    {
                        using (XmlReader reader = XmlReader.Create(objStream))
                        {
                            XmlSerializer serializer  = new XmlSerializer(typeof(ForumDetails));
                            ForumDetails forumDetails = (ForumDetails)serializer.Deserialize(reader);

                            bool isNewForum = false;

                            forum = ForumByName(forumDetails.Name);
                            if (forum == null)
                            {
                                forum      = new DirForum();
                                isNewForum = true;
                            }
                            forum.Name   = forumDetails.Name;
                            forum.Title  = forumDetails.Title;
                            forum.Desc   = forumDetails.Description;
                            forum.Cat    = forumDetails.Category;
                            forum.Sub    = forumDetails.SubCategory;
                            forum.Recent = forumDetails.Recent;
                            forum.Type   = forumDetails.Type;

                            lock (CIX.DBLock)
                            {
                                if (isNewForum)
                                {
                                    CIX.DB.Insert(forum);
                                    _allForums[forum.ID] = forum;
                                }
                                else
                                {
                                    CIX.DB.Update(forum);
                                }
                            }

                            LogFile.WriteLine("Directory for {0} updated", forum.Name);
                        }
                    }
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("DirectoryCollection.RefreshForum", e);
                }
                NotifyForumUpdated(forum);
            });

            t.Start();
        }
コード例 #28
0
ファイル: Program.cs プロジェクト: cixonline/cixreader
        /// <summary>
        /// Do database initialisation.
        /// </summary>
        /// <returns>True if we initialised successfully, false otherwise</returns>
        private static bool InitializeDatabase()
        {
            string username     = LastUser;
            string databasePath = _databasePath;
            string password     = null;

            if (databasePath != null)
            {
                username = Path.GetFileNameWithoutExtension(databasePath);
            }
            else
            {
                string docFolder = CIX.HomeFolder;

                if (!string.IsNullOrEmpty(username))
                {
                    databasePath = Path.Combine(docFolder, username + ".cixreader");
                    if (!File.Exists(databasePath))
                    {
                        // The lastuser was mysteriously deleted so clear it and start
                        // again by requesting login.
                        username = null;
                    }
                }

                if (string.IsNullOrEmpty(username))
                {
                    Settings.CurrentUser.SetString("LastUser", string.Empty);

                    Login loginDialog = new Login();
                    if (loginDialog.ShowDialog() == DialogResult.Cancel)
                    {
                        Application.Exit();
                        return(false);
                    }
                    username = loginDialog.Username;
                    password = loginDialog.Password;
                }

                databasePath = Path.Combine(docFolder, username + ".cixreader");

                if (!Directory.Exists(docFolder))
                {
                    Directory.CreateDirectory(docFolder);
                }
            }

            // Ensure all tables exist
            if (!CIX.Init(databasePath))
            {
                MessageBox.Show(@"Cannot open database: " + databasePath);
                return(false);
            }

            // If a cached username was specified and it matches the username we have then we
            // use that to indicate that the password in the DB is to be used. Otherwise we need
            // the user to authenticate against the database password.
            if (CIX.Password == null || CIX.Username == null)
            {
                // Prompt for credentials if we don't have them and ensure they match
                // what is in the database.
                if (username == null || password == null)
                {
                    Login loginDialog = new Login {
                        Username = CIX.Username,
                        Password = CIX.Password
                    };

                    if (loginDialog.ShowDialog() == DialogResult.Cancel)
                    {
                        Application.Exit();
                        return(false);
                    }

                    username = loginDialog.Username;
                    password = loginDialog.Password;
                }

                CIX.Username = username;
                CIX.Password = password;
            }

            string settingsPath = Path.Combine(CIX.HomeFolder, username + ".ini");

            Preferences.Open(settingsPath);

            if (IsFirstRun)
            {
                Preferences.StandardPreferences.StartOffline = true;
            }

            InitializeLogFile();

            LogFile.WriteLine("{0} {1} started", Resources.AppTitle, VersionString);
            LogFile.WriteLine("Opened database {0}", databasePath);

            // Compact the database if the time has come
            int cleanupFrequency = Preferences.StandardPreferences.CacheCleanUpFrequency;

            if (cleanupFrequency > 0)
            {
                DateTime cleanupDate = Preferences.StandardPreferences.LastCacheCleanUp;
                cleanupDate = cleanupDate.AddDays(cleanupFrequency);
                if (cleanupDate < DateTime.Now)
                {
                    CIX.CompactDatabase();
                    Preferences.StandardPreferences.LastCacheCleanUp = DateTime.Now;
                }
            }

            // Set initial state
            StartupOnline  = (!_forceOffline) && !Preferences.StandardPreferences.StartOffline;
            StartupAddress = _address ?? Preferences.StandardPreferences.LastAddress;

            // Use the beta API if the user has opted into beta.
            APIRequest.UseBetaAPI = Preferences.StandardPreferences.UseBeta;
            return(true);
        }
コード例 #29
0
ファイル: CIXMessage.cs プロジェクト: cixonline/cixreader
        /// <summary>
        /// Add or remove the star from this message on the server.
        /// </summary>
        private void StarMessage()
        {
            Folder folder = Topic;

            if (Starred)
            {
                StarAdd addStar = new StarAdd
                {
                    Forum = Topic.ParentFolder.Name,
                    Topic = folder.Name,
                    MsgID = RemoteID.ToString(CultureInfo.InvariantCulture)
                };
                LogFile.WriteLine("Adding star to message {0} in {1}/{2}", addStar.MsgID, addStar.Forum, addStar.Topic);

                try
                {
                    HttpWebRequest postUrl        = APIRequest.Post("starred/add", APIRequest.APIFormat.XML, addStar);
                    string         responseString = APIRequest.ReadResponseString(postUrl);

                    if (responseString.Contains("Success"))
                    {
                        LogFile.WriteLine("Star successfully added");
                    }
                    else
                    {
                        LogFile.WriteLine("Failed to add star to message {0} : {1}", RemoteID, responseString);
                    }
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("CIXMessage.StarMessage", e);
                }
                StarPending = false;
                lock (CIX.DBLock)
                {
                    CIX.DB.Update(this);
                }
            }
            else
            {
                string forumName = FolderCollection.EncodeForumName(Topic.ParentFolder.Name);
                string starUrl   = string.Format("starred/{0}/{1}/{2}/rem", forumName, Topic.Name, RemoteID);

                LogFile.WriteLine("Removing star from message {0} in {1}/{2}", RemoteID, forumName, Topic.Name);

                try
                {
                    HttpWebRequest getRequest     = APIRequest.Get(starUrl, APIRequest.APIFormat.XML);
                    string         responseString = APIRequest.ReadResponseString(getRequest);

                    if (responseString.Contains("Success"))
                    {
                        LogFile.WriteLine("Star successfully removed");
                    }
                    else
                    {
                        LogFile.WriteLine("Failed to remove star for message {0} : {1}", RemoteID, responseString);
                    }
                }
                catch (Exception e)
                {
                    CIX.ReportServerExceptions("CIXMessage.StarMessage", e);
                }
                if (StarPending)
                {
                    StarPending = false;
                    lock (CIX.DBLock)
                    {
                        CIX.DB.Update(this);
                    }
                }
            }
        }
コード例 #30
0
        /// <summary>
        /// Retrieve new conversations from the server since the last time we checked.
        /// </summary>
        public void Refresh()
        {
            try
            {
                List <CIXInboxItem> inboxItems = new List <CIXInboxItem>();

                int totalCountOfRead = 0;

                HttpWebRequest request   = APIRequest.GetWithQuery("personalmessage/inbox", APIRequest.APIFormat.XML, "since=" + _lastCheckDateTime.ToString("yyyy-MM-dd HH:mm:ss"));
                Stream         objStream = APIRequest.ReadResponse(request);

                if (objStream != null)
                {
                    using (XmlReader reader = XmlReader.Create(objStream))
                    {
                        XmlSerializer        serializer = new XmlSerializer(typeof(ConversationInboxSet));
                        ConversationInboxSet inboxSet   = (ConversationInboxSet)serializer.Deserialize(reader);

                        foreach (CIXInboxItem conv in inboxSet.Conversations)
                        {
                            inboxItems.Add(conv);
                            InboxConversation root = ConversationByID(conv.ID);
                            if (root == null)
                            {
                                root = new InboxConversation
                                {
                                    RemoteID = conv.ID,
                                    Date     = DateTime.Parse(conv.Date),
                                    Subject  = conv.Subject,
                                    Author   = conv.Sender
                                };
                                Add(root);
                            }
                        }
                    }
                }

                request   = APIRequest.GetWithQuery("personalmessage/outbox", APIRequest.APIFormat.XML, "since=" + _lastCheckDateTime.ToString("yyyy-MM-dd HH:mm:ss"));
                objStream = APIRequest.ReadResponse(request);

                _lastCheckDateTime = DateTime.Now;

                if (objStream != null)
                {
                    using (XmlReader reader = XmlReader.Create(objStream))
                    {
                        XmlSerializer         serializer = new XmlSerializer(typeof(ConversationOutboxSet));
                        ConversationOutboxSet inboxSet   = (ConversationOutboxSet)serializer.Deserialize(reader);

                        foreach (CIXOutboxItem conv in inboxSet.Conversations)
                        {
                            // Make a fake CIXInboxItem for each CIXOutboxItem so we can treat
                            // them equally later.
                            inboxItems.Add(new CIXInboxItem
                            {
                                Date    = conv.Date,
                                ID      = conv.ID,
                                Sender  = conv.Recipient,
                                Subject = conv.Subject,
                                Unread  = "false"
                            });
                            InboxConversation root = ConversationByID(conv.ID);
                            if (root == null)
                            {
                                root = new InboxConversation
                                {
                                    RemoteID = conv.ID,
                                    Date     = DateTime.Parse(conv.Date),
                                    Subject  = conv.Subject,
                                    Author   = conv.Recipient
                                };
                                Add(root);
                            }
                        }
                    }
                }

                // Defer sending the notification of new root messages until we've got the whole list added
                // to the database for performance reasons.
                if (inboxItems.Count > 0)
                {
                    NotifyConversationAdded(null);
                }

                // Once we've got the roots added, check each one for additions to the
                // conversation.
                foreach (CIXInboxItem conv in inboxItems)
                {
                    InboxConversation root = ConversationByID(conv.ID);
                    if (root == null)
                    {
                        continue;
                    }

                    DateTime latestMessageDate = root.Date;

                    int countOfRead = GetConversation(root, ref latestMessageDate);
                    if (countOfRead > 0)
                    {
                        root.UnreadCount = (conv.Unread == "true") ? countOfRead : 0;
                        root.Flags      &= ~InboxConversationFlags.MarkRead;
                        root.Date        = latestMessageDate;
                        lock (CIX.DBLock)
                        {
                            CIX.DB.Update(root);
                        }
                    }

                    totalCountOfRead += countOfRead;
                }
                if (totalCountOfRead > 0)
                {
                    NotifyConversationChanged(null);
                    LogFile.WriteLine("{0} new private messages retrieved from inbox", totalCountOfRead);
                }
            }
            catch (Exception e)
            {
                CIX.ReportServerExceptions("ConversationCollection.Refresh", e);
            }
        }