znc: drop playback patch and reference from github repository
We currently inclde the playback external module with a separate patch. This is ugly and can be better handled. Add required changes to download the external module from his own github repository. Then create a link in the znc modules to reference the cpp source. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
parent
8674af1b0a
commit
b1d68f3c97
2 changed files with 46 additions and 294 deletions
|
@ -136,6 +136,41 @@ define webskin
|
|||
ZNC_MODULES += znc-webskin-$(strip $(1))
|
||||
endef
|
||||
|
||||
define playback
|
||||
define Package/znc-mod-playback
|
||||
$(Package/znc/default)
|
||||
TITLE+= (playback plugin)
|
||||
DEPENDS:=znc
|
||||
endef
|
||||
|
||||
define Package/znc-mod-playback/description
|
||||
Avoid repetitive playback buffers on re-connect with supported clients (e.g. mutter, colluquy)
|
||||
endef
|
||||
|
||||
define Package/znc-mod-playback/install
|
||||
$(INSTALL_DIR) $$(1)/usr/lib/znc/
|
||||
$(INSTALL_BIN) $$(PKG_INSTALL_DIR)/usr/lib/znc/playback.so $$(1)/usr/lib/znc/
|
||||
endef
|
||||
|
||||
ZNC_MODULES += znc-mod-playback
|
||||
$(if $(CONFIG_PACKAGE_znc-mod-playback),ZNC_MODULE_TARGETS += playback.so)
|
||||
endef
|
||||
|
||||
define Download/znc-playback
|
||||
VERSION:=8dd128bfe2b24b2cc6a9ea2e2d28bfaa28d2a833
|
||||
SUBDIR:=znc-mod-playback
|
||||
FILE:=znc-playback-$$(VERSION).tar.xz
|
||||
URL:=https://github.com/jpnurmi/znc-playback.git
|
||||
MIRROR_HASH:=ac89d69048d62c5b15f39cc0d357a111ce4053816062e7bc1e553392b36fbd71
|
||||
PROTO:=git
|
||||
endef
|
||||
|
||||
define Prepare/znc-playback
|
||||
$(eval $(Download/znc-playback))
|
||||
xzcat $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
|
||||
$(LN) $(PKG_BUILD_DIR)/znc-mod-playback/playback.cpp $(PKG_BUILD_DIR)/modules/playback.cpp
|
||||
endef
|
||||
|
||||
, := ,
|
||||
|
||||
$(eval $(call module,adminlog,Log user connects and disconnects and failed \
|
||||
|
@ -233,9 +268,6 @@ $(eval $(call module,notify-connect,Sends a notice to all admins when a user \
|
|||
|
||||
$(eval $(call module,perform,Performs commands on connect.))
|
||||
|
||||
$(eval $(call module,playback,Avoid repetitive playback buffers on re-connect \
|
||||
with supported clients (e.g. mutter, colluquy)))
|
||||
|
||||
$(eval $(call module,raw,View all of the raw traffic.))
|
||||
|
||||
$(eval $(call module,route-replies,Routes back answers to the right client \
|
||||
|
@ -263,6 +295,8 @@ $(eval $(call module,stickychan,Keeps you sticked to specific channels.))
|
|||
$(eval $(call module,watch,Monitor activity for specific text patterns from \
|
||||
specific users and have the text sent to a special query window.))
|
||||
|
||||
$(eval $(call playback))
|
||||
|
||||
$(eval $(call webadmin))
|
||||
|
||||
$(eval $(call webskin,dark-clouds))
|
||||
|
@ -286,5 +320,14 @@ CMAKE_OPTIONS += \
|
|||
-DWANT_TCL=OFF \
|
||||
-DWANT_ZLIB=ON
|
||||
|
||||
define Build/Prepare
|
||||
$(call Build/Prepare/Default)
|
||||
|
||||
ifneq ($(CONFIG_PACKAGE_znc-mod-playback),)
|
||||
$(eval $(call Download,znc-playback))
|
||||
$(Prepare/znc-playback)
|
||||
endif
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,znc))
|
||||
$(foreach m,$(ZNC_MODULES),$(eval $(call BuildPackage,$(m))))
|
||||
|
|
|
@ -1,291 +0,0 @@
|
|||
--- /dev/null
|
||||
+++ b/modules/playback.cpp
|
||||
@@ -0,0 +1,288 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2015 J-P Nurmi
|
||||
+ *
|
||||
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
+ * you may not use this file except in compliance with the License.
|
||||
+ * You may obtain a copy of the License at
|
||||
+ *
|
||||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||
+ *
|
||||
+ * Unless required by applicable law or agreed to in writing, software
|
||||
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ * See the License for the specific language governing permissions and
|
||||
+ * limitations under the License.
|
||||
+ */
|
||||
+
|
||||
+#include <znc/Modules.h>
|
||||
+#include <znc/IRCNetwork.h>
|
||||
+#include <znc/Client.h>
|
||||
+#include <znc/Buffer.h>
|
||||
+#include <znc/Utils.h>
|
||||
+#include <znc/Query.h>
|
||||
+#include <znc/Chan.h>
|
||||
+#include <znc/znc.h>
|
||||
+#include <znc/version.h>
|
||||
+#include <sys/time.h>
|
||||
+#include <cfloat>
|
||||
+
|
||||
+#if (VERSION_MAJOR < 1) || (VERSION_MAJOR == 1 && VERSION_MINOR < 6)
|
||||
+#error The playback module requires ZNC version 1.6.0 or later.
|
||||
+#endif
|
||||
+
|
||||
+static const char* PlaybackCap = "znc.in/playback";
|
||||
+
|
||||
+class CPlaybackMod : public CModule
|
||||
+{
|
||||
+public:
|
||||
+ MODCONSTRUCTOR(CPlaybackMod)
|
||||
+ {
|
||||
+ m_play = false;
|
||||
+ AddHelpCommand();
|
||||
+ AddCommand("Clear", static_cast<CModCommand::ModCmdFunc>(&CPlaybackMod::ClearCommand), "<buffer(s)>", "Clears playback for given buffers.");
|
||||
+ AddCommand("Play", static_cast<CModCommand::ModCmdFunc>(&CPlaybackMod::PlayCommand), "<buffer(s)> [from] [to]", "Sends playback for given buffers.");
|
||||
+ AddCommand("List", static_cast<CModCommand::ModCmdFunc>(&CPlaybackMod::ListCommand), "[buffer(s)]", "Lists available/matching buffers.");
|
||||
+ AddCommand("Limit", static_cast<CModCommand::ModCmdFunc>(&CPlaybackMod::LimitCommand), "<client> [limit]", "Get/set the buffer limit (<= 0 to clear) for the given client.");
|
||||
+ }
|
||||
+
|
||||
+ void OnClientCapLs(CClient* client, SCString& caps) override
|
||||
+ {
|
||||
+ caps.insert(PlaybackCap);
|
||||
+ }
|
||||
+
|
||||
+ bool IsClientCapSupported(CClient* client, const CString& cap, bool state) override
|
||||
+ {
|
||||
+ return cap.Equals(PlaybackCap);
|
||||
+ }
|
||||
+
|
||||
+ EModRet OnChanBufferStarting(CChan& chan, CClient& client) override
|
||||
+ {
|
||||
+ if (!m_play && client.IsCapEnabled(PlaybackCap))
|
||||
+ return HALTCORE;
|
||||
+ return CONTINUE;
|
||||
+ }
|
||||
+
|
||||
+ EModRet OnChanBufferPlayLine(CChan& chan, CClient& client, CString& line) override
|
||||
+ {
|
||||
+ if (!m_play && client.IsCapEnabled(PlaybackCap))
|
||||
+ return HALTCORE;
|
||||
+ return CONTINUE;
|
||||
+ }
|
||||
+
|
||||
+ EModRet OnChanBufferEnding(CChan& chan, CClient& client) override
|
||||
+ {
|
||||
+ if (!m_play && client.IsCapEnabled(PlaybackCap))
|
||||
+ return HALTCORE;
|
||||
+ return CONTINUE;
|
||||
+ }
|
||||
+
|
||||
+ EModRet OnPrivBufferPlayLine(CClient& client, CString& line) override
|
||||
+ {
|
||||
+ if (!m_play && client.IsCapEnabled(PlaybackCap))
|
||||
+ return HALTCORE;
|
||||
+ return CONTINUE;
|
||||
+ }
|
||||
+
|
||||
+ void ClearCommand(const CString& line)
|
||||
+ {
|
||||
+ // CLEAR <buffer(s)>
|
||||
+ const CString arg = line.Token(1);
|
||||
+ if (arg.empty() || !line.Token(2).empty())
|
||||
+ return;
|
||||
+ std::vector<CChan*> chans = FindChans(arg);
|
||||
+ for (CChan* chan : chans)
|
||||
+ chan->ClearBuffer();
|
||||
+ std::vector<CQuery*> queries = FindQueries(arg);
|
||||
+ for (CQuery* query : queries)
|
||||
+ query->ClearBuffer();
|
||||
+ }
|
||||
+
|
||||
+ void PlayCommand(const CString& line)
|
||||
+ {
|
||||
+ // PLAY <buffer(s)> [from] [to]
|
||||
+ const CString arg = line.Token(1);
|
||||
+ if (arg.empty() || !line.Token(4).empty())
|
||||
+ return;
|
||||
+ double from = line.Token(2).ToDouble();
|
||||
+ double to = DBL_MAX;
|
||||
+ if (!line.Token(3).empty())
|
||||
+ to = line.Token(3).ToDouble();
|
||||
+ int limit = -1;
|
||||
+ if (CClient* client = GetClient())
|
||||
+ limit = GetLimit(client->GetIdentifier());
|
||||
+ std::vector<CChan*> chans = FindChans(arg);
|
||||
+ for (CChan* chan : chans) {
|
||||
+ if (chan->IsOn() && !chan->IsDetached()) {
|
||||
+ CBuffer lines = GetLines(chan->GetBuffer(), from, to, limit);
|
||||
+ m_play = true;
|
||||
+ chan->SendBuffer(GetClient(), lines);
|
||||
+ m_play = false;
|
||||
+ }
|
||||
+ }
|
||||
+ std::vector<CQuery*> queries = FindQueries(arg);
|
||||
+ for (CQuery* query : queries) {
|
||||
+ CBuffer lines = GetLines(query->GetBuffer(), from, to, limit);
|
||||
+ m_play = true;
|
||||
+ query->SendBuffer(GetClient(), lines);
|
||||
+ m_play = false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ void ListCommand(const CString& line)
|
||||
+ {
|
||||
+ // LIST [buffer(s)]
|
||||
+ CString arg = line.Token(1);
|
||||
+ if (arg.empty())
|
||||
+ arg = "*";
|
||||
+ std::vector<CChan*> chans = FindChans(arg);
|
||||
+ for (CChan* chan : chans) {
|
||||
+ if (chan->IsOn() && !chan->IsDetached()) {
|
||||
+ CBuffer buffer = chan->GetBuffer();
|
||||
+ if (!buffer.IsEmpty()) {
|
||||
+ timeval from = UniversalTime(buffer.GetBufLine(0).GetTime());
|
||||
+ timeval to = UniversalTime(buffer.GetBufLine(buffer.Size() - 1).GetTime());
|
||||
+ PutModule(chan->GetName() + " " + CString(Timestamp(from)) + " " + CString(Timestamp(to)));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ std::vector<CQuery*> queries = FindQueries(arg);
|
||||
+ for (CQuery* query : queries) {
|
||||
+ CBuffer buffer = query->GetBuffer();
|
||||
+ if (!buffer.IsEmpty()) {
|
||||
+ timeval from = UniversalTime(buffer.GetBufLine(0).GetTime());
|
||||
+ timeval to = UniversalTime(buffer.GetBufLine(buffer.Size() - 1).GetTime());
|
||||
+ PutModule(query->GetName() + " " + CString(Timestamp(from)) + " " + CString(Timestamp(to)));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ void LimitCommand(const CString& line)
|
||||
+ {
|
||||
+ // LIMIT <client> [limit]
|
||||
+ const CString client = line.Token(1);
|
||||
+ if (client.empty()) {
|
||||
+ PutModule("Usage: LIMIT <client> [limit]");
|
||||
+ return;
|
||||
+ }
|
||||
+ const CString arg = line.Token(2);
|
||||
+ int limit = GetLimit(client);
|
||||
+ if (!arg.empty()) {
|
||||
+ limit = arg.ToInt();
|
||||
+ SetLimit(client, limit);
|
||||
+ }
|
||||
+ if (limit <= 0)
|
||||
+ PutModule(client + " buffer limit: -");
|
||||
+ else
|
||||
+ PutModule(client + " buffer limit: " + CString(limit));
|
||||
+ }
|
||||
+
|
||||
+ EModRet OnSendToClient(CString& line, CClient& client) override
|
||||
+ {
|
||||
+ if (client.IsAttached() && client.IsCapEnabled(PlaybackCap) && !line.Token(0).Equals("CAP")) {
|
||||
+ MCString tags = CUtils::GetMessageTags(line);
|
||||
+ if (tags.find("time") == tags.end()) {
|
||||
+ // CUtils::FormatServerTime() converts to UTC
|
||||
+ tags["time"] = CUtils::FormatServerTime(LocalTime());
|
||||
+ CUtils::SetMessageTags(line, tags);
|
||||
+ }
|
||||
+ }
|
||||
+ return CONTINUE;
|
||||
+ }
|
||||
+
|
||||
+private:
|
||||
+ static double Timestamp(timeval tv)
|
||||
+ {
|
||||
+ return tv.tv_sec + tv.tv_usec / 1000000.0;
|
||||
+ }
|
||||
+
|
||||
+ static timeval LocalTime()
|
||||
+ {
|
||||
+ timeval tv;
|
||||
+ if (gettimeofday(&tv, NULL) == -1) {
|
||||
+ tv.tv_sec = time(NULL);
|
||||
+ tv.tv_usec = 0;
|
||||
+ }
|
||||
+ return tv;
|
||||
+ }
|
||||
+
|
||||
+ static timeval UniversalTime(timeval tv = LocalTime())
|
||||
+ {
|
||||
+ tm stm;
|
||||
+ memset(&stm, 0, sizeof(stm));
|
||||
+ const time_t secs = tv.tv_sec; // OpenBSD has tv_sec as int, so explicitly convert it to time_t to make gmtime_r() happy
|
||||
+ gmtime_r(&secs, &stm);
|
||||
+ const char* tz = getenv("TZ");
|
||||
+ setenv("TZ", "UTC", 1);
|
||||
+ tzset();
|
||||
+ tv.tv_sec = mktime(&stm);
|
||||
+ if (tz)
|
||||
+ setenv("TZ", tz, 1);
|
||||
+ else
|
||||
+ unsetenv("TZ");
|
||||
+ tzset();
|
||||
+ return tv;
|
||||
+ }
|
||||
+
|
||||
+ std::vector<CChan*> FindChans(const CString& arg) const
|
||||
+ {
|
||||
+ std::vector<CChan*> chans;
|
||||
+ CIRCNetwork* network = GetNetwork();
|
||||
+ if (network) {
|
||||
+ VCString vargs;
|
||||
+ arg.Split(",", vargs, false);
|
||||
+
|
||||
+ for (const CString& name : vargs) {
|
||||
+ std::vector<CChan*> found = network->FindChans(name);
|
||||
+ chans.insert(chans.end(), found.begin(), found.end());
|
||||
+ }
|
||||
+ }
|
||||
+ return chans;
|
||||
+ }
|
||||
+
|
||||
+ std::vector<CQuery*> FindQueries(const CString& arg) const
|
||||
+ {
|
||||
+ std::vector<CQuery*> queries;
|
||||
+ CIRCNetwork* network = GetNetwork();
|
||||
+ if (network) {
|
||||
+ VCString vargs;
|
||||
+ arg.Split(",", vargs, false);
|
||||
+
|
||||
+ for (const CString& name : vargs) {
|
||||
+ std::vector<CQuery*> found = network->FindQueries(name);
|
||||
+ queries.insert(queries.end(), found.begin(), found.end());
|
||||
+ }
|
||||
+ }
|
||||
+ return queries;
|
||||
+ }
|
||||
+
|
||||
+ int GetLimit(const CString& client) const
|
||||
+ {
|
||||
+ return GetNV(client).ToInt();
|
||||
+ }
|
||||
+
|
||||
+ void SetLimit(const CString& client, int limit)
|
||||
+ {
|
||||
+ if (limit > 0)
|
||||
+ SetNV(client, CString(limit));
|
||||
+ else
|
||||
+ DelNV(client);
|
||||
+ }
|
||||
+
|
||||
+ static CBuffer GetLines(const CBuffer& buffer, double from, double to, int limit)
|
||||
+ {
|
||||
+ CBuffer lines(buffer.Size());
|
||||
+ for (size_t i = 0; i < buffer.Size(); ++i) {
|
||||
+ const CBufLine& line = buffer.GetBufLine(i);
|
||||
+ timeval tv = UniversalTime(line.GetTime());
|
||||
+ if (from < Timestamp(tv) && to >= Timestamp(tv))
|
||||
+ lines.AddLine(line.GetFormat(), line.GetText(), &tv);
|
||||
+ }
|
||||
+ if (limit > 0)
|
||||
+ lines.SetLineCount(limit);
|
||||
+ return lines;
|
||||
+ }
|
||||
+
|
||||
+ bool m_play;
|
||||
+};
|
||||
+
|
||||
+GLOBALMODULEDEFS(CPlaybackMod, "An advanced playback module for ZNC")
|
Loading…
Reference in a new issue