Skip to content

Instantly share code, notes, and snippets.

@Ruxton

Ruxton/Gemfile Secret

Created June 20, 2016 08:58
Show Gist options
  • Save Ruxton/000fe3d21c9515a161eb2c5311953a84 to your computer and use it in GitHub Desktop.
Save Ruxton/000fe3d21c9515a161eb2c5311953a84 to your computer and use it in GitHub Desktop.
source 'http://rubygems.org'
gem 'rails', '~> 4.1.1'
gem 'microformats2'
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
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