]> jfr.im git - irc/quakenet/newserv.git/blob - a4stats/nterfacer_a4stats.c
a0aa2ee92a9c16c0b100b6992a1b2f49962573b0
[irc/quakenet/newserv.git] / a4stats / nterfacer_a4stats.c
1 #include <stdio.h>
2 #include <stdarg.h>
3 #include "../lib/version.h"
4 #include "../core/error.h"
5 #include "../nterfacer/library.h"
6 #include "../nterfacer/nterfacer.h"
7 #include "a4stats.h"
8
9 MODULE_VERSION("");
10
11 static struct service_node *a4stats_node;
12
13 static void a4stats_nt_query_cb(const struct DBAPIResult *result, void *uarg) {
14 struct rline *ri = uarg;
15 int i;
16
17 if (result) {
18 ri_append(ri, "%s", result->success ? "OK" : "FAILED");
19
20 if (result->success) {
21 ri_append(ri, "%d", result->fields);
22
23 while (result->next(result)) {
24 for (i = 0; i < result->fields; i++) {
25 const char *field = result->get(result, i);
26 ri_append(ri, "%s", field ? field : "");
27 }
28 }
29 }
30
31 result->clear(result);
32 } else
33 ri_append(ri, "FAILED");
34
35 ri_final(ri);
36 }
37
38 static int handle_getchannel(struct rline *ri, int argc, char **argv) {
39 a4statsdb->query(a4statsdb, a4stats_nt_query_cb, ri, "SELECT timestamp, active, privacy, deleted FROM ? WHERE name = ?", "Ts", "channels", argv[0]);
40 return 0;
41 }
42
43 static int handle_getlines(struct rline *ri, int argc, char **argv) {
44 a4statsdb->query(a4statsdb, a4stats_nt_query_cb, ri, "SELECT h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11,"
45 "h12, h13, h14, h15, h16, h17, h18, h19, h20, h21, h22, h23 "
46 "FROM ? WHERE name = ?", "Ts", "channels", argv[0]);
47
48 return 0;
49 }
50
51 static int handle_getusers(struct rline *ri, int argc, char **argv) {
52 a4statsdb->query(a4statsdb, a4stats_nt_query_cb, ri, "SELECT users.account, users.accountid, users.seen, users.rating, users.lines, users.chars, users.words, users.h0, users.h1, users.h2, users.h3, users.h4, users.h5, users.h6, users.h7, users.h8, users.h9, users.h10, users.h11, users."
53 "h12, users.h13, users.h14, users.h15, users.h16, users.h17, users.h18, users.h19, users.h20, users.h21, users.h22, users.h23, users."
54 "last, users.quote, users.quotereset, users.mood_happy, users.mood_sad, users.questions, users.yelling, users.caps, users."
55 "slaps, users.slapped, users.highlights, users.kicks, users.kicked, users.ops, users.deops, users.actions, users.skitzo, users.foul, users."
56 "firstseen, users.curnick FROM ? LEFT JOIN ? ON channels.id = users.channelid WHERE channels.name = ? AND users.quote IS NOT NULL ORDER BY lines DESC LIMIT 25", "TTs", "users", "channels", argv[0]);
57
58 return 0;
59 }
60
61 static int handle_getkicks(struct rline *ri, int argc, char **argv) {
62 a4statsdb->query(a4statsdb, a4stats_nt_query_cb, ri, "SELECT kicks.kicker, kicks.kickerid, ukicker.seen, ukicker.curnick, kicks.victim, kicks.victimid, uvictim.seen, uvictim.curnick, kicks.timestamp, kicks.reason "
63 "FROM ? "
64 "LEFT JOIN ? ON channels.id = kicks.channelid "
65 "LEFT JOIN ? AS ukicker ON (ukicker.channelid = channels.id AND (kicks.kickerid != 0 AND kicks.kickerid = ukicker.accountid OR kicks.kickerid = 0 AND kicks.kicker = ukicker.account)) "
66 "LEFT JOIN ? AS uvictim ON (uvictim.channelid = channels.id AND (kicks.victimid != 0 AND kicks.victimid = uvictim.accountid OR kicks.victimid = 0 AND kicks.victim = uvictim.account)) "
67 "WHERE channels.name = ? ORDER BY kicks.timestamp DESC LIMIT 10", "TTTTs", "kicks", "channels", "users", "users", argv[0]);
68
69 return 0;
70 }
71
72 static int handle_gettopics(struct rline *ri, int argc, char **argv) {
73 a4statsdb->query(a4statsdb, a4stats_nt_query_cb, ri, "SELECT topics.topic, topics.timestamp, topics.setby, topics.setbyid, users.seen, users.curnick "
74 "FROM ? "
75 "LEFT JOIN ? ON channels.id = topics.channelid "
76 "LEFT JOIN ? ON (users.channelid = channels.id AND (topics.setbyid != 0 AND topics.setbyid = users.accountid OR topics.setbyid = 0 AND topics.setby = users.account)) "
77 "WHERE channels.name = ? ORDER BY topics.timestamp DESC LIMIT 10", "TTTs", "topics", "channels", "users", argv[0]);
78
79 return 0;
80 }
81
82 static int handle_getuser(struct rline *ri, int argc, char **argv) {
83 #define USER_QUERY(a, b) a "users.account, users.accountid, users.seen, users.rating, users.lines, users.chars, users.words, " \
84 "users.h0, users.h1, users.h2, users.h3, users.h4, users.h5, users.h6, users.h7, users.h8, users.h9, " \
85 "users.h10, users.h11, users.h12, users.h13, users.h14, users.h15, users.h16, users.h17, users.h18, " \
86 "users.h19, users.h20, users.h21, users.h22, users.h23, users.last, users.quote, users.quotereset, " \
87 "users.mood_happy, users.mood_sad, users.questions, users.yelling, users.caps, users.slaps, users.slapped, " \
88 "users.highlights, users.kicks, users.kicked, users.ops, users.deops, users.actions, users.skitzo, " \
89 "users.foul, users.firstseen, users.curnick" b
90
91 /*
92 Possible cases:
93 accountid = 0, account = "username" -> new-style account, look up latest account for user
94 accountid = 0, account = "#username" -> legacy account or user not authed, look up using "username" (remove #)
95 accountid = <some value>, account = <unused> -> new-style account, look up by account id
96 */
97
98 if (argv[1][0] == '#') {
99 a4statsdb->query(a4statsdb, a4stats_nt_query_cb, ri, USER_QUERY("SELECT ", " FROM ? LEFT JOIN ? ON channels.id = users.channelid WHERE channels.name = ? AND (users.accountid = 0 AND users.account = ?)"),
100 "TTss", "users", "channels", argv[0], &(argv[1][1]));
101 } else if (atoi(argv[2]) == 0) {
102 a4statsdb->query(a4statsdb, a4stats_nt_query_cb, ri, USER_QUERY("SELECT ", " FROM ? LEFT JOIN ? ON channels.id = users.channelid WHERE channels.name = ? AND (users.accountid != 0 AND users.account = ?) ORDER BY users.accountid LIMIT 1"),
103 "TTss", "users", "channels", argv[0], argv[1]);
104 } else {
105 a4statsdb->query(a4statsdb, a4stats_nt_query_cb, ri, USER_QUERY("SELECT ", " FROM ? LEFT JOIN ? ON channels.id = users.channelid WHERE channels.name = ? AND users.accountid = ?"),
106 "TTss", "users", "channels", argv[0], argv[2]);
107 }
108
109 return 0;
110 }
111
112 static int handle_setprivacy(struct rline *ri, int argc, char **argv) {
113 a4statsdb->squery(a4statsdb, "UPDATE ? SET privacy = ? WHERE name = ?", "Tss", "channels", argv[1], argv[0]);
114 return ri_final(ri);
115 }
116
117 void _init(void) {
118 a4stats_node = register_service("a4stats");
119 if (!a4stats_node)
120 return;
121
122 register_handler(a4stats_node, "getchannel", 1, handle_getchannel);
123 register_handler(a4stats_node, "getlines", 1, handle_getlines);
124 register_handler(a4stats_node, "getusers", 1, handle_getusers);
125 register_handler(a4stats_node, "getkicks", 1, handle_getkicks);
126 register_handler(a4stats_node, "gettopics", 1, handle_gettopics);
127 register_handler(a4stats_node, "getuser", 3, handle_getuser);
128 register_handler(a4stats_node, "setprivacy", 2, handle_setprivacy);
129 }
130
131 void _fini(void) {
132 if (a4stats_node)
133 deregister_service(a4stats_node);
134 }