Commit 6afabd10 authored by Jan Köster's avatar Jan Köster
Browse files

test

parent f2706159
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ namespace blogi {
      '#'+uid+' .gr-track{display:flex;transition:transform .4s ease;gap:16px;}'+
      '#'+uid+' .gr-card{flex:0 0 calc(33.333% - 11px);max-width:calc(33.333% - 11px);background:#f9fafb;border-radius:14px;padding:16px;display:flex;flex-direction:row;gap:12px;border:1px solid rgba(148,163,184,.3);box-sizing:border-box;}'+
      '#'+uid+' .gr-av{width:40px;height:40px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:1.05em;color:#fff;}'+
      '#'+uid+' .gr-av-img{object-fit:cover;background:#e5e7eb;}'+
      '#'+uid+' .gr-bd{flex:1;font-size:.95em;color:#111827;}'+
      '#'+uid+' .gr-name{font-weight:600;margin-bottom:3px;}'+
      '#'+uid+' .gr-rstars{color:#fbbf24;font-size:.9em;margin-bottom:4px;}'+
@@ -160,14 +161,17 @@ namespace blogi {
    var track=root.querySelector('.gr-track');
    reviews.forEach(function(r){
      var name=r.author_name||'Anonym';
      var init=name.charAt(0).toUpperCase();
      var full=String(r.text||'');
      var isLong=full.length>100;
      var short=isLong?full.slice(0,100)+'…':full;
      var photoUrl=String(r.author_photo_url||'');
      var avatarHtml=photoUrl
        ? '<img class="gr-av gr-av-img" src="'+photoUrl+'" alt="'+name+'" loading="lazy">'
        : '<div class="gr-av" style="background:'+avColor(name)+'">'+name.charAt(0).toUpperCase()+'</div>';
      var card=document.createElement('div');
      card.className='gr-card';
      card.innerHTML=
        '<div class="gr-av" style="background:'+avColor(name)+'">'+init+'</div>'+
        avatarHtml+
        '<div class="gr-bd" data-full="'+encodeURIComponent(full)+'">'+
          '<div class="gr-name">'+name+'</div>'+
          '<div class="gr-rstars">'+starsHtml(r.rating||5)+'</div>'+
+28 −13
Original line number Diff line number Diff line
@@ -50,10 +50,17 @@ namespace blogi {
                << "rating integer NOT NULL,"
                << "text text,"
                << "time character varying(64),"
                << "author_photo_url text,"
                << "approved boolean DEFAULT false"
                << ");";
            Args->database[0]->exec(sql, res);

            // Migrate existing installations that lack the photo column
            dbpp::SQL sqlmig;
            dbpp::DBResult resmig;
            sqlmig << "ALTER TABLE google_reviews ADD COLUMN IF NOT EXISTS author_photo_url text;";
            try { Args->database[0]->exec(sqlmig, resmig); } catch(...) {}

            try { getConfig(*Args->database[0], "GOOGLE_PLACES_API_KEY", _apiKey); } catch(...) {}
            try { getConfig(*Args->database[0], "GOOGLE_PLACE_ID", _placeId); } catch(...) {}
            try { getConfig(*Args->database[0], "GOOGLE_REVIEW_NOTIFY_EMAIL", _notifyEmail); } catch(...) {}
@@ -237,7 +244,7 @@ namespace blogi {
            if(req.getRequestURL().compare(0, listUrl.length(), listUrl) == 0 && req.getRequestType() == GETREQUEST) {
                dbpp::SQL sql;
                dbpp::DBResult res;
                sql << "SELECT author_name, rating, text, time FROM google_reviews WHERE approved=true;";
                sql << "SELECT author_name, rating, text, time, author_photo_url FROM google_reviews WHERE approved=true;";
                int ncount = Args->database[tid]->exec(sql, res);

                json_object *list = json_object_new_array();
@@ -245,8 +252,9 @@ namespace blogi {
                    json_object *rev = json_object_new_object();
                    json_object_object_add(rev, "author_name", json_object_new_string(res[i][0]));
                    json_object_object_add(rev, "rating", json_object_new_int(atoi(res[i][1])));
                    json_object_object_add(rev, "text", json_object_new_string(res[i][2]));
                    json_object_object_add(rev, "time", json_object_new_string(res[i][3]));
                    json_object_object_add(rev, "text", json_object_new_string(res[i][2] ? res[i][2] : ""));
                    json_object_object_add(rev, "time", json_object_new_string(res[i][3] ? res[i][3] : ""));
                    json_object_object_add(rev, "author_photo_url", json_object_new_string(res[i][4] ? res[i][4] : ""));
                    json_object_array_add(list, rev);
                }
                const char* output = json_object_to_json_string(list);
@@ -273,17 +281,19 @@ namespace blogi {
                    for(int i = 0; i < len; ++i) {
                        json_object* jrev = json_object_array_get_idx(jobj, i);

                        json_object *jauthor, *jrating, *jtext, *jtime;
                        std::string author, text, time;
                        json_object *jauthor, *jrating, *jtext, *jtime, *jphoto;
                        std::string author, text, time, photoUrl;
                        int rating = 5;

                        if (json_object_object_get_ex(jrev, "author_name", &jauthor)) author = json_object_get_string(jauthor);
                        if (json_object_object_get_ex(jrev, "rating", &jrating)) rating = json_object_get_int(jrating);
                        if (json_object_object_get_ex(jrev, "text", &jtext)) text = json_object_get_string(jtext);
                        if (json_object_object_get_ex(jrev, "time", &jtime)) time = json_object_get_string(jtime);
                        if (json_object_object_get_ex(jrev, "author_photo_url", &jphoto)) photoUrl = json_object_get_string(jphoto);
                        if (json_object_object_get_ex(jrev, "profile_photo_url", &jphoto)) photoUrl = json_object_get_string(jphoto);

                        if(!author.empty())
                            _processReview(tid, author, rating, text, time);
                            _processReview(tid, author, rating, text, time, photoUrl);
                    }
                }

@@ -328,7 +338,7 @@ namespace blogi {
        void _fetchFromGoogle(int tid) {
            try {
                std::string path = "/maps/api/place/details/json?place_id=" + _placeId
                                 + "&fields=reviews&key=" + _apiKey;
                                 + "&fields=reviews%2Creviews.profile_photo_url&key=" + _apiKey;
                libhttppp::HttpUrl apiUrl("https://maps.googleapis.com" + path);
                libhttppp::HttpClient client(apiUrl);
                client.setTimeout(15);
@@ -353,8 +363,8 @@ namespace blogi {
                        int len = json_object_array_length(jreviews);
                        for (int i = 0; i < len; ++i) {
                            json_object *jrev = json_object_array_get_idx(jreviews, i);
                            json_object *jauthor, *jrating, *jtext, *jtime;
                            std::string author, text, timeStr;
                            json_object *jauthor, *jrating, *jtext, *jtime, *jphoto;
                            std::string author, text, timeStr, photoUrl;
                            int rating = 5;

                            if (json_object_object_get_ex(jrev, "author_name", &jauthor))
@@ -365,9 +375,11 @@ namespace blogi {
                                text = json_object_get_string(jtext);
                            if (json_object_object_get_ex(jrev, "time", &jtime))
                                timeStr = std::to_string(json_object_get_int64(jtime));
                            if (json_object_object_get_ex(jrev, "profile_photo_url", &jphoto))
                                photoUrl = json_object_get_string(jphoto);

                            if (!author.empty())
                                _processReview(tid, author, rating, text, timeStr);
                                _processReview(tid, author, rating, text, timeStr, photoUrl);
                        }
                    }
                }
@@ -380,7 +392,8 @@ namespace blogi {
        }

        void _processReview(int tid, const std::string &author, int rating,
                            const std::string &text, const std::string &time) {
                            const std::string &text, const std::string &time,
                            const std::string &photoUrl = "") {
            std::vector<char> buf;
            dbpp::SQL sqlexist;
            dbpp::DBResult res;
@@ -396,12 +409,14 @@ namespace blogi {
                sql << "UPDATE google_reviews SET rating=" << rating
                    << ", text='" << dbpp::SQL::escaped(buf, text.c_str()) << "'"
                    << ", time='" << dbpp::SQL::escaped(buf, time.c_str()) << "'"
                    << ", author_photo_url='" << dbpp::SQL::escaped(buf, photoUrl.c_str()) << "'"
                    << " WHERE author_name='" << dbpp::SQL::escaped(buf, author.c_str()) << "';";
            } else {
                sql << "INSERT INTO google_reviews (author_name, rating, text, time, approved) VALUES ('"
                sql << "INSERT INTO google_reviews (author_name, rating, text, time, author_photo_url, approved) VALUES ('"
                    << dbpp::SQL::escaped(buf, author.c_str()) << "', " << rating << ", '"
                    << dbpp::SQL::escaped(buf, text.c_str()) << "', '"
                    << dbpp::SQL::escaped(buf, time.c_str()) << "', false);";
                    << dbpp::SQL::escaped(buf, time.c_str()) << "', '"
                    << dbpp::SQL::escaped(buf, photoUrl.c_str()) << "', false);";
            }
            Args->database[tid]->exec(sql, res);