Esempio n. 1
0
        private static string /*letter id*/ CreateLetterInternal(string board_id, string discussion_id,
                                                                 string creator, string words, Subtype subtype, string delta_flags)
        {
            string partition_key = SandId.CombineId(board_id, discussion_id);

            if (NextIdStore.GetLastId(Warehouse.DiscussionLoadTable, partition_key) >= HeartsConfiguration.MAX_NUM_OF_LETTERS_IN_A_DISCUSSION)
            {
                Util.ThrowBadRequestException("留言數超過上限(" + HeartsConfiguration.MAX_NUM_OF_LETTERS_IN_A_DISCUSSION + ")則。");
            }

            int    next_id   = NextIdStore.Next(Warehouse.DiscussionLoadTable, partition_key);                  // null reference exception for nonexistent board id.
            string letter_id = SandId.MakeLetterId(next_id);
            // if exception is thrown after getting id, the id is lost.

            DynamicTableEntity entity = new DynamicTableEntity(partition_key, letter_id);

            LetterConverter.CreateLetterEntity(entity, creator, words, subtype, delta_flags, board_id, discussion_id);
            //
            Warehouse.DiscussionLoadPond.Get(board_id, discussion_id).AddLetter(entity);
            Warehouse.DiscussionSummaryPond.Get(board_id, discussion_id).AddLetter(entity);

            Warehouse.DiscussionLoadTable.Execute(TableOperation.Insert(entity));
            //
            return(letter_id);
        }
Esempio n. 2
0
        public static ControlHistory ControlLetter(string board_id, string discussion_id, string letter_id, string delta_flags)
        {
            string partition_key = SandId.CombineId(board_id, discussion_id);

            // todo: select only needed properties.
            TableResult        result = Warehouse.DiscussionLoadTable.Execute(TableOperation.Retrieve(partition_key, letter_id));
            DynamicTableEntity entity = (DynamicTableEntity)result.Result;

            // permanent deleting twice is not blocked.
            GroupStore.CheckControlRight(board_id, discussion_id, letter_id, ref delta_flags, entity);

            int ec = RevisionStore.IncreaseEditCount(entity);

            RevisionStore.CreateRevision(entity, board_id, discussion_id, letter_id, ec);

            int prev_report_cnt = SandFlags.GetNumber(entity.GetFlags(), SandFlags.MT_REPORT);

            LetterConverter.ModifyLetterFlags(entity, null, delta_flags);

            int new_report_cnt = SandFlags.GetNumber(entity.GetFlags(), SandFlags.MT_REPORT);

            Warehouse.DiscussionLoadTable.Execute(TableOperation.Replace(entity));                  // Throws StorageException ((412) Precondition Failed) if the entity is modified in between.

            Warehouse.DiscussionLoadPond.Notify(board_id, discussion_id);
            Warehouse.DiscussionSummaryPond.Notify(board_id, discussion_id);
            HttpResponse.RemoveOutputCacheItem("/discussionload/" + board_id + "/" + discussion_id);

            return(new ControlHistory {
                ReportCount = new_report_cnt - prev_report_cnt
            });
        }
Esempio n. 3
0
        public static void EditLetter(string board_id, string discussion_id, string letter_id, string editor, string words,
                                      string delta_flags, HttpFileCollectionBase files)
        {
            string partition_key = SandId.CombineId(board_id, discussion_id);

            TableResult        result = Warehouse.DiscussionLoadTable.Execute(TableOperation.Retrieve(partition_key, letter_id));
            DynamicTableEntity entity = (DynamicTableEntity)result.Result;

            GroupStore.CheckEditRight(board_id, discussion_id, entity);

            HashSet <string> files_set = new HashSet <string>();

            words = processUploadFiles(words, files, files_set);
            words = processWords(words);
            claimFiles(words, SandId.CombineId(board_id, discussion_id, letter_id), files_set);

            // if (entity != null)		// let it throw null reference exception.
            int ec = RevisionStore.IncreaseEditCount(entity);

            RevisionStore.CreateRevision(entity, board_id, discussion_id, letter_id, ec);

            LetterConverter.EditLetterEntity(entity, editor, words, delta_flags, board_id, discussion_id);

            Warehouse.DiscussionLoadTable.Execute(TableOperation.Replace(entity));                  // Throws StorageException ((412) Precondition Failed) if the entity is modified in between.

            Warehouse.DiscussionLoadPond.Notify(board_id, discussion_id);
            Warehouse.DiscussionSummaryPond.Notify(board_id, discussion_id);

            HttpResponse.RemoveOutputCacheItem("/discussionload/" + board_id + "/" + discussion_id);
        }
