File: index.cpp

package info (click to toggle)
bibledit 5.0.764-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 230,136 kB
  • sloc: xml: 863,336; ansic: 164,208; cpp: 81,648; sh: 4,684; makefile: 406; php: 69
file content (202 lines) | stat: -rw-r--r-- 6,095 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
Copyright (©) 2003-2018 Teus Benschop.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/


#include <journal/index.h>
#include <assets/view.h>
#include <assets/page.h>
#include <assets/header.h>
#include <webserver/request.h>
#include <filter/url.h>
#include <filter/string.h>
#include <filter/date.h>
#include <filter/roles.h>
#include <database/logs.h>
#include <locale/translate.h>
#include <menu/logic.h>
#include <client/logic.h>
#include <locale/logic.h>


const char * journal_index_url ()
{
  return "journal/index";
}


bool journal_index_acl (void * webserver_request)
{
  // In Client mode, anyone can view the journal.
#ifdef HAVE_CLIENT
  return true;
#endif
  // In the Cloud, the role of Consultant or higher can view the journal.
  if (Filter_Roles::access_control (webserver_request, Filter_Roles::consultant ())) {
    return true;
  }
  // No access.
  return false;
}


string render_journal_entry (string filename, int userlevel)
{
  // Sample filename: "146495380700927147".
  // The first 10 characters are the number of seconds past the Unix epoch,
  // followed by the number of microseconds within the current second.

  // Get the contents of the file.
  string path = filter_url_create_path (Database_Logs::folder (), filename);
  string entry = filter_url_file_get_contents (path);
  
  // Deal with the user-level of the entry.
  int entryLevel = convert_to_int (entry);
  // Cloud: Only render journal entries of a sufficiently high level.
  // Client: Render journal entries of any level.
#ifndef HAVE_CLIENT
  if (entryLevel > userlevel) return "";
#endif
  (void) userlevel;
  (void) entryLevel;
  // Remove the user's level.
  entry.erase (0, 2);
  
  // Split entry into lines.
  vector <string> lines = filter_string_explode (entry, '\n');
  if (!lines.empty ()) entry = lines [0];
  
  // Sanitize HTML.
  entry = escape_special_xml_characters (entry);
  
  bool limit = entry.size () > 150;
  if (limit) {
    entry.erase (150);
    entry.append ("...");
  }
    
  // Extract the seconds since the Unix epoch from the filename.
  time_t seconds = convert_to_int (filename.substr (0, 10));
  // Localized date and time stamp.
  string timestamp = locale_logic_date_time (seconds);

  string a_open, a_close;
  if (limit || lines.size () > 1) {
    a_open = "<a href=\"" + filename + "\">";
    a_close = "</a>";
  }
  
  // Done.
  return "<p>" + timestamp + " | " + a_open + entry + a_close + "</p>\n";
}


// Deal with AJAX call for a possible new journal entry.
string journal_index_ajax_next (Webserver_Request * request, string filename)
{
  int userLevel = request->session_logic()->currentLevel ();
  string result = Database_Logs::next (filename);
  if (!result.empty()) {
    result = render_journal_entry (result, userLevel);
    result.insert (0, filename + "\n");
  }
  return result;
}


string journal_index (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  int userLevel = request->session_logic()->currentLevel ();

  
  string filename = request->query ["filename"];
  if (!filename.empty ()) {
    return journal_index_ajax_next (request, filename);
  }
  
  
  string expansion = request->query ["expansion"];
  if (!expansion.empty ()) {
    // Get file path.
    expansion = filter_url_basename_web (expansion);
    string path = filter_url_create_path (Database_Logs::folder (), expansion);
    // Get contents of the record.
    expansion = filter_url_file_get_contents (path);
    // Remove the user's level.
    expansion.erase (0, 2);
    // The only formatting currently allowed in the journal is new lines.
    // The rest is sanitized.
    // To do this properly, the order is important:
    // 1. Clean it up.
    expansion = escape_special_xml_characters (expansion);
    // 2. Convert \n to <br>
    expansion = filter_string_str_replace ("\n", "<br>", expansion);
    // Done.
    return expansion;
  }
  
  
  Assets_Header header = Assets_Header (translate ("Journal"), webserver_request);
  header.addBreadCrumb (menu_logic_tools_menu (), menu_logic_tools_text ());
  string page = header.run ();


  Assets_View view;


  if (request->query.count ("clear")) {
    Database_Logs::clear ();
    // If the logbook has been cleared on a mobile device, and the screen goes off,
    // and then the user activates the screen on the mobile device,
    // the logbook will then again be cleared, because that was the last opened URL.
    // Redirecting the browser to a clean URL fixes this behaviour.
    redirect_browser (request, journal_index_url ());
    return "";
  }

  
  string lastfilename;
  vector <string> records = Database_Logs::get (lastfilename);


  string lines;
  for (string record : records) {
    string rendering = render_journal_entry (record, userLevel);
    if (!rendering.empty ()) {
      lines.append (rendering);
    }
  }
  view.set_variable ("lines", lines);

  
  // Pass the filename of the most recent entry to javascript
  // for use by the AJAX calls for getting subsequent journal entries.
  // It should be passed as a String object in JavaScript.
  // Because when it were passed as an Int, JavaScript would round the value off.
  // And rounding it off often led to double journal entries.
  string script = "var filename = \"" + lastfilename + "\";";
  view.set_variable ("script", script);


  page += view.render ("journal", "index");

  page += Assets_Page::footer ();

  return page;
}