Support for post subscriptions

This commit is contained in:
Yuki 2015-04-21 06:42:11 +05:30
parent aed2597de0
commit ecffd07344
18 changed files with 223 additions and 8 deletions

View File

@ -198,6 +198,45 @@ namespace :justask do
puts "Purged #{destroyed_count} dead notifications." puts "Purged #{destroyed_count} dead notifications."
end end
desc "Subscribes everyone to their answers"
task fix_submarines: :enviornment do
format = '%t (%c/%C) [%b>%i] %e'
total = Answer.count
progress = ProgressBar.create title: 'Processing answers', format: format, starting_at: 0, total: total
subscribed = 0
Answer.all.each do |a|
if not s.user.nil? and not s.answer.nil?
Subscription.subscribe a.user, a
subscribed += 1
end
progress.increment
end
puts "Subscribed to #{subscribed} posts."
end
desc "Destroy lost subscriptions"
task fix_torpedoes: :enviornment do
format = '%t (%c/%C) [%b>%i] %e'
total = Subscription.count
progress = ProgressBar.create title: 'Processing subscriptions', format: format, starting_at: 0, total: total
destroyed = 0
Subscription.all.each do |s|
if s.user.nil? or s.answer.nil?
s.destroy
destroyed += 1
end
progress.increment
end
puts "Put #{destroyed} subscriptions up for adoption."
end
desc "Fixes everything else" desc "Fixes everything else"
task fix_db: :environment do task fix_db: :environment do
format = '%t (%c/%C) [%b>%i] %e' format = '%t (%c/%C) [%b>%i] %e'
@ -206,7 +245,8 @@ namespace :justask do
question: 0, question: 0,
answer: 0, answer: 0,
smile: 0, smile: 0,
comment: 0 comment: 0,
subscription: 0
} }
total = Inbox.count total = Inbox.count
@ -250,10 +290,24 @@ namespace :justask do
progress.increment progress.increment
end end
total = Subscription.count
progress = ProgressBar.create title: 'Processing subscriptions', format: format, starting_at: 0, total: total
Subscription.all.each do |s|
if s.user.nil? or s.answer.nil?
s.destroy
destroyed_count[:subscription] += 1
end
progress.increment
end
puts "Put #{destroyed} subscriptions up for adoption."
puts "Purged #{destroyed_count[:inbox]} dead inbox entries." puts "Purged #{destroyed_count[:inbox]} dead inbox entries."
puts "Marked #{destroyed_count[:question]} questions as anonymous." puts "Marked #{destroyed_count[:question]} questions as anonymous."
puts "Purged #{destroyed_count[:answer]} dead answers." puts "Purged #{destroyed_count[:answer]} dead answers."
puts "Purged #{destroyed_count[:answer]} dead comments." puts "Purged #{destroyed_count[:answer]} dead comments."
puts "Purged #{destroyed_count[:subscription]} dead subscriptions."
end end
desc "Prints lonely people." desc "Prints lonely people."

View File

@ -39,6 +39,9 @@ $(document).on "keyup", "input[name=ab-comment-new]", (evt) ->
input.val '' input.val ''
ctr.html 160 ctr.html 160
$("span#ab-comment-count-#{aid}").html data.count $("span#ab-comment-count-#{aid}").html data.count
subs = $("a[data-action=ab-submarine][data-a-id=#{aid}]")[0]
subs.dataset.torpedo = "no"
subs.children[0].nextSibling.textContent = "Unsubscribe"
showNotification data.message, data.success showNotification data.message, data.success
error: (jqxhr, status, error) -> error: (jqxhr, status, error) ->
console.log jqxhr, status, error console.log jqxhr, status, error

View File

@ -0,0 +1,27 @@
# the laziest coding known to man
$(document).on "click", "a[data-action=ab-submarine]", (ev) ->
ev.preventDefault()
btn = $(this)
aid = btn[0].dataset.aId
torpedo = 0
if btn[0].dataset.torpedo == "yes"
torpedo = 1
endpoint = "subscribe"
if torpedo == 0
endpoint = "un" + endpoint
$.ajax
url: '/ajax/' + endpoint # TODO: find a way to use rake routes instead of hardcoding them here
type: 'POST'
data:
answer: aid
success: (data, status, jqxhr) ->
if data.success
btn[0].dataset.torpedo = ["yes", "no"][torpedo]
btn[0].children[0].nextSibling.textContent = ["Subscribe", "Unsubscribe"][torpedo]
showNotification "Successfully " + endpoint + "d.", true
else
showNotification "Couldn't unsubscribe from the answer.", false
error: (jqxhr, status, error) ->
console.log jqxhr, status, error
showNotification "An error occurred, a developer should check the console for details", false
complete: (jqxhr, status) ->

