Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all changes into v0.7.0 #109

Merged
merged 24 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9d9c28c
Start adding AppearanceTests - started with changeDefaultFontTest
matty-r Feb 4, 2024
a295547
Adds appearance tests. Fixed up saving the background colour as a res…
matty-r Feb 6, 2024
139e381
Don't fire listeners when deleting profiles during tests, and don't b…
matty-r Feb 10, 2024
6e9b951
Merge pull request #100 from matty-r/#83
matty-r Feb 10, 2024
85e1410
Test creating a parser for created logs, to load the history back int…
matty-r Feb 14, 2024
44c18e8
Log Pattern Parser
matty-r Feb 14, 2024
cd01b81
Adds a maximum message queue size constant, increased to 100 from 20.…
matty-r Feb 18, 2024
43241d2
Merge pull request #101 from matty-r/#83
matty-r Feb 18, 2024
c7ed704
Fix formatting. Improves messageQueue performance
matty-r Feb 23, 2024
34ef27b
Fix loading of the log4j2.xml. Adds the option to load channel logs/h…
matty-r Feb 26, 2024
90ce5ff
Improve deletion of testing profiles during the test execution. Tight…
matty-r Feb 26, 2024
d7c7e80
Update README.md
matty-r Mar 1, 2024
5b051f3
Update README.md
matty-r Mar 1, 2024
a6755c2
Introduces a stylesHash in order to not waste time updating lines tha…
matty-r Mar 2, 2024
d3d4442
Some test tweaks
matty-r Mar 2, 2024
288508f
test tweaks
matty-r Mar 3, 2024
e234d37
test tweaks
matty-r Mar 3, 2024
4347f18
Merge pull request #105 from matty-r/84
matty-r Mar 3, 2024
9db1ab3
Update README.md
matty-r Mar 3, 2024
417511f
Reenables favouriting of channels
matty-r Mar 4, 2024
cbefbfe
Merge pull request #106 from matty-r/99-adding-favourites-doesnt-work
matty-r Mar 4, 2024
e8d2f15
Ignore case when getting created channels. Set load channel history t…
matty-r Mar 5, 2024
38b2b61
Merge pull request #107 from matty-r/99-adding-favourites-doesnt-work
matty-r Mar 5, 2024
19f4beb
Change message queue
matty-r Mar 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[![Build](https://github.com/matty-r/urChat/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/matty-r/urChat/actions/workflows/build.yml)

urChat
======

Expand Down Expand Up @@ -54,6 +56,38 @@ Using the testng.xml - must be in the same directory as urchat.jar
Without testng.xml
* java -jar urTestRunner.jar

Update History
======

### Update - v0.6.1 (03 FEB 24)
* Rename room to channel, everywhere

### Update - v0.6.0 (02 FEB 24)
* Improved updateStyles performance
* Moved the Interface options panel to it's own InterfacePanel class. Rename Panels to URPanels. Move ProfilePanel and MainOptionsPanel from components to Panels. Created ConfigKeys which pairs the Preference Key to the default value in Constants. When AddToPanel is used, the appropriate preference key can be added which will then be associated with that component - this makes it easier to save the preferences instead of needing to add it for each individual component.
* Added component-label associations and fixed setting the sizes of components
* Adds a listener to Options Panels to grab the preferences as needed
* Moved the Connection stuff into its own component
* Added support for HTTP proxy, SOCKS and HTTP are now available
* Better handling of connecting to favourites
* Added an option to show tab icons
* Improved disconnection handling when connection times out, can now reconnect to the server and all open channels.
* Implemented log4j2. This raises the file size of the jar quite a bit - it may become optional at a later stage.
* Shows an error dialog if an error is received when trying to connect.

### Update - v0.5.1 (05 JAN 24)
* Improvements made for updating styles which should lead to better performance on large chat histor

### Update - v0.5.0 (03 JAN 24)
* Fixed a bug where saving the font didn't automatically update the Font preview
* Added an option to customise the nick format (Similar to the date format). The word nick in the Nick format text box will be replaced with the user nick, or it'll be split in half. For example: would result in the same format as <>, or <*>. But if you want a specific prefix and suffix, it's recommended to use the word nick.
* Fixed a bug with updating styles in tabs (Servers/Channels)
* Added a profiles page to better manage available profiles, such as cloning existing profiles, rename, and deleting
* A default profile can now also be set
* Saving changes to the font now only saves the difference
* Fixed a bug where changing the LAF wasn't updating the dialogs
* Add initial GitHub Actions build for Maven by @chabala in #77

### Update - v0.4.0 (12 DEC 23)
* Added custom styling support for the different styles used in messages
* Added custom Timestamp format
Expand Down
34 changes: 17 additions & 17 deletions src/urChatBasic/backend/MessageHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,7 @@ public void messageExec (Message myMessage)
// CAP ACK or CAP LS?
switch (myMessage.subType)
{
case "LS" ->
{
case "LS" -> {
printServerText(myMessage.body);

serverBase.setCapabilities(myMessage.body);
Expand All @@ -706,8 +705,7 @@ public void messageExec (Message myMessage)
serverBase.nickservRequestAuthentication();
}
}
case "ACK" ->
{
case "ACK" -> {
printServerText("Begin SASL Authentication");
serverBase.saslDoAuthentication();
}
Expand All @@ -733,20 +731,21 @@ public class NoticeMessage implements MessageBase
@Override
public void messageExec (Message myMessage)
{
if (myMessage.nick != null && myMessage.nick.equalsIgnoreCase("NickServ"))
// Send the message to the Channel or Private Channel if that is where it needs to go
// otherwise just print it as server text
IRCChannelBase messageChannel = myMessage.messageHandler.serverBase.getCreatedChannel(myMessage.getChannel());

if (messageChannel == null)
{
printPrivateText(myMessage.nick, myMessage.body, myMessage.nick);
serverBase.reconnectChannels();
messageChannel = myMessage.messageHandler.serverBase.getCreatedPrivateChannel(myMessage.getNick());
}

if (messageChannel != null)
{
messageChannel.printText(myMessage.getBody(), Constants.EVENT_USER);
} else
{
IRCChannelBase messageChannel = myMessage.messageHandler.serverBase.getCreatedChannel(myMessage.getChannel());
if (messageChannel != null)
{
messageChannel.printText(myMessage.getBody(), Constants.EVENT_USER);
} else
{
printServerText(myMessage.body);
}
printServerText(myMessage.body);
}
}
}
Expand Down Expand Up @@ -818,10 +817,11 @@ public class DisconnectErrorMessage implements MessageBase
public void messageExec (Message myMessage)
{
// Are we just quitting, then don't show an error message.
if(myMessage.getBody().contains("Goodbye cruel world"))
if (myMessage.getBody().contains("Goodbye cruel world"))
{
gui.quitServer(myMessage.messageHandler.serverBase);
} else {
} else
{
Constants.LOGGER.error(myMessage.getBody());
MessageDialog dialog = new MessageDialog("startUp() failed! " + myMessage.getBody(), "Error", JOptionPane.ERROR_MESSAGE);
dialog.setVisible(true);
Expand Down
32 changes: 30 additions & 2 deletions src/urChatBasic/backend/logging/URLogger.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
import java.util.Map;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
Expand All @@ -28,16 +29,19 @@ public class URLogger

public static void init () throws IOException, URISyntaxException
{
// System.out.println("LOG CONFIG: "+ LOG4J_CONFIG_FILE);
File logDir = new File(Constants.DIRECTORY_LOGS);
if (!logDir.exists())
{
logDir.mkdir();
}

System.setProperty("log4j2.configurationFile", DriverGUI.class.getResource(LOG4J_CONFIG_FILE).toURI().toString());


// System.setProperty("log4j2.debug", "true");
System.setProperty("log4j2.configurationFile", DriverGUI.class.getResource(LOG4J_CONFIG_FILE).toURI().toString());

LOGGER = LoggerFactory.getLogger(URLogger.class);
LOGGER = LoggerFactory.getLogger("urchat");

Logger testLog = getLogger(LOGGER.getName(), Logger.class);

Expand Down Expand Up @@ -84,6 +88,30 @@ public static Marker getMarker (String markerName)
// }
// }

/**
* Get the path for the logfile associated with the given markerName.
*
* @param markerName The markerName associated with the logfile.
* @return The path for the associated logfile, or null if not found.
*/
public static String getLogFilePath(String markerName) {
// Get the root LoggerConfig
Configuration rootLoggerConfig = currentConfig;
if (rootLoggerConfig != null) {
// Find the appender associated with the given markerName
Map<String, Appender> appenders = rootLoggerConfig.getAppenders();
String appenderName = markerName + "Appender";
Appender appender = appenders.get(appenderName);
if (appender instanceof FileAppender) {
// If the appender is a FileAppender, return its file name
FileAppender fileAppender = (FileAppender) appender;
return fileAppender.getFileName();
}
}
// Return null if the logfile for the given markerName is not found
return null;
}

public static void logChannelComms (IRCChannelBase ircChannel, String message)
{

Expand Down
177 changes: 177 additions & 0 deletions src/urChatBasic/backend/utils/LogPatternParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package urChatBasic.backend.utils;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LogPatternParser
{

// Define enum for log patterns
public enum LogPattern
{
DATE("%d", "(?<DATE>.*UTC?)", Date.class, "UTC "),
SERVER("%marker", "\\s(?<SERVER>[A-Za-z0-9.-]+)-", String.class, "-"),
CHANNEL("%marker", "(?<CHANNEL>#.*?)\\s", String.class, " "), // Named group for channel, excluding the trailing whitespace
USER("%msg", "(?<USER>.*?):", String.class, ": "),
MESSAGE("%msg", "\\s(?<MESSAGE>.*)$", String.class, "");

private final String pattern;
private final String regex;
private final String appendString;
private final Class<?> patternClass;
public final static String PATTERN_LAYOUT = "%d{yyy-MM-dd HH:mm:ss.SSS}{UTC}UTC %marker %msg%n";
public final static String DATE_LAYOUT = "yyyy-MM-dd HH:mm:ss.SSS";

LogPattern (String pattern, String regex, Class<?> patternClass, String appendString)
{
this.pattern = pattern;
this.regex = regex;
this.patternClass = patternClass;
this.appendString = appendString;
}

public String getPattern ()
{
return pattern;
}

public Class<?> getPatternClass ()
{
return patternClass;
}

public String getRegex ()
{
return regex;
}

public String getMatchGroup ()
{
return this.toString();
}

public String getAppendString ()
{
return appendString;
}
}

public static Date parseDate (String dateString)
{
dateString = dateString.trim();
// Step 1: Define the DateTimeFormatter with the pattern
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
TemporalAccessor temporalAccessor = null;
try{
// Step 2: Parse the string into a TemporalAccessor object using the formatter
temporalAccessor = formatter.parse(dateString.replace("UTC", ""));
} catch (Exception exc)
{
System.out.println(exc);
}

// Step 3: Convert the TemporalAccessor to a LocalDateTime object
LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);

// Step 4: Convert the LocalDateTime to the local timezone
LocalDateTime localDateTimeInLocalTimeZone = localDateTime
.atZone(ZoneId.of("UTC"))
.withZoneSameInstant(ZoneId.systemDefault())
.toLocalDateTime();

// Step 5: Convert the LocalDateTime to a Date object
Date date = Date.from(localDateTimeInLocalTimeZone.atZone(ZoneId.systemDefault()).toInstant());


return date;
}

// Method to format Date object to string in UTC
public static String formatDateToString(Date date) {
// Define the DateTimeFormatter with the pattern
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

// Convert the Date object to LocalDateTime
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

// Convert the LocalDateTime to UTC time zone
LocalDateTime localDateTimeInUtc = localDateTime.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime();

// Format the LocalDateTime to string
return formatter.format(localDateTimeInUtc);
}

// Parse log line using specified pattern
public static void parseLogLine (String logLine)
{
Map<String, Object> parsedValues = new HashMap<String, Object>();

for (LogPattern pattern : LogPattern.values())
{
Pattern regexPattern = Pattern.compile(pattern.getRegex());
Matcher matcher = regexPattern.matcher(logLine);
if (matcher.find())
{
String fullMatch = matcher.group(0);
String match = matcher.group(pattern.getMatchGroup());
System.out.println(pattern.name() + " group: " + match);
// parsedValues.put(pattern.toString(), match);
switch (pattern.getPatternClass().getSimpleName()) {
case "Date":
parsedValues.put(pattern.toString(), parseDate(match));
logLine = logLine.replaceFirst(fullMatch, "").trim();
break;
default:
parsedValues.put(pattern.toString(), match);
if(logLine.length() == fullMatch.length())
break;

logLine = logLine.replaceFirst(fullMatch, "").trim();
break;
}
}
}

System.out.println("Done");
}

public static Map<String, Object> parseLogLineFull (String logLine) {
logLine = logLine.trim();
Map<String, Object> parsedValues = new HashMap<>();

StringBuilder combinedRegexBuilder = new StringBuilder();
combinedRegexBuilder.append(LogPattern.DATE.getRegex());
combinedRegexBuilder.append(LogPattern.SERVER.getRegex());
combinedRegexBuilder.append(LogPattern.CHANNEL.getRegex());
combinedRegexBuilder.append(LogPattern.USER.getRegex());
combinedRegexBuilder.append(LogPattern.MESSAGE.getRegex());
String combinedRegex = combinedRegexBuilder.toString();

Pattern regexPattern = Pattern.compile(combinedRegex);
Matcher matcher = regexPattern.matcher(logLine);
while (matcher.find()) {
for (LogPattern pattern : LogPattern.values()) {
if (matcher.group(pattern.toString()) != null) {
String match = matcher.group(pattern.getMatchGroup());
switch (pattern.getPatternClass().getSimpleName()) {
case "Date":
parsedValues.put(pattern.toString(), parseDate(match));
break;
default:
parsedValues.put(pattern.toString(), match);
break;
}
}
}
}

return parsedValues;
}
}
Loading
Loading