-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
8 changed files
with
141 additions
and
9 deletions.
There are no files selected for viewing
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
class QuotedPost < ActiveRecord::Base | ||
belongs_to :post | ||
belongs_to :quoted_post, class_name: 'Post' | ||
|
||
# NOTE we already have a path that does this for topic links, | ||
# however topic links exclude quotes and links within a topic | ||
# we are double parsing this fragment, this may be worth optimising later | ||
def self.extract_from(post) | ||
|
||
doc = Nokogiri::HTML.fragment(post.cooked) | ||
|
||
uniq = {} | ||
ids = [] | ||
|
||
doc.css("aside.quote[data-topic]").each do |a| | ||
topic_id = a['data-topic'].to_i | ||
post_number = a['data-post'].to_i | ||
|
||
next if topic_id == 0 || post_number == 0 | ||
next if uniq[[topic_id,post_number]] | ||
uniq[[topic_id,post_number]] = true | ||
|
||
|
||
# It would be so much nicer if we used post_id in quotes | ||
results = exec_sql "INSERT INTO quoted_posts(post_id, quoted_post_id, created_at, updated_at) | ||
SELECT :post_id, id, current_timestamp, current_timestamp | ||
FROM posts | ||
WHERE post_number = :post_number AND | ||
topic_id = :topic_id | ||
RETURNING quoted_post_id | ||
", post_id: post.id, post_number: post_number, topic_id: topic_id | ||
|
||
results = results.to_a | ||
|
||
if results.length > 0 | ||
ids << results[0]["quoted_post_id"].to_i | ||
end | ||
end | ||
|
||
if ids.length > 0 | ||
exec_sql "DELETE FROM quoted_posts WHERE post_id = :post_id AND quoted_post_id NOT IN (:ids)", | ||
post_id: post.id, ids: ids | ||
end | ||
|
||
end | ||
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
class AddQuotedPosts < ActiveRecord::Migration | ||
def change | ||
create_table :quoted_posts do |t| | ||
t.integer :post_id, null: false | ||
t.integer :quoted_post_id, null: false | ||
t.timestamps | ||
end | ||
|
||
add_index :quoted_posts, [:post_id, :quoted_post_id], unique: true | ||
add_index :quoted_posts, [:quoted_post_id, :post_id], unique: true | ||
|
||
|
||
# NOTE this can be done in pg but too much of a headache | ||
id = 0 | ||
while id = backfill_batch(id, 1000); end | ||
end | ||
|
||
def backfill_batch(start_id, batch_size) | ||
|
||
results = execute <<SQL | ||
SELECT id, cooked | ||
FROM posts | ||
WHERE raw like '%quote=%' AND id > #{start_id} | ||
ORDER BY id | ||
LIMIT #{batch_size} | ||
SQL | ||
|
||
max_id = nil | ||
|
||
results.each do |row| | ||
post_id, max_id = row["id"].to_i | ||
doc = Nokogiri::HTML.fragment(row["cooked"]) | ||
|
||
uniq = {} | ||
|
||
doc.css("aside.quote[data-topic]").each do |a| | ||
topic_id = a['data-topic'].to_i | ||
post_number = a['data-post'].to_i | ||
|
||
next if uniq[[topic_id,post_number]] | ||
uniq[[topic_id,post_number]] = true | ||
|
||
|
||
execute "INSERT INTO quoted_posts(post_id, quoted_post_id, created_at, updated_at) | ||
SELECT #{post_id}, id, created_at, updated_at | ||
FROM posts | ||
WHERE post_number = #{post_number} AND | ||
topic_id = #{topic_id}" | ||
end | ||
end | ||
|
||
max_id | ||
end | ||
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
require 'spec_helper' | ||
|
||
describe QuotedPost do | ||
it 'correctly extracts quotes in integration test' do | ||
post1 = create_post | ||
post2 = create_post(topic_id: post1.topic_id, | ||
raw: "[quote=\"#{post1.user.username}, post: 1, topic:#{post1.topic_id}\"]\ntest\n[/quote]\nthis is a test post") | ||
|
||
QuotedPost.find_by(post_id: post2.id, quoted_post_id: post1.id).should_not be_nil | ||
end | ||
|
||
it 'correctly handles deltas' do | ||
post1 = Fabricate(:post) | ||
post2 = Fabricate(:post) | ||
|
||
post2.cooked = <<HTML | ||
<aside class="quote" data-post="#{post1.post_number}" data-topic="#{post1.topic_id}"><div class="title"><div class="quote-controls"></div><img width="20" height="20" src="/user_avatar/meta.discourse.org/techapj/20/3281.png" class="avatar">techAPJ said:</div><blockquote><p>When the user will v</p></blockquote></aside> | ||
HTML | ||
|
||
QuotedPost.create!(post_id: post2.id, quoted_post_id: 999) | ||
|
||
QuotedPost.extract_from(post2) | ||
QuotedPost.where(post_id: post2.id).count.should == 1 | ||
QuotedPost.find_by(post_id: post2.id, quoted_post_id: post1.id).should_not be_nil | ||
|
||
end | ||
end |