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 }