View File

@ -0,0 +1,19 @@
class Ajax::SubscriptionController < ApplicationController
before_filter :authenticate_user!
def subscribe
params.require :answer
@status = 418
@message = "418 I'm a torpedo"
state = Subscription.subscribe(current_user, Answer.find(params[:answer])).nil?
@success = state == false
end
def unsubscribe
params.require :answer
@status = 418
@message = "418 I'm a torpedo"
state = Subscription.unsubscribe(current_user, Answer.find(params[:answer])).nil?
@success = state == false
end
end

View File

@ -0,0 +1,2 @@
module SubscribeHelper
end

View File

@ -3,11 +3,13 @@ class Answer < ActiveRecord::Base
belongs_to :question belongs_to :question
has_many :comments, dependent: :destroy has_many :comments, dependent: :destroy
has_many :smiles, dependent: :destroy has_many :smiles, dependent: :destroy
has_many :subscriptions, dependent: :destroy
after_create do after_create do
Inbox.where(user: self.user, question: self.question).destroy_all Inbox.where(user: self.user, question: self.question).destroy_all
Notification.notify self.question.user, self unless self.question.author_is_anonymous Notification.notify self.question.user, self unless self.question.author_is_anonymous
Subscription.subscribe self.user, self
self.user.increment! :answered_count self.user.increment! :answered_count
self.question.increment! :answer_count self.question.increment! :answer_count
end end
@ -27,9 +29,10 @@ class Answer < ActiveRecord::Base
end end
self.comments.each do |comment| self.comments.each do |comment|
comment.user.decrement! :commented_count comment.user.decrement! :commented_count
Notification.denotify self.user, comment Subscription.denotify comment, self
end end
Notification.denotify self.question.user, self Notification.denotify self.question.user, self
Subscription.destruct self
end end
def notification_type(*_args) def notification_type(*_args)

View File

@ -7,14 +7,15 @@ class Comment < ActiveRecord::Base
validates :content, length: { maximum: 160 } validates :content, length: { maximum: 160 }
after_create do after_create do
Notification.notify answer.user, self unless answer.user == self.user Subscription.subscribe self.user, answer
Subscription.notify self, answer
user.increment! :commented_count user.increment! :commented_count
answer.increment! :comment_count answer.increment! :comment_count
end end
before_destroy do before_destroy do
Notification.denotify answer.user, self unless answer.user == self.user Subscription.denotify self, answer
user.decrement! :commented_count user.decrement! :commented_count
answer.decrement! :comment_count answer.decrement! :comment_count
end end

View File

@ -0,0 +1,48 @@
class Subscription < ActiveRecord::Base
belongs_to :user
belongs_to :answer
class << self
def subscribe(recipient, target)
if Subscription.find_by(user: recipient, answer: target).nil?
Subscription.new(user: recipient, answer: target).save!
end
end
def unsubscribe(recipient, target)
if recipient.nil? or target.nil?
return nil
end
subs = Subscription.find_by(user: recipient, answer: target)
subs.destroy unless subs.nil?
end
def destruct(target)
if target.nil?
return nil
end
Subscription.where(answer: target).destroy_all
end
def notify(source, target)
if source.nil? or target.nil?
return nil
end
Subscription.where(answer: target).each do |subs|
next unless not subs.user == source.user
Notification.notify subs.user, source
end
end
def denotify(source, target)
if source.nil? or target.nil?
return nil
end
Subscription.where(answer: target).each do |subs|
Notification.denotify subs.user, source
end
end
end
end

View File

@ -28,6 +28,8 @@ class User < ActiveRecord::Base
has_many :groups, dependent: :destroy has_many :groups, dependent: :destroy
has_many :group_memberships, class_name: "GroupMember", foreign_key: 'user_id', dependent: :destroy has_many :group_memberships, class_name: "GroupMember", foreign_key: 'user_id', dependent: :destroy
has_many :subscriptions, dependent: :destroy
SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]{1,16}\z/ SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]{1,16}\z/
WEBSITE_REGEX = /https?:\/\/([A-Za-z.\-]+)\/?(?:.*)/i WEBSITE_REGEX = /https?:\/\/([A-Za-z.\-]+)\/?(?:.*)/i

