Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

LoggingManager.java 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. /*
  2. * Copyright (c) 2006-2015 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.addons.logging;
  23. import com.dmdirc.ClientModule.GlobalConfig;
  24. import com.dmdirc.DMDircMBassador;
  25. import com.dmdirc.FrameContainer;
  26. import com.dmdirc.Query;
  27. import com.dmdirc.commandline.CommandLineOptionsModule.Directory;
  28. import com.dmdirc.config.prefs.PluginPreferencesCategory;
  29. import com.dmdirc.config.prefs.PreferencesCategory;
  30. import com.dmdirc.config.prefs.PreferencesDialogModel;
  31. import com.dmdirc.config.prefs.PreferencesSetting;
  32. import com.dmdirc.config.prefs.PreferencesType;
  33. import com.dmdirc.events.BaseChannelActionEvent;
  34. import com.dmdirc.events.BaseChannelMessageEvent;
  35. import com.dmdirc.events.BaseQueryActionEvent;
  36. import com.dmdirc.events.BaseQueryMessageEvent;
  37. import com.dmdirc.events.ChannelClosedEvent;
  38. import com.dmdirc.events.ChannelGotTopicEvent;
  39. import com.dmdirc.events.ChannelJoinEvent;
  40. import com.dmdirc.events.ChannelKickEvent;
  41. import com.dmdirc.events.ChannelModeChangeEvent;
  42. import com.dmdirc.events.ChannelNickChangeEvent;
  43. import com.dmdirc.events.ChannelOpenedEvent;
  44. import com.dmdirc.events.ChannelPartEvent;
  45. import com.dmdirc.events.ChannelQuitEvent;
  46. import com.dmdirc.events.ChannelTopicChangeEvent;
  47. import com.dmdirc.events.ClientPrefsOpenedEvent;
  48. import com.dmdirc.events.QueryClosedEvent;
  49. import com.dmdirc.events.QueryOpenedEvent;
  50. import com.dmdirc.events.UserErrorEvent;
  51. import com.dmdirc.interfaces.GroupChat;
  52. import com.dmdirc.interfaces.GroupChatUser;
  53. import com.dmdirc.interfaces.PrivateChat;
  54. import com.dmdirc.interfaces.User;
  55. import com.dmdirc.interfaces.config.AggregateConfigProvider;
  56. import com.dmdirc.interfaces.config.ConfigChangeListener;
  57. import com.dmdirc.logger.ErrorLevel;
  58. import com.dmdirc.plugins.PluginDomain;
  59. import com.dmdirc.plugins.PluginInfo;
  60. import com.dmdirc.ui.WindowManager;
  61. import com.dmdirc.ui.messages.BackBufferFactory;
  62. import com.dmdirc.ui.messages.Styliser;
  63. import com.dmdirc.util.io.ReverseFileReader;
  64. import com.dmdirc.util.io.StreamUtils;
  65. import java.awt.Color;
  66. import java.io.BufferedWriter;
  67. import java.io.File;
  68. import java.io.FileWriter;
  69. import java.io.IOException;
  70. import java.nio.file.Files;
  71. import java.nio.file.Path;
  72. import java.nio.file.Paths;
  73. import java.text.DateFormat;
  74. import java.text.SimpleDateFormat;
  75. import java.util.ArrayList;
  76. import java.util.Collection;
  77. import java.util.Collections;
  78. import java.util.Date;
  79. import java.util.HashMap;
  80. import java.util.Map;
  81. import java.util.Stack;
  82. import java.util.Timer;
  83. import java.util.TimerTask;
  84. import javax.inject.Inject;
  85. import javax.inject.Provider;
  86. import javax.inject.Singleton;
  87. import net.engio.mbassy.listener.Handler;
  88. /**
  89. * Manages logging activities.
  90. */
  91. @Singleton
  92. public class LoggingManager implements ConfigChangeListener {
  93. /** Date format used for "File Opened At" log. */
  94. private static final DateFormat OPENED_AT_FORMAT = new SimpleDateFormat(
  95. "EEEE MMMM dd, yyyy - HH:mm:ss");
  96. /** Object for synchronising access to the date forma.t */
  97. private static final Object FORMAT_LOCK = new Object();
  98. private static final String timestamp = "[dd/MM/yyyy HH:mm:ss]";
  99. /** This plugin's plugin info. */
  100. private final String domain;
  101. private final PluginInfo pluginInfo;
  102. /** Global config. */
  103. private final AggregateConfigProvider config;
  104. /** The manager to add history windows to. */
  105. private final WindowManager windowManager;
  106. /** Map of open files. */
  107. private final Map<String, OpenFile> openFiles = Collections.synchronizedMap(
  108. new HashMap<>());
  109. private final DMDircMBassador eventBus;
  110. private final Provider<String> directoryProvider;
  111. private final BackBufferFactory backBufferFactory;
  112. private final LogFileLocator locator;
  113. /** Timer used to close idle files. */
  114. private Timer idleFileTimer;
  115. /** Cached boolean settings. */
  116. private boolean addtime;
  117. private boolean stripcodes;
  118. private boolean channelmodeprefix;
  119. private boolean autobackbuffer;
  120. private boolean backbufferTimestamp;
  121. private String colour;
  122. /** Cached int settings. */
  123. private int historyLines;
  124. private int backbufferLines;
  125. @Inject
  126. public LoggingManager(@PluginDomain(LoggingPlugin.class) final String domain,
  127. @PluginDomain(LoggingPlugin.class) final PluginInfo pluginInfo,
  128. @GlobalConfig final AggregateConfigProvider globalConfig,
  129. final WindowManager windowManager, final DMDircMBassador eventBus,
  130. @Directory(LoggingModule.LOGS_DIRECTORY) final Provider<String> directoryProvider,
  131. final BackBufferFactory backBufferFactory,
  132. final LogFileLocator locator) {
  133. this.domain = domain;
  134. this.pluginInfo = pluginInfo;
  135. this.config = globalConfig;
  136. this.windowManager = windowManager;
  137. this.eventBus = eventBus;
  138. this.directoryProvider = directoryProvider;
  139. this.backBufferFactory = backBufferFactory;
  140. this.locator = locator;
  141. }
  142. public void load() {
  143. setCachedSettings();
  144. final File dir = new File(directoryProvider.get());
  145. if (dir.exists()) {
  146. if (!dir.isDirectory()) {
  147. eventBus.publishAsync(new UserErrorEvent(ErrorLevel.LOW, null,
  148. "Unable to create logging dir (file exists instead)", ""));
  149. }
  150. } else {
  151. if (!dir.mkdirs()) {
  152. eventBus.publishAsync(new UserErrorEvent(ErrorLevel.LOW, null,
  153. "Unable to create logging dir", ""));
  154. }
  155. }
  156. config.addChangeListener(domain, this);
  157. // Close idle files every hour.
  158. idleFileTimer = new Timer("LoggingPlugin Timer");
  159. idleFileTimer.schedule(new TimerTask() {
  160. @Override
  161. public void run() {
  162. timerTask();
  163. }
  164. }, 3600000);
  165. eventBus.subscribe(this);
  166. }
  167. public void unload() {
  168. if (idleFileTimer != null) {
  169. idleFileTimer.cancel();
  170. idleFileTimer.purge();
  171. }
  172. synchronized (openFiles) {
  173. for (OpenFile file : openFiles.values()) {
  174. StreamUtils.close(file.writer);
  175. }
  176. openFiles.clear();
  177. }
  178. eventBus.unsubscribe(this);
  179. }
  180. /**
  181. * What to do every hour when the timer fires.
  182. */
  183. protected void timerTask() {
  184. // Oldest time to allow
  185. final long oldestTime = System.currentTimeMillis() - 3480000;
  186. synchronized (openFiles) {
  187. final Collection<String> old = new ArrayList<>(openFiles.size());
  188. for (Map.Entry<String, OpenFile> entry : openFiles.entrySet()) {
  189. if (entry.getValue().lastUsedTime < oldestTime) {
  190. StreamUtils.close(entry.getValue().writer);
  191. old.add(entry.getKey());
  192. }
  193. }
  194. openFiles.keySet().removeAll(old);
  195. }
  196. }
  197. @Handler
  198. public void handleQueryOpened(final QueryOpenedEvent event) {
  199. final String filename = locator.getLogFile(event.getQuery().getUser());
  200. if (autobackbuffer) {
  201. showBackBuffer(event.getQuery(), filename);
  202. }
  203. synchronized (FORMAT_LOCK) {
  204. appendLine(filename, "*** Query opened at: %s", OPENED_AT_FORMAT.format(new Date()));
  205. appendLine(filename, "*** Query with User: %s", event.getQuery().getHost());
  206. appendLine(filename, "");
  207. }
  208. }
  209. @Handler
  210. public void handleQueryClosed(final QueryClosedEvent event) {
  211. final String filename = locator.getLogFile(event.getQuery().getUser());
  212. synchronized (FORMAT_LOCK) {
  213. appendLine(filename, "*** Query closed at: %s", OPENED_AT_FORMAT.format(new Date()));
  214. }
  215. if (openFiles.containsKey(filename)) {
  216. StreamUtils.close(openFiles.get(filename).writer);
  217. openFiles.remove(filename);
  218. }
  219. }
  220. @Handler
  221. public void handleQueryActions(final BaseQueryActionEvent event) {
  222. final User user = event.getUser();
  223. final String filename = locator.getLogFile(user);
  224. appendLine(filename, "* %s %s", user.getNickname(), event.getMessage());
  225. }
  226. @Handler
  227. public void handleQueryMessages(final BaseQueryMessageEvent event) {
  228. final User user = event.getUser();
  229. final String filename = locator.getLogFile(user);
  230. appendLine(filename, "<%s> %s", user.getNickname(), event.getMessage());
  231. }
  232. @Handler
  233. public void handleChannelMessage(final BaseChannelMessageEvent event) {
  234. final String filename = locator.getLogFile(event.getChannel());
  235. appendLine(filename, "<%s> %s", getDisplayName(event.getClient()), event.getMessage());
  236. }
  237. @Handler
  238. public void handleChannelAction(final BaseChannelActionEvent event) {
  239. final String filename = locator.getLogFile(event.getChannel());
  240. appendLine(filename, "* %s %s", getDisplayName(event.getClient()), event.getMessage());
  241. }
  242. @Handler
  243. public void handleChannelGotTopic(final ChannelGotTopicEvent event) {
  244. final String filename = locator.getLogFile(event.getChannel());
  245. final DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
  246. final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
  247. appendLine(filename, "*** Topic is: %s", event.getTopic().getTopic());
  248. appendLine(filename, "*** Set at: %s on %s by %s",
  249. timeFormat.format(1000 * event.getTopic().getTime()),
  250. dateFormat.format(1000 * event.getTopic().getTime()),
  251. event.getTopic().getClient()
  252. .map(GroupChatUser::getNickname).orElse("Unknown"));
  253. }
  254. @Handler
  255. public void handleChannelTopicChange(final ChannelTopicChangeEvent event) {
  256. final String filename = locator.getLogFile(event.getChannel());
  257. appendLine(filename, "*** %s Changed the topic to: %s",
  258. event.getTopic().getClient().map(this::getDisplayName).orElse(""), event.getTopic());
  259. }
  260. @Handler
  261. public void handleChannelJoin(final ChannelJoinEvent event) {
  262. final String filename = locator.getLogFile(event.getChannel());
  263. final GroupChatUser channelClient = event.getClient();
  264. appendLine(filename, "*** %s (%s) joined the channel", getDisplayName(channelClient),
  265. channelClient.getNickname());
  266. }
  267. @Handler
  268. public void handleChannelPart(final ChannelPartEvent event) {
  269. final String filename = locator.getLogFile(event.getChannel());
  270. final String message = event.getMessage();
  271. final GroupChatUser channelClient = event.getClient();
  272. if (message.isEmpty()) {
  273. appendLine(filename, "*** %s (%s) left the channel", getDisplayName(channelClient),
  274. channelClient.getNickname());
  275. } else {
  276. appendLine(filename, "*** %s (%s) left the channel (%s)",
  277. getDisplayName(channelClient), channelClient.getNickname(), message);
  278. }
  279. }
  280. @Handler
  281. public void handleChannelQuit(final ChannelQuitEvent event) {
  282. final String filename = locator.getLogFile(event.getChannel());
  283. final String reason = event.getMessage();
  284. final GroupChatUser channelClient = event.getClient();
  285. if (reason.isEmpty()) {
  286. appendLine(filename, "*** %s (%s) Quit IRC",
  287. getDisplayName(channelClient), channelClient.getNickname());
  288. } else {
  289. appendLine(filename, "*** %s (%s) Quit IRC (%s)",
  290. getDisplayName(channelClient), channelClient.getNickname(), reason);
  291. }
  292. }
  293. @Handler
  294. public void handleChannelKick(final ChannelKickEvent event) {
  295. final GroupChatUser victim = event.getVictim();
  296. final GroupChatUser perpetrator = event.getClient();
  297. final String reason = event.getReason();
  298. final String filename = locator.getLogFile(event.getChannel());
  299. if (reason.isEmpty()) {
  300. appendLine(filename, "*** %s was kicked by %s",
  301. getDisplayName(victim), getDisplayName(perpetrator));
  302. } else {
  303. appendLine(filename, "*** %s was kicked by %s (%s)",
  304. getDisplayName(victim), getDisplayName(perpetrator), reason);
  305. }
  306. }
  307. @Handler
  308. public void handleNickChange(final ChannelNickChangeEvent event) {
  309. final String filename = locator.getLogFile(event.getChannel());
  310. appendLine(filename, "*** %s is now %s", getDisplayName(event.getClient(),
  311. event.getOldNick()), getDisplayName(event.getClient()));
  312. }
  313. @Handler
  314. public void handleModeChange(final ChannelModeChangeEvent event) {
  315. final String filename = locator.getLogFile(event.getChannel());
  316. if (event.getClient().getNickname().isEmpty()) {
  317. appendLine(filename, "*** Channel modes are: %s", event.getModes());
  318. } else {
  319. appendLine(filename, "*** %s set modes: %s",
  320. getDisplayName(event.getClient()), event.getModes());
  321. }
  322. }
  323. @Override
  324. public void configChanged(final String domain, final String key) {
  325. setCachedSettings();
  326. }
  327. @Handler
  328. public void handleChannelOpened(final ChannelOpenedEvent event) {
  329. final String filename = locator.getLogFile(event.getChannel().getName());
  330. if (autobackbuffer) {
  331. showBackBuffer(event.getChannel().getWindowModel(), filename);
  332. }
  333. synchronized (FORMAT_LOCK) {
  334. appendLine(filename, "*** Channel opened at: %s", OPENED_AT_FORMAT.format(new Date()));
  335. appendLine(filename, "");
  336. }
  337. }
  338. @Handler
  339. public void handleChannelClosed(final ChannelClosedEvent event) {
  340. final String filename = locator.getLogFile(event.getChannel().getName());
  341. synchronized (FORMAT_LOCK) {
  342. appendLine(filename, "*** Channel closed at: %s", OPENED_AT_FORMAT.format(new Date()));
  343. }
  344. if (openFiles.containsKey(filename)) {
  345. StreamUtils.close(openFiles.get(filename).writer);
  346. openFiles.remove(filename);
  347. }
  348. }
  349. /**
  350. * Add a backbuffer to a frame.
  351. *
  352. * @param frame The frame to add the backbuffer lines to
  353. * @param filename File to get backbuffer from
  354. */
  355. protected void showBackBuffer(final FrameContainer frame, final String filename) {
  356. if (frame == null) {
  357. eventBus.publishAsync(new UserErrorEvent(ErrorLevel.LOW, null, "Given a null frame", ""));
  358. return;
  359. }
  360. final Path testFile = Paths.get(filename);
  361. if (Files.exists(testFile)) {
  362. try {
  363. final ReverseFileReader file = new ReverseFileReader(testFile);
  364. // Because the file includes a newline char at the end, an empty line
  365. // is returned by getLines. To counter this, we call getLines(1) and do
  366. // nothing with the output.
  367. file.getLines(1);
  368. final Stack<String> lines = file.getLines(backbufferLines);
  369. while (!lines.empty()) {
  370. frame.addLine(getColouredString(colour, lines.pop()), backbufferTimestamp);
  371. }
  372. file.close();
  373. frame.addLine(getColouredString(colour, "--- End of backbuffer\n"),
  374. backbufferTimestamp);
  375. } catch (IOException | SecurityException e) {
  376. eventBus.publishAsync(new UserErrorEvent(ErrorLevel.LOW, e,
  377. "Unable to show backbuffer (Filename: " + filename + "): " + e.getMessage(),
  378. ""));
  379. }
  380. }
  381. }
  382. /**
  383. * Get a coloured String. If colour is invalid, IRC Colour 14 will be used.
  384. *
  385. * @param colour The colour the string should be (IRC Colour or 6-digit hex colour)
  386. * @param line the line to colour
  387. *
  388. * @return The given line with the appropriate irc codes appended/prepended to colour it.
  389. */
  390. protected static String getColouredString(final String colour, final String line) {
  391. String res = null;
  392. if (colour.length() < 3) {
  393. int num;
  394. try {
  395. num = Integer.parseInt(colour);
  396. } catch (NumberFormatException ex) {
  397. num = -1;
  398. }
  399. if (num >= 0 && num <= 15) {
  400. res = String.format("%c%02d%s%1$c", Styliser.CODE_COLOUR, num, line);
  401. }
  402. } else if (colour.length() == 6) {
  403. try {
  404. Color.decode('#' + colour);
  405. res = String.format("%c%s%s%1$c", Styliser.CODE_HEXCOLOUR, colour, line);
  406. } catch (NumberFormatException ex) { /* Do Nothing */ }
  407. }
  408. if (res == null) {
  409. res = String.format("%c%02d%s%1$c", Styliser.CODE_COLOUR, 14, line);
  410. }
  411. return res;
  412. }
  413. /**
  414. * Add a line to a file.
  415. *
  416. * @param filename Name of file to write to
  417. * @param format Format of line to add. (NewLine will be added Automatically)
  418. * @param args Arguments for format
  419. *
  420. * @return true on success, else false.
  421. */
  422. protected boolean appendLine(final String filename, final String format, final Object... args) {
  423. return appendLine(filename, String.format(format, args));
  424. }
  425. /**
  426. * Add a line to a file.
  427. *
  428. * @param filename Name of file to write to
  429. * @param line Line to add. (NewLine will be added Automatically)
  430. *
  431. * @return true on success, else false.
  432. */
  433. protected boolean appendLine(final String filename, final String line) {
  434. final StringBuilder finalLine = new StringBuilder();
  435. if (addtime) {
  436. final DateFormat dateFormat = new SimpleDateFormat(timestamp);
  437. final String dateString = dateFormat.format(new Date()).trim();
  438. finalLine.append(dateString);
  439. finalLine.append(' ');
  440. }
  441. if (stripcodes) {
  442. finalLine.append(Styliser.stipControlCodes(line));
  443. } else {
  444. finalLine.append(line);
  445. }
  446. try {
  447. final BufferedWriter out;
  448. if (openFiles.containsKey(filename)) {
  449. final OpenFile of = openFiles.get(filename);
  450. of.lastUsedTime = System.currentTimeMillis();
  451. out = of.writer;
  452. } else {
  453. out = new BufferedWriter(new FileWriter(filename, true));
  454. openFiles.put(filename, new OpenFile(out));
  455. }
  456. out.write(finalLine.toString());
  457. out.newLine();
  458. out.flush();
  459. return true;
  460. } catch (IOException e) {
  461. /*
  462. * Do Nothing
  463. *
  464. * Makes no sense to keep adding errors to the logger when we can't write to the file,
  465. * as chances are it will happen on every incomming line.
  466. */
  467. }
  468. return false;
  469. }
  470. /**
  471. * Get name to display for channelClient (Taking into account the channelmodeprefix setting).
  472. *
  473. * @param channelClient The client to get the display name for
  474. *
  475. * @return name to display
  476. */
  477. protected String getDisplayName(final GroupChatUser channelClient) {
  478. return getDisplayName(channelClient, "");
  479. }
  480. /**
  481. * Get name to display for channelClient (Taking into account the channelmodeprefix setting).
  482. *
  483. * @param channelClient The client to get the display name for
  484. * @param overrideNick Nickname to display instead of real nickname
  485. *
  486. * @return name to display
  487. */
  488. protected String getDisplayName(final GroupChatUser channelClient, final String overrideNick) {
  489. if (channelClient == null) {
  490. return overrideNick.isEmpty() ? "Unknown Client" : overrideNick;
  491. } else if (overrideNick.isEmpty()) {
  492. return channelmodeprefix ? channelClient.getModePrefixedNickname()
  493. : channelClient.getNickname();
  494. } else {
  495. return channelmodeprefix ? channelClient.getImportantMode() + overrideNick :
  496. overrideNick;
  497. }
  498. }
  499. /**
  500. * Shows the history window for the specified target, if available.
  501. *
  502. * @param target The window whose history we're trying to open
  503. *
  504. * @return True if the history is available, false otherwise
  505. */
  506. protected boolean showHistory(final FrameContainer target) {
  507. final String descriptor;
  508. if (target instanceof GroupChat) {
  509. descriptor = target.getName();
  510. } else if (target instanceof Query) {
  511. descriptor = ((PrivateChat) target).getNickname();
  512. } else {
  513. // Unknown component
  514. return false;
  515. }
  516. final Path log = Paths.get(locator.getLogFile(descriptor));
  517. if (!Files.exists(log)) {
  518. // File doesn't exist
  519. return false;
  520. }
  521. windowManager.addWindow(target, new HistoryWindow("History", log, target,
  522. eventBus, backBufferFactory, historyLines));
  523. return true;
  524. }
  525. /** Updates cached settings. */
  526. public void setCachedSettings() {
  527. addtime = config.getOptionBool(domain, "general.addtime");
  528. stripcodes = config.getOptionBool(domain, "general.stripcodes");
  529. channelmodeprefix = config.getOptionBool(domain, "general.channelmodeprefix");
  530. autobackbuffer = config.getOptionBool(domain, "backbuffer.autobackbuffer");
  531. backbufferTimestamp = config.getOptionBool(domain, "backbuffer.timestamp");
  532. historyLines = config.getOptionInt(domain, "history.lines");
  533. colour = config.getOption(domain, "backbuffer.colour");
  534. backbufferLines = config.getOptionInt(domain, "backbuffer.lines");
  535. }
  536. @Handler
  537. public void showConfig(final ClientPrefsOpenedEvent event) {
  538. final PreferencesDialogModel manager = event.getModel();
  539. final PreferencesCategory general = new PluginPreferencesCategory(
  540. pluginInfo, "Logging", "General configuration for Logging plugin.");
  541. final PreferencesCategory backbuffer = new PluginPreferencesCategory(
  542. pluginInfo, "Back Buffer", "Options related to the automatic backbuffer");
  543. final PreferencesCategory advanced = new PluginPreferencesCategory(
  544. pluginInfo, "Advanced",
  545. "Advanced configuration for Logging plugin. You shouldn't need to edit this unless you know what you are doing.");
  546. general.addSetting(new PreferencesSetting(PreferencesType.DIRECTORY,
  547. pluginInfo.getDomain(), "general.directory", "Directory",
  548. "Directory for log files", manager.getConfigManager(),
  549. manager.getIdentity()));
  550. general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  551. pluginInfo.getDomain(), "general.networkfolders",
  552. "Separate logs by network",
  553. "Should the files be stored in a sub-dir with the networks name?",
  554. manager.getConfigManager(), manager.getIdentity()));
  555. general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  556. pluginInfo.getDomain(), "general.addtime", "Timestamp logs",
  557. "Should a timestamp be added to the log files?",
  558. manager.getConfigManager(), manager.getIdentity()));
  559. general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  560. pluginInfo.getDomain(), "general.stripcodes", "Strip Control Codes",
  561. "Remove known irc control codes from lines before saving?",
  562. manager.getConfigManager(), manager.getIdentity()));
  563. general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  564. pluginInfo.getDomain(), "general.channelmodeprefix",
  565. "Show channel mode prefix", "Show the @,+ etc next to nicknames",
  566. manager.getConfigManager(), manager.getIdentity()));
  567. backbuffer.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  568. pluginInfo.getDomain(), "backbuffer.autobackbuffer", "Automatically display",
  569. "Automatically display the backbuffer when a channel is joined",
  570. manager.getConfigManager(), manager.getIdentity()));
  571. backbuffer.addSetting(new PreferencesSetting(PreferencesType.COLOUR,
  572. pluginInfo.getDomain(), "backbuffer.colour", "Colour to use for display",
  573. "Colour used when displaying the backbuffer",
  574. manager.getConfigManager(), manager.getIdentity()));
  575. backbuffer.addSetting(new PreferencesSetting(PreferencesType.INTEGER,
  576. pluginInfo.getDomain(), "backbuffer.lines", "Number of lines to show",
  577. "Number of lines used when displaying backbuffer",
  578. manager.getConfigManager(), manager.getIdentity()));
  579. backbuffer.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  580. pluginInfo.getDomain(), "backbuffer.timestamp", "Show Formatter-Timestamp",
  581. "Should the line be added to the frame with the timestamp from "
  582. + "the formatter aswell as the file contents",
  583. manager.getConfigManager(), manager.getIdentity()));
  584. advanced.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  585. pluginInfo.getDomain(), "advanced.filenamehash", "Add Filename hash",
  586. "Add the MD5 hash of the channel/client name to the filename. "
  587. + "(This is used to allow channels with similar names "
  588. + "(ie a _ not a -) to be logged separately)",
  589. manager.getConfigManager(), manager.getIdentity()));
  590. advanced.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  591. pluginInfo.getDomain(), "advanced.usedate", "Use Date directories",
  592. "Should the log files be in separate directories based on the date?",
  593. manager.getConfigManager(), manager.getIdentity()));
  594. advanced.addSetting(new PreferencesSetting(PreferencesType.TEXT,
  595. pluginInfo.getDomain(), "advanced.usedateformat", "Archive format",
  596. "The String to pass to 'SimpleDateFormat' to format the "
  597. + "directory name(s) for archiving",
  598. manager.getConfigManager(), manager.getIdentity()));
  599. general.addSubCategory(backbuffer.setInline());
  600. general.addSubCategory(advanced.setInline());
  601. manager.getCategory("Plugins").addSubCategory(general.setInlineAfter());
  602. }
  603. /** Open File. */
  604. private static class OpenFile {
  605. /** Last used time. */
  606. public long lastUsedTime = System.currentTimeMillis();
  607. /** Open file's writer. */
  608. public final BufferedWriter writer;
  609. /**
  610. * Creates a new open file.
  611. *
  612. * @param writer Writer that has file open
  613. */
  614. protected OpenFile(final BufferedWriter writer) {
  615. this.writer = writer;
  616. }
  617. }
  618. }