Example #1
0
        void render(mg_connection* conn, int id, bool reverse){
            ConfigManager configs;
            // int id = cc_extract_uri_num(conn);

            int limit, count;
            auto r = unq_read_thread_sp(pDb, 0); // get the root thread
            count = r.get()->childCount;
            limit = count - configs.global().get<int>("user::viewable_threads");
            // delete r;

            if (id < 0 || (id < limit && limit != 0) || id > count){
                views::info::render(conn, templates.invoke("misc").toggle("invalid_thread_no").build_destory().c_str());
                return;
            }

            r = unq_read_thread_sp(pDb, id); // get the root thread
            int pid = unq_thread_parent(pDb, r.get());
            
            if ((pid == -1) && !is_admin(conn)){
                views::info::render(conn, templates.invoke("misc").toggle("invalid_thread_no").build_destory().c_str());
                // delete r;
                return;
            }
            
            templates.invoke("site_header").toggle("thread_page").toggle("is_admin", is_admin(conn)) \
                .var("THREAD_NO", id).var("THREAD_TITLE", r.get()->author).pipe_to(conn).destory();

            templates.invoke("single_thread_header").toggle("homepage", !pid).var("THREAD_NO", id) \
                .var("PARENT_NO", pid).toggle("thread", strstr(conn->uri, "/thread/")).pipe_to(conn).destory();
            
            clock_t startc = clock();

            // bool reverse = strstr(conn->uri, "/daerht/");
            bool admin_view = is_admin(conn);
            string username = cck_verify_ssid(conn);

            views::each_thread(conn, r.get(), 0, admin_view);
            mg_printf_data(conn, "<hr>");

            char iid[10];
            strcpy(iid, r.get()->ssid);

            if(!configs.global().get<bool>("archive"))
                templates.invoke("post_form") \
                    .var("THREAD_NO", to_string(id)).toggle("reply_to_thread"). \
                    toggle("is_admin", admin_view || !is_assist(conn).empty()).pipe_to(conn).destory();
                
            if (r.get()->childThread) {
                // int r_childThread = r->childThread;
                // delete r;

                int limit = configs.global().get<int>("user::collapse_image");

                r = unq_read_thread_sp(pDb, r.get()->childThread); // beginning of the circle
                int rid = r.get()->threadID; //the ID
                bool too_many_replies = (r.get()->childCount > limit);

                int di = 1;

                if(reverse)
                {
                    int n_rid = r.get()->prevThread;
                    // delete r;
                    r = unq_read_thread_sp(pDb, r.get()->prevThread);

                    views::each_thread(conn, r.get(), SEND_IS_REPLY + SEND_SHOW_REPLY_LINK, admin_view, iid, username.c_str());

                    while (r.get()->prevThread != n_rid){
                        di++;
                        // int r_prevThread = r->prevThread;

                        // delete r;
                        r = unq_read_thread_sp(pDb, r.get()->prevThread);

                        if(too_many_replies && (di > limit))
                            views::each_thread(conn, r.get(), SEND_IS_REPLY + SEND_SHOW_REPLY_LINK + SEND_CUT_IMAGE, admin_view, iid, username.c_str());
                        else
                            views::each_thread(conn, r.get(), SEND_IS_REPLY + SEND_SHOW_REPLY_LINK, admin_view, iid, username.c_str());
                    }
                }
                else
                {
                    views::each_thread(conn, r.get(), SEND_IS_REPLY + SEND_SHOW_REPLY_LINK, admin_view, iid, username.c_str());

                    while (r.get()->nextThread != rid){
                        // int r_nextThread = r->nextThread;
                        // delete r;

                        r = unq_read_thread_sp(pDb, r.get()->nextThread);
                        di++;

                        //views::each_thread(conn, r, true, true, false, too_many_replies && (di > 20), admin_view, iid);
                        if(too_many_replies && (di > limit))
                            views::each_thread(conn, r.get(), SEND_IS_REPLY + SEND_SHOW_REPLY_LINK + SEND_CUT_IMAGE, admin_view, iid, username.c_str());
                        else
                            views::each_thread(conn, r.get(), SEND_IS_REPLY + SEND_SHOW_REPLY_LINK, admin_view, iid, username.c_str());
                    }

                    // if(r) delete r;
                } 
            }

            clock_t endc = clock();

            // site_footer(conn, (float)(endc-startc)/CLOCKS_PER_SEC);
            templates.invoke("site_footer").var("TIME", (int)((endc-startc) * 1000 / CLOCKS_PER_SEC)).pipe_to(conn).destory();
        }
