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