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

Support parsing for m3u and m3u8 files #187

Merged
merged 5 commits into from
Jan 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ and [dimensions,](https://github.com/sstephenson/dimensions) borrowing from them
* DOCX, PPTX, XLSX
* OGG
* MPEG, MPG
* M3U

...with [more](https://github.com/WeTransfer/format_parser/issues?q=is%3Aissue+is%3Aopen+label%3Aformats) on the way!

Expand Down Expand Up @@ -194,6 +195,9 @@ Unless specified otherwise in this section the fixture files are MIT licensed an
manipulated using the [https://github.com/recurser/exif-orientation-examples](exif-orientation-examples)
script.

### M3U
- The M3U fixture files were created by one of the project maintainers

### .key
- The `keynote_recognized_as_jpeg.key` file was created by the project maintainers

Expand Down
1 change: 1 addition & 0 deletions lib/format_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module FormatParser
require_relative 'io_constraint'
require_relative 'care'
require_relative 'active_storage/blob_analyzer'
require_relative 'text'

# Define Measurometer in the internal namespace as well
# so that we stay compatible for the applications that use it
Expand Down
21 changes: 21 additions & 0 deletions lib/parsers/m3u_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class FormatParser::M3UParser
include FormatParser::IOUtils

HEADER = '#EXTM3U'

def likely_match?(filename)
filename =~ /\.m3u8?$/i
end

def call(io)
io = FormatParser::IOConstraint.new(io)

header = safe_read(io, 7)
return unless HEADER.eql?(header)

FormatParser::Text.new(
format: :m3u
)
end
FormatParser.register_parser new, natures: :text, formats: :m3u
end
18 changes: 18 additions & 0 deletions lib/text.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module FormatParser
class Text
include FormatParser::AttributesJSON

NATURE = :text

attr_accessor :format

# Only permits assignments via defined accessors
def initialize(**attributes)
attributes.map { |(k, v)| public_send("#{k}=", v) }
end

def nature
NATURE
end
end
end
2 changes: 2 additions & 0 deletions spec/fixtures/M3U/plain_text.m3u
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
C:\My Music\Artist\Year\1.Test.mp3
C:\My Music\Artist\Year\10.Test.mp3
5 changes: 5 additions & 0 deletions spec/fixtures/M3U/sample.m3u
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#EXTM3U
#EXTINF:170,Artist - 1
C:\My Music\Artist\Year\1.Test.mp3
#EXTINF:3,Artist - 10
C:\My Music\Artist\Year\10.Test.mp3
5 changes: 5 additions & 0 deletions spec/fixtures/M3U/sample.m3u8
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#EXTM3U
#EXTINF:170,Artist - 1
C:\My Music\Artist\Year\1.Test.mp3
#EXTINF:3,Artist - 10
C:\My Music\Artist\Year\10.Test.mp3
40 changes: 40 additions & 0 deletions spec/parsers/m3u_parser_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'spec_helper'

describe FormatParser::M3UParser do
let(:parsed_m3u) do
subject.call(
File.open(
Pathname.new(fixtures_dir).join('M3U').join(m3u_file),
'rb'
)
)
end

describe 'an m3u file with missing header' do
let(:m3u_file) { 'plain_text.m3u' }

it 'does not parse the file successfully' do
expect(parsed_m3u).to be_nil
end
end

describe 'an m3u file with valid header' do
let(:m3u_file) { 'sample.m3u' }

it 'parses the file successfully' do
expect(parsed_m3u).not_to be_nil
expect(parsed_m3u.nature).to eq(:text)
expect(parsed_m3u.format).to eq(:m3u)
end
end

describe 'an m3u8 file with valid header' do
let(:m3u_file) { 'sample.m3u8' }

it 'parses the file successfully' do
expect(parsed_m3u).not_to be_nil
expect(parsed_m3u.nature).to eq(:text)
expect(parsed_m3u.format).to eq(:m3u)
end
end
end