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