blob: 8fba2d2b5cb78b3c09f0e66325422e509118a844 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// www.news.c -- WWW frontend for reading mud news
4//
5// $Id: www.news.c 8755 2014-04-26 13:13:40Z Zesstra $
6
7#pragma strong_types
8#pragma combine_strings
9
10#include <www.h>
Zesstra8b258db2019-12-29 15:13:00 +010011#include <news.h>
MG Mud User88f12472016-06-24 23:31:02 +020012
13#define DBG(x) tell_object(find_player("hate"), sprintf("DBG: %O\n", x))
14
15#define NEWSD "/secure/news"
16
17#define N_GROUP 0
18#define N_AUTHOR 1
19#define N_TID 2
20#define N_DATE 3
21#define N_TITLE 4
22#define N_ARTICLE 5
23
24varargs private string url(string group, string article)
25{
26 return "\""+MUDWWW+"?"+REQ+"="+R_NEWS
27 +(group?"&"+GROUP+"="+group:"")
28 +(article?"&"+ARTICLE+"="+article:"")+"\"";
29}
30
31varargs private string make_link(string text, string group, string article)
32{
33 if(!text || !sizeof(text)) text = "-Unbenannt-";
34 return "<A HREF="+url(group, article)+">"+text+"</A>";
35}
36
37string GroupList()
38{
39 string *list, ret;
40 int i, t;
41
42 list = NEWSD->GetGroups();
43 for (i = 0, ret = ""; i < sizeof(list); i++)
44 ret += sprintf("[%3d Artikel, %-6s] %s\n",
45 sizeof(NEWSD->GetNotes(list[i])),
46 dtime(t = NEWSD->GetNewsTime(list[i]))[5..11],
47 make_link(list[i],list[i]+":"+t));
48 return "<H2>&Uuml;bersicht</H2>"
49 +"<H3>["+sizeof(list)+" Gruppen, "
50 +"letzte &Auml;nderung "+dtime(NEWSD->GetNewsTime())+"]</H3>"
51 +"<PRE>" + ret +"</PRE>";
52}
53
54#define THREAD(a) ("~#! rn="+(a[N_AUTHOR])+" rt="+(a[N_DATE])+ \
55 " rg="+(a[N_GROUP]))
56#define TEXPR "rn=[^\n ]*|rt=[^\n ]*|rg=[^\n ]*"
57
58private mixed tinfo(mixed article)
59{
60 mixed tmp, info;
61 string rn, rt, rg, tid;
62 int j, k;
63
64 tmp = regexp(old_explode(article[N_ARTICLE], "\n"), "^~#!");
65 for(j = sizeof(tmp); j--;) {
66 mixed line;
67 line = old_explode(tmp[j], " ");
68 for(k = sizeof(line); k--;) {
69 if(line[k][0..1]=="rn") rn = line[k][3..];
70 if(line[k][0..1]=="rt") rt = line[k][3..];
71 if(line[k][0..1]=="rg") rg = line[k][3..];
72 if(line[k][0..2]=="tid") tid = line[k][4..];
73 }
74 }
75 if(!tid) tid = ""+article[N_DATE];
76 return ({ rn, rt, rg, tid });
77}
78
79#define RN 0
80#define RT 1
81#define RG 2
82#define TID 3
83
84private int thread(mixed article, int i, mapping t)
85{
86 mixed info;
87 info = tinfo(article);
88
89 if(info[TID]) {
90 t[info[TID]]++;
91 t[info[TID], 1] = sprintf("%3.3d [%-12s %-6s]%-3s %s\n",
92 i+1,
93 article[N_AUTHOR]+":",
94 dtime(article[N_DATE])[5..11],
95 (t[info[TID]] - 1) ? "+"+(t[info[TID]]-1) : " - ",
96 make_link(article[N_TITLE],
97 article[N_GROUP], to_string(i)))
98 + (t[info[TID], 1] ? t[info[TID], 1] : "");
99 t[info[TID], 2] = info;
100 if(article[N_DATE] > to_int(t[info[TID], 3]))
101 t[info[TID], 3] = ""+article[N_DATE];
102 return 1;
103 }
Arathornc1ebe9d2022-02-07 22:15:58 +0100104 return 0;
MG Mud User88f12472016-06-24 23:31:02 +0200105}
106
107private int expired(mixed *list, int i)
108{
109 mixed info;
110 info = tinfo(list[i]);
111 for(i--; i >= 0; i--)
112 if(list[i][N_AUTHOR] == info[RN] &&
113 list[i][N_DATE] == to_int(info[RT]))
114 return 0;
115 return 1;
116}
117
118string ArticleList(string group)
119{
Zesstrabe894b42019-11-27 19:56:32 +0100120 string ret;
MG Mud User88f12472016-06-24 23:31:02 +0200121 mapping t;
122 int i;
123
Zesstrabe894b42019-11-27 19:56:32 +0100124 mixed list = NEWSD->GetNotes(group = old_explode(group, ":")[0]);
MG Mud User88f12472016-06-24 23:31:02 +0200125 if (!pointerp(list)) {
126 return "<H2>Gruppe: "+group+"</H2>"
127 "<H3>existiert nicht.</H3>"
128 "["+make_link("Gruppen&uuml;bersicht")+"]";
129 }
130 t = m_allocate(0,4);
131 for (i = sizeof(list)-1, ret = ""; i >= 0; i--)
Zesstra8b258db2019-12-29 15:13:00 +0100132 {
133 list[i][M_TITLE] = to_text(to_bytes(list[i][M_TITLE],"ASCII//TRANSLIT"),
134 "ASCII");
MG Mud User88f12472016-06-24 23:31:02 +0200135 if(!thread(list[i], i, t) || expired(list, i))
136 {
137 int ttmp;
138 string tid;
139 mixed tt; tt = tinfo(list[i]);
140 ttmp = t[tid = tt[TID]] - 1;
141 ret = sprintf("%3.3d [%-12s %-6s]%-3s %s\n",
142 i+1,
143 list[i][N_AUTHOR]+":",
144 dtime(list[i][N_DATE])[5..11],
145 ttmp > 0 ? "+"+ttmp : " - ",
146 make_link((string)list[i][N_TITLE]
147 +(ttmp > 0 ?
148 " ("+dtime(to_int(t[tid, 3]))[5..11]
149 +dtime(to_int(t[tid, 3]))[17..]+")" : ""),
150 group, to_string(i)+":"+t[tid, 3])) + ret;
151 }
Zesstra8b258db2019-12-29 15:13:00 +0100152 }
MG Mud User88f12472016-06-24 23:31:02 +0200153 return "<H2>Gruppe: "+group+"</H2>"
154 +"<H3>["+sizeof(list)+" Artikel, "
155 +"letzte &Auml;nderung "+dtime(NEWSD->GetNewsTime(group))+"]</H3>"
156 +"<PRE>" + ret + "</PRE>"
157 +"["+make_link("Gruppen&uuml;bersicht")+"]";
158}
159
160private varargs string Message(string group, mixed article)
161{
162 mixed text, tmp, ttmp, next, prev, info;
163 string art;
164 mapping t;
165 int i;
166
167 if (!article) article = 0;
168 else article = to_int(old_explode(article, ":")[0]);
169
170 tmp = NEWSD->GetNotes(group = old_explode(group, ":")[0]);
171 if (pointerp(tmp) && (article >= sizeof(tmp)))
172 return("Artikel nicht gefunden, soviele Artikel hat diese Rubrik "
173 "nicht!\n");
MG Mud User88f12472016-06-24 23:31:02 +0200174 text = tmp[article];
Zesstra8b258db2019-12-29 15:13:00 +0100175 text[M_TITLE] = to_text(to_bytes(text[M_TITLE], "ASCII//TRANSLIT"),"ASCII");
176 text[M_MESSAGE] = to_text(to_bytes(text[M_MESSAGE], "ASCII//TRANSLIT"),
177 "ASCII");
MG Mud User88f12472016-06-24 23:31:02 +0200178
179 t = m_allocate(0,4);
180 for(i = sizeof(tmp)-1; i > article; i--)
181 thread(tmp[i], i, t);
182 next = "N&auml;chster Artikel";
183 prev = "Voriger Artikel";
184
185 art = implode((ttmp = old_explode(text[N_ARTICLE], "\n"))
186 - regexp(ttmp, "^~#!"), "\n");
187
188 art = regreplace(art, "<", "\\&lt;", 1);
189 art = regreplace(art, ">", "\\&gt;", 1);
190 art = regreplace(art, "([a-zA-Z][a-zA-Z]*://[^ \n\t][^ \n\t]*)", "<a href=\"\\1\">\\1</a>", 1);
191
192 info = tinfo(text);
193
194 return "<H1>" + text[N_TITLE] + "</H1><HR>\n"
195 + "<H3>" + group + ": " + text[N_AUTHOR]
196 + " (Artikel " + (article + 1) + ", " + dtime(text[N_DATE]) + ")\n</H3>"
197 + (info[RN] ? ("<H4>Antwort auf "+info[RN]+
198 (expired(tmp, article) ? " (verfallen)" : "")+"</H4>")
199 : "")
200 + "<PRE>" + art + "</PRE>\n"
201 + (t[info[TID]] ?
202 "<HR>Weitere Artikel zu diesem Thema:"
203 + "<PRE>" + t[info[TID], 1] + "</PRE><HR>" : "")
204 + " ["+(article < sizeof(tmp)-1 ? make_link(next, group,to_string(article+1)) :
205 next)+"]"
206 + " ["+(article ? make_link(prev, group, to_string(article-1)) : prev)+"]"
207 + " ["+make_link("Artikel&uuml;bersicht", group)+"]"
208 + " ["+make_link("Gruppen&uuml;bersicht")+"]";
209}
210
211string Request(mapping cmds)
212{
213 string text;
214 if(!cmds[GROUP]) text = GroupList();
215 else
216 if(!cmds[ARTICLE]) text = ArticleList(cmds[GROUP]);
217 else text = Message(cmds[GROUP], cmds[ARTICLE]);
218
219 return "<H2>"+MUDNAME+" Zeitung</H2><HR>"
220 +text;
221}