Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for deviceType detection inluding tests
- Loading branch information
1 parent
7d1c47b
commit 706c211
Showing
6 changed files
with
215 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,30 @@ | ||
package uaparser | ||
var ( | ||
iPad = &itemSpec{ | ||
name: "iPad", | ||
mustContains: []string{"iPad"}, | ||
} | ||
|
||
iPhone = &itemSpec{ | ||
name: "iPhone", | ||
mustContains: []string{"iPhone"}, | ||
} | ||
var ( | ||
iPad = &itemSpec{ | ||
name: "iPad", | ||
mustContains: []string{"iPad"}, | ||
} | ||
|
||
iPod = &itemSpec{ | ||
name: "iPod", | ||
mustContains: []string{"iPod"}, | ||
} | ||
iPhone = &itemSpec{ | ||
name: "iPhone", | ||
mustContains: []string{"iPhone"}, | ||
} | ||
|
||
mac = &itemSpec{ | ||
name: "Macintosh", | ||
mustContains: []string{"Macintosh"}, | ||
} | ||
iPod = &itemSpec{ | ||
name: "iPod", | ||
mustContains: []string{"iPod"}, | ||
} | ||
|
||
pc = &itemSpec{ | ||
name: "PC", | ||
mustContains: []string{"Windows", "Linux"}, | ||
mustNotContains: []string{"Windows Phone", "Android"}, | ||
} | ||
mac = &itemSpec{ | ||
name: "Macintosh", | ||
mustContains: []string{"Macintosh"}, | ||
} | ||
|
||
_DEVICES = []*itemSpec { | ||
iPad, | ||
iPhone, | ||
iPod, | ||
mac, | ||
pc, | ||
} | ||
_DEVICES = []*itemSpec{ | ||
iPad, | ||
iPhone, | ||
iPod, | ||
mac, | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package uaparser | ||
|
||
var ( | ||
desktop = &itemSpec{ | ||
name: "Desktop", | ||
mustContains: []string{"Windows", "Linux"}, | ||
mustNotContains: []string{"Windows Phone", "Android", "ARM"}, | ||
} | ||
|
||
tablet = &itemSpec{ | ||
name: "Tablet", | ||
mustContains: []string{"iPad", "Android", "Windows NT"}, | ||
mustNotContains: []string{ | ||
"Mobile ", | ||
"C6802", // Xperia Z Android (which is a phone) does not include Mobile in UA-string so without this is seen as a tablet | ||
}, | ||
} | ||
|
||
phone = &itemSpec{ | ||
name: "Phone", | ||
mustContains: []string{ | ||
"iPhone", | ||
"Android", | ||
"Windows Phone", | ||
}, | ||
mustNotContains: []string{}, | ||
} | ||
|
||
car = &itemSpec{ | ||
name: "Car", | ||
mustContains: []string{ | ||
"QtCarBrowser", | ||
}, | ||
mustNotContains: []string{}, | ||
} | ||
|
||
smartTv = &itemSpec{ | ||
name: "SmartTV", | ||
mustContains: []string{ | ||
"SMART-TV", | ||
"AppleTV", | ||
"CrKey", | ||
"Large Screen", | ||
"HbbTV", | ||
"LG Browser", | ||
"PhilipsTV", | ||
"Opera TV", | ||
}, | ||
mustNotContains: []string{}, | ||
} | ||
|
||
_DEVICETYPES = []*itemSpec{ | ||
tablet, | ||
phone, | ||
car, | ||
smartTv, | ||
desktop, | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,88 @@ | ||
package uaparser | ||
|
||
import ( | ||
"strings" | ||
"unicode" | ||
"strings" | ||
"unicode" | ||
) | ||
|
||
type itemSpec struct { | ||
name string | ||
mustContains []string | ||
mustNotContains []string | ||
versionSplitters [][]string | ||
name string | ||
mustContains []string | ||
mustNotContains []string | ||
versionSplitters [][]string | ||
} | ||
|
||
type InfoItem struct { | ||
Name string | ||
Version string | ||
Name string | ||
Version string | ||
} | ||
|
||
type UAInfo struct { | ||
Browser, | ||
Device, | ||
OS *InfoItem | ||
Browser, | ||
Device, | ||
DeviceType, | ||
OS *InfoItem | ||
} | ||
|
||
func isEmptyString(str string) bool { | ||
for _, char := range str { | ||
if !unicode.IsSpace(char) { | ||
return false | ||
} | ||
} | ||
return true | ||
for _, char := range str { | ||
if !unicode.IsSpace(char) { | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
|
||
func contains(ua string, tokens []string) bool { | ||
for _, tk := range tokens { | ||
if strings.Contains(ua, tk) { | ||
return true | ||
} | ||
} | ||
return false | ||
for _, tk := range tokens { | ||
if strings.Contains(ua, tk) { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func matchSpec(ua string, spec *itemSpec) (info *InfoItem, ok bool) { | ||
if !contains(ua, spec.mustContains) { return } | ||
if contains(ua, spec.mustNotContains) { return } | ||
if !contains(ua, spec.mustContains) { | ||
return | ||
} | ||
if contains(ua, spec.mustNotContains) { | ||
return | ||
} | ||
|
||
info = new(InfoItem) | ||
info.Name = spec.name | ||
ok = true | ||
info = new(InfoItem) | ||
info.Name = spec.name | ||
ok = true | ||
|
||
for _, splitter := range spec.versionSplitters { | ||
if strings.Contains(ua, splitter[0]) { | ||
if rmLeft := strings.Split(ua, splitter[0])[1]; | ||
strings.Contains(rmLeft, splitter[1]) || isEmptyString(splitter[1]) { | ||
rmRight := strings.Split(rmLeft, splitter[1])[0] | ||
info.Version = strings.TrimSpace(rmRight) | ||
break | ||
} | ||
} | ||
} | ||
return | ||
for _, splitter := range spec.versionSplitters { | ||
if strings.Contains(ua, splitter[0]) { | ||
if rmLeft := strings.Split(ua, splitter[0])[1]; strings.Contains(rmLeft, splitter[1]) || isEmptyString(splitter[1]) { | ||
rmRight := strings.Split(rmLeft, splitter[1])[0] | ||
info.Version = strings.TrimSpace(rmRight) | ||
break | ||
} | ||
} | ||
} | ||
return | ||
} | ||
|
||
func searchIn(ua string, specs []*itemSpec) (info *InfoItem) { | ||
for _, spec := range specs { | ||
if result, ok := matchSpec(ua, spec); ok { | ||
info = result | ||
break | ||
} | ||
} | ||
return | ||
for _, spec := range specs { | ||
if result, ok := matchSpec(ua, spec); ok { | ||
info = result | ||
break | ||
} | ||
} | ||
return | ||
} | ||
|
||
func Parse(ua string) (info *UAInfo) { | ||
info = new(UAInfo) | ||
info = new(UAInfo) | ||
|
||
info.Browser = searchIn(ua, _BROWSERS) | ||
info.Device = searchIn(ua, _DEVICES) | ||
info.OS = searchIn(ua, _OS) | ||
info.Browser = searchIn(ua, _BROWSERS) | ||
info.Device = searchIn(ua, _DEVICES) | ||
info.DeviceType = searchIn(ua, _DEVICETYPES) | ||
info.OS = searchIn(ua, _OS) | ||
|
||
return | ||
return | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters