MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | // 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> |
| 11 | |
| 12 | #define DBG(x) tell_object(find_player("hate"), sprintf("DBG: %O\n", x)) |
| 13 | |
| 14 | #define NEWSD "/secure/news" |
| 15 | |
| 16 | #define N_GROUP 0 |
| 17 | #define N_AUTHOR 1 |
| 18 | #define N_TID 2 |
| 19 | #define N_DATE 3 |
| 20 | #define N_TITLE 4 |
| 21 | #define N_ARTICLE 5 |
| 22 | |
| 23 | varargs private string url(string group, string article) |
| 24 | { |
| 25 | return "\""+MUDWWW+"?"+REQ+"="+R_NEWS |
| 26 | +(group?"&"+GROUP+"="+group:"") |
| 27 | +(article?"&"+ARTICLE+"="+article:"")+"\""; |
| 28 | } |
| 29 | |
| 30 | varargs private string make_link(string text, string group, string article) |
| 31 | { |
| 32 | if(!text || !sizeof(text)) text = "-Unbenannt-"; |
| 33 | return "<A HREF="+url(group, article)+">"+text+"</A>"; |
| 34 | } |
| 35 | |
| 36 | string GroupList() |
| 37 | { |
| 38 | string *list, ret; |
| 39 | int i, t; |
| 40 | |
| 41 | list = NEWSD->GetGroups(); |
| 42 | for (i = 0, ret = ""; i < sizeof(list); i++) |
| 43 | ret += sprintf("[%3d Artikel, %-6s] %s\n", |
| 44 | sizeof(NEWSD->GetNotes(list[i])), |
| 45 | dtime(t = NEWSD->GetNewsTime(list[i]))[5..11], |
| 46 | make_link(list[i],list[i]+":"+t)); |
| 47 | return "<H2>Übersicht</H2>" |
| 48 | +"<H3>["+sizeof(list)+" Gruppen, " |
| 49 | +"letzte Änderung "+dtime(NEWSD->GetNewsTime())+"]</H3>" |
| 50 | +"<PRE>" + ret +"</PRE>"; |
| 51 | } |
| 52 | |
| 53 | #define THREAD(a) ("~#! rn="+(a[N_AUTHOR])+" rt="+(a[N_DATE])+ \ |
| 54 | " rg="+(a[N_GROUP])) |
| 55 | #define TEXPR "rn=[^\n ]*|rt=[^\n ]*|rg=[^\n ]*" |
| 56 | |
| 57 | private mixed tinfo(mixed article) |
| 58 | { |
| 59 | mixed tmp, info; |
| 60 | string rn, rt, rg, tid; |
| 61 | int j, k; |
| 62 | |
| 63 | tmp = regexp(old_explode(article[N_ARTICLE], "\n"), "^~#!"); |
| 64 | for(j = sizeof(tmp); j--;) { |
| 65 | mixed line; |
| 66 | line = old_explode(tmp[j], " "); |
| 67 | for(k = sizeof(line); k--;) { |
| 68 | if(line[k][0..1]=="rn") rn = line[k][3..]; |
| 69 | if(line[k][0..1]=="rt") rt = line[k][3..]; |
| 70 | if(line[k][0..1]=="rg") rg = line[k][3..]; |
| 71 | if(line[k][0..2]=="tid") tid = line[k][4..]; |
| 72 | } |
| 73 | } |
| 74 | if(!tid) tid = ""+article[N_DATE]; |
| 75 | return ({ rn, rt, rg, tid }); |
| 76 | } |
| 77 | |
| 78 | #define RN 0 |
| 79 | #define RT 1 |
| 80 | #define RG 2 |
| 81 | #define TID 3 |
| 82 | |
| 83 | private int thread(mixed article, int i, mapping t) |
| 84 | { |
| 85 | mixed info; |
| 86 | info = tinfo(article); |
| 87 | |
| 88 | if(info[TID]) { |
| 89 | t[info[TID]]++; |
| 90 | t[info[TID], 1] = sprintf("%3.3d [%-12s %-6s]%-3s %s\n", |
| 91 | i+1, |
| 92 | article[N_AUTHOR]+":", |
| 93 | dtime(article[N_DATE])[5..11], |
| 94 | (t[info[TID]] - 1) ? "+"+(t[info[TID]]-1) : " - ", |
| 95 | make_link(article[N_TITLE], |
| 96 | article[N_GROUP], to_string(i))) |
| 97 | + (t[info[TID], 1] ? t[info[TID], 1] : ""); |
| 98 | t[info[TID], 2] = info; |
| 99 | if(article[N_DATE] > to_int(t[info[TID], 3])) |
| 100 | t[info[TID], 3] = ""+article[N_DATE]; |
| 101 | return 1; |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | private int expired(mixed *list, int i) |
| 106 | { |
| 107 | mixed info; |
| 108 | info = tinfo(list[i]); |
| 109 | for(i--; i >= 0; i--) |
| 110 | if(list[i][N_AUTHOR] == info[RN] && |
| 111 | list[i][N_DATE] == to_int(info[RT])) |
| 112 | return 0; |
| 113 | return 1; |
| 114 | } |
| 115 | |
| 116 | string ArticleList(string group) |
| 117 | { |
| 118 | string *list, ret; |
| 119 | mapping t; |
| 120 | int i; |
| 121 | |
| 122 | list = NEWSD->GetNotes(group = old_explode(group, ":")[0]); |
| 123 | if (!pointerp(list)) { |
| 124 | return "<H2>Gruppe: "+group+"</H2>" |
| 125 | "<H3>existiert nicht.</H3>" |
| 126 | "["+make_link("Gruppenübersicht")+"]"; |
| 127 | } |
| 128 | t = m_allocate(0,4); |
| 129 | for (i = sizeof(list)-1, ret = ""; i >= 0; i--) |
| 130 | if(!thread(list[i], i, t) || expired(list, i)) |
| 131 | { |
| 132 | int ttmp; |
| 133 | string tid; |
| 134 | mixed tt; tt = tinfo(list[i]); |
| 135 | ttmp = t[tid = tt[TID]] - 1; |
| 136 | ret = sprintf("%3.3d [%-12s %-6s]%-3s %s\n", |
| 137 | i+1, |
| 138 | list[i][N_AUTHOR]+":", |
| 139 | dtime(list[i][N_DATE])[5..11], |
| 140 | ttmp > 0 ? "+"+ttmp : " - ", |
| 141 | make_link((string)list[i][N_TITLE] |
| 142 | +(ttmp > 0 ? |
| 143 | " ("+dtime(to_int(t[tid, 3]))[5..11] |
| 144 | +dtime(to_int(t[tid, 3]))[17..]+")" : ""), |
| 145 | group, to_string(i)+":"+t[tid, 3])) + ret; |
| 146 | } |
| 147 | |
| 148 | return "<H2>Gruppe: "+group+"</H2>" |
| 149 | +"<H3>["+sizeof(list)+" Artikel, " |
| 150 | +"letzte Änderung "+dtime(NEWSD->GetNewsTime(group))+"]</H3>" |
| 151 | +"<PRE>" + ret + "</PRE>" |
| 152 | +"["+make_link("Gruppenübersicht")+"]"; |
| 153 | } |
| 154 | |
| 155 | private varargs string Message(string group, mixed article) |
| 156 | { |
| 157 | mixed text, tmp, ttmp, next, prev, info; |
| 158 | string art; |
| 159 | mapping t; |
| 160 | int i; |
| 161 | |
| 162 | if (!article) article = 0; |
| 163 | else article = to_int(old_explode(article, ":")[0]); |
| 164 | |
| 165 | tmp = NEWSD->GetNotes(group = old_explode(group, ":")[0]); |
| 166 | if (pointerp(tmp) && (article >= sizeof(tmp))) |
| 167 | return("Artikel nicht gefunden, soviele Artikel hat diese Rubrik " |
| 168 | "nicht!\n"); |
| 169 | |
| 170 | text = tmp[article]; |
| 171 | |
| 172 | t = m_allocate(0,4); |
| 173 | for(i = sizeof(tmp)-1; i > article; i--) |
| 174 | thread(tmp[i], i, t); |
| 175 | next = "Nächster Artikel"; |
| 176 | prev = "Voriger Artikel"; |
| 177 | |
| 178 | art = implode((ttmp = old_explode(text[N_ARTICLE], "\n")) |
| 179 | - regexp(ttmp, "^~#!"), "\n"); |
| 180 | |
| 181 | art = regreplace(art, "<", "\\<", 1); |
| 182 | art = regreplace(art, ">", "\\>", 1); |
| 183 | art = regreplace(art, "([a-zA-Z][a-zA-Z]*://[^ \n\t][^ \n\t]*)", "<a href=\"\\1\">\\1</a>", 1); |
| 184 | |
| 185 | info = tinfo(text); |
| 186 | |
| 187 | return "<H1>" + text[N_TITLE] + "</H1><HR>\n" |
| 188 | + "<H3>" + group + ": " + text[N_AUTHOR] |
| 189 | + " (Artikel " + (article + 1) + ", " + dtime(text[N_DATE]) + ")\n</H3>" |
| 190 | + (info[RN] ? ("<H4>Antwort auf "+info[RN]+ |
| 191 | (expired(tmp, article) ? " (verfallen)" : "")+"</H4>") |
| 192 | : "") |
| 193 | + "<PRE>" + art + "</PRE>\n" |
| 194 | + (t[info[TID]] ? |
| 195 | "<HR>Weitere Artikel zu diesem Thema:" |
| 196 | + "<PRE>" + t[info[TID], 1] + "</PRE><HR>" : "") |
| 197 | + " ["+(article < sizeof(tmp)-1 ? make_link(next, group,to_string(article+1)) : |
| 198 | next)+"]" |
| 199 | + " ["+(article ? make_link(prev, group, to_string(article-1)) : prev)+"]" |
| 200 | + " ["+make_link("Artikelübersicht", group)+"]" |
| 201 | + " ["+make_link("Gruppenübersicht")+"]"; |
| 202 | } |
| 203 | |
| 204 | string Request(mapping cmds) |
| 205 | { |
| 206 | string text; |
| 207 | if(!cmds[GROUP]) text = GroupList(); |
| 208 | else |
| 209 | if(!cmds[ARTICLE]) text = ArticleList(cmds[GROUP]); |
| 210 | else text = Message(cmds[GROUP], cmds[ARTICLE]); |
| 211 | |
| 212 | return "<H2>"+MUDNAME+" Zeitung</H2><HR>" |
| 213 | +text; |
| 214 | } |