Skip to content

Commit

Permalink
Merge pull request #13 from ExpandingMan/0p6update
Browse files Browse the repository at this point in the history
update for 0.6
  • Loading branch information
randyzwitch committed Dec 4, 2017
2 parents fa82eae + 20b51b0 commit 13073b8
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 79 deletions.
154 changes: 77 additions & 77 deletions src/UAParser.jl
Expand Up @@ -10,7 +10,7 @@ export parsedevice, parseuseragent, parseos, DeviceResult, OSResult, UAResult, D
##
##############################################################################

using YAML, DataFrames, Nulls
using YAML, DataFrames, Missings
import DataFrames.DataFrame, DataFrames.names!

##############################################################################
Expand All @@ -28,46 +28,46 @@ const REGEXES = YAML.load(open(joinpath(dirname(@__FILE__), "..", "regexes.yaml"
##############################################################################

# helper function used by constructors
_check_null_string(s::AbstractString) = String(s)
_check_null_string(::Null) = null
_check_null_string(::Void) = null
_check_null_string(x) = ArgumentError("Invalid string or null passed: $x")
_check_missing_string(s::AbstractString) = String(s)
_check_missing_string(::Missing) = missing
_check_missing_string(::Void) = missing
_check_missing_string(x) = ArgumentError("Invalid string or missing passed: $x")

struct UserAgentParser
user_agent_re::Regex
family_replacement::Union{String, Null}
v1_replacement::Union{String, Null}
v2_replacement::Union{String, Null}
family_replacement::Union{String, Missing}
v1_replacement::Union{String, Missing}
v2_replacement::Union{String, Missing}

function UserAgentParser(user_agent_re::Regex, family_replacement, v1_replacement,
v2_replacement)
new(user_agent_re, _check_null_string(family_replacement),
_check_null_string(v1_replacement), _check_null_string(v2_replacement))
new(user_agent_re, _check_missing_string(family_replacement),
_check_missing_string(v1_replacement), _check_missing_string(v2_replacement))
end
end

struct OSParser
user_agent_re::Regex
os_replacement::Union{String, Null}
os_v1_replacement::Union{String, Null}
os_v2_replacement::Union{String, Null}
os_replacement::Union{String, Missing}
os_v1_replacement::Union{String, Missing}
os_v2_replacement::Union{String, Missing}

function OSParser(user_agent_re::Regex, os_replacement, os_v1_replacement, os_v2_replacement)
new(user_agent_re, _check_null_string(os_replacement), _check_null_string(os_v1_replacement),
_check_null_string(os_v2_replacement))
new(user_agent_re, _check_missing_string(os_replacement), _check_missing_string(os_v1_replacement),
_check_missing_string(os_v2_replacement))
end
end

struct DeviceParser
user_agent_re::Regex
device_replacement::Union{String, Null}
brand_replacement::Union{String, Null}
model_replacement::Union{String, Null}
device_replacement::Union{String, Missing}
brand_replacement::Union{String, Missing}
model_replacement::Union{String, Missing}

function DeviceParser(user_agent_re::Regex, device_replacement, brand_replacement,
model_replacement)
new(user_agent_re, _check_null_string(device_replacement),
_check_null_string(brand_replacement), _check_null_string(model_replacement))
new(user_agent_re, _check_missing_string(device_replacement),
_check_missing_string(brand_replacement), _check_missing_string(model_replacement))
end
end

Expand All @@ -79,36 +79,36 @@ end

struct DeviceResult
family::String
brand::Union{String, Null}
model::Union{String, Null}
brand::Union{String, Missing}
model::Union{String, Missing}

function DeviceResult(family::AbstractString, brand, model)
new(string(family), _check_null_string(brand), _check_null_string(model))
new(string(family), _check_missing_string(brand), _check_missing_string(model))
end
end

struct UAResult
family::String
major::Union{String, Null}
minor::Union{String, Null}
patch::Union{String, Null}
major::Union{String, Missing}
minor::Union{String, Missing}
patch::Union{String, Missing}

function UAResult(family::AbstractString, major, minor, patch)
new(string(family), _check_null_string(major), _check_null_string(minor),
_check_null_string(patch))
new(string(family), _check_missing_string(major), _check_missing_string(minor),
_check_missing_string(patch))
end
end

struct OSResult
family::String
major::Union{String, Null}
minor::Union{String, Null}
patch::Union{String, Null}
patch_minor::Union{String, Null}
major::Union{String, Missing}
minor::Union{String, Missing}
patch::Union{String, Missing}
patch_minor::Union{String, Missing}

function OSResult(family::AbstractString, major, minor, patch, patch_minor)
new(string(family), _check_null_string(major), _check_null_string(minor),
_check_null_string(patch), _check_null_string(patch_minor))
new(string(family), _check_missing_string(major), _check_missing_string(minor),
_check_missing_string(patch), _check_missing_string(patch_minor))
end
end

Expand All @@ -125,9 +125,9 @@ function loadua()
#Loop over entire set of user_agent_parsers, add to USER_AGENT_PARSERS
for _ua_parser in REGEXES["user_agent_parsers"]
_user_agent_re = Regex(_ua_parser["regex"])
_family_replacement = get(_ua_parser, "family_replacement", null)
_v1_replacement = get(_ua_parser, "v1_replacement", null)
_v2_replacement = get(_ua_parser, "v2_replacement", null)
_family_replacement = get(_ua_parser, "family_replacement", missing)
_v1_replacement = get(_ua_parser, "v1_replacement", missing)
_v2_replacement = get(_ua_parser, "v2_replacement", missing)

#Add values to array
push!(temp, UserAgentParser(_user_agent_re,
Expand All @@ -148,9 +148,9 @@ function loados()
#Loop over entire set of os_parsers, add to OS_PARSERS
for _os_parser in REGEXES["os_parsers"]
_user_agent_re = Regex(_os_parser["regex"])
_os_replacement = get(_os_parser, "os_replacement", null)
_os_v1_replacement = get(_os_parser, "os_v1_replacement", null)
_os_v2_replacement = get(_os_parser, "os_v2_replacement", null)
_os_replacement = get(_os_parser, "os_replacement", missing)
_os_v1_replacement = get(_os_parser, "os_v1_replacement", missing)
_os_v2_replacement = get(_os_parser, "os_v2_replacement", missing)

#Add values to array
push!(temp, OSParser(_user_agent_re,
Expand All @@ -172,9 +172,9 @@ function loaddevice()
#Loop over entire set of device_parsers, add to DEVICE_PARSERS
for _device_parser in REGEXES["device_parsers"]
_user_agent_re = Regex(_device_parser["regex"])
_device_replacement = get(_device_parser, "device_replacement", null)
_brand_replacement = get(_device_parser, "brand_replacement", null)
_model_replacement = get(_device_parser, "model_replacement", null)
_device_replacement = get(_device_parser, "device_replacement", missing)
_brand_replacement = get(_device_parser, "brand_replacement", missing)
_model_replacement = get(_device_parser, "model_replacement", missing)

#Add values to array
push!(temp, DeviceParser(_user_agent_re, _device_replacement, _brand_replacement,
Expand Down Expand Up @@ -206,7 +206,7 @@ end
function _multireplace(str::AbstractString, mtch::RegexMatch)
_str = replace(str, r"\$(\d)", m -> _inner_replace(m, mtch.captures))
_str = replace(_str, r"^\s+|\s+$", "")
length(_str) == 0 ? null : _str
length(_str) == 0 ? missing : _str
end


Expand All @@ -218,36 +218,36 @@ function parsedevice(user_agent_string::AbstractString)
_match = match(value.user_agent_re, user_agent_string)

# family
if !isnull(value.device_replacement)
if !ismissing(value.device_replacement)
device = _multireplace(value.device_replacement, _match)
else
device = _match.captures[1]
end

# brand
if !isnull(value.brand_replacement)
if !ismissing(value.brand_replacement)
brand = _multireplace(value.brand_replacement, _match)
elseif length(_match.captures) > 1
brand = match_vals[2]
else
brand = null
brand = missing
end

# model
if !isnull(value.model_replacement)
if !ismissing(value.model_replacement)
model = _multireplace(value.model_replacement, _match)
elseif length(_match.captures) > 2
model = match_vals[3]
else
model = null
model = missing
end

return DeviceResult(device, brand, model)
end
end
DeviceResult("Other",null,null) #Fail-safe for no match
DeviceResult("Other",missing,missing) #Fail-safe for no match
end # parsedevice
parsedevice(::Null) = null
parsedevice(::Missing) = missing


function parseuseragent(user_agent_string::AbstractString)
Expand All @@ -257,7 +257,7 @@ function parseuseragent(user_agent_string::AbstractString)
match_vals = match(value.user_agent_re, user_agent_string).captures

#family
if !isnull(value.family_replacement)
if !ismissing(value.family_replacement)
if ismatch(r"\$1", value.family_replacement)
family = replace(value.family_replacement, "\$1", match_vals[1])
else
Expand All @@ -268,38 +268,38 @@ function parseuseragent(user_agent_string::AbstractString)
end

#major
if !isnull(value.v1_replacement)
if !ismissing(value.v1_replacement)
v1 = value.v1_replacement
elseif length(match_vals) > 1
v1 = match_vals[2]
else
v1 = null
v1 = missing
end

#minor
if !isnull(value.v2_replacement)
if !ismissing(value.v2_replacement)
v2 = value.v2_replacement
elseif length(match_vals) > 2
v2 = match_vals[3]
else
v2 = null
v2 = missing
end

#patch
if length(match_vals) > 3
v3 = match_vals[4]
else
v3 = null
v3 = missing
end

return UAResult(family, v1, v2, v3)

end
end

return UAResult("Other", null, null, null) #Fail-safe for no match
return UAResult("Other", missing, missing, missing) #Fail-safe for no match
end #End parseuseragent
parseuseragent(::Null) = null
parseuseragent(::Missing) = missing


function parseos(user_agent_string::AbstractString)
Expand All @@ -308,52 +308,52 @@ function parseos(user_agent_string::AbstractString)
match_vals = match(value.user_agent_re, user_agent_string).captures

#os
if !isnull(value.os_replacement)
if !ismissing(value.os_replacement)
os = value.os_replacement
else
os = match_vals[1]
end

#os_v1
if !isnull(value.os_v1_replacement)
if !ismissing(value.os_v1_replacement)
os_v1 = value.os_v1_replacement
elseif length(match_vals) > 1
os_v1 = match_vals[2]
else
os_v1 = null
os_v1 = missing
end

#os_v2
if !isnull(value.os_v2_replacement)
if !ismissing(value.os_v2_replacement)
os_v2 = value.os_v2_replacement
elseif length(match_vals) > 2
os_v2 = match_vals[3]
else
os_v2 = null
os_v2 = missing
end

#os_v3
if length(match_vals) > 3
os_v3 = match_vals[4]
else
os_v3 = null
os_v3 = missing
end

#os_v4
if length(match_vals) > 4
os_v4 = match_vals[5]
else
os_v4 = null
os_v4 = missing
end

return OSResult(os, os_v1, os_v2, os_v3, os_v4)

end
end

return OSResult("Other", null, null, null, null) #Fail-safe if no match
return OSResult("Other", missing, missing, missing, missing) #Fail-safe if no match
end #End parseos
parseos(::Null) = null
parseos(::Missing) = missing


##############################################################################
Expand All @@ -368,9 +368,9 @@ function DataFrame(x::AbstractVector{DeviceResult})

temp["device"] = String[element.family for element in x]

temp["brand"] = Union{String,Null}[element.brand for element in x]
temp["brand"] = Union{String,Missing}[element.brand for element in x]

temp["model"] = Union{String,Null}[element.model for element in x]
temp["model"] = Union{String,Missing}[element.model for element in x]

temp
end
Expand All @@ -383,16 +383,16 @@ function DataFrame(x::AbstractVector{OSResult})
temp["os_family"] = String[element.family for element in x]

#Major
temp["os_major"] = Union{String,Null}[element.major for element in x]
temp["os_major"] = Union{String,Missing}[element.major for element in x]

#Minor
temp["os_minor"] = Union{String,Null}[element.minor for element in x]
temp["os_minor"] = Union{String,Missing}[element.minor for element in x]

#Patch
temp["os_patch"] = Union{String,Null}[element.patch for element in x]
temp["os_patch"] = Union{String,Missing}[element.patch for element in x]

#Patch_Minor
temp["os_patch_minor"] = Union{String,Null}[element.patch_minor for element in x]
temp["os_patch_minor"] = Union{String,Missing}[element.patch_minor for element in x]

temp
end
Expand All @@ -406,13 +406,13 @@ function DataFrame(x::AbstractVector{UAResult})
temp["browser_family"] = String[element.family for element in x]

#Major
temp["browser_major"] = Union{String,Null}[element.major for element in x]
temp["browser_major"] = Union{String,Missing}[element.major for element in x]

#Minor
temp["browser_minor"] = Union{String,Null}[element.minor for element in x]
temp["browser_minor"] = Union{String,Missing}[element.minor for element in x]

#Patch
temp["browser_patch"] = Union{String,Null}[element.patch for element in x]
temp["browser_patch"] = Union{String,Missing}[element.patch for element in x]

temp
end
Expand Down
4 changes: 2 additions & 2 deletions test/runtests.jl
@@ -1,4 +1,4 @@
using UAParser, YAML, Base.Test
using UAParser, YAML, Missings, Base.Test

#These user-agents look to be older, may not still be out in wild

Expand All @@ -8,7 +8,7 @@ macro testparseval(obj::Symbol, valname::String, outputname::Symbol)
valsymb = Symbol(valname)
esc(quote
if $obj[$valname] == nothing
@test isnull($outputname.$valsymb)
@test ismissing($outputname.$valsymb)
else
@test $obj[$valname] == $outputname.$valsymb
end
Expand Down

0 comments on commit 13073b8

Please sign in to comment.