sg_node_mapper 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +39 -0
- data/Rakefile +2 -0
- data/lib/sg_node_mapper.rb +57 -0
- data/lib/sg_node_mapper/version.rb +3 -0
- data/sg_node_mapper.gemspec +20 -0
- data/spec/sg_node_mapper_spec.rb +8 -0
- data/spec/spec_helper.rb +13 -0
- data/vendor/sg_node_mapper/LICENSE +12 -0
- data/vendor/sg_node_mapper/nodemapper.js +1862 -0
- metadata +109 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Chris Mytton
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# SgNodeMapper
|
2
|
+
|
3
|
+
Lightweight ruby wrapper around the Social Graph Node Mapper [javascript
|
4
|
+
library](https://github.com/webjay/sgNodeMapper).
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'sg_node_mapper'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install sg_node_mapper
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
This library simply delegates to the javascript library, so you can call
|
23
|
+
any methods defined in there (see `vendor/sg_node_mapper/nodemapper.js` for more details.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
SgNodeMapper.url_to_graph_node('http://twitter.com/hecticjeff')
|
27
|
+
# => "sgn://twitter.com/?ident=hecticjeff"
|
28
|
+
|
29
|
+
SgNodeMapper.parse_sgn_url('sgn://twitter.com/?ident=hecticjeff')
|
30
|
+
# => {"domain"=>"twitter.com", "keyName"=>"ident", "value"=>"hecticjeff"}
|
31
|
+
```
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# Core
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
# Gems
|
5
|
+
require 'execjs'
|
6
|
+
require 'active_support/core_ext'
|
7
|
+
|
8
|
+
# Internal
|
9
|
+
require 'sg_node_mapper/version'
|
10
|
+
|
11
|
+
# Simple wrapper for the sgNodeMapper javascript library. Uses
|
12
|
+
# [ExecJS](https://github.com/sstephenson/execjs) to dynamically select the best
|
13
|
+
# available javascript platform to execute the code on.
|
14
|
+
#
|
15
|
+
# This class will dynamically call methods in the sgNodeMapper javascript
|
16
|
+
# library. In the case that the the method doesn't exist, it will return nil,
|
17
|
+
# rather than raising a NoMethodError, this is a side effect of blindly
|
18
|
+
# delegating to javascript.
|
19
|
+
class SgNodeMapper
|
20
|
+
include Singleton
|
21
|
+
|
22
|
+
# When a method is called on this class, we intercept it and pass it through
|
23
|
+
# to the javascript context by converting the method name from underscore_case
|
24
|
+
# to camelCase, then calling that method on the javascript context with the
|
25
|
+
# given *args.
|
26
|
+
#
|
27
|
+
# method - The Symbol name of the method being called.
|
28
|
+
# args - The Array of arguments (optional).
|
29
|
+
#
|
30
|
+
# Returns the result from javascript.
|
31
|
+
def self.method_missing(method, *args)
|
32
|
+
instance.context.call("nodemapper.#{method.to_s.camelize(:lower)}", *args)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get a (potentially cached) version of the compiled source code for sgNodeMapper.
|
36
|
+
#
|
37
|
+
# Returns an ExecJS::ExternalRuntime::Context.
|
38
|
+
def context
|
39
|
+
@context ||= ExecJS.compile(source)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# Get a (potentially cached) string of the sgNodeMapper source code.
|
45
|
+
#
|
46
|
+
# Returns the String javascript source code.
|
47
|
+
def source
|
48
|
+
@source ||= File.read(source_path)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get the full path to the sgNodeMapper.js source code.
|
52
|
+
#
|
53
|
+
# Returns the String path to sgNodeMapper.
|
54
|
+
def source_path
|
55
|
+
File.join(File.expand_path('../../', __FILE__), 'vendor', 'sg_node_mapper', 'nodemapper.js')
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/sg_node_mapper/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Chris Mytton"]
|
6
|
+
gem.email = ["self@hecticjeff.net"]
|
7
|
+
gem.description = %q{Map social networking sites' URLs to and from a canonical form.}
|
8
|
+
gem.summary = %q{The Social Graph Node Mapper is a community project to build a portable library to map social networking sites' URLs to and from a canonical form (sgn:// URLs).}
|
9
|
+
gem.homepage = "https://github.com/hecticjeff/sg_node_mapper"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "sg_node_mapper"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = SgNodeMapper::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'execjs', '>= 1.4'
|
19
|
+
gem.add_dependency 'activesupport', '>= 3.0'
|
20
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
require 'sg_node_mapper'
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
11
|
+
config.run_all_when_everything_filtered = true
|
12
|
+
config.filter_run :focus
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
+
you may not use this file except in compliance with the License.
|
3
|
+
You may obtain a copy of the License at
|
4
|
+
|
5
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
|
7
|
+
Unless required by applicable law or agreed to in writing, software
|
8
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
See the License for the specific language governing permissions and
|
11
|
+
limitations under the License.
|
12
|
+
|
@@ -0,0 +1,1862 @@
|
|
1
|
+
//############################################################
|
2
|
+
// AUTO-GENERATED FILE; DO NOT EDIT. This is a concatenantion
|
3
|
+
// of nodemapper-base.js, and sites/*.js. Edit those.
|
4
|
+
//#############################################################
|
5
|
+
// -*-java-*-
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Copyright 2007 Google Inc.
|
9
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
10
|
+
* you may not use this file except in compliance with the License.
|
11
|
+
* You may obtain a copy of the License at
|
12
|
+
*
|
13
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
14
|
+
*
|
15
|
+
* Unless required by applicable law or agreed to in writing, software
|
16
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
17
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
18
|
+
* See the License for the specific language governing permissions and
|
19
|
+
* limitations under the License.
|
20
|
+
*/
|
21
|
+
nodemapper = {};
|
22
|
+
nodemapper.IDENT_REGEXP = /^\w*[a-zA-Z]+\w*$/;
|
23
|
+
nodemapper.PK_REGEXP = /^\d+$/;
|
24
|
+
nodemapper.pkRegexp = function(handler) {
|
25
|
+
return handler.pkRegexp ? handler.pkRegexp : nodemapper.PK_REGEXP;
|
26
|
+
};
|
27
|
+
nodemapper.identRegexp = function(handler) {
|
28
|
+
return handler.identRegexp ? handler.identRegexp : nodemapper.IDENT_REGEXP;
|
29
|
+
};
|
30
|
+
nodemapper.handlers = {};
|
31
|
+
nodemapper.registerDomain = function(domain, handler) {
|
32
|
+
if (!handler.identRegexp) {
|
33
|
+
handler.identRegexp = nodemapper.IDENT_REGEXP;
|
34
|
+
}
|
35
|
+
if (!handler.pkRegexp) {
|
36
|
+
handler.pkRegexp = nodemapper.PK_REGEXP;
|
37
|
+
}
|
38
|
+
if (domain instanceof Array) {
|
39
|
+
for (var i = 0; i < domain.length; i++) {
|
40
|
+
nodemapper.handlers[domain[i]] = handler;
|
41
|
+
}
|
42
|
+
} else {
|
43
|
+
nodemapper.handlers[domain] = handler;
|
44
|
+
}
|
45
|
+
};
|
46
|
+
nodemapper.addSimpleHandler = function(domain, handlerName,
|
47
|
+
prefix, suffix) {
|
48
|
+
var handlers = nodemapper.handlers[domain];
|
49
|
+
if (!handlers) {
|
50
|
+
handlers = nodemapper.handlers[domain] = {};
|
51
|
+
}
|
52
|
+
if (!suffix) { suffix = ""; }
|
53
|
+
var sgnType;
|
54
|
+
var m;
|
55
|
+
if (m = /^(ident|pk)_to_/.exec(handlerName)) {
|
56
|
+
sgnType = m[1];
|
57
|
+
}
|
58
|
+
if (!handlers.sgnToHttpPatterns) {
|
59
|
+
handlers.sgnToHttpPatterns = [];
|
60
|
+
}
|
61
|
+
handlers.sgnToHttpPatterns.push([prefix, suffix, sgnType]);
|
62
|
+
handlers[handlerName] = function (pk_or_ident) {
|
63
|
+
return prefix + pk_or_ident + suffix;
|
64
|
+
};
|
65
|
+
};
|
66
|
+
nodemapper.HTTP_REGEX = new RegExp("^(https?)://([^/]+)(.*)");
|
67
|
+
nodemapper.urlToGraphNode = function(url) {
|
68
|
+
var m = nodemapper.HTTP_REGEX.exec(url);
|
69
|
+
if (!m) {
|
70
|
+
return nodemapper.urlToGraphNodeNotHTTP(url);
|
71
|
+
}
|
72
|
+
var scheme = m[1];
|
73
|
+
var host = m[2].toLowerCase();
|
74
|
+
var path = m[3];
|
75
|
+
var hostparts = host.split(".");
|
76
|
+
var handler;
|
77
|
+
var matchedDomain; // the domain that matched tightest
|
78
|
+
for (var i = 0; i < hostparts.length; ++i) {
|
79
|
+
var subhost = hostparts.slice(i, hostparts.length);
|
80
|
+
matchedDomain = subhost.join(".");
|
81
|
+
handler = nodemapper.handlers[matchedDomain];
|
82
|
+
if (!handler) continue;
|
83
|
+
var graphNode;
|
84
|
+
if (scheme == "https" && !handler.httpsLikeHttp) {
|
85
|
+
graphNode = nodemapper.urlToGraphNodeNotHTTP(url);
|
86
|
+
}
|
87
|
+
if (handler.urlToGraphNode) {
|
88
|
+
graphNode = handler.urlToGraphNode(url, host, path);
|
89
|
+
}
|
90
|
+
if ((!graphNode || graphNode == url) && !handler.skipAutomaticHttpToSgn) {
|
91
|
+
graphNode = nodemapper.sgnFromHttpUsingToHttpRules(matchedDomain, url);
|
92
|
+
}
|
93
|
+
if (!graphNode || graphNode == url) {
|
94
|
+
continue;
|
95
|
+
}
|
96
|
+
return graphNode;
|
97
|
+
}
|
98
|
+
return url;
|
99
|
+
};
|
100
|
+
nodemapper.pairToGraphNode = function (host, account) {
|
101
|
+
if (!account) {
|
102
|
+
return;
|
103
|
+
}
|
104
|
+
if (account.substr(0, 4) == "http") {
|
105
|
+
var sgn = nodemapper.urlToGraphNode(account);
|
106
|
+
if (sgn && sgn.length >= 3 && sgn.substr(0, 3) == "sgn") {
|
107
|
+
return sgn;
|
108
|
+
}
|
109
|
+
return;
|
110
|
+
}
|
111
|
+
if (!host) {
|
112
|
+
return;
|
113
|
+
}
|
114
|
+
var domain = nodemapper.parseDomain(host);
|
115
|
+
if (!domain) {
|
116
|
+
return;
|
117
|
+
}
|
118
|
+
var accountToSgn = {};
|
119
|
+
var handler;
|
120
|
+
handler = nodemapper.lookupHandlerWithProperty(domain, "accountToSgn");
|
121
|
+
if (handler) {
|
122
|
+
accountToSgn = handler.accountToSgn;
|
123
|
+
} else {
|
124
|
+
handler = nodemapper.lookupHandlerWithProperty(domain, "pkRegexp");
|
125
|
+
if (handler) {
|
126
|
+
accountToSgn.pk = [handler._registeredOnDomain, handler.pkRegexp];
|
127
|
+
}
|
128
|
+
handler = nodemapper.lookupHandlerWithProperty(domain, "identRegexp");
|
129
|
+
if (handler) {
|
130
|
+
accountToSgn.ident = [handler._registeredOnDomain, handler.identRegexp];
|
131
|
+
}
|
132
|
+
}
|
133
|
+
if (accountToSgn.pk) {
|
134
|
+
var sgnDomain = accountToSgn.pk[0];
|
135
|
+
var sgnRegexp = accountToSgn.pk[1] || /^\d+$/;
|
136
|
+
var m;
|
137
|
+
if (m = sgnRegexp.exec(account)) {
|
138
|
+
if (m[1]) {
|
139
|
+
return "sgn://" + sgnDomain + "/?pk=" + m[1];
|
140
|
+
} else {
|
141
|
+
return "sgn://" + sgnDomain + "/?pk=" + account;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
}
|
145
|
+
if (accountToSgn.ident) {
|
146
|
+
var sgnDomain = accountToSgn.ident[0];
|
147
|
+
var sgnRegexp = accountToSgn.ident[1] || /^\w+$/;
|
148
|
+
if (sgnRegexp.exec(account)) {
|
149
|
+
if (nodemapper.lookupHandlerWithProperty(host, "identCasePreserve")) {
|
150
|
+
} else {
|
151
|
+
account = account.toLowerCase();
|
152
|
+
}
|
153
|
+
return "sgn://" + sgnDomain + "/?ident=" + account;
|
154
|
+
}
|
155
|
+
}
|
156
|
+
return;
|
157
|
+
};
|
158
|
+
nodemapper.lookupHandlerWithProperty = function (host, property) {
|
159
|
+
return nodemapper.lookupHandler(host, function (h) {
|
160
|
+
if (h[property]) {
|
161
|
+
return h;
|
162
|
+
}
|
163
|
+
return;
|
164
|
+
});
|
165
|
+
};
|
166
|
+
nodemapper.lookupHandler_unittest = function (host, property) {
|
167
|
+
var handler = nodemapper.lookupHandlerWithProperty(host, property);
|
168
|
+
if (handler) {
|
169
|
+
return handler._name_for_testing;
|
170
|
+
}
|
171
|
+
return;
|
172
|
+
}
|
173
|
+
nodemapper.lookupHandler = function (host, filterFunc) {
|
174
|
+
var hostparts = host.split(".");
|
175
|
+
var handler;
|
176
|
+
var matchedDomain; // the domain that matched tightest
|
177
|
+
for (var i = 0; i < hostparts.length; ++i) {
|
178
|
+
var subhost = hostparts.slice(i, hostparts.length);
|
179
|
+
matchedDomain = subhost.join(".");
|
180
|
+
handler = nodemapper.handlers[matchedDomain];
|
181
|
+
if (!handler) continue;
|
182
|
+
if (filterFunc(handler)) {
|
183
|
+
handler._registeredOnDomain = matchedDomain;
|
184
|
+
return handler;
|
185
|
+
}
|
186
|
+
}
|
187
|
+
return;
|
188
|
+
};
|
189
|
+
nodemapper.DOMAIN_RE = /^(?:\w+:\/{0,2})?([^:\/]*?)(?:[:\/]|$)/;
|
190
|
+
nodemapper.parseDomain = function (arg) {
|
191
|
+
var m;
|
192
|
+
if ((m = nodemapper.DOMAIN_RE.exec(arg)) && m[1].length > 0) {
|
193
|
+
return m[1];
|
194
|
+
}
|
195
|
+
return;
|
196
|
+
};
|
197
|
+
nodemapper.sgnFromHttpUsingToHttpRules = function(domain, url) {
|
198
|
+
var handler = nodemapper.handlers[domain];
|
199
|
+
if (!handler || !handler.sgnToHttpPatterns) {
|
200
|
+
return;
|
201
|
+
}
|
202
|
+
var m;
|
203
|
+
var matches = [];
|
204
|
+
for (var i = 0; i < handler.sgnToHttpPatterns.length; i++) {
|
205
|
+
var pattern = handler.sgnToHttpPatterns[i];
|
206
|
+
var prefix = pattern[0];
|
207
|
+
var suffix = pattern[1];
|
208
|
+
var type = pattern[2];
|
209
|
+
if (url.substr(0, prefix.length) == prefix &&
|
210
|
+
url.substr(url.length - suffix.length, suffix.length) == suffix) {
|
211
|
+
var midLength = url.length - prefix.length - suffix.length;
|
212
|
+
if (midLength >= 1) {
|
213
|
+
var match = url.substr(prefix.length, midLength);
|
214
|
+
if (type == "pk" &&
|
215
|
+
(m = nodemapper.pkRegexp(handler).exec(match))) {
|
216
|
+
matches.push("sgn://" + domain + "/?pk=" + match);
|
217
|
+
} else if (type == "ident" &&
|
218
|
+
(m = nodemapper.identRegexp(handler).exec(match))) {
|
219
|
+
if (! handler.caseSensitiveIdent) {
|
220
|
+
match = match.toLowerCase();
|
221
|
+
}
|
222
|
+
if (!(match == "www" ||
|
223
|
+
(handler.notUsernames && handler.notUsernames[match]))) {
|
224
|
+
matches.push("sgn://" + domain + "/?ident=" + match);
|
225
|
+
}
|
226
|
+
}
|
227
|
+
}
|
228
|
+
}
|
229
|
+
}
|
230
|
+
if (matches.length == 1) {
|
231
|
+
return matches[0];
|
232
|
+
} else {
|
233
|
+
debug("More/less than 1 match for " + url + ". Potential matches: [" + matches + "]");
|
234
|
+
}
|
235
|
+
return;
|
236
|
+
};
|
237
|
+
nodemapper.SGN_REGEX = new RegExp("^sgn://([^/]+)/\\?(ident|pk)=(.*)");
|
238
|
+
nodemapper.parseSgnUrl = function(sgnUrl) {
|
239
|
+
var m = nodemapper.SGN_REGEX.exec(sgnUrl);
|
240
|
+
if (!m) return null;
|
241
|
+
return {
|
242
|
+
"domain": m[1],
|
243
|
+
"keyName": m[2],
|
244
|
+
"value": m[3]
|
245
|
+
};
|
246
|
+
}
|
247
|
+
nodemapper.urlFromGraphNode = function(sgnUrl, type) {
|
248
|
+
var node = nodemapper.parseSgnUrl(sgnUrl);
|
249
|
+
if (!node) {
|
250
|
+
return;
|
251
|
+
}
|
252
|
+
var handler = nodemapper.handlers[node.domain];
|
253
|
+
if (!handler) {
|
254
|
+
return;
|
255
|
+
}
|
256
|
+
var attrName = node.keyName + "_to_" + type;
|
257
|
+
var toFunc = handler[attrName];
|
258
|
+
if (!toFunc) {
|
259
|
+
return;
|
260
|
+
}
|
261
|
+
return toFunc(node.value);
|
262
|
+
};
|
263
|
+
nodemapper.nonHTTPHandlers = [];
|
264
|
+
nodemapper.registerNonHTTPHandler = function(handler) {
|
265
|
+
nodemapper.nonHTTPHandlers.push(handler);
|
266
|
+
};
|
267
|
+
nodemapper.urlToGraphNodeNotHTTP = function(url) {
|
268
|
+
for (var i=0; i < nodemapper.nonHTTPHandlers.length; ++i) {
|
269
|
+
var ident = nodemapper.nonHTTPHandlers[i](url);
|
270
|
+
if (ident) return ident;
|
271
|
+
}
|
272
|
+
return url;
|
273
|
+
};
|
274
|
+
nodemapper.createPathRegexpHandler = function(domain, re, opt_opts) {
|
275
|
+
if (!opt_opts) opt_opts = {};
|
276
|
+
return function(url, host, path) {
|
277
|
+
if (opt_opts.pathTransform) {
|
278
|
+
path = opt_opts.pathTransform(path);
|
279
|
+
}
|
280
|
+
var m = re.exec(path);
|
281
|
+
if (!m) {
|
282
|
+
return opt_opts.fallbackHandler ?
|
283
|
+
opt_opts.fallbackHandler(url, host, path) :
|
284
|
+
url;
|
285
|
+
}
|
286
|
+
var keyName = opt_opts.keyName || 'ident'; // ident= or pk=; TODO: enforce valid key names?
|
287
|
+
var value = (opt_opts.casePreserve ? m[1] : m[1].toLowerCase());
|
288
|
+
if (opt_opts.notUsernames && opt_opts.notUsernames[value]) {
|
289
|
+
return opt_opts.fallbackHandler ?
|
290
|
+
opt_opts.fallbackHandler(url, host, path) :
|
291
|
+
url;
|
292
|
+
}
|
293
|
+
return "sgn://" + domain + "/?" + keyName + "=" + value;
|
294
|
+
};
|
295
|
+
};
|
296
|
+
nodemapper.createHostRegexpHandler = function(domain, re, opt_opts) {
|
297
|
+
if (!opt_opts) opt_opts = {};
|
298
|
+
return function(url, host, path) {
|
299
|
+
var m = re.exec(host);
|
300
|
+
var ident = m ? m[1].toLowerCase() : "";
|
301
|
+
if (!m || ident == "www") {
|
302
|
+
return opt_opts.fallbackHandler ?
|
303
|
+
opt_opts.fallbackHandler(url, host, path) :
|
304
|
+
url;
|
305
|
+
}
|
306
|
+
return "sgn://" + domain + "/?ident=" + ident;
|
307
|
+
};
|
308
|
+
};
|
309
|
+
nodemapper.createSlashUsernameHandler = function(domain, opt_opts) {
|
310
|
+
var slashUsernameRE = /^\/(\w+)\/?$/;
|
311
|
+
if (opt_opts && opt_opts.slashAnything) {
|
312
|
+
slashUsernameRE = /^\/(\w+)(?:\/|$)/;
|
313
|
+
}
|
314
|
+
return nodemapper.createPathRegexpHandler(domain, slashUsernameRE, opt_opts);
|
315
|
+
};
|
316
|
+
nodemapper.createSomethingSlashUsernameHandler = function(prefix,
|
317
|
+
domain,
|
318
|
+
opt_opts) {
|
319
|
+
var slashSomethingUserRE = new RegExp("^/" + prefix + "/" +
|
320
|
+
"(\\w+)(?:/|$)");
|
321
|
+
return nodemapper.createPathRegexpHandler(domain,
|
322
|
+
slashSomethingUserRE,
|
323
|
+
opt_opts);
|
324
|
+
};
|
325
|
+
nodemapper.createUserIsSubdomainHandler = function(domain) {
|
326
|
+
var subdomainRE = new RegExp("([\\w\\-]+)\." + domain + "$", "i");
|
327
|
+
return nodemapper.createHostRegexpHandler(domain, subdomainRE);
|
328
|
+
};
|
329
|
+
nodemapper.createFirstMatchHandler = function(handlerList) {
|
330
|
+
return function (url, host, path) {
|
331
|
+
for (var i = 0; i < handlerList.length; i++) {
|
332
|
+
var out = handlerList[i](url, host, path);
|
333
|
+
if (out != url) {
|
334
|
+
return out;
|
335
|
+
}
|
336
|
+
}
|
337
|
+
return url; // unchanged
|
338
|
+
};
|
339
|
+
};
|
340
|
+
nodemapper.namedSites = function() {
|
341
|
+
if (nodemapper._memoizedNamedSites) {
|
342
|
+
return nodemapper._memoizedNamedSites;
|
343
|
+
}
|
344
|
+
var ret = [];
|
345
|
+
for (var domain in nodemapper.handlers) {
|
346
|
+
var handler = nodemapper.handlers[domain];
|
347
|
+
if (handler.name) {
|
348
|
+
if (handler.primaryDomain && handler.primaryDomain != domain) {
|
349
|
+
continue;
|
350
|
+
}
|
351
|
+
var canGenerateFeedUrl = false;
|
352
|
+
if (handler.ident_to_atom || handler.ident_to_rss
|
353
|
+
|| handler.pk_to_atom || handler.pk_to_rss) {
|
354
|
+
canGenerateFeedUrl = true;
|
355
|
+
}
|
356
|
+
ret.push({
|
357
|
+
domain: domain,
|
358
|
+
name: handler.name,
|
359
|
+
notMassMarketSite: nodemapper.handlers[domain].notMassMarketSite,
|
360
|
+
canGenerateFeedUrl: canGenerateFeedUrl
|
361
|
+
});
|
362
|
+
}
|
363
|
+
}
|
364
|
+
ret.sort(function(a, b) {
|
365
|
+
if (a.name.toLowerCase() < b.name.toLowerCase()) return -1;
|
366
|
+
if (a.name.toLowerCase() > b.name.toLowerCase()) return 1;
|
367
|
+
return 0;
|
368
|
+
});
|
369
|
+
nodemapper._memoizedNamedSites = ret;
|
370
|
+
return ret;
|
371
|
+
}
|
372
|
+
nodemapper.namedSitesCount = function() {
|
373
|
+
return nodemapper.namedSites().length;
|
374
|
+
}
|
375
|
+
nodemapper.namedSiteProperty = function(n, property) {
|
376
|
+
return nodemapper.namedSites()[n][property];
|
377
|
+
}
|
378
|
+
/* install null debug handler, if host container hasn't */
|
379
|
+
try {
|
380
|
+
if (debug) { }
|
381
|
+
} catch (e) {
|
382
|
+
debug = function() {};
|
383
|
+
}
|
384
|
+
(function(){
|
385
|
+
var amazonPkHandler = nodemapper.createFirstMatchHandler([
|
386
|
+
nodemapper.createSomethingSlashUsernameHandler(
|
387
|
+
"gp/pdp/profile", "amazon.com",
|
388
|
+
{keyName: "pk", casePreserve: 1}),
|
389
|
+
nodemapper.createSomethingSlashUsernameHandler(
|
390
|
+
"rss/people", "amazon.com",
|
391
|
+
{keyName: "pk", casePreserve: 1})]);
|
392
|
+
nodemapper.registerDomain("amazon.com", {
|
393
|
+
accountToSgn: { pk: ["amazon.com", /^\w{14,14}$/] },
|
394
|
+
urlToGraphNode: amazonPkHandler,
|
395
|
+
name: "Amazon.com"
|
396
|
+
});
|
397
|
+
nodemapper.registerDomain("amazon.co.uk", {
|
398
|
+
urlToGraphNode: amazonPkHandler
|
399
|
+
});
|
400
|
+
nodemapper.addSimpleHandler("amazon.com", "pk_to_profile",
|
401
|
+
"http://www.amazon.com/gp/pdp/profile/");
|
402
|
+
nodemapper.addSimpleHandler("amazon.com", "pk_to_rss",
|
403
|
+
"http://www.amazon.com/rss/people/", "/reviews");
|
404
|
+
})();
|
405
|
+
(function(){
|
406
|
+
var AIM_REGEX = /^aim:(?:goim\?(?:message=[^&\s]+&)?screenname=)?([%\w \+]+)$/i;
|
407
|
+
nodemapper.registerNonHTTPHandler(function(url) {
|
408
|
+
var m = AIM_REGEX.exec(url);
|
409
|
+
if (m) {
|
410
|
+
var screenname = m[1].toLowerCase().replace(/(?:[\s\+]|%20)/g, "");
|
411
|
+
return "sgn://aol.com/?ident=" + screenname;
|
412
|
+
}
|
413
|
+
});
|
414
|
+
nodemapper.registerDomain(["openid.aol.com", "profiles.aim.com"], {
|
415
|
+
urlToGraphNode: nodemapper.createSlashUsernameHandler("aol.com")
|
416
|
+
});
|
417
|
+
var aimPagesHandler = function(url, host, path) {
|
418
|
+
var slashProfile = /^\/{1,2}([\w\+]+)(?:\/(?:profile\.html)?|$)/;
|
419
|
+
var m;
|
420
|
+
if (!(m = slashProfile.exec(path)))
|
421
|
+
return url;
|
422
|
+
return "sgn://aol.com/?ident=" + m[1].toLowerCase().replace(/[\s\+]/g, "");
|
423
|
+
};
|
424
|
+
nodemapper.registerDomain(
|
425
|
+
"aimpages.com",
|
426
|
+
{urlToGraphNode: aimPagesHandler});
|
427
|
+
nodemapper.registerDomain(
|
428
|
+
"aol.com",
|
429
|
+
{
|
430
|
+
name: "AIM/AOL",
|
431
|
+
identRegexp: /^\w+$/,
|
432
|
+
ident_to_openid: function (ident) { return "http://openid.aol.com/" + ident; },
|
433
|
+
ident_to_chat: function (ident) { return "aim:GoIM?screenname=" + ident; },
|
434
|
+
ident_to_profile: function (ident) {
|
435
|
+
return "http://profiles.aim.com/" + ident;
|
436
|
+
}
|
437
|
+
});
|
438
|
+
nodemapper.registerDomain("pictures.aol.com",
|
439
|
+
{name: "AOL Pictures",
|
440
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler("galleries",
|
441
|
+
"pictures.aol.com")});
|
442
|
+
nodemapper.addSimpleHandler("pictures.aol.com", "ident_to_profile",
|
443
|
+
"http://pictures.aol.com/galleries/");
|
444
|
+
nodemapper.addSimpleHandler("pictures.aol.com", "ident_to_atom",
|
445
|
+
"http://pictures.aol.com/galleries/", "/atom.xml");
|
446
|
+
})();
|
447
|
+
(function(){
|
448
|
+
var BLOGSPOT_REGEX = /^(?:www\.)?([\w\-]+)\.blogspot\.com$/;
|
449
|
+
nodemapper.registerDomain("blogspot.com", {
|
450
|
+
name: "Blogger (Blogspot)",
|
451
|
+
urlToGraphNode: nodemapper.createHostRegexpHandler("blogspot.com",
|
452
|
+
BLOGSPOT_REGEX)
|
453
|
+
});
|
454
|
+
nodemapper.addSimpleHandler("blogspot.com", "ident_to_blog",
|
455
|
+
"http://", ".blogspot.com/");
|
456
|
+
nodemapper.addSimpleHandler("blogspot.com", "ident_to_content",
|
457
|
+
"http://", ".blogspot.com/");
|
458
|
+
nodemapper.addSimpleHandler("blogspot.com", "ident_to_rss",
|
459
|
+
"http://", ".blogspot.com/feeds/posts/default?alt=rss");
|
460
|
+
nodemapper.addSimpleHandler("blogspot.com", "ident_to_atom",
|
461
|
+
"http://", ".blogspot.com/feeds/posts/default");
|
462
|
+
nodemapper.registerDomain("blogger.com", {
|
463
|
+
name: "Blogger (Profile)",
|
464
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
465
|
+
"blogger.com",
|
466
|
+
/^\/profile\/(\d+)/, { keyName: "pk" })
|
467
|
+
});
|
468
|
+
nodemapper.addSimpleHandler("blogger.com", "pk_to_profile",
|
469
|
+
"http://www.blogger.com/profile/");
|
470
|
+
})();
|
471
|
+
(function(){
|
472
|
+
var FACEBOOK_ALT_DOMAINS = [
|
473
|
+
"facebook.at",
|
474
|
+
"facebook.ca",
|
475
|
+
"facebook.co.nz",
|
476
|
+
"facebook.co.za",
|
477
|
+
"facebook.com.au",
|
478
|
+
"facebook.de",
|
479
|
+
"facebook.dk",
|
480
|
+
"facebook.es",
|
481
|
+
"facebook.ie",
|
482
|
+
"facebook.jp",
|
483
|
+
"facebook.net.nz",
|
484
|
+
"facebook.no",
|
485
|
+
"facebook.pl",
|
486
|
+
"facebook.se",
|
487
|
+
"facebook.vn"
|
488
|
+
];
|
489
|
+
var PRIVATE_PROFILE_RE = /^(?:\/home\.php\#)?\/profile\.php\?id=(\d+)/;
|
490
|
+
var PUBLIC_PROFILE_RE = /^\/(?:p|people)\/([^\/]+\/(\d+))/;
|
491
|
+
var USERNAME_RE = /^\/(\w[\w\.\-]{2,30}\w)(?:$|[\/\?])/;
|
492
|
+
var NOT_USERNAME = {
|
493
|
+
people: 1,
|
494
|
+
pages: 1,
|
495
|
+
directory: 1,
|
496
|
+
video: 1,
|
497
|
+
apps: 1,
|
498
|
+
discography: 1,
|
499
|
+
networks: 1,
|
500
|
+
help: 1,
|
501
|
+
applications: 1,
|
502
|
+
reviews: 1,
|
503
|
+
ext: 1,
|
504
|
+
marketplace: 1
|
505
|
+
};
|
506
|
+
var facebookHandler = function(url, host, path) {
|
507
|
+
var m;
|
508
|
+
if (m = PRIVATE_PROFILE_RE.exec(path)) {
|
509
|
+
return "sgn://facebook.com/?pk=" + m[1];
|
510
|
+
}
|
511
|
+
if (m = PUBLIC_PROFILE_RE.exec(path)) {
|
512
|
+
return "sgn://facebook.com/?ident=" + m[1];
|
513
|
+
}
|
514
|
+
if (m = USERNAME_RE.exec(path)) {
|
515
|
+
if (m[1].lastIndexOf(".php") == m[1].length - 4 ||
|
516
|
+
NOT_USERNAME[m[1].toLowerCase()]) {
|
517
|
+
return url;
|
518
|
+
}
|
519
|
+
return "sgn://facebook.com/?ident=" + m[1].toLowerCase().replace(/[\-\.]/g, "");
|
520
|
+
}
|
521
|
+
return url;
|
522
|
+
};
|
523
|
+
nodemapper.registerDomain(
|
524
|
+
FACEBOOK_ALT_DOMAINS,
|
525
|
+
{ urlToGraphNode: facebookHandler });
|
526
|
+
nodemapper.registerDomain(
|
527
|
+
"facebook.com",
|
528
|
+
{name: "Facebook",
|
529
|
+
urlToGraphNode: facebookHandler,
|
530
|
+
ident_to_profile: function (ident) {
|
531
|
+
if (/\//.exec(ident)) {
|
532
|
+
return "http://www.facebook.com/people/" + ident;
|
533
|
+
} else {
|
534
|
+
return "http://www.facebook.com/" + ident;
|
535
|
+
}
|
536
|
+
},
|
537
|
+
pk_to_profile: function (pk) { return "http://www.facebook.com/profile.php?id=" + pk; },
|
538
|
+
pkRegexp: /^\d+$/,
|
539
|
+
identRegexp: /^(?:.+\/\d+)|(?:\w[\w\.\-]{2,30}\w)$/,
|
540
|
+
identCasePreserve: 1
|
541
|
+
});
|
542
|
+
})();
|
543
|
+
(function(){
|
544
|
+
function urlToGraphNodeFlickrFallback(url, host, path) {
|
545
|
+
var flickerPathRE = /^\/(?:people|photos)\/(\d+@\w+)(?:\/|$)/;
|
546
|
+
var m = flickerPathRE.exec(path);
|
547
|
+
if (m) {
|
548
|
+
return "sgn://flickr.com/?pk=" + m[1];
|
549
|
+
}
|
550
|
+
return; // undef
|
551
|
+
};
|
552
|
+
var urlToGraphNodeFlickr =
|
553
|
+
nodemapper.createPathRegexpHandler(
|
554
|
+
"flickr.com",
|
555
|
+
/^(?:\/(?:people|photos))?\/([\w\-]+)(?:\/|$)/,
|
556
|
+
{fallbackHandler: urlToGraphNodeFlickrFallback,
|
557
|
+
notUsernames: {
|
558
|
+
photos: 1,
|
559
|
+
groups: 1,
|
560
|
+
people: 1,
|
561
|
+
search: 1,
|
562
|
+
places: 1,
|
563
|
+
help: 1,
|
564
|
+
services: 1,
|
565
|
+
explore: 1,
|
566
|
+
groups_topics: 1,
|
567
|
+
photo: 1,
|
568
|
+
creativecommons: 1,
|
569
|
+
commons: 1,
|
570
|
+
cameras: 1,
|
571
|
+
photo_zoom: 1,
|
572
|
+
signin: 1,
|
573
|
+
forums: 1,
|
574
|
+
apps: 1,
|
575
|
+
slideShow: 1,
|
576
|
+
map: 1,
|
577
|
+
account: 1,
|
578
|
+
groups_topic: 1
|
579
|
+
},
|
580
|
+
pathTransform: function(path) { return path.replace('%40', '@'); }
|
581
|
+
});
|
582
|
+
nodemapper.registerDomain(
|
583
|
+
"flickr.com", {
|
584
|
+
name: "Flickr",
|
585
|
+
urlToGraphNode: urlToGraphNodeFlickr,
|
586
|
+
pkRegexp: /^\d+@\w\d+$/,
|
587
|
+
accountToSgn: { pk: ["flickr.com", /^\d+@\w\d+$/],
|
588
|
+
ident: ["flickr.com", /^[\-\w]+$/] }
|
589
|
+
});
|
590
|
+
nodemapper.addSimpleHandler("flickr.com", "pk_to_rss",
|
591
|
+
"http://api.flickr.com/services/feeds/photos_public.gne?id=", "&lang=en-us&format=rss_200");
|
592
|
+
nodemapper.addSimpleHandler("flickr.com", "pk_to_atom",
|
593
|
+
"http://api.flickr.com/services/feeds/photos_public.gne?id=", "&lang=en-us&format=atom");
|
594
|
+
for (var i = 0; i < 2; i++) {
|
595
|
+
var type = ["pk", "ident"][i];
|
596
|
+
nodemapper.addSimpleHandler("flickr.com", type + "_to_profile",
|
597
|
+
"http://www.flickr.com/people/", "/");
|
598
|
+
nodemapper.addSimpleHandler("flickr.com", type + "_to_addfriend",
|
599
|
+
"http://www.flickr.com/people/", "/relationship/");
|
600
|
+
nodemapper.addSimpleHandler("flickr.com", type + "_to_content",
|
601
|
+
"http://www.flickr.com/photos/", "/");
|
602
|
+
}
|
603
|
+
})();
|
604
|
+
(function(){
|
605
|
+
nodemapper.registerDomain("friendfeed.com",
|
606
|
+
{
|
607
|
+
name: "FriendFeed",
|
608
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
609
|
+
"friendfeed.com", /^\/(\w+)/)
|
610
|
+
});
|
611
|
+
nodemapper.addSimpleHandler("friendfeed.com", "ident_to_profile",
|
612
|
+
"http://friendfeed.com/");
|
613
|
+
nodemapper.addSimpleHandler("friendfeed.com", "ident_to_atom",
|
614
|
+
"http://friendfeed.com/", "?format=atom");
|
615
|
+
})();
|
616
|
+
(function(){
|
617
|
+
var GOOGLE_TLDS = "ad ae am as at az ba be bg bi bs ca cd cg ch ci cl cn co.bw co.ck co.cr co.id co.il co.im co.in co.je co.jp co.ke co.kr co.ls co.ma co.mw co.nz co.pn co.th co.tt co.ug co.uk co.uz co.ve co.vi co.yu co.za co.zm co.zw com com.af com.ag com.ar com.au com.bd com.bh com.bn com.bo com.br com.bz com.cn com.co com.cu com.do com.ec com.eg com.et com.fj com.gi com.gr com.gt com.hk com.jm com.kh com.kz com.lv com.ly com.mt com.mw com.mx com.my com.na com.nf com.ng com.ni com.np com.om com.pa com.pe com.ph com.pk com.pl com.pr com.py com.qa com.ru com.sa com.sb com.sg com.sl com.sv com.tj com.tr com.tt com.tw com.ua com.uy com.vc com.ve com.vn cz de dj dk dm ee es fi fm fr ge gg gl gm gp gr gy hk hn hr ht hu ie is it je jo kg ki kz la li lk lt lu lv md me mn ms mu mv mw ne.jp nl no nr nu off.ai ph pl pn pt ro ru rw sc se sg sh si sk sl sm sn st tk tl tm to tp tt us vg vn vu ws".split(" ");
|
618
|
+
function googleDomains(prefix) {
|
619
|
+
var ret = [];
|
620
|
+
for (var idx in GOOGLE_TLDS) {
|
621
|
+
ret.push(prefix + GOOGLE_TLDS[idx]);
|
622
|
+
}
|
623
|
+
return ret;
|
624
|
+
}
|
625
|
+
var GOOGLE_DOMAINS = googleDomains("google.");
|
626
|
+
var READER_RE = /^\/reader\/(?:shared|public\/atom\/user)\/(\d{7,})(?:\/state\/com.google\/broadcast)?/;
|
627
|
+
var googleIdentProfileHandler = nodemapper.createPathRegexpHandler(
|
628
|
+
"profiles.google.com", // fake domain
|
629
|
+
/^(?:\/s2)?\/(?:profiles\/|sharing\/stuff\?user=)([\w+\.]+)/,
|
630
|
+
{keyName: "ident"});
|
631
|
+
var googleProfileHandler = nodemapper.createPathRegexpHandler(
|
632
|
+
"profiles.google.com", // fake domain
|
633
|
+
/^(?:\/s2)?\/(?:profiles\/|sharing\/stuff\?user=)(\d+)/,
|
634
|
+
{keyName: "pk", fallbackHandler: googleIdentProfileHandler });
|
635
|
+
var readerHandler = nodemapper.createPathRegexpHandler(
|
636
|
+
"reader.google.com", // fake domain
|
637
|
+
READER_RE,
|
638
|
+
{keyName: "pk"});
|
639
|
+
var profilesDomainIdentHandler = nodemapper.createPathRegexpHandler(
|
640
|
+
"profiles.google.com", // fake domain
|
641
|
+
/^\/([\w+\.]+)(?:\?|$)/,
|
642
|
+
{keyName: "ident"})
|
643
|
+
googleMasterHandler = function(url, host, path) {
|
644
|
+
var handler = null;
|
645
|
+
if (path.indexOf("/reader") == 0) {
|
646
|
+
handler = readerHandler;
|
647
|
+
} else if (path.indexOf("/s2/") == 0) {
|
648
|
+
handler = googleProfileHandler;
|
649
|
+
} else if (path.indexOf("/profiles/") == 0) {
|
650
|
+
handler = googleProfileHandler;
|
651
|
+
}
|
652
|
+
if (handler) return handler(url, host, path);
|
653
|
+
return url;
|
654
|
+
};
|
655
|
+
nodemapper.registerDomain(GOOGLE_DOMAINS, {urlToGraphNode: googleMasterHandler});
|
656
|
+
nodemapper.registerDomain("reader.google.com", {
|
657
|
+
name: "Google Reader",
|
658
|
+
pkRegexp: /^\d{7,}$/
|
659
|
+
});
|
660
|
+
nodemapper.addSimpleHandler("reader.google.com", "pk_to_content",
|
661
|
+
"http://www.google.com/reader/shared/", "");
|
662
|
+
nodemapper.addSimpleHandler("reader.google.com", "pk_to_profile",
|
663
|
+
"http://www.google.com/reader/shared/", "");
|
664
|
+
nodemapper.addSimpleHandler("reader.google.com", "pk_to_atom",
|
665
|
+
"http://www.google.com/reader/public/atom/user/",
|
666
|
+
"/state/com.google/broadcast");
|
667
|
+
var PROFILE_RE = /^\/profile\?user=(\w+)/;
|
668
|
+
var USER_RE = /^\/(?:(?:rss\/)?user\/)?(\w+)\b/;
|
669
|
+
var YOUTUBE_NOT_USERNAME = {
|
670
|
+
'blog': true,
|
671
|
+
'browse': true,
|
672
|
+
'community': true,
|
673
|
+
'dev': true,
|
674
|
+
'feeds': true,
|
675
|
+
'greetings': true,
|
676
|
+
'inbox': true,
|
677
|
+
'jobs': true,
|
678
|
+
'members': true,
|
679
|
+
'my_account': true,
|
680
|
+
'my_favorites': true,
|
681
|
+
'my_playlists': true,
|
682
|
+
'my_subscriptions': true,
|
683
|
+
'my_videos': true,
|
684
|
+
'press_room': true,
|
685
|
+
'support': true,
|
686
|
+
't': true,
|
687
|
+
'testtube': true,
|
688
|
+
'watch': true,
|
689
|
+
'watch_queue': true,
|
690
|
+
'youtubeonyoursite': true
|
691
|
+
};
|
692
|
+
var youTubeToSgn = function(url, host, path) {
|
693
|
+
var m;
|
694
|
+
if ((m = PROFILE_RE.exec(path)) || (m = USER_RE.exec(path))) {
|
695
|
+
var username = m[1].toLowerCase();
|
696
|
+
if (YOUTUBE_NOT_USERNAME[username]) {
|
697
|
+
return url;
|
698
|
+
}
|
699
|
+
return "sgn://youtube.com/?ident=" + username;
|
700
|
+
}
|
701
|
+
return url;
|
702
|
+
};
|
703
|
+
nodemapper.registerDomain(
|
704
|
+
"youtube.com",
|
705
|
+
{name: "YouTube",
|
706
|
+
urlToGraphNode: youTubeToSgn});
|
707
|
+
nodemapper.registerDomain(
|
708
|
+
"gdata.youtube.com",
|
709
|
+
{urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
710
|
+
"feeds/base/users",
|
711
|
+
"youtube.com")});
|
712
|
+
nodemapper.addSimpleHandler(
|
713
|
+
"youtube.com", "ident_to_profile",
|
714
|
+
"http://youtube.com/user/");
|
715
|
+
nodemapper.addSimpleHandler(
|
716
|
+
"youtube.com", "ident_to_rss",
|
717
|
+
"http://youtube.com/rss/user/", "/videos.rss");
|
718
|
+
nodemapper.registerDomain(
|
719
|
+
googleDomains("picasaweb.google."),
|
720
|
+
{name: "Picasa Web Albums",
|
721
|
+
primaryDomain: "picasaweb.google.com",
|
722
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
723
|
+
"picasaweb.google.com",
|
724
|
+
/^\/([\w\.]+)\/?$/
|
725
|
+
)});
|
726
|
+
nodemapper.addSimpleHandler("picasaweb.google.com", "ident_to_profile",
|
727
|
+
"http://picasaweb.google.com/");
|
728
|
+
nodemapper.addSimpleHandler("picasaweb.google.com", "ident_to_rss",
|
729
|
+
"http://picasaweb.google.com/data/feed/base/user/",
|
730
|
+
"?kind=album&alt=rss&hl=en_US&access=public");
|
731
|
+
nodemapper.registerDomain(
|
732
|
+
"dodgeball.com",
|
733
|
+
{name: "Dodgeball",
|
734
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
735
|
+
"dodgeball.com",
|
736
|
+
/^\/user\?uid=(\d+)/, { keyName: "pk" })
|
737
|
+
});
|
738
|
+
nodemapper.addSimpleHandler("dodgeball.com", "pk_to_profile",
|
739
|
+
"http://www.dodgeball.com/user?uid=", "");
|
740
|
+
nodemapper.registerDomain(
|
741
|
+
"orkut.com",
|
742
|
+
{name: "Orkut",
|
743
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
744
|
+
"orkut.com",
|
745
|
+
/^\/Profile.aspx\?uid=(\d+)/, { keyName: "pk" })
|
746
|
+
});
|
747
|
+
nodemapper.addSimpleHandler("orkut.com", "pk_to_profile",
|
748
|
+
"http://www.orkut.com/Profile.aspx?uid=");
|
749
|
+
nodemapper.registerDomain("profiles.google.com", {
|
750
|
+
urlToGraphNode: profilesDomainIdentHandler,
|
751
|
+
name: "Google Profile",
|
752
|
+
pkRegexp: /^\d{7,}$/,
|
753
|
+
identRegexp: /^[\w\.]{1,40}$/
|
754
|
+
});
|
755
|
+
nodemapper.addSimpleHandler("profiles.google.com", "pk_to_profile",
|
756
|
+
"http://www.google.com/profiles/");
|
757
|
+
nodemapper.addSimpleHandler("profiles.google.com", "ident_to_profile",
|
758
|
+
"http://www.google.com/profiles/");
|
759
|
+
})();
|
760
|
+
(function(){
|
761
|
+
var HAS_ID_REGEXP = /\b(?:ownerId=|userid=|friend\/|\/profile\/foaf\/)(\d+)/;
|
762
|
+
var FRIEND_ID_REGEXP = /^\/friend\/p(\d+)-/;
|
763
|
+
var DISPLAY_PROFILE = /^\/friend\/profile\/displayHi5URL\.do\?nickname=([\w\-]{6,})\b/;
|
764
|
+
var NUMERIC_DOMAIN = /^(\d+)\.hi5\.com$/;
|
765
|
+
function urlToGraphNodeHi5(url, host, path) {
|
766
|
+
var m;
|
767
|
+
if ((m = HAS_ID_REGEXP.exec(path)) ||
|
768
|
+
(m = FRIEND_ID_REGEXP.exec(path))) {
|
769
|
+
return "sgn://hi5.com/?pk=" + m[1];
|
770
|
+
}
|
771
|
+
if (path == "/" && (m = /^([\w\-]{6,})\.hi5\.com$/.exec(host))) {
|
772
|
+
var match = m[1];
|
773
|
+
if (/[^\d]/.exec(match)) {
|
774
|
+
return "sgn://hi5.com/?ident=" + m[1].toLowerCase();
|
775
|
+
} else {
|
776
|
+
return "sgn://hi5.com/?pk=" + m[1];
|
777
|
+
}
|
778
|
+
}
|
779
|
+
if (m = DISPLAY_PROFILE.exec(path)) {
|
780
|
+
return "sgn://hi5.com/?ident=" + m[1].toLowerCase();
|
781
|
+
}
|
782
|
+
if ((m = NUMERIC_DOMAIN.exec(host)) && !/\?/.exec(path)) {
|
783
|
+
return "sgn://hi5.com/?pk=" + m[1];
|
784
|
+
}
|
785
|
+
return url;
|
786
|
+
}
|
787
|
+
nodemapper.registerDomain(
|
788
|
+
"hi5.com", {
|
789
|
+
name: "hi5",
|
790
|
+
urlToGraphNode: urlToGraphNodeHi5
|
791
|
+
});
|
792
|
+
nodemapper.addSimpleHandler("hi5.com", "pk_to_foaf",
|
793
|
+
"http://api.hi5.com/rest/profile/foaf/", "");
|
794
|
+
nodemapper.addSimpleHandler("hi5.com", "pk_to_content",
|
795
|
+
"http://www.hi5.com/friend/profile/displayProfile.do?userid=", "");
|
796
|
+
nodemapper.addSimpleHandler("hi5.com", "pk_to_profile",
|
797
|
+
"http://www.hi5.com/friend/profile/displayProfile.do?userid=", "");
|
798
|
+
nodemapper.addSimpleHandler("hi5.com", "pk_to_atom",
|
799
|
+
"http://api.hi5.com/rest/feed/journal/", "");
|
800
|
+
nodemapper.addSimpleHandler("hi5.com", "pk_to_foaf",
|
801
|
+
"http://api.hi5.com/rest/profile/foaf/", "");
|
802
|
+
nodemapper.addSimpleHandler("hi5.com", "pk_to_blog",
|
803
|
+
"http://www.hi5.com/friend/profile/displayJournal.do?userid=", "");
|
804
|
+
nodemapper.addSimpleHandler("hi5.com", "ident_to_content",
|
805
|
+
"http://", ".hi5.com/");
|
806
|
+
nodemapper.addSimpleHandler("hi5.com", "ident_to_profile",
|
807
|
+
"http://", ".hi5.com/");
|
808
|
+
})();
|
809
|
+
(function(){
|
810
|
+
var LAST_FM_ALT_DOMAINS = [
|
811
|
+
"cn.last.fm",
|
812
|
+
"lastfm.excite.co.jp",
|
813
|
+
"lastfm.spiegel.de",
|
814
|
+
"www.last.fm",
|
815
|
+
"www.lastfm.com.br",
|
816
|
+
"www.lastfm.at",
|
817
|
+
"www.lastfm.ch",
|
818
|
+
"www.lastfm.co.kr",
|
819
|
+
"www.lastfm.com.br",
|
820
|
+
"www.lastfm.com.tr",
|
821
|
+
"www.lastfm.de",
|
822
|
+
"www.lastfm.es",
|
823
|
+
"www.lastfm.fr",
|
824
|
+
"www.lastfm.it",
|
825
|
+
"www.lastfm.jp",
|
826
|
+
"www.lastfm.pl",
|
827
|
+
"www.lastfm.pt",
|
828
|
+
"www.lastfm.ru",
|
829
|
+
"www.lastfm.se"
|
830
|
+
];
|
831
|
+
var lastFmHttpToSgn = nodemapper.createPathRegexpHandler(
|
832
|
+
"last.fm", /^\/user\/([\w\-]+)(?:\/|$)/);
|
833
|
+
nodemapper.registerDomain(
|
834
|
+
"last.fm",
|
835
|
+
{name: "Last.fm",
|
836
|
+
urlToGraphNode: lastFmHttpToSgn});
|
837
|
+
nodemapper.registerDomain(
|
838
|
+
LAST_FM_ALT_DOMAINS,
|
839
|
+
{urlToGraphNode: lastFmHttpToSgn});
|
840
|
+
nodemapper.addSimpleHandler("last.fm", "ident_to_profile",
|
841
|
+
"http://www.last.fm/user/", "/");
|
842
|
+
})();
|
843
|
+
(function(){
|
844
|
+
var LJCOM_MAIN_DOMAIN_REGEX = /^\/(?:~|users\/|community\/)(\w+)(?:\/|$)/;
|
845
|
+
var LJCOM_USERINFO_BML_REGEX = /^\/userinfo\.bml\?(user|userid)=(\w+)/;
|
846
|
+
var LJCOM_MISC_BML_REGEX = /^\/(?:go|talkread)\.bml\?.*\bjournal=(\w+)/;
|
847
|
+
var LJCOM_MISC_FDATA_REGEX = /^\/misc\/fdata2?\.bml\?.*\buser=(\w+)/;
|
848
|
+
var urlToGraphNodeUsersCommunity = function(url, host, path) {
|
849
|
+
var slashUserMaybeProfile = /^\/(\w+)(?:\/|\/profile|$)/;
|
850
|
+
var m;
|
851
|
+
if (!(m = slashUserMaybeProfile.exec(path))) {
|
852
|
+
return url;
|
853
|
+
}
|
854
|
+
return "sgn://livejournal.com/?ident=" + m[1].toLowerCase();
|
855
|
+
};
|
856
|
+
nodemapper.registerDomain(["users.livejournal.com",
|
857
|
+
"community.livejournal.com"],
|
858
|
+
{urlToGraphNode:urlToGraphNodeUsersCommunity});
|
859
|
+
var urlToGraphNodeGeneral = function(url, host, path) {
|
860
|
+
var m;
|
861
|
+
if (host == "pics.livejournal.com") {
|
862
|
+
return url;
|
863
|
+
}
|
864
|
+
if (host == "www.livejournal.com" || host == "livejournal.com") {
|
865
|
+
if (m = LJCOM_MAIN_DOMAIN_REGEX.exec(path)) {
|
866
|
+
return "sgn://livejournal.com/?ident=" + m[1].toLowerCase();
|
867
|
+
}
|
868
|
+
if (m = LJCOM_USERINFO_BML_REGEX.exec(path)) {
|
869
|
+
if (m[1] == "user") {
|
870
|
+
return "sgn://livejournal.com/?ident=" + m[2].toLowerCase();
|
871
|
+
} else {
|
872
|
+
return "sgn://livejournal.com/?pk=" + m[2];
|
873
|
+
}
|
874
|
+
}
|
875
|
+
if (m = LJCOM_MISC_BML_REGEX.exec(path)) {
|
876
|
+
return "sgn://livejournal.com/?ident=" + m[1].toLowerCase();
|
877
|
+
}
|
878
|
+
if (m = LJCOM_MISC_FDATA_REGEX.exec(path)) {
|
879
|
+
return "sgn://livejournal.com/?ident=" + m[1].toLowerCase();
|
880
|
+
}
|
881
|
+
return url;
|
882
|
+
}
|
883
|
+
var hostparts = host.split(".");
|
884
|
+
var user = hostparts[0].replace(/-/g, "_");
|
885
|
+
return "sgn://livejournal.com/?ident=" + user;
|
886
|
+
};
|
887
|
+
var journalBase = function (ident) {
|
888
|
+
if (ident.indexOf("_") == 0) {
|
889
|
+
return "http://www.livejournal.com/~" + ident + "/";
|
890
|
+
}
|
891
|
+
return "http://" + ident.replace("_", "-") + ".livejournal.com/";
|
892
|
+
};
|
893
|
+
var appendToBase = function (suffix) {
|
894
|
+
return function(ident) { return journalBase(ident) + suffix; };
|
895
|
+
};
|
896
|
+
var identToContent = journalBase;
|
897
|
+
var identToRss = appendToBase("data/rss");
|
898
|
+
var identToAtom = appendToBase("data/atom");
|
899
|
+
var identToFoaf = appendToBase("data/foaf");
|
900
|
+
var identToProfile = appendToBase("profile");
|
901
|
+
var identToOpenid = journalBase;
|
902
|
+
nodemapper.registerDomain("livejournal.com",
|
903
|
+
{urlToGraphNode: urlToGraphNodeGeneral,
|
904
|
+
ident_to_content: identToContent,
|
905
|
+
ident_to_rss: identToRss,
|
906
|
+
ident_to_atom: identToAtom,
|
907
|
+
ident_to_foaf: identToFoaf,
|
908
|
+
ident_to_profile: identToProfile,
|
909
|
+
ident_to_openid: identToOpenid,
|
910
|
+
identRegexp: /^\w+$/,
|
911
|
+
name: "LiveJournal"
|
912
|
+
});
|
913
|
+
nodemapper.registerDomain(
|
914
|
+
"pics.livejournal.com",
|
915
|
+
{urlToGraphNode: nodemapper.createSlashUsernameHandler(
|
916
|
+
"livejournal.com",
|
917
|
+
{ slashAnything: 1 })});
|
918
|
+
})();
|
919
|
+
(function(){
|
920
|
+
meetupHandler = function(url, host, path) {
|
921
|
+
var primaryKeyRegexp = /\/members\/(\d+)(?:\/|$)/;
|
922
|
+
var m;
|
923
|
+
if (!(m = primaryKeyRegexp.exec(path))) {
|
924
|
+
return url;
|
925
|
+
}
|
926
|
+
return "sgn://meetup.com/?pk=" + m[1];
|
927
|
+
};
|
928
|
+
nodemapper.registerDomain("meetup.com", {
|
929
|
+
name: "Meetup",
|
930
|
+
urlToGraphNode: meetupHandler
|
931
|
+
});
|
932
|
+
nodemapper.addSimpleHandler("meetup.com", "pk_to_profile",
|
933
|
+
"http://www.meetup.com/members/", "/");
|
934
|
+
})();
|
935
|
+
(function(){
|
936
|
+
var BUZZ_MEMBER_REGEXP = /^\/buzz\/members\/(?:mybloglog([0-9a-f]{20,20})|([\w\-]+))(?:\/|$)/;
|
937
|
+
var toSgn = function(url, host, path) {
|
938
|
+
var m;
|
939
|
+
if (!(m = BUZZ_MEMBER_REGEXP.exec(path))) {
|
940
|
+
return url;
|
941
|
+
}
|
942
|
+
if (m[1]) {
|
943
|
+
return "sgn://mybloglog.com/?pk=" + m[1].toLowerCase();
|
944
|
+
} else {
|
945
|
+
return "sgn://mybloglog.com/?ident=" + m[2].toLowerCase();
|
946
|
+
}
|
947
|
+
};
|
948
|
+
var PK_REGEXP = /^(?:mybloglog)?([0-9a-f]{20,20})$/;
|
949
|
+
nodemapper.registerDomain("mybloglog.com", {
|
950
|
+
urlToGraphNode: toSgn,
|
951
|
+
accountToSgn: { pk: ["mybloglog.com", PK_REGEXP],
|
952
|
+
ident: ["mybloglog.com", /^[\w-]+$/] },
|
953
|
+
pkRegexp: PK_REGEXP,
|
954
|
+
name: "MyBlogLog"
|
955
|
+
});
|
956
|
+
nodemapper.addSimpleHandler("mybloglog.com", "ident_to_foaf",
|
957
|
+
"http://www.mybloglog.com/buzz/members/", "/foaf");
|
958
|
+
nodemapper.addSimpleHandler("mybloglog.com", "ident_to_profile",
|
959
|
+
"http://www.mybloglog.com/buzz/members/", "/");
|
960
|
+
nodemapper.addSimpleHandler("mybloglog.com", "pk_to_foaf",
|
961
|
+
"http://www.mybloglog.com/buzz/members/mybloglog", "/foaf");
|
962
|
+
nodemapper.addSimpleHandler("mybloglog.com", "pk_to_profile",
|
963
|
+
"http://www.mybloglog.com/buzz/members/mybloglog", "/");
|
964
|
+
})();
|
965
|
+
(function(){
|
966
|
+
var ACTION_REGEX = /index\.cfm\?fuseaction=(.+)&friendID=(\d+)/i;
|
967
|
+
var SLASH_WHATEVER_REGEX = /^\/(\d+)|([a-z]\w*)(?:\?|$)/;
|
968
|
+
var MYSPACE_USER_ACTIONS = {
|
969
|
+
"user.viewprofile": 1,
|
970
|
+
"user.viewfriends": 1,
|
971
|
+
"blog.listall": 1,
|
972
|
+
"blog.confirmsubscribe": 1
|
973
|
+
};
|
974
|
+
function urlToGraphNodeMySpace(url, host, path) {
|
975
|
+
var m = ACTION_REGEX.exec(path);
|
976
|
+
if (m) {
|
977
|
+
var action = m[1].toLowerCase();
|
978
|
+
var userid = m[2];
|
979
|
+
if (MYSPACE_USER_ACTIONS[action]) {
|
980
|
+
return "sgn://myspace.com/?pk=" + userid;
|
981
|
+
}
|
982
|
+
}
|
983
|
+
if (host == "profile.myspace.com") {
|
984
|
+
m = SLASH_WHATEVER_REGEX.exec(path);
|
985
|
+
if (m) {
|
986
|
+
if (m[1]) {
|
987
|
+
return "sgn://myspace.com/?pk=" + m[1];
|
988
|
+
}
|
989
|
+
if (m[2]) {
|
990
|
+
return "sgn://myspace.com/?ident=" + m[2];
|
991
|
+
}
|
992
|
+
}
|
993
|
+
}
|
994
|
+
return url;
|
995
|
+
};
|
996
|
+
var urlToGraphNodeMySpaceUsername =
|
997
|
+
nodemapper.createSlashUsernameHandler(
|
998
|
+
"myspace.com",
|
999
|
+
{fallbackHandler: urlToGraphNodeMySpace});
|
1000
|
+
nodemapper.registerDomain(
|
1001
|
+
"myspace.com",
|
1002
|
+
{name: "MySpace",
|
1003
|
+
urlToGraphNode: urlToGraphNodeMySpaceUsername,
|
1004
|
+
accountToSgn: { pk: ["myspace.com"], ident: ["myspace.com"] }
|
1005
|
+
});
|
1006
|
+
nodemapper.addSimpleHandler(
|
1007
|
+
"myspace.com", "ident_to_profile",
|
1008
|
+
"http://www.myspace.com/");
|
1009
|
+
nodemapper.addSimpleHandler(
|
1010
|
+
"myspace.com", "ident_to_content",
|
1011
|
+
"http://www.myspace.com/");
|
1012
|
+
nodemapper.addSimpleHandler(
|
1013
|
+
"myspace.com", "pk_to_profile",
|
1014
|
+
"http://profile.myspace.com/index.cfm?fuseaction=user.viewprofile&friendid=");
|
1015
|
+
nodemapper.addSimpleHandler(
|
1016
|
+
"myspace.com", "pk_to_content",
|
1017
|
+
"http://profile.myspace.com/index.cfm?fuseaction=user.viewprofile&friendid=");
|
1018
|
+
nodemapper.addSimpleHandler(
|
1019
|
+
"myspace.com", "pk_to_rss",
|
1020
|
+
"http://blog.myspace.com/blog/rss.cfm?friendID=");
|
1021
|
+
nodemapper.addSimpleHandler(
|
1022
|
+
"myspace.com", "pk_to_blog",
|
1023
|
+
"http://blog.myspace.com/index.cfm?fuseaction=blog.ListAll&friendID=");
|
1024
|
+
nodemapper.registerDomain(
|
1025
|
+
["profile.myspace.com", "blog.myspace.com"],
|
1026
|
+
{urlToGraphNode: urlToGraphNodeMySpace});
|
1027
|
+
})();
|
1028
|
+
(function(){
|
1029
|
+
var XMPP_REGEX = /^(?:xmpp|jabber):(.+)/i;
|
1030
|
+
var MAILTO_REGEX = /^mailto:(.+)/i;
|
1031
|
+
nodemapper.registerNonHTTPHandler(function(url) {
|
1032
|
+
var m;
|
1033
|
+
if (m = XMPP_REGEX.exec(url)) {
|
1034
|
+
return "xmpp:" + m[1].replace(/%40/, "@");
|
1035
|
+
}
|
1036
|
+
if (m = MAILTO_REGEX.exec(url)) {
|
1037
|
+
return "mailto:" + m[1].replace(/%40/, "@");
|
1038
|
+
}
|
1039
|
+
});
|
1040
|
+
})();
|
1041
|
+
(function(){
|
1042
|
+
var IDENT_REGEXP = /^[\w\-\%\.\:\*]+$/;
|
1043
|
+
var SLASH_WHATEVER = /^\/([^\/]+)(?:\/|$)/;
|
1044
|
+
var toSgn = function(url, host, path) {
|
1045
|
+
var m;
|
1046
|
+
if (!(m = SLASH_WHATEVER.exec(path))) {
|
1047
|
+
return;
|
1048
|
+
}
|
1049
|
+
var username = m[1];
|
1050
|
+
if (!(m = IDENT_REGEXP.exec(username))) {
|
1051
|
+
return url;
|
1052
|
+
}
|
1053
|
+
return "sgn://my.opera.com/?ident=" + username.toLowerCase();
|
1054
|
+
};
|
1055
|
+
nodemapper.registerDomain("my.opera.com", {
|
1056
|
+
name: "My Opera",
|
1057
|
+
identRegexp: IDENT_REGEXP,
|
1058
|
+
pkRegexp: /^ dontmatchme $/,
|
1059
|
+
urlToGraphNode: toSgn
|
1060
|
+
});
|
1061
|
+
nodemapper.addSimpleHandler("my.opera.com", "ident_to_profile",
|
1062
|
+
"http://my.opera.com/", "/about/");
|
1063
|
+
nodemapper.addSimpleHandler("my.opera.com", "ident_to_foaf",
|
1064
|
+
"http://my.opera.com/", "/xml/foaf/");
|
1065
|
+
})();
|
1066
|
+
(function(){
|
1067
|
+
nodemapper.registerDomain(
|
1068
|
+
"gallery.ru",
|
1069
|
+
{urlToGraphNode: nodemapper.createUserIsSubdomainHandler("gallery.ru"),
|
1070
|
+
name: "Gallery.ru"
|
1071
|
+
});
|
1072
|
+
nodemapper.addSimpleHandler("gallery.ru", "ident_to_foaf",
|
1073
|
+
"http://", ".gallery.ru/foaf/");
|
1074
|
+
nodemapper.addSimpleHandler("gallery.ru", "ident_to_profile",
|
1075
|
+
"http://", ".gallery.ru/");
|
1076
|
+
nodemapper.registerDomain(
|
1077
|
+
"blogonline.ru",
|
1078
|
+
{urlToGraphNode: nodemapper.createUserIsSubdomainHandler("blogonline.ru"),
|
1079
|
+
name: "blogonline.ru"
|
1080
|
+
});
|
1081
|
+
nodemapper.addSimpleHandler("blogonline.ru", "ident_to_foaf",
|
1082
|
+
"http://", ".blogonline.ru/data/foaf");
|
1083
|
+
nodemapper.addSimpleHandler("blogonline.ru", "ident_to_profile",
|
1084
|
+
"http://", ".blogonline.ru/profile");
|
1085
|
+
nodemapper.addSimpleHandler("blogonline.ru", "ident_to_blog",
|
1086
|
+
"http://", ".blogonline.ru/");
|
1087
|
+
nodemapper.registerDomain(
|
1088
|
+
"privet.ru",
|
1089
|
+
{urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler("user", "privet.ru"),
|
1090
|
+
name: "privet.ru"
|
1091
|
+
});
|
1092
|
+
nodemapper.addSimpleHandler("privet.ru", "ident_to_foaf",
|
1093
|
+
"http://www.privet.ru/user/", "/foaf");
|
1094
|
+
nodemapper.addSimpleHandler("privet.ru", "ident_to_blog",
|
1095
|
+
"http://blogs.privet.ru/user/");
|
1096
|
+
nodemapper.addSimpleHandler("privet.ru", "ident_to_profile",
|
1097
|
+
"http://www.privet.ru/user/");
|
1098
|
+
})();
|
1099
|
+
(function(){
|
1100
|
+
nodemapper.registerDomain(
|
1101
|
+
"blogs.sapo.pt",
|
1102
|
+
{urlToGraphNode: nodemapper.createUserIsSubdomainHandler("blogs.sapo.pt"),
|
1103
|
+
name: "SAPO"
|
1104
|
+
});
|
1105
|
+
nodemapper.addSimpleHandler("blogs.sapo.pt", "ident_to_foaf",
|
1106
|
+
"http://", ".blogs.sapo.pt/data/foaf");
|
1107
|
+
nodemapper.addSimpleHandler("blogs.sapo.pt", "ident_to_blog",
|
1108
|
+
"http://", ".blogs.sapo.pt/");
|
1109
|
+
})();
|
1110
|
+
(function(){
|
1111
|
+
nodemapper.registerDomain(
|
1112
|
+
"digg.com",
|
1113
|
+
{name: "Digg",
|
1114
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1115
|
+
"(?:users|rss)",
|
1116
|
+
"digg.com")});
|
1117
|
+
nodemapper.addSimpleHandler("digg.com", "ident_to_profile",
|
1118
|
+
"http://digg.com/users/", "/");
|
1119
|
+
nodemapper.addSimpleHandler("digg.com", "ident_to_rss",
|
1120
|
+
"http://digg.com/users/", "/history/diggs.rss");
|
1121
|
+
nodemapper.registerDomain(
|
1122
|
+
"pownce.com",
|
1123
|
+
{name: "Pownce",
|
1124
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1125
|
+
"pownce.com", /^\/(?:feeds\/public\/)?(\w+)(?:[.\/]|$)/, {slashAnything: 1})});
|
1126
|
+
nodemapper.addSimpleHandler("pownce.com", "ident_to_profile",
|
1127
|
+
"http://pownce.com/");
|
1128
|
+
nodemapper.addSimpleHandler("pownce.com", "ident_to_rss",
|
1129
|
+
"http://pownce.com/feeds/public/", ".rss");
|
1130
|
+
nodemapper.addSimpleHandler("pownce.com", "ident_to_atom",
|
1131
|
+
"http://pownce.com/feeds/public/", ".atom");
|
1132
|
+
nodemapper.registerDomain(
|
1133
|
+
"jaiku.com",
|
1134
|
+
{name: "Jaiku",
|
1135
|
+
urlToGraphNode: nodemapper.createUserIsSubdomainHandler("jaiku.com")});
|
1136
|
+
nodemapper.addSimpleHandler("jaiku.com", "ident_to_profile",
|
1137
|
+
"http://", ".jaiku.com/");
|
1138
|
+
nodemapper.addSimpleHandler("jaiku.com", "ident_to_rss",
|
1139
|
+
"http://", ".jaiku.com/feed/rss");
|
1140
|
+
nodemapper.registerDomain(
|
1141
|
+
"mugshot.org",
|
1142
|
+
{name: "Mugshot",
|
1143
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1144
|
+
"mugshot.org",
|
1145
|
+
/^\/person\?who=(\w+)/,
|
1146
|
+
{casePreserve: 1}),
|
1147
|
+
identCasePreserve: 1,
|
1148
|
+
accountToSgn: {ident: ["mugshot.org"]}
|
1149
|
+
});
|
1150
|
+
nodemapper.addSimpleHandler("mugshot.org", "ident_to_profile",
|
1151
|
+
"http://mugshot.org/person?who=", "");
|
1152
|
+
nodemapper.registerDomain(
|
1153
|
+
"linkedin.com",
|
1154
|
+
{name: "LinkedIn",
|
1155
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1156
|
+
"in",
|
1157
|
+
"linkedin.com")});
|
1158
|
+
nodemapper.addSimpleHandler("linkedin.com", "ident_to_profile",
|
1159
|
+
"http://www.linkedin.com/in/", "");
|
1160
|
+
nodemapper.registerDomain(
|
1161
|
+
"ma.gnolia.com",
|
1162
|
+
{name: "Ma.gnolia",
|
1163
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1164
|
+
"people",
|
1165
|
+
"ma.gnolia.com")});
|
1166
|
+
nodemapper.addSimpleHandler("ma.gnolia.com", "ident_to_profile",
|
1167
|
+
"http://ma.gnolia.com/people/");
|
1168
|
+
nodemapper.addSimpleHandler("ma.gnolia.com", "ident_to_rss",
|
1169
|
+
"http://ma.gnolia.com/rss/full/people/");
|
1170
|
+
nodemapper.registerDomain(
|
1171
|
+
"ziki.com",
|
1172
|
+
{name: "Ziki",
|
1173
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1174
|
+
"ziki.com",
|
1175
|
+
/^\/\w\w\/people\/(\w+)\/?/)});
|
1176
|
+
nodemapper.addSimpleHandler("ziki.com", "ident_to_profile",
|
1177
|
+
"http://www.ziki.com/people/", "");
|
1178
|
+
nodemapper.registerDomain(
|
1179
|
+
["del.icio.us", "delicious.com"],
|
1180
|
+
{name: "del.icio.us",
|
1181
|
+
primaryDomain: "del.icio.us",
|
1182
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1183
|
+
"del.icio.us", /^\/(?:rss\/)?(\w+)/,
|
1184
|
+
{ notUsernames: { "rss": 1 }, slashAnything: 1})});
|
1185
|
+
nodemapper.addSimpleHandler("del.icio.us", "ident_to_profile",
|
1186
|
+
"http://delicious.com/");
|
1187
|
+
nodemapper.addSimpleHandler("del.icio.us", "ident_to_rss",
|
1188
|
+
"http://feeds.delicious.com/rss/");
|
1189
|
+
nodemapper.registerDomain(
|
1190
|
+
["tungle.me", "tgl.me"],
|
1191
|
+
{name: "Tungle.me",
|
1192
|
+
primaryDomain: "tungle.me",
|
1193
|
+
urlToGraphNode: nodemapper.createSlashUsernameHandler(
|
1194
|
+
"tungle.me")});
|
1195
|
+
nodemapper.addSimpleHandler("tungle.me", "ident_to_profile",
|
1196
|
+
"http://tungle.me/");
|
1197
|
+
nodemapper.registerDomain("webshots.com", {
|
1198
|
+
name: "Webshots",
|
1199
|
+
identRegexp: /^\w+$/
|
1200
|
+
});
|
1201
|
+
nodemapper.registerDomain("community.webshots.com",
|
1202
|
+
{urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler("user",
|
1203
|
+
"webshots.com")});
|
1204
|
+
nodemapper.addSimpleHandler("webshots.com", "ident_to_profile",
|
1205
|
+
"http://community.webshots.com/user/");
|
1206
|
+
nodemapper.addSimpleHandler("webshots.com", "ident_to_rss",
|
1207
|
+
"http://community.webshots.com/rss?contentType=rss&type=user&value=");
|
1208
|
+
nodemapper.registerDomain(
|
1209
|
+
"smugmug.com",
|
1210
|
+
{name: "SmugMug",
|
1211
|
+
urlToGraphNode: nodemapper.createUserIsSubdomainHandler("smugmug.com")});
|
1212
|
+
nodemapper.addSimpleHandler("smugmug.com", "ident_to_profile",
|
1213
|
+
"http://", ".smugmug.com/");
|
1214
|
+
nodemapper.addSimpleHandler("smugmug.com", "ident_to_atom",
|
1215
|
+
"http://www.smugmug.com/hack/feed.mg?Type=nicknameRecentPhotos&Data=",
|
1216
|
+
"&format=atom03");
|
1217
|
+
nodemapper.registerDomain(
|
1218
|
+
"vox.com",
|
1219
|
+
{name: "Vox",
|
1220
|
+
urlToGraphNode: nodemapper.createUserIsSubdomainHandler("vox.com")});
|
1221
|
+
nodemapper.addSimpleHandler("vox.com", "ident_to_content",
|
1222
|
+
"http://", ".vox.com/");
|
1223
|
+
nodemapper.addSimpleHandler("vox.com", "ident_to_profile",
|
1224
|
+
"http://", ".vox.com/profile/");
|
1225
|
+
nodemapper.addSimpleHandler("vox.com", "ident_to_rss",
|
1226
|
+
"http://", ".vox.com/library/rss-full.xml");
|
1227
|
+
nodemapper.addSimpleHandler("vox.com", "ident_to_atom",
|
1228
|
+
"http://", ".vox.com/library/atom-full.xml");
|
1229
|
+
nodemapper.addSimpleHandler("vox.com", "ident_to_foaf",
|
1230
|
+
"http://", ".vox.com/profile/foaf.rdf");
|
1231
|
+
nodemapper.registerDomain(
|
1232
|
+
"tumblr.com",
|
1233
|
+
{name: "Tumblr",
|
1234
|
+
urlToGraphNode: nodemapper.createUserIsSubdomainHandler("tumblr.com")});
|
1235
|
+
nodemapper.addSimpleHandler("tumblr.com", "ident_to_profile",
|
1236
|
+
"http://", ".tumblr.com/");
|
1237
|
+
nodemapper.addSimpleHandler("tumblr.com", "ident_to_rss",
|
1238
|
+
"http://", ".tumblr.com/rss");
|
1239
|
+
nodemapper.registerDomain(
|
1240
|
+
"xanga.com",
|
1241
|
+
{name: "Xanga",
|
1242
|
+
urlToGraphNode: nodemapper.createSlashUsernameHandler(
|
1243
|
+
"xanga.com", { slashAnything: 1 })});
|
1244
|
+
nodemapper.addSimpleHandler("xanga.com", "ident_to_profile",
|
1245
|
+
"http://xanga.com/");
|
1246
|
+
nodemapper.addSimpleHandler("xanga.com", "ident_to_rss",
|
1247
|
+
"http://xanga.com/", "/rss");
|
1248
|
+
nodemapper.registerDomain(
|
1249
|
+
"360.yahoo.com",
|
1250
|
+
{name: "Yahoo! 360",
|
1251
|
+
urlToGraphNode: nodemapper.createSlashUsernameHandler(
|
1252
|
+
"360.yahoo.com", { slashAnything: 1 })});
|
1253
|
+
nodemapper.addSimpleHandler("360.yahoo.com", "ident_to_profile",
|
1254
|
+
"http://360.yahoo.com/");
|
1255
|
+
nodemapper.addSimpleHandler("360.yahoo.com", "ident_to_rss",
|
1256
|
+
"http://blog.360.yahoo.com/");
|
1257
|
+
nodemapper.registerDomain(
|
1258
|
+
"spaces.live.com",
|
1259
|
+
{name: "Windows Live Spaces",
|
1260
|
+
urlToGraphNode: nodemapper.createUserIsSubdomainHandler(
|
1261
|
+
"spaces.live.com")});
|
1262
|
+
nodemapper.addSimpleHandler("spaces.live.com", "ident_to_profile",
|
1263
|
+
"http://", ".spaces.live.com");
|
1264
|
+
nodemapper.addSimpleHandler("spaces.live.com", "ident_to_rss",
|
1265
|
+
"http://", ".spaces.live.com/feed.rss");
|
1266
|
+
nodemapper.registerDomain(
|
1267
|
+
"travelpod.com",
|
1268
|
+
{name: "TravelPod",
|
1269
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1270
|
+
"members", "travelpod.com")});
|
1271
|
+
nodemapper.addSimpleHandler("travelpod.com", "ident_to_profile",
|
1272
|
+
"http://travelpod.com/members/");
|
1273
|
+
nodemapper.addSimpleHandler("travelpod.com", "ident_to_rss",
|
1274
|
+
"http://travelpod.com/syndication/rss/");
|
1275
|
+
nodemapper.registerDomain(
|
1276
|
+
"imageshack.us",
|
1277
|
+
{name: "ImageShack",
|
1278
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1279
|
+
"user", "imageshack.us")});
|
1280
|
+
nodemapper.addSimpleHandler("imageshack.us", "ident_to_profile",
|
1281
|
+
"http://profile.imageshack.us/user/");
|
1282
|
+
nodemapper.addSimpleHandler("imageshack.us", "ident_to_rss",
|
1283
|
+
"http://rss.imageshack.us/user/", "/rss/");
|
1284
|
+
nodemapper.registerDomain("bloglines.com",
|
1285
|
+
{name: "Bloglines",
|
1286
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1287
|
+
"(?:blog|public)", "bloglines.com", {slashAnything: 1})});
|
1288
|
+
nodemapper.addSimpleHandler("bloglines.com", "ident_to_profile",
|
1289
|
+
"http://www.bloglines.com/blog/");
|
1290
|
+
nodemapper.addSimpleHandler("bloglines.com", "ident_to_rss",
|
1291
|
+
"http://www.bloglines.com/blog/", "/rss");
|
1292
|
+
nodemapper.registerDomain("nytimes.com",
|
1293
|
+
{name: "TimesPeople",
|
1294
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler("view/user",
|
1295
|
+
"nytimes.com", {keyName: "pk", slashAnything: 1})});
|
1296
|
+
nodemapper.addSimpleHandler("nytimes.com", "pk_to_profile",
|
1297
|
+
"http://timespeople.nytimes.com/view/user/", "/activities.html");
|
1298
|
+
nodemapper.addSimpleHandler("nytimes.com", "pk_to_rss",
|
1299
|
+
"http://timespeople.nytimes.com/view/user/", "/rss.xml");
|
1300
|
+
upcomingHandler = nodemapper.createSomethingSlashUsernameHandler("user",
|
1301
|
+
"upcoming.yahoo.com", {keyName: "pk"});
|
1302
|
+
nodemapper.registerDomain("upcoming.yahoo.com",
|
1303
|
+
{name: "Upcoming",
|
1304
|
+
urlToGraphNode: upcomingHandler});
|
1305
|
+
nodemapper.registerDomain("upcoming.org",
|
1306
|
+
{urlToGraphNode: upcomingHandler});
|
1307
|
+
nodemapper.addSimpleHandler("upcoming.yahoo.com", "pk_to_profile",
|
1308
|
+
"http://upcoming.yahoo.com/user/", "/");
|
1309
|
+
nodemapper.addSimpleHandler("upcoming.yahoo.com", "pk_to_rss",
|
1310
|
+
"http://upcoming.yahoo.com/syndicate/v2/my_events/");
|
1311
|
+
nodemapper.registerDomain("socializr.com",
|
1312
|
+
{name: "Socializr",
|
1313
|
+
identRegexp: /^[A-Za-z]\w{2,}$/});
|
1314
|
+
nodemapper.addSimpleHandler("socializr.com", "ident_to_profile",
|
1315
|
+
"http://www.socializr.com/user/");
|
1316
|
+
nodemapper.addSimpleHandler("socializr.com", "ident_to_rss",
|
1317
|
+
"http://www.socializr.com/rss/user/", "/rss.xml");
|
1318
|
+
nodemapper.addSimpleHandler("socializr.com", "pk_to_profile",
|
1319
|
+
"http://www.socializr.com/user/");
|
1320
|
+
nodemapper.addSimpleHandler("socializr.com", "pk_to_rss",
|
1321
|
+
"http://www.socializr.com/rss/user/", "/rss.xml");
|
1322
|
+
nodemapper.registerDomain("furl.net",
|
1323
|
+
{name: "Furl",
|
1324
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1325
|
+
"members", "furl.net", {slashAnything: 1})});
|
1326
|
+
nodemapper.addSimpleHandler("furl.net", "ident_to_profile",
|
1327
|
+
"http://www.furl.net/members/");
|
1328
|
+
nodemapper.addSimpleHandler("furl.net", "ident_to_rss",
|
1329
|
+
"http://www.furl.net/members/", "/rss.xml");
|
1330
|
+
nodemapper.registerDomain("dailymotion.com",
|
1331
|
+
{name: "DailyMotion",
|
1332
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1333
|
+
"dailymotion.com", /^\/(?:rss\/)?(\w+)(?:\/|$|\?from=)/, {slashAnything: 1})});
|
1334
|
+
nodemapper.addSimpleHandler("dailymotion.com", "ident_to_profile",
|
1335
|
+
"http://www.dailymotion.com/");
|
1336
|
+
nodemapper.addSimpleHandler("dailymotion.com", "ident_to_rss",
|
1337
|
+
"http://www.dailymotion.com/rss/", "/1");
|
1338
|
+
nodemapper.registerDomain("vimeo.com",
|
1339
|
+
{name: "Vimeo",
|
1340
|
+
urlToGraphNode: nodemapper.createSlashUsernameHandler(
|
1341
|
+
"vimeo.com", {slashAnything: 1})});
|
1342
|
+
nodemapper.addSimpleHandler("vimeo.com", "ident_to_profile",
|
1343
|
+
"http://www.vimeo.com/");
|
1344
|
+
nodemapper.addSimpleHandler("vimeo.com", "ident_to_rss",
|
1345
|
+
"http://www.vimeo.com/", "/videos/rss");
|
1346
|
+
nodemapper.registerDomain("d.hatena.ne.jp",
|
1347
|
+
{name: "Hatena::Diary",
|
1348
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1349
|
+
"d.hatena.ne.jp", /^\/([\w-]+)(?:\/|$)/, {casePreserve: 1})});
|
1350
|
+
nodemapper.addSimpleHandler("d.hatena.ne.jp", "ident_to_profile",
|
1351
|
+
"http://d.hatena.ne.jp/", "/");
|
1352
|
+
nodemapper.addSimpleHandler("d.hatena.ne.jp", "ident_to_rss",
|
1353
|
+
"http://d.hatena.ne.jp/", "/rss");
|
1354
|
+
nodemapper.addSimpleHandler("d.hatena.ne.jp", "ident_to_foaf",
|
1355
|
+
"http://d.hatena.ne.jp/", "/foaf");
|
1356
|
+
nodemapper.registerDomain("disqus.com",
|
1357
|
+
{name: "Disqus",
|
1358
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1359
|
+
"people", "disqus.com", {slashAnything: 1})});
|
1360
|
+
nodemapper.addSimpleHandler("disqus.com", "ident_to_profile",
|
1361
|
+
"http://www.disqus.com/people/");
|
1362
|
+
nodemapper.addSimpleHandler("disqus.com", "ident_to_rss",
|
1363
|
+
"http://www.disqus.com/people/", "/comments.rss");
|
1364
|
+
var rateitallHandler = function(url, host, path) {
|
1365
|
+
var handler;
|
1366
|
+
if (path.match(/\/rss-u-[A-Za-z]/)) {
|
1367
|
+
handler = nodemapper.createPathRegexpHandler(
|
1368
|
+
"rateitall.com", /^\/rss-u-([A-Za-z][\w-]*).aspx$/);
|
1369
|
+
} else if (path.match(/\/rss-u-[0-9]/)) {
|
1370
|
+
handler = nodemapper.createPathRegexpHandler(
|
1371
|
+
"rateitall.com", /^\/rss-u-([0-9]+).aspx$/, {keyName: "pk"});
|
1372
|
+
} else if (path.match(/\/usercommentsrss.aspx\?RI=[A-Za-z]/)) {
|
1373
|
+
handler = nodemapper.createPathRegexpHandler(
|
1374
|
+
"rateitall.com", /^\/usercommentsrss.aspx\?RI=([A-Za-z][\w-]*)/);
|
1375
|
+
} else if (path.match(/\/usercommentsrss.aspx\?RI=[0-9]/)) {
|
1376
|
+
handler = nodemapper.createPathRegexpHandler(
|
1377
|
+
"rateitall.com", /^\/usercommentsrss.aspx\?RI=([0-9]+)/, {keyName: "pk"});
|
1378
|
+
} else {
|
1379
|
+
handler = nodemapper.createSlashUsernameHandler("rateitall.com");
|
1380
|
+
}
|
1381
|
+
return handler(url, host, path);
|
1382
|
+
};
|
1383
|
+
nodemapper.registerDomain("rateitall.com",
|
1384
|
+
{name: "RateItAll",
|
1385
|
+
identRegexp: /^(?!rss-)[A-Za-z][\w-]*$/,
|
1386
|
+
urlToGraphNode: rateitallHandler});
|
1387
|
+
nodemapper.addSimpleHandler("rateitall.com", "ident_to_profile",
|
1388
|
+
"http://www.rateitall.com/");
|
1389
|
+
nodemapper.addSimpleHandler("rateitall.com", "pk_to_profile",
|
1390
|
+
"http://www.rateitall.com/Profile.aspx?userID=");
|
1391
|
+
nodemapper.addSimpleHandler("rateitall.com", "ident_to_rss",
|
1392
|
+
"http://www.rateitall.com/rss-u-", ".aspx");
|
1393
|
+
nodemapper.addSimpleHandler("rateitall.com", "pk_to_rss",
|
1394
|
+
"http://www.rateitall.com/rss-u-", ".aspx");
|
1395
|
+
nodemapper.registerDomain("slideshare.net",
|
1396
|
+
{name: "SlideShare",
|
1397
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1398
|
+
"slideshare.net", /^\/(?:rss\/user\/)?(\w+)(?:\/|$)/, {slashAnything: 1})});
|
1399
|
+
nodemapper.addSimpleHandler("slideshare.net", "ident_to_profile",
|
1400
|
+
"http://www.slideshare.net/");
|
1401
|
+
nodemapper.addSimpleHandler("slideshare.net", "ident_to_rss",
|
1402
|
+
"http://www.slideshare.net/rss/user/");
|
1403
|
+
nodemapper.registerDomain("blog.sina.com.cn",
|
1404
|
+
{name: "Sina Blog"});
|
1405
|
+
nodemapper.addSimpleHandler("blog.sina.com.cn", "ident_to_profile",
|
1406
|
+
"http://blog.sina.com.cn/");
|
1407
|
+
nodemapper.addSimpleHandler("blog.sina.com.cn", "ident_to_rss",
|
1408
|
+
"http://blog.sina.com.cn/rss/", ".xml");
|
1409
|
+
nodemapper.registerDomain("hi.baidu.com",
|
1410
|
+
{name: "Baidu Space"});
|
1411
|
+
nodemapper.addSimpleHandler("hi.baidu.com", "ident_to_profile",
|
1412
|
+
"http://hi.baidu.com/");
|
1413
|
+
nodemapper.addSimpleHandler("hi.baidu.com", "ident_to_rss",
|
1414
|
+
"http://hi.baidu.com/", "/rss");
|
1415
|
+
nodemapper.registerDomain(
|
1416
|
+
"blogbus.com",
|
1417
|
+
{name: "Blogbus",
|
1418
|
+
urlToGraphNode: nodemapper.createUserIsSubdomainHandler("blogbus.com")});
|
1419
|
+
nodemapper.addSimpleHandler("blogbus.com", "ident_to_profile",
|
1420
|
+
"http://", ".blogbus.com/");
|
1421
|
+
nodemapper.addSimpleHandler("blogbus.com", "ident_to_rss",
|
1422
|
+
"http://", ".blogbus.com/index.rdf");
|
1423
|
+
nodemapper.registerDomain("bebo.com",
|
1424
|
+
{name: "Bebo",
|
1425
|
+
identRegexp: /^[A-Za-z]\w{2,}$/});
|
1426
|
+
nodemapper.addSimpleHandler("bebo.com", "pk_to_profile",
|
1427
|
+
"http://bebo.com/Profile.jsp?MemberId=");
|
1428
|
+
nodemapper.addSimpleHandler("bebo.com", "ident_to_profile",
|
1429
|
+
"http://bebo.com/");
|
1430
|
+
nodemapper.addSimpleHandler("bebo.com", "pk_to_rss",
|
1431
|
+
"http://bebo.com/api/BlogRss.jsp?MemberId=");
|
1432
|
+
nodemapper.registerDomain("reddit.com",
|
1433
|
+
{name: "Reddit",
|
1434
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1435
|
+
"user", "reddit.com", {slashAnything: 1})});
|
1436
|
+
nodemapper.addSimpleHandler("reddit.com", "ident_to_profile",
|
1437
|
+
"http://reddit.com/user/");
|
1438
|
+
nodemapper.addSimpleHandler("reddit.com", "ident_to_rss",
|
1439
|
+
"http://reddit.com/user/", "/submitted.rss");
|
1440
|
+
nodemapper.registerDomain("ilike.com",
|
1441
|
+
{name: "iLike",
|
1442
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1443
|
+
"user", "ilike.com", {slashAnything: 1})});
|
1444
|
+
nodemapper.addSimpleHandler("ilike.com", "ident_to_profile",
|
1445
|
+
"http://www.ilike.com/user/");
|
1446
|
+
nodemapper.addSimpleHandler("ilike.com", "ident_to_rss",
|
1447
|
+
"http://www.ilike.com/user/", "/songs_ilike.rss");
|
1448
|
+
nodemapper.registerDomain(
|
1449
|
+
"multiply.com",
|
1450
|
+
{name: "Multiply",
|
1451
|
+
urlToGraphNode: nodemapper.createUserIsSubdomainHandler("multiply.com")});
|
1452
|
+
nodemapper.addSimpleHandler("multiply.com", "ident_to_profile",
|
1453
|
+
"http://", ".multiply.com/");
|
1454
|
+
nodemapper.addSimpleHandler("multiply.com", "ident_to_rss",
|
1455
|
+
"http://", ".multiply.com/feed.rss");
|
1456
|
+
nodemapper.registerDomain(
|
1457
|
+
"dopplr.com",
|
1458
|
+
{name: "Dopplr",
|
1459
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1460
|
+
"traveller", "dopplr.com")});
|
1461
|
+
nodemapper.addSimpleHandler("dopplr.com", "ident_to_profile",
|
1462
|
+
"http://www.dopplr.com/traveller/", "");
|
1463
|
+
nodemapper.registerDomain(
|
1464
|
+
"c2.com",
|
1465
|
+
{name: "c2.com",
|
1466
|
+
notMassMarketSite: true,
|
1467
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1468
|
+
"c2.com",
|
1469
|
+
/^\/cgi\/wiki\?(.*)/,
|
1470
|
+
{casePreserve: 1}),
|
1471
|
+
identCasePreserve: 1
|
1472
|
+
});
|
1473
|
+
nodemapper.addSimpleHandler("c2.com", "ident_to_profile",
|
1474
|
+
"http://c2.com/cgi/wiki?");
|
1475
|
+
nodemapper.registerDomain(
|
1476
|
+
"bookshelved.org",
|
1477
|
+
{name: "Bookshelved",
|
1478
|
+
notMassMarketSite: true,
|
1479
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1480
|
+
"bookshelved.org",
|
1481
|
+
/^\/cgi\-bin\/wiki\.pl\?(.*)/,
|
1482
|
+
{casePreserve: 1}),
|
1483
|
+
identCasePreserve: 1
|
1484
|
+
});
|
1485
|
+
nodemapper.addSimpleHandler("bookshelved.org", "ident_to_profile",
|
1486
|
+
"http://bookshelved.org/cgi-bin/wiki.pl?");
|
1487
|
+
nodemapper.registerDomain(
|
1488
|
+
["xpdeveloper.net", "xpdeveloper.org"],
|
1489
|
+
{name: "XP Developer",
|
1490
|
+
primaryDomain: "xpdeveloper.net", // is this?
|
1491
|
+
notMassMarketSite: true,
|
1492
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1493
|
+
"xpdeveloper.net",
|
1494
|
+
/^\/xpdwiki\/Wiki\.jsp\?page=(.*)/,
|
1495
|
+
{casePreserve: 1}),
|
1496
|
+
identCasePreserve: 1
|
1497
|
+
});
|
1498
|
+
nodemapper.addSimpleHandler("xpdeveloper.net", "ident_to_profile",
|
1499
|
+
"http://xpdeveloper.net/xpdwiki/Wiki.jsp?page=");
|
1500
|
+
nodemapper.registerDomain(
|
1501
|
+
"usemod.com",
|
1502
|
+
{name: "UseModWiki",
|
1503
|
+
notMassMarketSite: true,
|
1504
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1505
|
+
"usemod.com",
|
1506
|
+
/^\/cgi\-bin\/mb\.pl\?(.*)/,
|
1507
|
+
{casePreserve: 1}),
|
1508
|
+
identCasePreserve: 1
|
1509
|
+
});
|
1510
|
+
nodemapper.addSimpleHandler("usemod.com", "ident_to_profile",
|
1511
|
+
"http://usemod.com/cgi-bin/mb.pl?");
|
1512
|
+
nodemapper.registerDomain(
|
1513
|
+
"advogato.org",
|
1514
|
+
{name: "Advogato",
|
1515
|
+
notMassMarketSite: true,
|
1516
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1517
|
+
"advogato.org",
|
1518
|
+
/^\/person\/(\w+)/)
|
1519
|
+
});
|
1520
|
+
nodemapper.addSimpleHandler("advogato.org", "ident_to_profile",
|
1521
|
+
"http://www.advogato.org/person/", "/");
|
1522
|
+
nodemapper.addSimpleHandler("advogato.org", "ident_to_foaf",
|
1523
|
+
"http://www.advogato.org/person/", "/foaf.rdf");
|
1524
|
+
nodemapper.registerDomain("weeloop.com",
|
1525
|
+
{name: "weeloop",
|
1526
|
+
urlToGraphNode: nodemapper.createUserIsSubdomainHandler("weeloop.com")
|
1527
|
+
});
|
1528
|
+
nodemapper.addSimpleHandler("weeloop.com", "ident_to_foaf",
|
1529
|
+
"http://", ".weeloop.com/foaf.rdf");
|
1530
|
+
nodemapper.addSimpleHandler("weeloop.com", "ident_to_profile",
|
1531
|
+
"http://", ".weeloop.com/profile");
|
1532
|
+
nodemapper.addSimpleHandler("weeloop.com", "ident_to_atom",
|
1533
|
+
"http://", ".weeloop.com/api/post?mimeType=application/atom+xml");
|
1534
|
+
nodemapper.registerDomain("planeta.rambler.ru",
|
1535
|
+
{name: "Rambler-Planeta",
|
1536
|
+
identRegexp: /^[\w\.]+$/,
|
1537
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1538
|
+
"planeta.rambler.ru",
|
1539
|
+
/^\/users\/([\w\.]+)/)
|
1540
|
+
});
|
1541
|
+
nodemapper.addSimpleHandler("planeta.rambler.ru", "ident_to_foaf",
|
1542
|
+
"http://planeta.rambler.ru/users/", "/friends/foaf/");
|
1543
|
+
nodemapper.addSimpleHandler("planeta.rambler.ru", "ident_to_rss",
|
1544
|
+
"http://planeta.rambler.ru/users/", "/rss/");
|
1545
|
+
nodemapper.registerDomain("mojageneracja.pl",
|
1546
|
+
{name: "MojaGeneracja",
|
1547
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1548
|
+
"mojageneracja.pl",
|
1549
|
+
/^\/(\d+)(?:\/|$)/, {keyName: "pk"})
|
1550
|
+
});
|
1551
|
+
nodemapper.addSimpleHandler("mojageneracja.pl", "pk_to_profile",
|
1552
|
+
"http://www.mojageneracja.pl/", "/");
|
1553
|
+
nodemapper.addSimpleHandler("mojageneracja.pl", "pk_to_rss",
|
1554
|
+
"http://www.mojageneracja.pl/", "/rss");
|
1555
|
+
nodemapper.registerDomain(
|
1556
|
+
"goodreads.com",
|
1557
|
+
{name: "goodreads",
|
1558
|
+
urlToGraphNode: nodemapper.createSomethingSlashUsernameHandler(
|
1559
|
+
"user/show", "goodreads.com", {keyName: "pk"})});
|
1560
|
+
nodemapper.addSimpleHandler("goodreads.com", "pk_to_profile",
|
1561
|
+
"http://www.goodreads.com/user/show/");
|
1562
|
+
nodemapper.addSimpleHandler("goodreads.com", "pk_to_rss",
|
1563
|
+
"http://www.goodreads.com/review/list_rss/");
|
1564
|
+
nodemapper.registerDomain("tripit.com", {
|
1565
|
+
name: "TripIt",
|
1566
|
+
identRegexp: /^[-\w\+\.]+$/,
|
1567
|
+
urlToGraphNode: nodemapper.createPathRegexpHandler(
|
1568
|
+
"tripit.com", /^\/people\/([-\w\+\.]+)/ )
|
1569
|
+
});
|
1570
|
+
nodemapper.addSimpleHandler("tripit.com", "ident_to_profile",
|
1571
|
+
"http://tripit.com/people/");
|
1572
|
+
})();
|
1573
|
+
(function(){
|
1574
|
+
spinPkHandler = function(url, host, path) {
|
1575
|
+
var primaryKeyRegexp = /^\/(?:hp|foaf)\/,([0-9a-fA-F]+)($|\/)/;
|
1576
|
+
var m;
|
1577
|
+
if (!(m = primaryKeyRegexp.exec(path))) {
|
1578
|
+
return url;
|
1579
|
+
}
|
1580
|
+
return "sgn://spin.de/?pk=" + m[1].toLowerCase();
|
1581
|
+
};
|
1582
|
+
spinIdentHandler = nodemapper.createPathRegexpHandler(
|
1583
|
+
"spin.de",
|
1584
|
+
/^\/(?:hp|foaf)\/([^\/,]+)/,
|
1585
|
+
{ fallbackHandler: spinPkHandler,
|
1586
|
+
casePreserve: 0
|
1587
|
+
});
|
1588
|
+
nodemapper.registerDomain("spin.de", {
|
1589
|
+
name: "spin.de",
|
1590
|
+
urlToGraphNode: spinIdentHandler,
|
1591
|
+
pkRegexp: /^,[0-9a-fA-F]+$/,
|
1592
|
+
identRegexp: /^\w+$/
|
1593
|
+
});
|
1594
|
+
nodemapper.addSimpleHandler("spin.de", "ident_to_foaf",
|
1595
|
+
"http://www.spin.de/foaf/", "");
|
1596
|
+
nodemapper.addSimpleHandler("spin.de", "pk_to_foaf",
|
1597
|
+
"http://www.spin.de/foaf/,", "");
|
1598
|
+
nodemapper.addSimpleHandler("spin.de", "ident_to_profile",
|
1599
|
+
"http://www.spin.de/hp/", "/");
|
1600
|
+
nodemapper.addSimpleHandler("spin.de", "pk_to_profile",
|
1601
|
+
"http://www.spin.de/hp/,", "/");
|
1602
|
+
nodemapper.addSimpleHandler("spin.de", "ident_to_blog",
|
1603
|
+
"http://www.spin.de/hp/", "/blog");
|
1604
|
+
nodemapper.addSimpleHandler("spin.de", "pk_to_blog",
|
1605
|
+
"http://www.spin.de/hp/,", "/blog");
|
1606
|
+
})();
|
1607
|
+
(function(){
|
1608
|
+
var stumbleuponCompoundHandler = function(url, host, path) {
|
1609
|
+
var handler;
|
1610
|
+
if (host.indexOf('www.') == 0 || host.indexOf('rss.') == 0) {
|
1611
|
+
if (path.indexOf('syndicate.php') != -1) {
|
1612
|
+
handler = nodemapper.createPathRegexpHandler("stumbleupon.com",
|
1613
|
+
/^\/syndicate.php\?stumbler=([^&]+)/);
|
1614
|
+
} else {
|
1615
|
+
handler = nodemapper.createSomethingSlashUsernameHandler(
|
1616
|
+
"(?:user|stumbler)", "stumbleupon.com", {slashAnything:1});
|
1617
|
+
}
|
1618
|
+
} else handler = nodemapper.createUserIsSubdomainHandler("stumbleupon.com");
|
1619
|
+
return handler(url, host, path);
|
1620
|
+
};
|
1621
|
+
nodemapper.registerDomain(
|
1622
|
+
"stumbleupon.com",
|
1623
|
+
{name: "StumbleUpon",
|
1624
|
+
urlToGraphNode: stumbleuponCompoundHandler});
|
1625
|
+
nodemapper.addSimpleHandler("stumbleupon.com", "ident_to_profile",
|
1626
|
+
"http://", ".stumbleupon.com");
|
1627
|
+
nodemapper.addSimpleHandler("stumbleupon.com", "ident_to_rss",
|
1628
|
+
"http://rss.stumbleupon.com/user/", "/favorites");
|
1629
|
+
})();
|
1630
|
+
(function(){
|
1631
|
+
nodemapper.registerDomain(
|
1632
|
+
"x.foo.test", {
|
1633
|
+
blah: {},
|
1634
|
+
_name_for_testing: "x.foo.test (the specific one)"
|
1635
|
+
});
|
1636
|
+
nodemapper.registerDomain(
|
1637
|
+
"foo.test", {
|
1638
|
+
accountToSgn: {},
|
1639
|
+
_name_for_testing: "foo.test"
|
1640
|
+
});
|
1641
|
+
})();
|
1642
|
+
(function(){
|
1643
|
+
var pkMatcher = nodemapper.createPathRegexpHandler(
|
1644
|
+
"threadless.com",
|
1645
|
+
/\/(?:profile|rss\/blog)\/(\d+)\/?$/,
|
1646
|
+
{keyName:"pk"});
|
1647
|
+
var identMatcher = nodemapper.createPathRegexpHandler(
|
1648
|
+
"threadless.com",
|
1649
|
+
/\/(?:profile|rss\/blog)\/(\d+\/\w+)(?:\/.*)?$/,
|
1650
|
+
{fallbackHandler: pkMatcher});
|
1651
|
+
nodemapper.registerDomain(
|
1652
|
+
"threadless.com",
|
1653
|
+
{name: "Threadless",
|
1654
|
+
urlToGraphNode: identMatcher,
|
1655
|
+
identRegexp: /^\d+\/\w+$/});
|
1656
|
+
nodemapper.addSimpleHandler("threadless.com", "pk_to_rss",
|
1657
|
+
"http://www.threadless.com/rss/blog/", "");
|
1658
|
+
nodemapper.addSimpleHandler("threadless.com", "ident_to_rss",
|
1659
|
+
"http://www.threadless.com/rss/blog/", "");
|
1660
|
+
nodemapper.addSimpleHandler("threadless.com", "pk_to_profile",
|
1661
|
+
"http://www.threadless.com/profile/", "");
|
1662
|
+
nodemapper.addSimpleHandler("threadless.com", "ident_to_profile",
|
1663
|
+
"http://www.threadless.com/profile/", "");
|
1664
|
+
nodemapper.addSimpleHandler("threadless.com", "ident_to_blog",
|
1665
|
+
"http://www.threadless.com/profile/", "/blogs");
|
1666
|
+
})();
|
1667
|
+
(function(){
|
1668
|
+
tribePkHandler = function(url, host, path) {
|
1669
|
+
var primaryKeyRegexp = /^\/([\w\-]{36})(?:\/(?:foaf|blog)|\/$|$)/;
|
1670
|
+
var m;
|
1671
|
+
if (!(m = primaryKeyRegexp.exec(path))) {
|
1672
|
+
return url;
|
1673
|
+
}
|
1674
|
+
return "sgn://tribe.net/?pk=" + m[1].toLowerCase();
|
1675
|
+
};
|
1676
|
+
tribeIdentHandler = nodemapper.createPathRegexpHandler(
|
1677
|
+
"tribe.net",
|
1678
|
+
/^\/(\w+)(?:\/(?:foaf|blog)|\/$|$)/,
|
1679
|
+
{ fallbackHandler: tribePkHandler }
|
1680
|
+
);
|
1681
|
+
nodemapper.registerDomain("tribe.net", {
|
1682
|
+
name: "Tribe.net",
|
1683
|
+
pkRegexp: /^[\w\-]{36}$/,
|
1684
|
+
identRegexp: /^\w+$/
|
1685
|
+
});
|
1686
|
+
nodemapper.registerDomain("people.tribe.net", {
|
1687
|
+
urlToGraphNode: tribeIdentHandler
|
1688
|
+
});
|
1689
|
+
nodemapper.addSimpleHandler("tribe.net", "ident_to_foaf",
|
1690
|
+
"http://people.tribe.net/", "/foaf");
|
1691
|
+
nodemapper.addSimpleHandler("tribe.net", "pk_to_foaf",
|
1692
|
+
"http://people.tribe.net/", "/foaf");
|
1693
|
+
nodemapper.addSimpleHandler("tribe.net", "ident_to_profile",
|
1694
|
+
"http://people.tribe.net/");
|
1695
|
+
nodemapper.addSimpleHandler("tribe.net", "pk_to_profile",
|
1696
|
+
"http://people.tribe.net/");
|
1697
|
+
})();
|
1698
|
+
(function(){
|
1699
|
+
var FRIENDS_API1_RE = /^\/friends\/ids\/(\w+)\.(?:xml|json)/;
|
1700
|
+
var FRIENDS_API2_RE = /^\/friends\/ids\.(?:xml|json)\?screen_name=(\w+)/;
|
1701
|
+
var HASH_BANG_RE = /^\/#!\/(\w+)/;
|
1702
|
+
var twitterFallbackHandler = function(url, host, path) {
|
1703
|
+
var m;
|
1704
|
+
if ((m = FRIENDS_API1_RE.exec(path)) ||
|
1705
|
+
(m = FRIENDS_API2_RE.exec(path)) ||
|
1706
|
+
(m = HASH_BANG_RE.exec(path))) {
|
1707
|
+
var username = m[1].toLowerCase();
|
1708
|
+
return "sgn://twitter.com/?ident=" + username;
|
1709
|
+
}
|
1710
|
+
return url;
|
1711
|
+
};
|
1712
|
+
var NOT_USERNAMES = {
|
1713
|
+
"statuses": 1,
|
1714
|
+
"friends": 1
|
1715
|
+
};
|
1716
|
+
nodemapper.registerDomain(
|
1717
|
+
"twitter.com",
|
1718
|
+
{ httpsLikeHttp: 1,
|
1719
|
+
name: "Twitter",
|
1720
|
+
accountToSgn: { pk: ["twitter.com"], ident: ["twitter.com"] },
|
1721
|
+
notUsernames: NOT_USERNAMES,
|
1722
|
+
urlToGraphNode: nodemapper.createSlashUsernameHandler(
|
1723
|
+
"twitter.com",
|
1724
|
+
{slashAnything: 1,
|
1725
|
+
notUsernames: NOT_USERNAMES,
|
1726
|
+
fallbackHandler: twitterFallbackHandler
|
1727
|
+
})
|
1728
|
+
});
|
1729
|
+
nodemapper.addSimpleHandler("twitter.com", "ident_to_profile",
|
1730
|
+
"http://twitter.com/");
|
1731
|
+
nodemapper.addSimpleHandler("twitter.com", "ident_to_rss",
|
1732
|
+
"http://twitter.com/statuses/user_timeline/", ".rss");
|
1733
|
+
nodemapper.addSimpleHandler("twitter.com", "ident_to_atom",
|
1734
|
+
"http://twitter.com/statuses/user_timeline/", ".atom");
|
1735
|
+
nodemapper.addSimpleHandler("twitter.com", "pk_to_rss",
|
1736
|
+
"http://twitter.com/statuses/user_timeline/", ".rss");
|
1737
|
+
nodemapper.addSimpleHandler("twitter.com", "pk_to_atom",
|
1738
|
+
"http://twitter.com/statuses/user_timeline/", ".atom");
|
1739
|
+
})();
|
1740
|
+
(function(){
|
1741
|
+
var SOFTWARE_REGEXP = /^\/software\/([\w-]+)/;
|
1742
|
+
var USER_REGEXP = /^\/(\w+)(?:\/|$)/;
|
1743
|
+
var toSgn = function(url, host, path) {
|
1744
|
+
var m;
|
1745
|
+
if (m = SOFTWARE_REGEXP.exec(path)) {
|
1746
|
+
return "sgn://software.wakoopa.com/?ident=" + m[1].toLowerCase();
|
1747
|
+
}
|
1748
|
+
if (m = USER_REGEXP.exec(path)) {
|
1749
|
+
return "sgn://wakoopa.com/?ident=" + m[1].toLowerCase();
|
1750
|
+
}
|
1751
|
+
return url;
|
1752
|
+
};
|
1753
|
+
nodemapper.registerDomain("wakoopa.com", {
|
1754
|
+
name: "Wakoopa",
|
1755
|
+
urlToGraphNode: toSgn
|
1756
|
+
});
|
1757
|
+
nodemapper.registerDomain("software.wakoopa.com", {
|
1758
|
+
name: "Wakoopa Software",
|
1759
|
+
notMassMarketSite: true,
|
1760
|
+
identRegexp: /^[\w-]+$/
|
1761
|
+
});
|
1762
|
+
nodemapper.addSimpleHandler("wakoopa.com", "ident_to_profile",
|
1763
|
+
"http://wakoopa.com/");
|
1764
|
+
nodemapper.addSimpleHandler("software.wakoopa.com", "ident_to_profile",
|
1765
|
+
"http://wakoopa.com/software/");
|
1766
|
+
})();
|
1767
|
+
(function(){
|
1768
|
+
var DOMAIN_RE = /^(?:www\.)?([\w\-]+)\.wordpress\.com$/;
|
1769
|
+
function wordpressHandler(url, host, path) {
|
1770
|
+
var m = DOMAIN_RE.exec(host);
|
1771
|
+
var ident = m ? m[1].toLowerCase() : "";
|
1772
|
+
if (!m || ident == "www" || ident.length == 2 ||
|
1773
|
+
(ident.length == 5 && ident.substr(2, 1) == "-")) {
|
1774
|
+
return url;
|
1775
|
+
}
|
1776
|
+
return "sgn://wordpress.com/?ident=" + ident;
|
1777
|
+
}
|
1778
|
+
nodemapper.registerDomain(
|
1779
|
+
"wordpress.com",
|
1780
|
+
{name: "WordPress",
|
1781
|
+
skipAutomaticHttpToSgn: true,
|
1782
|
+
urlToGraphNode: wordpressHandler});
|
1783
|
+
nodemapper.addSimpleHandler("wordpress.com", "ident_to_blog",
|
1784
|
+
"http://", ".wordpress.com/");
|
1785
|
+
})();
|
1786
|
+
(function(){
|
1787
|
+
var yelpCompoundHandler = function(url, host, path) {
|
1788
|
+
var handler;
|
1789
|
+
if (host.indexOf("www.") == 0 || path.indexOf('user_details') != -1 || path.indexOf('syndicate/user') != -1) {
|
1790
|
+
handler = nodemapper.createPathRegexpHandler("yelp.com",
|
1791
|
+
/^(?:\/user_details\?userid=|\/syndicate\/user\/)([\w\-]+)/,
|
1792
|
+
{keyName: "pk", casePreserve: 1});
|
1793
|
+
} else handler = nodemapper.createUserIsSubdomainHandler("yelp.com");
|
1794
|
+
return handler(url, host, path);
|
1795
|
+
};
|
1796
|
+
nodemapper.registerDomain("yelp.com", {
|
1797
|
+
name: "Yelp",
|
1798
|
+
urlToGraphNode: yelpCompoundHandler,
|
1799
|
+
pkRegexp: /^(?=\w)[\w-]{22}$/,
|
1800
|
+
identRegexp: /^[\w\-]+$/
|
1801
|
+
});
|
1802
|
+
nodemapper.addSimpleHandler("yelp.com", "pk_to_rss",
|
1803
|
+
"http://www.yelp.com/syndicate/user/", "/rss.xml");
|
1804
|
+
nodemapper.addSimpleHandler("yelp.com", "pk_to_profile",
|
1805
|
+
"http://www.yelp.com/user_details?userid=");
|
1806
|
+
nodemapper.addSimpleHandler("yelp.com", "ident_to_profile",
|
1807
|
+
"http://", ".yelp.com");
|
1808
|
+
})();
|
1809
|
+
(function(){
|
1810
|
+
var SLASH_WORD_MAYBEWORD = /^\/(\w+)(?:\/(\w+))?(?:\/|$)/;
|
1811
|
+
var SLASH_PK_REGEXP = /\b(\d+\@Z\d\d)\b/;
|
1812
|
+
var userFirstPaths = {
|
1813
|
+
'people': 1,
|
1814
|
+
'photos': 1,
|
1815
|
+
'zipline': 1
|
1816
|
+
};
|
1817
|
+
var userSecondPaths = {
|
1818
|
+
'fans': 1,
|
1819
|
+
'statuses': 1,
|
1820
|
+
'favorites': 1,
|
1821
|
+
'mutual': 1,
|
1822
|
+
'with_friends': 1
|
1823
|
+
};
|
1824
|
+
var toSgn = function(url, host, path) {
|
1825
|
+
var m;
|
1826
|
+
if (m = SLASH_PK_REGEXP.exec(path)) {
|
1827
|
+
return "sgn://zooomr.com/?pk=" + m[1];
|
1828
|
+
}
|
1829
|
+
if (!(m = SLASH_WORD_MAYBEWORD.exec(path))) {
|
1830
|
+
return url;
|
1831
|
+
}
|
1832
|
+
if (userFirstPaths[m[1]]) {
|
1833
|
+
if (!m[2]) {
|
1834
|
+
return url;
|
1835
|
+
}
|
1836
|
+
return "sgn://zooomr.com/?ident=" + m[2].toLowerCase();
|
1837
|
+
}
|
1838
|
+
if (!m[2] || userSecondPaths[m[2]] || m[2].substr(0, 4) == "page") {
|
1839
|
+
return "sgn://zooomr.com/?ident=" + m[1].toLowerCase();
|
1840
|
+
}
|
1841
|
+
return url;
|
1842
|
+
};
|
1843
|
+
nodemapper.registerDomain("zooomr.com",
|
1844
|
+
{name: "Zooomr",
|
1845
|
+
urlToGraphNode: toSgn,
|
1846
|
+
pkRegexp: /^\d+\@Z\d\d$/
|
1847
|
+
});
|
1848
|
+
nodemapper.addSimpleHandler("zooomr.com", "ident_to_profile",
|
1849
|
+
"http://www.zooomr.com/people/", "/");
|
1850
|
+
nodemapper.addSimpleHandler("zooomr.com", "ident_to_content",
|
1851
|
+
"http://www.zooomr.com/photos/", "/");
|
1852
|
+
nodemapper.addSimpleHandler("zooomr.com", "ident_to_rss",
|
1853
|
+
"http://www.zooomr.com/services/feeds/public_photos/?id=",
|
1854
|
+
"&format=rss_200");
|
1855
|
+
nodemapper.addSimpleHandler("zooomr.com", "pk_to_profile",
|
1856
|
+
"http://www.zooomr.com/people/", "/");
|
1857
|
+
nodemapper.addSimpleHandler("zooomr.com", "pk_to_content",
|
1858
|
+
"http://www.zooomr.com/photos/", "/");
|
1859
|
+
nodemapper.addSimpleHandler("zooomr.com", "pk_to_rss",
|
1860
|
+
"http://www.zooomr.com/services/feeds/public_photos/?id=",
|
1861
|
+
"&format=rss_200");
|
1862
|
+
})();
|