1 module vibelog.controller;
2 
3 public import vibelog.settings;
4 
5 import vibelog.db.dbcontroller;
6 import diskuto.commentstore : DiskutoCommentStore;
7 import diskuto.commentstores.mongodb;
8 
9 import std.conv : to;
10 
11 
12 class VibeLogController {
13 	private {
14 		DBController m_db;
15 		VibeLogSettings m_settings;
16 		Config m_config;
17 		DiskutoCommentStore m_diskuto;
18 	}
19 
20 	this(VibeLogSettings settings)
21 	{
22 		m_settings = settings;
23 		m_diskuto = new MongoDBCommentStore(settings.databaseURL);
24 		m_db = createDBController(settings);
25 
26 		try m_config = m_db.getConfig(settings.configName, true);
27 		catch( Exception e ){
28 			import vibe.core.log;
29 			logError("Error reading configuration '%s': %s", settings.configName, e.msg);
30 			throw e;
31 		}
32 		m_db.invokeOnConfigChange({ m_config = m_db.getConfig(settings.configName, true); });
33 	}
34 
35 	@property inout(DBController) db() inout { return m_db; }
36 	@property inout(VibeLogSettings) settings() inout { return m_settings; }
37 	@property inout(Config) config() inout { return m_config; }
38 	@property inout(DiskutoCommentStore) diskuto() inout { return m_diskuto; }
39 
40 	PostListInfo getPostListInfo(int page = 0, int page_size = 0)
41 	{
42 		auto info = PostListInfo(m_settings);
43 		info.users = m_db.getAllUsers();
44 		info.pageCount = getPageCount(page_size);
45 		info.pageNumber = page;
46 		info.posts = getPostsForPage(info.pageNumber, page_size);
47 		foreach (p; info.posts) info.commentCount ~= m_diskuto.getActiveCommentCount("vibelog-"~p.id.toString());
48 		info.recentPosts = getRecentPosts();
49 		return info;
50 	}
51 
52 	int getPageCount(int page_size = 0)
53 	{
54 		if (page_size <= 0) page_size = m_settings.postsPerPage;
55 		int cnt = m_db.countPostsForCategory(m_config.categories);
56 		return (cnt + page_size - 1) / page_size;
57 	}
58 
59 	Post[] getPostsForPage(int n, int page_size = 0)
60 	{
61 		if (page_size <= 0) page_size = m_settings.postsPerPage;
62 		Post[] ret;
63 		try {
64 			size_t cnt = 0;
65 			m_db.getPublicPostsForCategory(m_config.categories, n*page_size, (size_t i, Post p){
66 				ret ~= p;
67 				if( ++cnt >= page_size )
68 					return false;
69 				return true;
70 			});
71 		} catch( Exception e ){
72 			auto p = new Post;
73 			p.header = "ERROR";
74 			p.subHeader = e.msg;
75 			ret ~= p;
76 		}
77 		return ret;
78 	}
79 
80 	Post[] getRecentPosts()
81 	{
82 		Post[] ret;
83 		m_db.getPublicPostsForCategory(m_config.categories, 0, (i, p){
84 			if (i >= m_settings.maxRecentPosts) return false;
85 			ret ~= p;
86 			return true;
87 		});
88 		return ret;
89 	}
90 
91 	string getShowPagePath(int page)
92 	{
93 		return m_settings.rootDir ~ "?page=" ~ to!string(page+1);
94 	}
95 }
96 
97 struct PostListInfo
98 {
99 	import vibelog.info : VibeLogInfo;
100 	VibeLogInfo vli;
101 	alias vli this;
102 
103 	User[string] users;
104 	int pageNumber = 0;
105 	int pageCount;
106 	Post[] posts;
107 	long[] commentCount;
108 	Post[] recentPosts;
109 
110 	import vibelog.settings : VibeLogSettings;
111 	this(VibeLogSettings settings)
112 	{
113 		vli = VibeLogInfo(settings);
114 	}
115 }
116 
117 struct VibelogHeadlineListConfig
118 {
119 	bool showSummaries = true;
120 	size_t maxPosts = 10;
121 	size_t headerLevel = 2;
122 	bool headerLinks = true;
123 	bool footerLinks = false;
124 	bool dateFirst = true;
125 }