Add IsVideo to types/camtypes FileInfo

It is based on MIME type then falls back to extension.

Change-Id: I71d80ec7cdcf94f4fa7feffa8186943abe0279ce
This commit is contained in:
Antonin Amand 2014-09-16 00:06:37 +02:00
parent 5fe955c061
commit 31ebc20ba7
2 changed files with 94 additions and 0 deletions

View File

@ -19,6 +19,7 @@ package camtypes
import (
"bytes"
"fmt"
"path/filepath"
"strings"
"time"
@ -111,6 +112,57 @@ func (fi *FileInfo) IsImage() bool {
return strings.HasPrefix(fi.MIMEType, "image/")
}
var videoExtensions = map[string]bool{
"3gp": true,
"avi": true,
"flv": true,
"m1v": true,
"m2v": true,
"m4v": true,
"mkv": true,
"mov": true,
"mp4": true,
"mpeg": true,
"mpg": true,
"ogv": true,
"wmv": true,
}
func (fi *FileInfo) IsVideo() bool {
if strings.HasPrefix(fi.MIMEType, "video/") {
return true
}
var ext string
if e := filepath.Ext(fi.FileName); strings.HasPrefix(e, ".") {
ext = e[1:]
} else {
return false
}
// Case-insensitive lookup.
// Optimistically assume a short ASCII extension and be
// allocation-free in that case.
var buf [10]byte
lower := buf[:0]
const utf8RuneSelf = 0x80 // from utf8 package, but not importing it.
for i := 0; i < len(ext); i++ {
c := ext[i]
if c >= utf8RuneSelf {
// Slow path.
return videoExtensions[strings.ToLower(ext)]
}
if 'A' <= c && c <= 'Z' {
lower = append(lower, c+('a'-'A'))
} else {
lower = append(lower, c)
}
}
// The conversion from []byte to string doesn't allocate in
// a map lookup.
return videoExtensions[string(lower)]
}
// ImageInfo describes an image file.
//
// The Width and Height are uint16s to save memory in index/corpus.go, and that's

View File

@ -0,0 +1,42 @@
/*
Copyright 2014 The Camlistore Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package camtypes
import "testing"
var fileInfoVideoTable = []struct {
fi *FileInfo
video bool
}{
{&FileInfo{FileName: "some.mp4", MIMEType: "application/octet-stream"}, true},
{&FileInfo{FileName: "IMG_1231.MOV", MIMEType: "application/octet-stream"}, true},
{&FileInfo{FileName: "movie.mkv", MIMEType: "application/octet-stream"}, true},
{&FileInfo{FileName: "movie.məv", MIMEType: "application/octet-stream"}, false},
{&FileInfo{FileName: "tape", MIMEType: "video/webm"}, true},
{&FileInfo{FileName: "tape", MIMEType: "application/ogg"}, false},
{&FileInfo{FileName: "IMG_12312.jpg", MIMEType: "application/octet-stream"}, false},
{&FileInfo{FileName: "IMG_12312.jpg", MIMEType: "image/jpeg"}, false},
}
func TestIsVideo(t *testing.T) {
for _, example := range fileInfoVideoTable {
if example.fi.IsVideo() != example.video {
t.Errorf("IsVideo failed video=%t filename=%s mimetype=%s",
example.video, example.fi.FileName, example.fi.MIMEType)
}
}
}