Skip to content

Commit

Permalink
Merge pull request satoshi-takano#23 from mt-hodaka/feature/property-…
Browse files Browse the repository at this point in the history
…then-content

Parse OGP also When other attributes are included in the meta tag.
  • Loading branch information
satoshi-takano authored Jan 15, 2017
2 parents 1240a41 + 4f9bb0e commit 24e9986
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 24 deletions.
10 changes: 10 additions & 0 deletions OpenGraph.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
6A7310FF1E279D5D00CE1756 /* example3.com.html in Resources */ = {isa = PBXBuildFile; fileRef = 6A7310FB1E279C7E00CE1756 /* example3.com.html */; };
6A7311001E279D5D00CE1756 /* example2.com.html in Resources */ = {isa = PBXBuildFile; fileRef = 6A7310FC1E279C7E00CE1756 /* example2.com.html */; };
7B24FB191D3B2583005275B0 /* OpenGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B24FB181D3B2583005275B0 /* OpenGraph.h */; settings = {ATTRIBUTES = (Public, ); }; };
7B24FB201D3B2583005275B0 /* OpenGraph.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B24FB151D3B2583005275B0 /* OpenGraph.framework */; };
7B24FB3E1D3B26C4005275B0 /* OpenGraphTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B24FB3D1D3B26C4005275B0 /* OpenGraphTests.swift */; };
Expand All @@ -29,6 +31,8 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
6A7310FB1E279C7E00CE1756 /* example3.com.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = example3.com.html; sourceTree = "<group>"; };
6A7310FC1E279C7E00CE1756 /* example2.com.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = example2.com.html; sourceTree = "<group>"; };
7B24FB151D3B2583005275B0 /* OpenGraph.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OpenGraph.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7B24FB181D3B2583005275B0 /* OpenGraph.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OpenGraph.h; sourceTree = "<group>"; };
7B24FB1A1D3B2583005275B0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -98,6 +102,8 @@
isa = PBXGroup;
children = (
7B24FB521D3B2DD4005275B0 /* example.com.html */,
6A7310FC1E279C7E00CE1756 /* example2.com.html */,
6A7310FB1E279C7E00CE1756 /* example3.com.html */,
7B24FB261D3B2583005275B0 /* Info.plist */,
7B24FB3D1D3B26C4005275B0 /* OpenGraphTests.swift */,
);
Expand Down Expand Up @@ -199,13 +205,17 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6A7310FD1E279C7E00CE1756 /* example3.com.html in Resources */,
6A7310FE1E279C7E00CE1756 /* example2.com.html in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
7B24FB1D1D3B2583005275B0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6A7310FF1E279D5D00CE1756 /* example3.com.html in Resources */,
6A7311001E279D5D00CE1756 /* example2.com.html in Resources */,
7B24FB531D3B2DD4005275B0 /* example.com.html in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
45 changes: 21 additions & 24 deletions OpenGraph/OpenGraphParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,35 @@ public protocol OpenGraphParser {
extension OpenGraphParser {
func parse(htmlString: String) -> [OpenGraphMetadata: String] {
// matching
let pattern1 = "<meta\\s+property=\"og:(\\w+)\"\\s+content=\"([^<>]*)\"\\s*?/*?>.*?"
let pattern2 = "<meta\\s+content=\"([^<>]*)\"\\s+property=\"og:(\\w+)\"\\s*?/*?>.*?"
let pattern = "\(pattern1)|\(pattern2)"
let regexp = try! NSRegularExpression(pattern: pattern, options: [.dotMatchesLineSeparators])
let matches = regexp.matches(in: htmlString, options: [], range: NSMakeRange(0, htmlString.characters.count))
if matches.isEmpty {
let pattern1 = "<meta\\s.*?property=\"og:(\\w+?)\".*?/?>"
let pattern2 = "content=\"([^<>]*?)\""
let regexp1 = try! NSRegularExpression(pattern: pattern1, options: [.dotMatchesLineSeparators])
let regexp2 = try! NSRegularExpression(pattern: pattern2, options: [.dotMatchesLineSeparators])
let matches1 = regexp1.matches(in: htmlString,
options: [],
range: NSMakeRange(0, htmlString.characters.count))
if matches1.isEmpty {
return [:]
}

// create attribute dictionary
let nsString = htmlString as NSString
let attributes = matches.reduce([OpenGraphMetadata: String]()) { (attributes, result) -> [OpenGraphMetadata: String] in
let attributes = matches1.reduce([OpenGraphMetadata: String]()) { (attributes, result) -> [OpenGraphMetadata: String] in
var copiedAttributes = attributes
var property: String?
var content: String?
let property = nsString.substring(with: result.rangeAt(1))
let content = { () -> String in
let metaTag = nsString.substring(with: result.rangeAt(0))
let matches2 = regexp2.matches(in: metaTag,
options: [],
range: NSMakeRange(0, metaTag.characters.count))
guard let result = matches2.first else { return "" }
return (metaTag as NSString).substring(with: result.rangeAt(1))
}()

if result.rangeAt(1).length > 0 && result.rangeAt(2).length > 0 {
property = nsString.substring(with: result.rangeAt(1))
content = nsString.substring(with: result.rangeAt(2))
guard let metadata = OpenGraphMetadata(rawValue: property) else {
return copiedAttributes
}

if result.rangeAt(3).length > 0 && result.rangeAt(4).length > 0 {
property = nsString.substring(with: result.rangeAt(4))
content = nsString.substring(with: result.rangeAt(3))
}

if let property = property, let content = content {
if let property = OpenGraphMetadata(rawValue: property) {
copiedAttributes[property] = content
}
}

copiedAttributes[metadata] = content
return copiedAttributes
}

Expand Down
60 changes: 60 additions & 0 deletions Tests/OpenGraphTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,66 @@ class OpenGraphTests: XCTestCase {
}
}

// Detect og:xxx also when order of attributes are reversed.
func testFetching2() {
let responseArrived = expectation(description: "response of async request has arrived")

OHHTTPStubs.stubRequests(passingTest: { request -> Bool in
return true
}) { request -> OHHTTPStubsResponse in
let path = Bundle(for: type(of: self)).path(forResource: "example2.com", ofType: "html")
return OHHTTPStubsResponse(fileAtPath: path!, statusCode: 200, headers: nil)
}

let url = URL(string: "https://www.example2.com")!
var og: OpenGraph!
var error: Error?
OpenGraph.fetch(url: url) { _og, _error in
og = _og
error = _error
responseArrived.fulfill()
}

waitForExpectations(timeout: 10) { _ in
XCTAssert(og[.title] == "example2.com title")
XCTAssert(og[.type] == "website2")
XCTAssert(og[.url] == "https://www.example2.com")
XCTAssert(og[.image] == "https://www.example2.com/images/example2.png")

XCTAssert(error == nil)
}
}

// When the meta tag contains other attributes.
func testFetching3() {
let responseArrived = expectation(description: "response of async request has arrived")

OHHTTPStubs.stubRequests(passingTest: { request -> Bool in
return true
}) { request -> OHHTTPStubsResponse in
let path = Bundle(for: type(of: self)).path(forResource: "example3.com", ofType: "html")
return OHHTTPStubsResponse(fileAtPath: path!, statusCode: 200, headers: nil)
}

let url = URL(string: "https://www.example3.com")!
var og: OpenGraph!
var error: Error?
OpenGraph.fetch(url: url) { _og, _error in
og = _og
error = _error
responseArrived.fulfill()
}

waitForExpectations(timeout: 10) { _ in
XCTAssert(og[.title] == "example3.com title")
XCTAssert(og[.type] == "website3")
XCTAssert(og[.url] == "https://www.example3.com")
XCTAssert(og[.image] == "https://www.example3.com/images/example3.png")

XCTAssert(error == nil)
}
}

func testHTTPResponseError() {
let responseArrived = expectation(description: "response of async request has arrived")

Expand Down
12 changes: 12 additions & 0 deletions Tests/example2.com.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html>
<head>
<meta content="example2.com title" property="og:title" />
<meta content="website2" property="og:type" />
<meta content="https://www.example2.com" property="og:url" />
<meta content="https://www.example2.com/images/example2.png" property="og:image" />
<meta content="example2.com description" property="og:description" />
</head>
<body>
<p>Hello, world.</p>
</body>
</html>
12 changes: 12 additions & 0 deletions Tests/example3.com.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html>
<head>
<meta property="og:title" content="example3.com title" id="og-title"/>
<meta content="website3" id="og-type" property="og:type" />
<meta id="og-url" property="og:url" content="https://www.example3.com" />
<meta property="og:image" id="og-image" content="https://www.example3.com/images/example3.png" />
<meta content="example3.com description" id="og-description" property="og:description"/>
</head>
<body>
<p>Hello, world.</p>
</body>
</html>

0 comments on commit 24e9986

Please sign in to comment.