-
-
Save Ruxton/000fe3d21c9515a161eb2c5311953a84 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source 'http://rubygems.org' | |
gem 'rails', '~> 4.1.1' | |
gem 'microformats2' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ActiveRecord::Schema.define(version: 20160614073723) do | |
create_table "comments", force: true do |t| | |
t.string "title", limit: 50, default: "" | |
t.text "comment" | |
t.integer "commentable_id" | |
t.string "commentable_type" | |
t.integer "user_id" | |
t.datetime "created_at", null: false | |
t.datetime "updated_at", null: false | |
t.string "comment_author" | |
t.string "comment_author_email" | |
t.string "comment_author_url" | |
t.string "user_agent" | |
t.string "ip_address" | |
t.string "status" | |
t.integer "site_id" | |
t.string "canonical" | |
t.string "comment_type", default: "reply" | |
t.string "source" | |
t.string "commenter_avatar_url" | |
end | |
add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_id", using: :btree | |
add_index "comments", ["commentable_type"], name: "index_comments_on_commentable_type", using: :btree | |
add_index "comments", ["site_id"], name: "index_comments_on_site_id", using: :btree | |
add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree | |
create_table "sites", force: true do |t| | |
t.string "domain", null: false | |
t.string "title", null: false | |
end | |
add_index "sites", ["domain"], name: "index_sites_on_domain", using: :btree | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class WebmentionsController < HostedController | |
def create | |
source_uri = params.require(:source) | |
target_uri = params.require(:target) | |
if !URI(target_uri).host.match(current_site.subdomain) | |
render text: "'target' is not on this site", status: 400 | |
end | |
if source_uri == target_uri | |
render text: "'source' and 'target' should not be the same", status: 400 | |
return | |
end | |
if source = ensure_source_has_target(source_uri,target_uri) | |
site = site_from_uri(target_uri) | |
mentioned_model = model_from_uri(site,target_uri) | |
if mentioned_model.nil? | |
render text: "'target' is not on this site", status: 400 | |
return | |
end | |
items = mf2_parse(source,mentioned_model) | |
if items.empty? | |
render text: "No mf2 h-entry on the source page", status: 400 | |
return | |
end | |
if comment = create_mention(source_uri,mentioned_model) | |
items.each do |item| | |
parse_reply_to(item,comment) | |
end | |
url = url_for([:hosted, mentioned_model]) | |
render text: url+"#comment-#{comment.id}", status: 200 | |
return | |
else | |
render text: "Error creating mention for #{target_uri}", status: 500 | |
return | |
end | |
else | |
render text: "'source' does not contain 'target' in it's content", status: 400 | |
return | |
end | |
end | |
private | |
def site_from_uri(uri) | |
uri = URI.parse(uri) | |
subdomain = uri.host.split(".")[0] | |
Site.find_by_domain( "#{subdomain}.subdomain") | |
end | |
def model_from_uri(site,uri) | |
uri = URI.parse(uri) | |
path = uri.path | |
model, slug = path.split("/")[1..-1] | |
site.send(model.pluralize).find(slug) | |
end | |
def ensure_source_has_target(source_uri,target_uri) | |
source = Net::HTTP.get(URI(source_uri)) | |
replacements = ['http://www.', 'http://', 'https://www.', 'https://'] | |
replacements.each do |replacement| | |
target_uri = target_uri.gsub(replacement,'') | |
end | |
if !source.downcase.include?(target_uri) | |
return false | |
else | |
return source | |
end | |
end | |
def create_mention(source_uri,mentioned_model) | |
mentioned_model.comments.create( | |
source: source_uri, | |
comment_type: "mention", | |
commenter_avatar_url: '', | |
comment_author: source_uri, | |
comment_author_url: source_uri, | |
ip_address: request.env['HTTP_X_FORWARDED_FOR'], | |
user_agent: request.env['HTTP_USER_AGENT'], | |
status: "pending", | |
site: mentioned_model.site, | |
comment: "This was mentioned on <a rel=\"nofollow\" href=\"#{source_uri}\">#{source_uri}</a>" | |
) | |
end | |
def parse_like(item,comment) | |
end | |
def parse_repost(item,comment) | |
end | |
def parse_favorite(item,comment) | |
end | |
def parse_bookmark(item,comment) | |
end | |
def parse_reply_to(item,comment) | |
reply_to = item["properties"]["in_reply_to"] | |
unless reply_to.nil? | |
reply_to.each do |reply| | |
if reply["properties"]["url"].present? && reply["properties"]["url"][0] == target_uri | |
author = reply["properties"]["author"] || item["properties"]["author"] | |
comment = item["properties"]["content"] | |
comment_author = author["properties"]["name"] | |
comment_author_url = author["properties"]["url"] | |
comment_avatar_url = author["properties"]["photo"] || nil | |
comment.update_attributes({comment: comment, comment_author: comment_author, comment_author_url: comment_author_url, comment_avatar_url: comment_avatar_url}) | |
end | |
end | |
end | |
end | |
def mf2_parse(source,mentioned_model) | |
source_mf2 = Microformats2.parse(source) | |
source_mf2 = JSON.parse(source_mf2.to_json) | |
source_mf2["items"].select { |a| a["type"][0] == "h-entry"} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment