do not reset cursor position if it was on a purged message
[chiroptera.git] / sqbase_experiment / zsq_show_threads_tty.d
blobf789dc5214dae64c5672f8a9ec79e82252b20094
1 /* E-Mail Client
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module zsq_show_threads_tty is aliced;
19 import iv.encoding;
20 import iv.sq3;
21 import iv.strex;
22 import iv.timer;
23 import iv.vfs;
24 import iv.vfs.io;
26 import chibackend;
29 // ////////////////////////////////////////////////////////////////////////// //
30 void main (string[] args) {
31 ChiroTimerEnabled = true;
32 chiroParseCommonCLIArgs(args);
34 // here, i don't have any threads at all
35 //chiroSwitchToSingleThread();
37 bool speedTest = false;
38 bool showLast = false;
39 bool allowThreads = true;
40 int monthes = 6; // last 6 monthes
42 writeln("opening message support db...");
43 chiroOpenViewDB();
45 if (args.length > 1 && args[1] == "list") {
46 string[] folderlist = chiroGetTagList();
47 foreach (string fld; folderlist) writeln(" ", fld);
48 return;
51 string tagname = "/dmars_ng/general";
52 bool tagset = false;
54 for (usize aidx = 1; aidx < args.length; ) {
55 string arg = args[aidx++];
56 if (args.length == 0) continue;
57 if (arg == "speed") { speedTest = true; continue; }
58 if (arg == "last") { showLast = true; continue; }
59 if (arg == "threads") { allowThreads = true; continue; }
60 if (arg == "nothreads") { allowThreads = false; continue; }
61 if (arg == "list") {
62 string[] folderlist = chiroGetTagList();
63 foreach (string fld; folderlist) writeln(" ", fld);
64 continue;
66 if (arg == "limit") {
67 // limit in monthes
68 if (aidx >= args.length) throw new Exception("\"limit\" requires an argument");
69 import std.conv : to;
70 monthes = args[aidx++].to!int;
71 continue;
73 if (tagset) throw new Exception("tag already selected");
74 tagset = true;
75 tagname = arg;
76 while (tagname.length > 1 && tagname[$-1] == '/') tagname = tagname[0..$-1];
79 writeln("collecting messages...");
81 Timer ctm = Timer(true);
82 version(all) {
83 chiroCreateTreePaneTable(tagname, monthes, allowThreads);
84 } else {
85 chiroCreateTreePaneTable(chiroGetTagUid(tagname), monthes, allowThreads);
87 ctm.stop;
89 uint ncount = 0;
90 foreach (auto row; dbView.statement(`SELECT max(rowid) AS ncount FROM treepane;`).range) ncount = row.ncount!uint;
91 writeln("collect time (", ncount, " messages): ", ctm);
93 if (speedTest) return;
95 // 128 spaces for slicing
96 immutable string padstr = ` `;
97 // 128 dots for slicing
98 immutable string paddot = `................................................................................................................................`;
100 uint pgstart = 0;
101 uint pgsize = 128;
102 //if (pgstart > ncount) pgstart = 0;
103 if (showLast && ncount > pgsize) pgstart = ncount-pgsize+2;
104 ctm.restart;
105 auto count = chiroGetPaneTablePage(pgstart, pgsize,
106 delegate (uint pgofs, /* offset from the page start, from zero and up to `limit` */
107 uint iid, /* item id, never zero */
108 uint uid, /* msguid, never zero */
109 uint parentuid, /* parent msguid, may be zero */
110 uint level, /* threading level, from zero */
111 int appearance, /* flags, etc. */
112 SQ3Text date, /* string representation of receiving date and time */
113 SQ3Text subj, /* message subject, can be empty string */
114 SQ3Text fromName, /* message sender name, can be empty string */
115 SQ3Text fromMail) /* message sender email, can be empty string */
117 version(all) {
118 writef("%3s | ", pgofs);
119 writef("%6s | ", iid);
120 writef("%6s | ", uid);
121 writef("%6s | ", parentuid);
122 write(date, " | ");
123 //foreach (; 0..level) write(".");
124 if (level > paddot.length) level = cast(uint)paddot.length;
125 write(paddot[0..level]);
126 subj = subj.recodeToKOI8;
127 auto nlen = 64-level;
128 if (nlen > 0) {
129 if (subj.length > nlen) {
130 if (nlen > 3) {
131 write(subj[0..nlen-3], "...");
132 } else {
133 write(subj[0..nlen]);
135 } else {
136 write(subj);
139 //foreach (; subj.length..cast(usize)nlen) write(" ");
140 if (subj.length < cast(usize)nlen) write(padstr[0..cast(usize)nlen-subj.length]);
141 enum MaxNameLen = 32;
142 fromName = fromName.recodeToKOI8;
143 if (fromName.length > MaxNameLen) {
144 write(" | ", fromName[0..MaxNameLen-3], "...");
145 } else {
146 write(" | ", fromName);
147 //foreach (; fromName.length..MaxNameLen) write(" ");
148 write(padstr[0..cast(usize)MaxNameLen-fromName.length]);
150 if (fromMail.length > MaxNameLen) {
151 writeln(" | <", fromMail[0..MaxNameLen-3], "...");
152 } else {
153 writeln(" | <", fromMail, ">");
157 ctm.stop;
158 writeln("render time for ", count, " items: ", ctm);
160 // this is not necessary, but meh...
161 //chiroReleaseTreePaneTable();
163 writeln("closing the db");
164 dbView.close();