module Api module V1 class Articles < Grape::API ARTICLE_TYPES = Article.descendants.map{|a| a.to_s} MAX_PER_PAGE = 50 resource :articles do paginate max_per_page: MAX_PER_PAGE # Collect articles # # Parameters: # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created # oldest - Collect the oldest articles. If nothing is passed the newest articles are collected # limit - amount of articles returned. The default value is 20 # # Example Request: # GET host/api/v1/articles?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317 desc 'Return all articles of all kinds' do detail 'Get all articles filtered by fields in query params' params Entities::Article.documentation success Entities::Article failure [[403, 'Forbidden']] named 'ArticlesList' headers [ 'Per-Page' => { description: 'Total number of records', required: false } ] end get do present_articles_for_asset(environment) end desc "Return one article by id" do detail 'Get only one article by id. If not found the "forbidden" http error is showed' params Entities::Article.documentation success Entities::Article failure [[403, 'Forbidden']] named 'ArticleById' end get ':id', requirements: {id: /[0-9]+/} do present_article(environment) end post ':id' do article = environment.articles.find(params[:id]) return forbidden! unless article.allow_edit?(current_person) article.update_attributes!(asset_with_image(params[:article])) present_partial article, :with => Entities::Article end delete ':id' do article = environment.articles.find(params[:id]) return forbidden! unless article.allow_delete?(current_person) begin article.destroy { :success => true } rescue Exception => exception render_api_error!(_('The article couldn\'t be removed due to some problem. Please contact the administrator.'), 400) end end desc 'Report a abuse and/or violent content in a article by id' do detail 'Submit a abuse (in general, a content violation) report about a specific article' params Entities::Article.documentation failure [[400, 'Bad Request']] named 'ArticleReportAbuse' end post ':id/report_abuse' do article = find_article(environment.articles, params[:id]) profile = article.profile begin abuse_report = AbuseReport.new(:reason => params[:report_abuse]) if !params[:content_type].blank? article = params[:content_type].constantize.find(params[:content_id]) abuse_report.content = article_reported_version(article) end current_person.register_report(abuse_report, profile) if !params[:content_type].blank? abuse_report = AbuseReport.find_by reporter_id: current_person.id, abuse_complaint_id: profile.opened_abuse_complaint.id Delayed::Job.enqueue DownloadReportedImagesJob.new(abuse_report, article) end { :success => true, :message => _('Your abuse report was registered. The administrators are reviewing your report.'), } rescue Exception => exception #logger.error(exception.to_s) render_api_error!(_('Your report couldn\'t be saved due to some problem. Please contact the administrator.'), 400) end end desc "Returns the articles I voted" do detail 'Get the Articles I make a vote' failure [[403, 'Forbidden']] named 'ArticleFollowers' end #FIXME refactor this method get 'voted_by_me' do present_articles(current_person.votes.where(:voteable_type => 'Article').collect(&:voteable)) end desc 'Perform a vote on a article by id' do detail 'Vote on a specific article with values: 1 (if you like) or -1 (if not)' params Entities::UserLogin.documentation failure [[401,'Unauthorized']] named 'ArticleVote' end post ':id/vote' do authenticate! value = (params[:value] || 1).to_i # FIXME verify allowed values render_api_error!('Vote value not allowed', 400) unless [-1, 1].include?(value) article = find_article(environment.articles, params[:id]) begin vote = Vote.new(:voteable => article, :voter => current_person, :vote => value) {:vote => vote.save!} rescue ActiveRecord::RecordInvalid => e render_api_error!(e.message, 400) end end desc "Returns the total followers for the article" do detail 'Get the followers of a specific article by id' failure [[403, 'Forbidden']] named 'ArticleFollowers' end get ':id/followers' do article = find_article(environment.articles, params[:id]) total = article.person_followers.count {:total_followers => total} end desc "Return the articles followed by me" get 'followed_by_me' do present_articles_for_asset(current_person, 'following_articles') end desc "Add a follower for the article" do detail 'Add the current user identified by private token, like a follower of a article' params Entities::UserLogin.documentation failure [[401, 'Unauthorized']] named 'ArticleFollow' end post ':id/follow' do authenticate! article = find_article(environment.articles, params[:id]) if article.article_followers.exists?(:person_id => current_person.id) {:success => false, :already_follow => true} else article_follower = ArticleFollower.new article_follower.article = article article_follower.person = current_person article_follower.save! {:success => true} end end desc 'Return the children of a article identified by id' do detail 'Get all children articles of a specific article' params Entities::Article.documentation failure [[403, 'Forbidden']] named 'ArticleChildren' end paginate per_page: MAX_PER_PAGE, max_per_page: MAX_PER_PAGE get ':id/children' do article = find_article(environment.articles, params[:id]) #TODO make tests for this situation votes_order = params.delete(:order) if params[:order]=='votes_score' articles = select_filtered_collection_of(article, 'children', params) articles = articles.display_filter(current_person, article.profile) #TODO make tests for this situation if votes_order articles = articles.joins('left join votes on articles.id=votes.voteable_id').group('articles.id').reorder('sum(coalesce(votes.vote, 0)) DESC') end Article.hit(articles) present_articles(articles) end desc 'Return one child of a article identified by id' do detail 'Get a child of a specific article' params Entities::Article.documentation success Entities::Article failure [[403, 'Forbidden']] named 'ArticleChild' end get ':id/children/:child_id' do article = find_article(environment.articles, params[:id]) child = find_article(article.children, params[:child_id]) child.hit present_partial child, :with => Entities::Article end desc 'Suggest a article to another profile' do detail 'Suggest a article to another profile (person, community...)' params Entities::Article.documentation success Entities::Task failure [[401,'Unauthorized']] named 'ArticleSuggest' end post ':id/children/suggest' do authenticate! parent_article = environment.articles.find(params[:id]) suggest_article = SuggestArticle.new suggest_article.article = params[:article] suggest_article.article[:parent_id] = parent_article.id suggest_article.target = parent_article.profile suggest_article.requestor = current_person unless suggest_article.save render_api_errors!(suggest_article.article_object.errors.full_messages) end present_partial suggest_article, :with => Entities::Task end # Example Request: # POST api/v1/articles/:id/children?private_token=234298743290432&article[name]=title&article[body]=body desc 'Add a child article to a parent identified by id' do detail 'Create a new article and associate to a parent' params Entities::Article.documentation success Entities::Article failure [[401,'Unauthorized']] named 'ArticleAddChild' end post ':id/children' do parent_article = environment.articles.find(params[:id]) params[:article][:parent_id] = parent_article.id post_article(parent_article.profile, params) end end resource :profiles do get ':id/home_page' do profiles = environment.profiles profiles = profiles.visible_for_person(current_person) profile = profiles.find_by id: params[:id] present_partial profile.home_page, :with => Entities::Article end end kinds = %w[profile community person enterprise] kinds.each do |kind| resource kind.pluralize.to_sym do segment "/:#{kind}_id" do resource :articles do desc "Return all articles associate with a profile of type #{kind}" do detail 'Get a list of articles of a profile' params Entities::Article.documentation success Entities::Article failure [[403, 'Forbidden']] named 'ArticlesOfProfile' end get do profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) if params[:path].present? article = profile.articles.find_by path: params[:path] if !article || !article.display_to?(current_person) article = forbidden! end present_partial article, :with => Entities::Article, current_person: current_person else present_articles_for_asset(profile) end end desc "Return a article associate with a profile of type #{kind}" do detail 'Get only one article of a profile' params Entities::Article.documentation success Entities::Article failure [[403, 'Forbidden']] named 'ArticleOfProfile' end get ':id' do profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) present_article(profile) end # Example Request: # POST api/v1/{people,communities,enterprises}/:asset_id/articles?private_token=234298743290432&article[name]=title&article[body]=body desc "Add a new article associated with a profile of type #{kind}" do detail 'Create a new article and associate with a profile' params Entities::Article.documentation success Entities::Article failure [[403, 'Forbidden']] named 'ArticleCreateToProfile' end post do profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) post_article(profile, params) end end end end end end end end