M3U parser works, done some unit tests

This commit is contained in:
mykola2312 2024-04-20 14:33:02 +03:00
parent fbec61ffa5
commit 2c8a181b1c
3 changed files with 134 additions and 45 deletions

View file

@ -1,64 +1,39 @@
package com.mykola2312.mptv.parser;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.checkerframework.checker.nullness.qual.NonNull;
import com.mykola2312.mptv.parser.M3UException.Type;
public class M3U {
public class Item {
@NonNull
public String title;
@NonNull
public String title;
public String groupTitle;
public String tvgLogo;
public String groupTitle;
public String tvgLogo;
@NonNull
public String url;
@NonNull
public String url;
public M3U(String tags, String title) {
parseTags(tags);
this.title = title;
}
public ArrayList<Item> items = new ArrayList<>();
private static final Pattern EXTINF_TAG = Pattern.compile("^(.*)=\"(.*)\"");
public M3U(ArrayList<Item> items) {
this.items = items;
}
private void parseTags(String tags) {
for (String tag : tags.split(" ")) {
Matcher matcher = EXTINF_TAG.matcher(tag);
if (matcher.find()) {
String name = matcher.group(1);
String value = matcher.group(2);
private static final Pattern HEADER = Pattern.compile("^#EXTM3U");
private static final Pattern EXTINF = Pattern.compile("^(?:#EXTINF:-?\\d\\s*)(.*?),(.*)$");
public static M3U parse(String data) throws M3UException {
ArrayList<Item> items = new ArrayList<>();
// state
boolean headerLine = true;
try (Scanner scanner = new Scanner(data)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (headerLine) {
Matcher matcher = HEADER.matcher(line);
if (!matcher.find()) {
throw new M3UException(Type.NOT_AN_M3U);
}
headerLine = false;
} else {
Matcher matcher = EXTINF.matcher(line);
if (matcher.find()) {
String tags = matcher.group(1);
String title = matcher.group(2);
System.out.printf("tags: %s | title: %s\n", tags, title);
}
switch (name) {
case "group-title" -> groupTitle = value;
case "tvg-logo" -> tvgLogo = value;
}
}
}
return new M3U(items);
}
}

View file

@ -0,0 +1,66 @@
package com.mykola2312.mptv.parser;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.mykola2312.mptv.parser.M3UException.Type;
public class M3UParser {
private static final Pattern HEADER = Pattern.compile("^#EXTM3U");
private static final Pattern EXTINF = Pattern.compile("^(?:#EXTINF:-?\\d\\s*)(.*?),(.*)$");
private enum ParserState {
HEADER_LINE,
EXTINF_LINE,
URL_LINE
}
public static ArrayList<M3U> parse(String data) throws M3UException {
ArrayList<M3U> items = new ArrayList<>();
ParserState state = ParserState.HEADER_LINE;
M3U item = null;
try (Scanner scanner = new Scanner(data)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
switch (state) {
case HEADER_LINE -> {
Matcher matcher = HEADER.matcher(line);
if (!matcher.find()) {
throw new M3UException(Type.NOT_AN_M3U);
}
state = ParserState.EXTINF_LINE;
}
case EXTINF_LINE -> {
Matcher matcher = EXTINF.matcher(line);
if (matcher.find()) {
String tags = matcher.group(1);
String title = matcher.group(2);
item = new M3U(tags, title);
state = ParserState.URL_LINE;
}
}
case URL_LINE -> {
String url = line;
item.url = url;
items.add(item);
state = ParserState.EXTINF_LINE;
}
}
}
}
return items;
}
}

View file

@ -0,0 +1,48 @@
package com.mykola2312.mptv;
import static org.junit.jupiter.api.Assertions.*;
import java.util.ArrayList;
import org.junit.jupiter.api.Test;
import com.mykola2312.mptv.parser.M3U;
import com.mykola2312.mptv.parser.M3UException;
import com.mykola2312.mptv.parser.M3UParser;
public class TestM3U {
private static final String M3U_GOOD = """
#EXTM3U
#EXTINF:-1 group-title="test1" tvg-logo="https://example.com/logo.jpg",Test title 1
http://example.org/video1.m3u8
#EXTINF:-1 group-title="test2" ,Test title 2
http://example.org/video2.m3u8
""";
@Test
public void testM3uGood() {
ArrayList<M3U> items = M3UParser.parse(M3U_GOOD);
assertNotEquals(0, items.size());
M3U item = items.get(0);
assertEquals("Test title 1", item.title);
assertEquals("test1", item.groupTitle);
assertEquals("http://example.org/video1.m3u8", item.url);
assertEquals("https://example.com/logo.jpg", item.tvgLogo);
item = items.get(1);
assertEquals("Test title 2", item.title);
assertEquals("test2", item.groupTitle);
assertEquals("http://example.org/video2.m3u8", item.url);
assertNull(item.tvgLogo);
}
@Test
public void testM3uBad() {
assertThrows(M3UException.class, () -> M3UParser.parse("some random gibberish data"));
ArrayList<M3U> items = M3UParser.parse("#EXTM3U");
assertEquals(0, items.size());
}
}