Example #2
0
    void each_thread(mg_connection* conn, struct Thread* r, char display_state, bool admin_view, 
        const char* iid,
        const char* uid){
        time_t now = time(NULL);

        string thread_post_time = cc_timestamp_to_time(r->date);
        int diff_day = cc_timestamp_diff_day(now, r->date);

        const char* content = unq_read_string(pDb, r->content);
        string thread_content(content);
        delete [] content;

        if((display_state & SEND_CUT_LONG_COMMENT) && thread_content.size() > 1024) 
            thread_content = thread_content.substr(0, 1024) + templates.invoke("misc").toggle("more_contents").build_destory();
            //+ "<font color='red'><b>&#128065;" + STRING_MORE + "</b></font>";

        HTMLTemplate *ht = templates.invoke_pointer("single_thread");

        map<string, bool> stats;
        map<string, string> vars;

        ConfigManager c;

        stats["reply"]                      = display_state & SEND_IS_REPLY;
        stats["show_reply"]                 = display_state & SEND_SHOW_REPLY_LINK;
        stats["archive"]                    = c.global().get<bool>("archive");
        stats["normal_display"]             = r->state & NORMAL_DISPLAY || admin_view;
        stats["thread_poster_is_admin"]     = (strcmp(r->ssid, "Admin") == 0);
        stats["thread_poster_is_sameone"]   = (strcmp(r->ssid, iid) == 0);
        stats["is_sameone"]                 = (strcmp(r->ssid, uid) == 0);
        stats["sage"]                       = (r->state & SAGE_THREAD && !stats["reply"]);
        stats["lock"]                       = (r->state & LOCKED_THREAD);
        stats["delete"]                     = !(r->state & NORMAL_DISPLAY);
        stats["show_admin"]                 = admin_view;
        if (strlen(r->imgSrc) >= 4){
            string fname(r->imgSrc);
            vars["THREAD_IMAGE"]            = fname;

            if (!cc_valid_image_ext(fname).empty()){
                stats["image_attached"]     = true;
                if(display_state & SEND_CUT_IMAGE){
                    struct stat st;
                    stat(("images/" + fname).c_str(), &st);
                    stats["show_size_only"] = true;
                    vars["THREAD_IMAGE_SIZE"] = to_string((int)(st.st_size / 1024));
                }
                else{
                    stats["show_full_image"] = true;
                    vars["THREAD_THUMB_PREFIX"] = c.global().get("image::thumb_prefix");
                }
            }else{
                stats["file_attached"]      = true;
            }
        }
        if(r->childThread && !(display_state & SEND_CUT_REPLY_COUNT)){
            struct Thread* c = unq_read_thread(pDb, r->childThread);
            const char *first_reply = unq_read_string(pDb, c->content);
            string display_reply = (c->state & NORMAL_DISPLAY) ? string(first_reply) : "";

            stats["show_num_replies"]       = true;
            vars["NUM_REPLIES"]             = to_string(c->childCount);
            vars["FIRST_REPLY"]             = cc_smart_shorten(display_reply);// display_reply.substr(0, display_reply.find_first_of("<")).substr(0,15);

            delete c;
            delete[] first_reply;
        }

        vars["THREAD_POSTER"]               = string(r->ssid);
        vars["THREAD_NO"]                   = to_string(r->threadID);
        vars["THREAD_CONTENT"]              = thread_content;

        // stats["show_title"]					= !stats["reply"] || strcmp(r->author, STRING_UNTITLED) != 0;
        vars["THREAD_TITLE"]                = string(r->author);

        vars["THREAD_IP"]                   = string(r->email);
        vars["THREAD_POST_TIME"]            = thread_post_time;
        vars["THREAD_STATE"]                = to_string(r->state);

        if(diff_day >= 0 && diff_day <= 2){
            stats["show_easy_date"]         = true;
            vars["THREAD_POST_DATE"]        = to_string(diff_day);
        }else{
            char timetmp[64];
            struct tm post_date;
            localtime_r(&(r->date), &post_date);

            strftime(timetmp, 64, "%Y-%m-%d", &post_date);
            vars["THREAD_POST_DATE"]        = string(timetmp);
        }

        map<string, queue<string>> loops; //nothing

        mg_printf_data(conn, "%s", ht->build(vars, stats, loops).c_str());

        // if(content) delete [] content;
        delete ht;
    }