View File

@ -0,0 +1 @@
json.partial! 'ajax/shared/status'

View File

@ -0,0 +1 @@
json.partial! 'ajax/shared/status'

View File

@ -53,9 +53,15 @@
%p.notification--text %p.notification--text
commented on commented on
%a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id), title: "#{notification.target.answer.content[0..40]}...", data: { toggle: :tooltip, placement: :top }} %a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id), title: "#{notification.target.answer.content[0..40]}...", data: { toggle: :tooltip, placement: :top }}
your answer - if notification.target.answer.user == current_user
your
- elsif notification.target.user == notification.target.answer.user
their
- else
= user_screen_name(notification.target.answer.user, false, false) + "'s"
answer
%span{title: notification.target.created_at, data: { toggle: :tooltip, placement: :bottom }} %span{title: notification.target.created_at, data: { toggle: :tooltip, placement: :bottom }}
= time_ago_in_words notification.target.created_at = time_ago_in_words notification.target.created_at
ago ago
.notification--icon .notification--icon
%i.fa.fa-comments %i.fa.fa-comments

View File

@ -21,6 +21,17 @@
%button.btn.btn-default.btn-sm.dropdown-toggle{data: { toggle: :dropdown }, aria: { expanded: :false }} %button.btn.btn-default.btn-sm.dropdown-toggle{data: { toggle: :dropdown }, aria: { expanded: :false }}
%span.caret %span.caret
%ul.dropdown-menu.dropdown-menu-right{role: :menu} %ul.dropdown-menu.dropdown-menu-right{role: :menu}
- if a.subscriptions.find_by(user: current_user)
%li
-# fun joke should subscribe?
%a{href: '#', data: { a_id: a.id, action: 'ab-submarine', torpedo: "no" }}
%i.fa.fa-anchor
Unubscribe
- else
%li
%a{href: '#', data: { a_id: a.id, action: 'ab-submarine', torpedo: "yes" }}
%i.fa.fa-anchor
Subscribe
- if privileged? a.user - if privileged? a.user
%li.text-danger %li.text-danger
%a{href: '#', data: { a_id: a.id, action: 'ab-destroy' }} %a{href: '#', data: { a_id: a.id, action: 'ab-destroy' }}
@ -30,4 +41,4 @@
%li %li
%a{href: '#', data: { a_id: a.id, action: 'ab-report' }} %a{href: '#', data: { a_id: a.id, action: 'ab-report' }}
%i.fa.fa-exclamation-triangle %i.fa.fa-exclamation-triangle
Report Report

View File

@ -82,6 +82,8 @@ Rails.application.routes.draw do
match '/destroy_group', to: 'group#destroy', via: :post, as: :destroy_group match '/destroy_group', to: 'group#destroy', via: :post, as: :destroy_group
match '/group_membership', to: 'group#membership', via: :post, as: :group_membership match '/group_membership', to: 'group#membership', via: :post, as: :group_membership
match '/preview', to: "question#preview", via: :post, as: :preview match '/preview', to: "question#preview", via: :post, as: :preview
match '/subscribe', to: 'subscription#subscribe', via: :post, as: :subscribe_answer
match '/unsubscribe', to: 'subscription#unsubscribe', via: :post, as: :unsubscribe_answer
end end
match '/public', to: 'public#index', via: :get, as: :public_timeline match '/public', to: 'public#index', via: :get, as: :public_timeline

View File

@ -0,0 +1,10 @@
class CreateSubscriptions < ActiveRecord::Migration
def change
create_table :subscriptions do |t|
t.integer :user_id, null: false
t.integer :answer_id, null: false
t.timestamps null: false
end
end
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe SubscribeController, :type => :controller do
end

View File

@ -0,0 +1,15 @@
require 'rails_helper'
# Specs in this file have access to a helper object that includes
# the SubscribeHelper. For example:
#
# describe SubscribeHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
RSpec.describe SubscribeHelper, :type => :helper do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Subscription, :type => :model do
pending "add some examples to (or delete) #{__FILE__}"
end