Skip to content

Commit

Permalink
Add group (#EXTGRP) support for playlist entries
Browse files Browse the repository at this point in the history
  • Loading branch information
kirill-gr committed Apr 3, 2019
1 parent 7016006 commit 8428946
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 12 deletions.
20 changes: 14 additions & 6 deletions src/main/antlr/M3uLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,28 @@ CHANNEL_START: EXTINF;
NUMBER: '-'? DIGIT+;
SAFE_STRING: SAFE_CHAR+;
QUOTED_STRING: QUOTE (SAFE_CHAR | NUMBER | COLON | EQUALS | SPACES | COMMA)+ QUOTE;
COMMA: ',' -> pushMode(FREE_TEXT);
COMMA: ',' -> pushMode(CHANNEL_DESC);
COLON: ':';
EQUALS: '=';

mode FREE_TEXT;
mode CHANNEL_DESC;

FREE_TEXT_NEWLINE: NEWLINES -> skip;
FREE_TEXT_CHANNEL_START: EXTINF -> popMode;
FREE_TEXT_TEXT: FREE_TEXT_SAFE_CHAR+;
CHANNEL_DESC_NEWLINE: NEWLINES -> skip;
CHANNEL_DESC_TEXT: CHANNEL_DESC_SAFE_CHAR+;
CHANNEL_DESC_GROUP: '#EXTGRP' -> pushMode(CHANNEL_GROUP);
CHANNEL_DESC_CHANNEL_START: EXTINF -> popMode;

mode CHANNEL_GROUP;

CHANNEL_GROUP_COLON: ':';
CHANNEL_GROUP_TEXT: CHANNEL_GROUP_SAFE_CHAR+;
CHANNEL_GROUP_NEWLINE: NEWLINES -> popMode, skip;

fragment NEWLINES: ('\r\n' | '\r' | '\n');
fragment EXTINF: '#EXTINF';
fragment QUOTE: '"';
fragment SPACES: [ \t];
fragment DIGIT: [0-9];
fragment SAFE_CHAR: ~[":= \t,\r\n];
fragment FREE_TEXT_SAFE_CHAR: ~[#\r\n];
fragment CHANNEL_DESC_SAFE_CHAR: ~[#\r\n];
fragment CHANNEL_GROUP_SAFE_CHAR: ~[:\r\n];
9 changes: 5 additions & 4 deletions src/main/antlr/M3uParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ options { tokenVocab=M3uLexer; }
file: file_header entries;
file_header: FILE_START parameters;
entries: entry_info+;
entry_info: (CHANNEL_START | FREE_TEXT_CHANNEL_START) COLON length parameters COMMA enrty_basic_info;
entry_info: (CHANNEL_START | CHANNEL_DESC_CHANNEL_START) COLON length parameters COMMA enrty_basic_info;
length: NUMBER;
enrty_basic_info: entry_name entry_uri;
entry_name: FREE_TEXT_TEXT;
entry_uri: FREE_TEXT_TEXT;
enrty_basic_info: entry_name (CHANNEL_DESC_GROUP CHANNEL_GROUP_COLON group_name)? entry_uri;
entry_name: CHANNEL_DESC_TEXT;
group_name: CHANNEL_GROUP_TEXT;
entry_uri: CHANNEL_DESC_TEXT;
parameters: parameter*;
parameter: key EQUALS value;
key: SAFE_STRING;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class DefaultM3uParser(input: String) : M3uParserWrapper {
parsedEntry.enrty_basic_info().entry_name().text.trim(),
parsedEntry.enrty_basic_info().entry_uri().text.trim(),
parsedEntry.length().text.toInt(),
parsedEntry.enrty_basic_info().group_name().text.trim(),
createParameterMap(parsedEntry.parameters().parameter())
)
}
Expand Down
1 change: 1 addition & 0 deletions src/main/kotlin/ru/grushetsky/m3uparser/PlaylistEntry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ data class PlaylistEntry(
val name: String,
val path: String,
val length: Int,
val group: String,
val parameters: Map<String, String>
)
13 changes: 11 additions & 2 deletions src/test/kotlin/ru/grushetsky/m3uparser/M3uParserTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.junit.jupiter.params.provider.ValueSource
class M3uParserTest {

companion object {
const val FREE_TEXT_MODE = 1
const val CHANNEL_DESC_MODE = 1
}

private fun getParser(input: String, initMode: Int = 0): M3uParser {
Expand Down Expand Up @@ -48,7 +48,7 @@ class M3uParserTest {
"\"quoted name\"\nfoo"
])
fun `entry basic info parsed correctly`(entryBasicInfo: String) {
val entryNameParser = getParser(entryBasicInfo, FREE_TEXT_MODE).enrty_basic_info()
val entryNameParser = getParser(entryBasicInfo, CHANNEL_DESC_MODE).enrty_basic_info()
val (entryName, entryUri) = entryBasicInfo.split("\n")

assertThat(entryNameParser.entry_name().text).isEqualTo(entryName)
Expand All @@ -65,6 +65,15 @@ class M3uParserTest {
assertThat(entryParser.length().text).isEqualTo("-1")
}

@Test
fun `entry group parsed correctly`() {
val entryParser = getParser(getResourceAsString("/entry_with_group.txt")).entry_info()

assertThat(entryParser.enrty_basic_info().entry_name().text).isEqualTo("Some channel")
assertThat(entryParser.enrty_basic_info().group_name().text).isEqualTo("Some group")
assertThat(entryParser.enrty_basic_info().entry_uri().text).isEqualTo("http://1.2.3.4:1234/udp/4.3.2.1:5678")
}

@ParameterizedTest
@CsvSource(
"header_example.txt, 5",
Expand Down
3 changes: 3 additions & 0 deletions src/test/resources/entry_with_group.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#EXTINF:-1 tvg-name="Some_channel",Some channel
#EXTGRP:Some group
http://1.2.3.4:1234/udp/4.3.2.1:5678

0 comments on commit 8428946

Please sign in to comment.