Skip to content

Commit

Permalink
#144 deleter
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor256 committed May 13, 2020
1 parent 7ccf07c commit baf9e1a
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 43 deletions.
38 changes: 38 additions & 0 deletions liquibase/2020/012-deleters.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0"?>
<!--
(The MIT License)
Copyright (c) 2020 Yegor Bugayenko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the 'Software'), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd" logicalFilePath="001-initial-schema.xml">
<changeSet id="012" author="yegor256">
<sql>
ALTER TABLE project ADD COLUMN deleter INT REFERENCES author(id);
UPDATE project SET deleter=s.id FROM (SELECT id FROM author WHERE login='yegor256') AS s WHERE deleted IS NOT NULL;
ALTER TABLE project DROP COLUMN deleted;
</sql>
<sql>
ALTER TABLE review ADD COLUMN deleter INT REFERENCES author(id);
UPDATE review SET deleter=s.id FROM (SELECT id FROM author WHERE login='yegor256') AS s WHERE deleted IS NOT NULL;
ALTER TABLE review DROP COLUMN deleted;
</sql>
</changeSet>
</databaseChangeLog>
22 changes: 11 additions & 11 deletions objects/karma.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def legend
points: {
'2000-01-01': +1
},
query: 'SELECT * FROM project AS t WHERE author=$1 AND deleted IS NULL',
query: 'SELECT * FROM project AS t WHERE author=$1 AND deleter IS NULL',
terms: 'each project you submitted',
history: 'The project #[id]:[coordinates] you submitted',
bot: {
Expand Down Expand Up @@ -83,7 +83,7 @@ def legend
query: [
'SELECT DISTINCT t.id, t.coordinates, t.created FROM project AS t',
'JOIN badge ON badge.project=t.id AND badge.text LIKE \'L%\'',
'WHERE t.author=$1 AND t.deleted IS NULL'
'WHERE t.author=$1 AND t.deleter IS NULL'
].join(' '),
terms: 'each promoted project',
history: 'The project #[id]:[coordinates] you submitted got a promotion',
Expand All @@ -96,7 +96,7 @@ def legend
points: {
'2000-01-01': +1
},
query: 'SELECT * FROM review AS t WHERE author=$1 AND deleted IS NULL',
query: 'SELECT * FROM review AS t WHERE author=$1 AND deleter IS NULL',
terms: 'each review you submitted',
history: 'The review #[id] you submitted',
bot: {
Expand All @@ -112,7 +112,7 @@ def legend
'SELECT DISTINCT t.id, t.created FROM review AS t',
'JOIN project ON t.project=project.id',
'JOIN badge ON project.id=badge.project AND badge.text LIKE \'L%\'',
'WHERE t.author=$1 AND t.deleted IS NULL'
'WHERE t.author=$1 AND t.deleter IS NULL'
].join(' '),
terms: 'each review you submitted for L1+ project',
history: 'The review #[id] you submitted for L1+ project',
Expand All @@ -129,7 +129,7 @@ def legend
'SELECT t.* FROM (',
' SELECT *, (SELECT COUNT(*) FROM vote WHERE review.id=vote.review AND positive=true) AS votes',
' FROM review',
' WHERE author=$1 AND deleted IS NULL',
' WHERE author=$1 AND deleter IS NULL',
') AS t WHERE votes >= 10'
].join(' '),
terms: 'each review of yours, which collected 10+ upvotes',
Expand Down Expand Up @@ -176,9 +176,9 @@ def legend
'2020-04-22': -40,
'2000-01-01': -25
},
query: 'SELECT t.* FROM project AS t WHERE author=$1 AND deleted IS NOT NULL',
terms: 'each project you submitted, which was deleted later',
history: 'The project #[id]:[coordinates] you submitted was deleted',
query: 'SELECT t.* FROM project AS t WHERE author=$1 AND deleter IS NOT NULL',
terms: 'each project you submitted, which was deleter later',
history: 'The project #[id]:[coordinates] you submitted was deleter',
bot: {
'2020-04-22': -10,
'2000-01-01': -25
Expand All @@ -189,9 +189,9 @@ def legend
'2020-04-22': -25,
'2000-01-01': -50
},
query: 'SELECT * FROM review AS t WHERE author=$1 AND deleted IS NOT NULL',
terms: 'each review you submitted, which was deleted later',
history: 'The review #[id] you submitted was deleted',
query: 'SELECT * FROM review AS t WHERE author=$1 AND deleter IS NOT NULL',
terms: 'each review you submitted, which was deleter later',
history: 'The review #[id] you submitted was deleter',
bot: {
'2020-04-22': -10,
'2000-01-01': -50
Expand Down
13 changes: 9 additions & 4 deletions objects/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,13 @@ def platform
column(:platform)
end

def deleted
column(:deleted)
def deleter
d = column(:deleter)
return d if d.nil?
Xia::Sieve.new(
Xia::Author.new(@pgsql, d.to_i, log: @log, telepost: @telepost),
:id, :login, :karma
)
end

def created
Expand Down Expand Up @@ -96,8 +101,8 @@ def delete
Xia::Rank.new(@author).enter('projects.delete')
end
@pgsql.exec(
'UPDATE project SET deleted = $2 WHERE id=$1',
[@id, "Deleted by @#{@author.login} on #{Time.now.utc.iso8601}"]
'UPDATE project SET deleter=$1 WHERE id=$2',
[@author.id, @id]
)
@telepost.spam(
"The project no.#{@id} [#{coordinates}](https://github.com/#{coordinates}) has been deleted",
Expand Down
19 changes: 15 additions & 4 deletions objects/projects.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def initialize(pgsql, author, log: Loog::NULL, telepost: Telepost::Fake.new)
def get(id)
Xia::Sieve.new(
Xia::Project.new(@pgsql, @author, id, log: @log, telepost: @telepost),
:id, :coordinates, :platform, :created, :deleted, :submitter, :badges, :meta
:id, :coordinates, :platform, :created, :deleter, :submitter, :badges, :meta
)
end

Expand Down Expand Up @@ -94,13 +94,15 @@ def quota

def recent(badges: [], limit: 10, offset: 0, show_deleted: false)
terms = []
terms << 'p.deleted IS NULL' unless show_deleted
terms << 'p.deleter IS NULL' unless show_deleted
terms << 'badge.text IN (' + badges.map { |b| "'#{b}'" }.join(',') + ')' unless badges.empty?
q = [
'SELECT DISTINCT p.*, author.login AS author_login, author.id AS author_id,',
'deleter.id AS deleter_id, deleter.login AS deleter_login,',
'ARRAY(SELECT CONCAT(id,\':\',text) FROM badge WHERE project=p.id) as badges,',
'(SELECT COUNT(*) FROM review WHERE review.project=p.id) AS reviews_count',
'FROM project AS p',
'LEFT JOIN author AS deleter ON deleter.id=p.deleter',
'LEFT JOIN badge ON p.id=badge.project',
'JOIN author ON author.id=p.author',
terms.empty? ? '' : 'WHERE ' + terms.join(' AND '),
Expand All @@ -115,11 +117,13 @@ def recent(badges: [], limit: 10, offset: 0, show_deleted: false)
def inbox(limit: 10, offset: 0)
q = [
'SELECT DISTINCT p.*, author.login AS author_login, author.id AS author_id,',
'deleter.id AS deleter_id, deleter.login AS deleter_login,',
'ARRAY(SELECT CONCAT(id,\':\',text) FROM badge WHERE project=p.id) as badges,',
'(SELECT COUNT(*) FROM review WHERE review.project=p.id) AS reviews_count',
'FROM project AS p',
'LEFT JOIN badge ON p.id=badge.project',
'JOIN author ON author.id=p.author',
'LEFT JOIN author AS deleter ON deleter.id=p.deleter',
'LEFT JOIN seen ON p.id=seen.project AND seen.author=$1',
'WHERE seen.id IS NULL',
'ORDER BY p.created DESC'
Expand All @@ -140,7 +144,14 @@ def to_obj(r)
id: p.id,
coordinates: r['coordinates'],
platform: r['platform'],
deleted: r['deleted'],
deleter: r['deleter_id'].nil? ? nil : Xia::Sieve.new(
Veil.new(
Xia::Author.new(@pgsql, r['deleter_id'].to_i, log: @log, telepost: @telepost),
id: r['deleter_id'].to_i,
login: r['deleter_login']
),
:id, :login
),
created: Time.parse(r['created']),
submitter: Xia::Sieve.new(
Veil.new(
Expand Down Expand Up @@ -169,7 +180,7 @@ def to_obj(r)
:to_a
)
),
:id, :coordinates, :platform, :created, :deleted, :submitter, :badges, :reviews_count
:id, :coordinates, :platform, :created, :deleter, :submitter, :badges, :reviews_count
)
end
end
19 changes: 10 additions & 9 deletions objects/review.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ def created
Time.parse(column(:created))
end

def deleted
column(:deleted)
def deleter
d = column(:deleter)
return d if d.nil?
Xia::Author.new(@pgsql, d.to_i, log: @log, telepost: @telepost)
end

def submitter
Expand All @@ -73,14 +75,13 @@ def html
def delete
if submitter.id == @project.author.id
Xia::Rank.new(@project.author).enter('reviews.delete-own')
@pgsql.exec('DELETE FROM review WHERE id=$1', [@id])
else
Xia::Rank.new(@project.author).enter('reviews.delete')
@pgsql.exec(
'UPDATE review SET deleted = $2 WHERE id=$1',
[@id, "Deleted by @#{@project.author.login} on #{Time.now.utc.iso8601}"]
)
end
@pgsql.exec(
'UPDATE review SET deleter=$1 WHERE id=$2',
[@project.author.id, @id]
)
@project.unseen!
end

Expand All @@ -98,8 +99,8 @@ def vote(up)
Xia::Rank.new(@project.author).enter('reviews.upvote') if up
Xia::Rank.new(@project.author).enter('reviews.downvote') unless up
raise Xia::Urror, 'You are voting too fast' if quota.negative?
raise Xia::Urror, 'It is already deleted, can\'t vote' if deleted
raise Xia::Urror, 'The project is deleted, can\'t vote' if @project.deleted
raise Xia::Urror, "The review is already deleted by @#{deleter.login}, can\'t vote" if deleter
raise Xia::Urror, 'The project is deleted, can\'t vote' if @project.deleter
@pgsql.exec(
[
'INSERT INTO vote (review, author, positive)',
Expand Down
17 changes: 13 additions & 4 deletions objects/reviews.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ def exists?(hash)

def post(text, hash = SecureRandom.hex)
Xia::Rank.new(@project.author).enter('reviews.post')
raise Xia::Urror, 'The project is dead, can\'t review' unless @project.deleted.nil?
unless @project.deleter.nil?
raise Xia::Urror, "The project is already deleted by @#{@project.deleter.login}, can\'t review"
end
raise Xia::Urror, "The review is too short for us, just #{text.length}" if text.length < 30
raise Xia::Urror, 'You are reviewing too fast' if quota.negative?
raise Xia::Urror, 'Hash can\'t be empty' if hash.empty?
Expand Down Expand Up @@ -98,7 +100,7 @@ def recent(limit: 10, offset: 0, show_deleted: false)
'FROM review AS r',
'JOIN author ON author.id=r.author',
'WHERE project=$1',
show_deleted ? '' : ' AND r.deleted IS NULL',
show_deleted ? '' : ' AND r.deleter IS NULL',
'ORDER BY r.created DESC',
'LIMIT $2 OFFSET $3'
].join(' ')
Expand All @@ -110,7 +112,14 @@ def recent(limit: 10, offset: 0, show_deleted: false)
html: carpet.render(r['text']),
up: r['up'].to_i,
down: r['down'].to_i,
deleted: r['deleted'],
deleter: r['deleter'].nil? ? nil : Xia::Sieve.new(
Veil.new(
Xia::Author.new(@pgsql, r['deleter_id'].to_i, log: @log, telepost: @telepost),
id: r['deleter_id'].to_i,
login: r['deleter_login']
),
:id, :login
),
created: Time.parse(r['created']),
submitter: Xia::Sieve.new(
Veil.new(
Expand All @@ -121,7 +130,7 @@ def recent(limit: 10, offset: 0, show_deleted: false)
:id, :login
)
),
:id, :text, :html, :up, :down, :created, :deleted, :submitter
:id, :text, :html, :up, :down, :created, :deleter, :submitter
)
end
end
Expand Down
4 changes: 2 additions & 2 deletions test/test_codexia.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def test_api_fetch_json
assert(json.is_a?(Hash), "No projects in the JSON response: #{last_response.body.inspect}")
assert(json['id'].is_a?(Integer), 'ID is not present')
assert(json['submitter']['id'].is_a?(Integer))
assert(json['deleted'].nil?)
assert(json['deleter'].nil?)
assert(json['badges'].is_a?(Array))
assert_equal('newbie', json['badges'][0]['text'])
assert(json['created'].is_a?(String))
Expand All @@ -113,7 +113,7 @@ def test_api_fetch_json
json = JSON.parse(last_response.body)
assert(json['id'].is_a?(Integer))
assert(json['submitter']['id'].is_a?(Integer))
assert(json['deleted'].nil?)
assert(json['deleter'].nil?)
assert(json['badges'].is_a?(Array))
end

Expand Down
18 changes: 10 additions & 8 deletions views/project.haml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@
%a{href: iri.cut('/p').append(project.id).append('delete'), onclick: 'return confirm("Are you sure?");'}<
= '/delete'

- if !project.deleted.nil?
- if !project.deleter.nil?
%p
%strong.firebrick
&= project.deleted
Deleted by
= "@#{project.deleter.login}"

%p
- project.badges.to_a.each do |b|
Expand All @@ -42,21 +43,22 @@
= '✘'

- if Xia::Rank.new(the_author).ok?('badges.attach')
- if project.deleted.nil?
- if project.deleter.nil?
%form{action: iri.cut('/p').append(project.id).append('attach'), method: 'POST'}
%input{type: 'text', name: 'text', size: 25, placeholder: 'attach a new badge...', autocomplete: 'off'}
%button{type: 'submit'} Attach

- reviews.each do |r|
%div.block{style: 'border-left: 2px solid lightgray; padding-left: 1em;'}
%p{style: 'margin-bottom: 1em; clear: both;'}
- if r.deleted
- if r.deleter
%strong.firebrick
&= r.deleted
Deleted by
= "@#{r.deleter}"
%br
%span.smaller.gray
= partial(:author, locals, a: r.submitter)
%span.item{title: "##{r.id} on #{r.created}", style: (r.deleted ? 'text-decoration:line-through' : '')}
%span.item{title: "##{r.id} on #{r.created}", style: (r.deleter ? 'text-decoration:line-through' : '')}
= RelativeTime.in_words(r.created)
%span.item
= r.up
Expand All @@ -81,7 +83,7 @@
= partial(:paging, locals, page: page, list: reviews)

- if Xia::Rank.new(the_author).ok?('reviews.post')
- if project.deleted.nil?
- if project.deleter.nil?
%div.block
%form{action: iri.cut('/p').append(project.id).append('post'), method: 'POST'}
%fieldset
Expand All @@ -102,7 +104,7 @@
terms of use
and don't abuse the platform.

- if project.deleted.nil? && Xia::Bots.new.is?(the_author)
- if project.deleter.nil? && Xia::Bots.new.is?(the_author)
%div.block
- metas = project.meta.to_a
- unless metas.empty?
Expand Down
2 changes: 1 addition & 1 deletion views/recent.haml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
projects
- list.each do |p|
%p
%a{href: iri.cut('/p').append(p.id), style: (p.deleted ? 'text-decoration:line-through' : '')}
%a{href: iri.cut('/p').append(p.id), style: (p.deleter ? 'text-decoration:line-through' : '')}
&= p.coordinates
%br
- p.badges.to_a.each do |b|
Expand Down

0 comments on commit baf9e1a

Please sign in to comment.