mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2024-11-14 04:57:21 +01:00
Added a PagedArticle class. It goes through a given folder, evaluates all first level subfolders, and creates an article from each directory, and page into those articles from each file with pagination.
This commit is contained in:
parent
3ff8c5a20b
commit
c0c76f1481
12
modules/paged_article/SCsub
Normal file
12
modules/paged_article/SCsub
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
Import("env_mod")
|
||||||
|
Import("env")
|
||||||
|
|
||||||
|
env_mod.core_sources = []
|
||||||
|
|
||||||
|
env_mod.add_source_files(env_mod.core_sources, "*.cpp")
|
||||||
|
|
||||||
|
# Build it all as a library
|
||||||
|
lib = env_mod.add_library("list_page", env_mod.core_sources)
|
||||||
|
env.Prepend(LIBS=[lib])
|
27
modules/paged_article/detect.py
Normal file
27
modules/paged_article/detect.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def is_active():
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_name():
|
||||||
|
return "list_page"
|
||||||
|
|
||||||
|
|
||||||
|
def can_build():
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_opts():
|
||||||
|
return []
|
||||||
|
|
||||||
|
def get_flags():
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def configure(env):
|
||||||
|
pass
|
210
modules/paged_article/paged_article.cpp
Normal file
210
modules/paged_article/paged_article.cpp
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
#include "paged_article.h"
|
||||||
|
|
||||||
|
#include "core/query_builder.h"
|
||||||
|
#include "core/query_result.h"
|
||||||
|
#include "core/table_builder.h"
|
||||||
|
#include "core/utils.h"
|
||||||
|
|
||||||
|
#include <tinydir/tinydir.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "core/application.h"
|
||||||
|
|
||||||
|
void PagedArticle::index(Request *request) {
|
||||||
|
const std::string r = request->get_current_path_segment();
|
||||||
|
|
||||||
|
Article *s = pages[r];
|
||||||
|
|
||||||
|
if (s == nullptr) {
|
||||||
|
Application::get_instance()->send_error(404, request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->push_path();
|
||||||
|
|
||||||
|
const std::string rp = request->get_current_path_segment();
|
||||||
|
|
||||||
|
if (rp == "") {
|
||||||
|
//summary page
|
||||||
|
request->body += s->summary_page;
|
||||||
|
|
||||||
|
request->compile_and_send_body();
|
||||||
|
request->pop_path();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string *page = s->pages[rp];
|
||||||
|
|
||||||
|
if (page == nullptr) {
|
||||||
|
//bad url
|
||||||
|
Application::get_instance()->send_error(404, request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->body += (*page);
|
||||||
|
request->compile_and_send_body();
|
||||||
|
request->pop_path();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PagedArticle::load() {
|
||||||
|
if (folder == "") {
|
||||||
|
printf("Error: PagedArticle::load called, but a folder is not set!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base_path.size() > 0 && base_path[base_path.size() - 1] == '/') {
|
||||||
|
base_path.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
tinydir_dir dir;
|
||||||
|
if (tinydir_open(&dir, folder.c_str()) == -1) {
|
||||||
|
printf("Error opening PagedArticle::folder!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dir.has_next) {
|
||||||
|
tinydir_file file;
|
||||||
|
if (tinydir_readfile(&dir, &file) == -1) {
|
||||||
|
tinydir_next(&dir);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.is_dir) {
|
||||||
|
if (file.name[0] == '.' || (file.name[0] == '.' && file.name[1] == '.')) {
|
||||||
|
tinydir_next(&dir);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string np = file.path;
|
||||||
|
std::string fn = file.name;
|
||||||
|
|
||||||
|
Article *a = load_folder(np, base_path + "/" + fn);
|
||||||
|
|
||||||
|
if (a) {
|
||||||
|
|
||||||
|
std::string p = file.name;
|
||||||
|
|
||||||
|
a->url = p;
|
||||||
|
pages[p] = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tinydir_next(&dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
tinydir_close(&dir);
|
||||||
|
|
||||||
|
generate_summaries();
|
||||||
|
}
|
||||||
|
|
||||||
|
Article *PagedArticle::load_folder(const std::string &folder, const std::string &path) {
|
||||||
|
printf("PagedArticle: loading: %s\n", folder.c_str());
|
||||||
|
|
||||||
|
std::vector<std::string> files;
|
||||||
|
|
||||||
|
tinydir_dir dir;
|
||||||
|
if (tinydir_open(&dir, folder.c_str()) == -1) {
|
||||||
|
printf("PagedArticle::load_folder: Error opening folder %s!\n", folder.c_str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dir.has_next) {
|
||||||
|
tinydir_file file;
|
||||||
|
if (tinydir_readfile(&dir, &file) == -1) {
|
||||||
|
tinydir_next(&dir);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file.is_dir) {
|
||||||
|
std::string np = file.name;
|
||||||
|
|
||||||
|
files.push_back(np);
|
||||||
|
}
|
||||||
|
|
||||||
|
tinydir_next(&dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
tinydir_close(&dir);
|
||||||
|
|
||||||
|
if (files.size() == 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(files.begin(), files.end());
|
||||||
|
|
||||||
|
Article *article = new Article();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < files.size(); ++i) {
|
||||||
|
std::string file_path = folder;
|
||||||
|
|
||||||
|
if (file_path.size() > 0 && file_path[file_path.size() - 1] != '/')
|
||||||
|
file_path += "/";
|
||||||
|
|
||||||
|
file_path += files[i].c_str();
|
||||||
|
|
||||||
|
FILE *f = fopen(file_path.c_str(), "r");
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
printf("PagedArticle::load_folder: Error opening file! %s\n", file_path.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long fsize = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET); /* same as rewind(f); */
|
||||||
|
|
||||||
|
std::string fd;
|
||||||
|
fd.resize(fsize);
|
||||||
|
|
||||||
|
fread(&fd[0], 1, fsize, f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
Utils::markdown_to_html(&fd);
|
||||||
|
|
||||||
|
std::string pagination;
|
||||||
|
|
||||||
|
pagination = Utils::get_pagination_links(path, files, i);
|
||||||
|
|
||||||
|
std::string *finals = new std::string();
|
||||||
|
|
||||||
|
(*finals) += pagination;
|
||||||
|
(*finals) += fd;
|
||||||
|
(*finals) += pagination;
|
||||||
|
|
||||||
|
article->pages[files[i]] = finals;
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
article->summary_page = (*finals);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return article;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PagedArticle::generate_summaries() {
|
||||||
|
for (std::map<std::string, Article *>::iterator it = pages.begin(); it != pages.end(); ++it) {
|
||||||
|
generate_summary((*it).second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PagedArticle::generate_summary(Article *article) {
|
||||||
|
if (article->summary_page != "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::map<std::string, std::string *>::iterator it = article->pages.begin(); it != article->pages.end(); ++it) {
|
||||||
|
std::string *s = (*it).second;
|
||||||
|
|
||||||
|
if (s != nullptr) {
|
||||||
|
article->summary_page = (*s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PagedArticle::PagedArticle() :
|
||||||
|
Object() {
|
||||||
|
}
|
||||||
|
|
||||||
|
PagedArticle::~PagedArticle() {
|
||||||
|
pages.clear();
|
||||||
|
}
|
46
modules/paged_article/paged_article.h
Normal file
46
modules/paged_article/paged_article.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef PAGED_ARTICLE_H
|
||||||
|
#define PAGED_ARTICLE_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "core/object.h"
|
||||||
|
|
||||||
|
#include "core/request.h"
|
||||||
|
|
||||||
|
struct Article {
|
||||||
|
std::string url;
|
||||||
|
std::string summary_page;
|
||||||
|
std::map<std::string, std::string *> pages;
|
||||||
|
|
||||||
|
Article() {}
|
||||||
|
~Article() {
|
||||||
|
for (std::map<std::string, std::string *>::iterator it = pages.begin(); it != pages.end(); ++it) {
|
||||||
|
delete ((*it).second);
|
||||||
|
}
|
||||||
|
|
||||||
|
pages.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PagedArticle : public Object {
|
||||||
|
RCPP_OBJECT(PagedArticle, Object);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void index(Request *request);
|
||||||
|
|
||||||
|
void load();
|
||||||
|
Article *load_folder(const std::string &folder, const std::string &path);
|
||||||
|
void generate_summaries();
|
||||||
|
void generate_summary(Article *article);
|
||||||
|
|
||||||
|
PagedArticle();
|
||||||
|
~PagedArticle();
|
||||||
|
|
||||||
|
std::map<std::string, Article *> pages;
|
||||||
|
std::string folder;
|
||||||
|
std::string base_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user