Esempio n. 4
0
        public static void CheckControlRight(string board_id, string discussion_id, string letter_id, ref string delta_flags,
                                             DynamicTableEntity entity)
        {
            Subtype subtype = LetterConverter.GetSubtype(entity);

            if (subtype == Subtype.d)
            {
                Util.ThrowUnauthorizedException("不能修改的類型。");
            }

            bool auto_unreport = false;

            if (SandFlags.Check(delta_flags, SandFlags.MT_PERMANENT_DELETE, 1))
            {
                GroupStore.CheckPermanentDeleteRight(board_id, discussion_id, letter_id, entity);
                auto_unreport = true;
            }

            int delete_num = SandFlags.GetNumber(delta_flags, SandFlags.MT_DELETED);

            if (delete_num == 1 || delete_num == -1)
            {
                //bool is_undelete = SandFlags.Check(delta_flags, SandFlags.DELETED_FLAG_CHAR, -1);

                int user_level = GroupStore.CheckDeleteRight(board_id, discussion_id, letter_id, entity, delete_num == -1);

                //delta_flags = SandFlags.DELETED_FLAG_CHAR + (delete_num * user_level).ToString();
                //delta_flags = SandFlags.MultiplyNumber(delta_flags, SandFlags.DELETED_FLAG_CHAR, user_level);
                delta_flags = SandFlags.Operate(delta_flags, new FlagOperation
                {
                    type      = FlagOperation.Type.Multiply,
                    MetaTitle = SandFlags.MT_DELETED,
                    N         = user_level
                });

                string current_flags = entity.GetFlags();
                SandFlags.CheckLevel(current_flags, SandFlags.MT_DELETED, delta_flags);

                auto_unreport = true;
            }
            if (SandFlags.Check(delta_flags, SandFlags.MT_REPORT, 0))
            {
                GroupStore.CheckUnreportRight(board_id);
            }
            else if (SandFlags.Check(delta_flags, SandFlags.MT_REPORT, 1))
            {
            }
            else
            {
                if (auto_unreport)
                {
                    delta_flags = SandFlags.Add(delta_flags, SandFlags.MT_REPORT, 0);
                }
            }
        }
Esempio n. 5
0
        public static void CreateRevision(DynamicTableEntity letter_entity, string board_id, string discussion_id,
                                          string letter_id, int version)
        {
            string partition_key = SandId.CombineId(board_id, discussion_id, letter_id);

            DynamicTableEntity entity = new DynamicTableEntity(partition_key, SandId.MakeRevisionId(version));

            LetterConverter.CopyLetterRevision(letter_entity, entity, version);

            Warehouse.RevisionTable.Execute(TableOperation.Insert(entity));                     // If an exception is thrown after revision created but before edit count in letter entity is updated, next time edit will fail because the revision already exists.
        }
Esempio n. 6
0
        public static void CheckEditRight(string board_id, string discussion_id, DynamicTableEntity entity)
        {
            Subtype subtype = LetterConverter.GetSubtype(entity);

            if (subtype == Subtype.d)
            {
                Util.ThrowUnauthorizedException("不能編輯的類型。");
            }

            if (!CreatorConverter.IsCurrentUserCreator(entity) &&
                !DiscussionLoadStore.IsCurrentUserDiscussionCreator(board_id, discussion_id) &&
                !IsBoardOwner(board_id))
            {
                Util.ThrowUnauthorizedException("沒有編輯權限。只有副板主以上、串主、或原作者可以編輯。");
            }
        }
Esempio n. 7
0
        private static void moveForeMeta()
        {
            Regex regex = new Regex(@"^>>(.+?)\n", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant);
            //Regex regex = new Regex(@"^>>(.+?)$", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant);
            // some abstract contain only ">>(0,0)" and no "\n".

            string pkFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.GreaterThanOrEqual, "");

            TableQuery query = new TableQuery().Where(pkFilter).Select(new string[] { "flags2", "abstract" });

            int count = 0;

            foreach (DynamicTableEntity entity in Warehouse.DiscussionLoadTable.ExecuteQuery(query))
            {
                string flags = null;
                string ab    = LetterConverter.GetAbstract(entity);

                if (ab != null)
                {
                    ab = regex.Replace(ab, (Match match) =>
                    {
                        if (match.Groups[1].Value[0] == '(')
                        {
                            flags = entity.GetFlags();
                            flags = SandFlags.Add(flags, SandFlags.MT_COORDINATE, match.Groups[1].Value);
                        }
                        return(string.Empty);
                    });
                }

                if (flags != null)
                {
                    count++;

                    entity["flags2"]   = new EntityProperty(flags);
                    entity["abstract"] = new EntityProperty(ab);

                    Warehouse.DiscussionLoadTable.Execute(TableOperation.Merge(entity));

                    //if (count > 0)
                    //	break;
                }
            }
        }
Esempio n. 8
0
        public void AddLetter(DynamicTableEntity entity)
        {
            Subtype subtype = LetterConverter.GetSubtype(entity);

            if (subtype == Subtype.h)
            {
                this.viewType = entity.GetViewType();
            }

            string json = LetterConverter.LetterToJson(entity, this.BoardId, this.DiscussionId, this.viewType);

            if (subtype == Subtype.h)
            {
                if (this.headingJson == null)
                {
                    this.headingJson = json;
                }
            }
            else if (entity.RowKey == SandId.FIRST_SUBJECT_LETTER_ID)
            {
                if (this.subjectJson == null)
                {
                    this.subjectJson = json;
                }
            }
            else if (subtype == Subtype.s || subtype == Subtype.r)
            {
                this.replyQueue.Enqueue(json);

                if (this.replyQueue.Count > REPLY_COUNT)
                {
                    string dummy;
                    this.replyQueue.TryDequeue(out dummy);
                }
            }
            // subtype d is ignored. when there are lots of subtype d, replies will be pushed out of queue.
        }
Esempio n. 9
0
        private void addLetter(TextWriter writer, DynamicTableEntity entity)
        {
            LetterConverter.WriteForCrawler(writer, entity, false, null);

            Subtype subtype = LetterConverter.GetSubtype(entity);

            switch (subtype)
            {
            case Subtype.h:
                if (this.Heading == null)
                {
                    this.Heading = /*RemoveForeMeta*/ (LetterConverter.GetAbstract(entity));
                }
                break;

            case Subtype.s:
                // when subject is split to multiple segments, subtype s will be met multiple times.
                if (this.Description == null)
                {
                    this.Description = extractOgImage(LetterConverter.GetWholeWords(entity, false));
                }
                break;
            }
        }