Orbit Feed Module

This commit is contained in:
Manson Wang 2014-02-12 12:08:37 +08:00
commit 320803b4b9
32 changed files with 706 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.bundle/
log/*.log
pkg/
test/dummy/db/*.sqlite3
test/dummy/log/*.log
test/dummy/tmp/

17
Gemfile Normal file
View File

@ -0,0 +1,17 @@
source "http://rubygems.org"
# Declare your gem's dependencies in location.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec
# jquery-rails is used by the dummy application
gem "jquery-rails"
# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.
# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'

20
MIT-LICENSE Normal file
View File

@ -0,0 +1,20 @@
Copyright 2012 YOURNAME
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.

3
README.rdoc Normal file
View File

@ -0,0 +1,3 @@
= Location
This project rocks and uses MIT-LICENSE.

39
Rakefile Normal file
View File

@ -0,0 +1,39 @@
#!/usr/bin/env rake
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
begin
require 'rdoc/task'
rescue LoadError
require 'rdoc/rdoc'
require 'rake/rdoctask'
RDoc::Task = Rake::RDocTask
end
RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'Location'
rdoc.options << '--line-numbers'
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/**/*.rb')
end
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
Bundler::GemHelper.install_tasks
require 'rake/testtask'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = false
end
task :default => :test

View File

View File

View File

@ -0,0 +1,2 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.

View File

View File

View File

@ -0,0 +1,4 @@
/*
Place all the styles related to the matching controller here.
They will automatically be included in application.css.
*/

View File

@ -0,0 +1,4 @@
/*
Place all the styles related to the matching controller here.
They will automatically be included in application.css.
*/

0
app/controllers/.gitkeep Normal file
View File

View File

@ -0,0 +1,34 @@
# encoding: utf-8
class Panel::Feed::BackEnd::FeedRequestsController < OrbitBackendController
skip_before_filter :verify_authenticity_token
open_for_visitor :only => [:transferred_request, :accepted_request]
def transferred_request
if request.headers["HTTP_X_AUTH_TOKEN"] == '3kjlfksjDFJ'
permission_feed = AnnouncementFeed.new(
link: params['link'],
name: params['name'],
categories: params['categories'].split,
from_request: true,
from_request_link: request.host)
permission_feed.save!
render :nothing => true
else
render :status => 500
end
end
def accepted_request
if request.headers["HTTP_X_AUTH_TOKEN"] == '3kjlfksjDFJ'
accepted_feed = AnnouncementFeed.where({name: params['name'], link: params['link'], categories: params['categories'].split}).first
accepted_feed.update_attributes({accepted: true})
render :nothing => true
else
render :status => 500
end
end
end

View File

@ -0,0 +1,147 @@
# encoding: utf-8
class Panel::Feed::BackEnd::FeedsController < OrbitBackendController
before_filter :skip_current_site, only: [:new, :create]
CATEGORIES = %w{全部 緊急 一般 研討會 演講 活動 徵才 招標 拖吊 校外 過期 H1N1 失物招領 近期}
# Sites available for subscription
SITES = [ ["總務處 - 總務處", "www.ga.ntu.edu.tw", "0"],
["總務處 - 總務長室暨總務處秘書室", "sec.ga.ntu.edu.tw", "1"],
["總務處 - 文書組", "doc.ga.ntu.edu.tw", "2"],
["總務處 - 事務組", "general.ga.ntu.edu.tw", "3"],
["總務處 - 保管組", "property.ga.ntu.edu.tw", "4"],
["總務處 - 營繕組", "construction.ga.ntu.edu.tw", "5"],
["總務處 - 出納組", "cashier.ga.ntu.edu.tw", "6"],
["總務處 - 採購組", "procurement.ga.ntu.edu.tw", "7"],
["總務處 - 經營管理組", "fss.ga.ntu.edu.tw", "8"],
["總務處 - 駐警隊", "police.ga.ntu.edu.tw", "9"],
["社科院總務分處", "social.ga.ntu.edu.tw", "10"],
["醫學院總務分處", "medicine.ga.ntu.edu.tw", "11"] ]
def index
@feeds = AnnouncementFeed.where({from_request: false})
@permission_feeds = AnnouncementFeed.where({from_request: true})
respond_to do |format|
format.html
end
end
def new
@feed = AnnouncementFeed.new
@categories = CATEGORIES
@sites = @filtered_sites
end
def edit
@feed = AnnouncementFeed.find(params[:id])
@current_categories = @feed.categories
@categories = CATEGORIES
end
def create
@feed = AnnouncementFeed.new(params[:announcement_feed])
@feed.name = SITES[ params[:site].to_i ][0]
@feed.link = SITES[ params[:site].to_i ][1]
@categories = CATEGORIES
@sites = @filtered_sites
# if @feed.save
## Testing(TO-DO) ##
if permission_request(@feed)
@feed.save
redirect_to panel_feed_back_end_feeds_url
else
flash.now[:notice] = t('feed.connection_fail')
render 'new'
end
end
def update
@feed = AnnouncementFeed.find(params[:id])
if @feed.update_attributes(params[:announcement_feed])
redirect_to panel_feed_back_end_feeds_url
else
render 'edit'
end
end
def destroy
@feed = AnnouncementFeed.find(params[:id])
@feed.destroy
redirect_to panel_feed_back_end_feeds_url
end
def agree
require 'net/http'
require 'uri'
require 'json'
@feed = AnnouncementFeed.find(params[:id], conditions: [ "from_request = ?", true])
uri_path = "/panel/feed/back_end/feed_requests/accepted_request"
http = Net::HTTP.new(@feed.from_request_link, 80)
request = Net::HTTP::Post.new(uri_path)
categories = @feed.categories.join(' ')
body = {
'link' => @feed.link,
'name' => @feed.name,
'categories' => categories
}
3.times do
request.set_form_data(body)
request.add_field 'X-Auth-Token', '3kjlfksjDFJ'
response = http.request(request)
if response.code == "200"
@feed.destroy
break
end
end
redirect_to panel_feed_back_end_feeds_url
end
def permission_request(feed)
require 'net/http'
require 'uri'
require 'json'
uri_path = "/panel/feed/back_end/feed_requests/transferred_request"
# http = Net::HTTP.new(feed.link, 80)
http = Net::HTTP.new(feed.link, 80)
request = Net::HTTP::Post.new(uri_path)
categories = feed.categories.join(' ') unless feed.categories.blank?
body = {
'link' => feed.link,
'name' => feed.name,
'categories' => categories
}
status = false
3.times do
request.set_form_data(body)
request.add_field 'X-Auth-Token', '3kjlfksjDFJ'
response = http.request(request)
if response.code == "200"
status = true
break
end
end
return status
end
private
def skip_current_site
@filtered_sites = SITES.collect {|site| site unless site[1] == request.host}
@filtered_sites.compact!
end
end

0
app/helpers/.gitkeep Normal file
View File

0
app/mailers/.gitkeep Normal file
View File

0
app/models/.gitkeep Normal file
View File

View File

@ -0,0 +1,13 @@
class AnnouncementFeed
include Mongoid::Document
include Mongoid::Timestamps
field :link, type: String
field :name, type: String
field :categories, type: Array
field :accepted, type: Boolean, default: false
field :from_request, type: Boolean, default: false
field :from_request_link, type: String
validates :categories, presence: true
end

0
app/views/.gitkeep Normal file
View File

View File

@ -0,0 +1,28 @@
<legend><h3 style="margin-left: 10px;"><%= t('feed.channel') %></h3></legend>
<fieldset style="margin-left: -25px;">
<div class="control-group">
<label class="control-label" for="inputURL"><%= t('feed.choose_rss') %>:</label>
<div class="controls">
<%= select_tag(:site, options_for_select(@sites)) %>
</div>
</div>
<div class="control-group">
<label class="control-label" for="inputURL"><%= t('feed.choose') %>:</label>
<div class="controls">
<% @categories.each_with_index do |category, i| %>
<%= content_tag :label, :class => "checkbox inline" do -%>
<%= check_box("announcement_feed", "categories", {:multiple => true, :id => i}, category, nil) %>
<label for="<%= i %>"><%= category %></label>
<% end -%>
<% end %>
</div>
</div>
<div class="control-group">
<div class="controls">
<%= f.submit t("submit"), :class => "btn btn-primary" %>
</div>
</div>
</fieldset>

View File

@ -0,0 +1,63 @@
<%= form_for @feed, :url => panel_feed_back_end_feed_path, :method => :put, :html => {:class => "form-horizontal"} do |f| %>
<legend><h3 style="margin-left: 10px;"><%= t('feed.channel') %></h3></legend>
<fieldset style="margin-left: -25px;">
<div class="control-group">
<label class="control-label" for="inputURL"><%= t('feed.current_rss') %>:</label>
<div class="controls">
<h4><%= @feed.name %></h4>
</div>
</div>
<div class="control-group">
<label class="control-label" for="inputURL"><%= t('feed.choose') %>:</label>
<div class="controls">
<% @categories.each_with_index do |category, i| %>
<%= content_tag :label, :class => "checkbox inline" do -%>
<%= check_box("announcement_feed", "categories", {:multiple => true, :id => i}, category, nil) %>
<label for="<%= i %>"><%= category %></label>
<% end -%>
<% end %>
</div>
</div>
<div class="control-group">
<div class="controls">
<%= f.submit t("submit"), :class => "btn btn-primary" %>
</div>
</div>
</fieldset>
<% end %>
<script type="text/javascript">
$(function() {
var $checkboxes = $('.checkbox').find('input');
var categories = <%= @current_categories.to_json.html_safe %>;
for (var i = 0; i < $checkboxes.length; i++) {
if ($.inArray($checkboxes[i].value, categories) != -1) {
$checkboxes[i].checked = true;
} else {
continue;
}
}
$checkboxes.on('click', function() {
if ($(this).val() == "全部") {
for (var i = 1; i < $checkboxes.length; i++) {
$checkboxes[i].checked = false;
}
} else {
$checkboxes[0].checked = false;
}
});
$('.controls').find('h4').css({'margin-top': '5px'})
});
</script>

View File

@ -0,0 +1,60 @@
<table class="table">
<thead>
<tr><th><h3><%= t('feed.channel') %></h3></th></tr>
<tr>
<th class="span4"><%= t('RSS') %></th>
<%if is_manager? %>
<th class="span4"><%= t('feed.edit') %></th>
<th class="span4"><%= t('feed.delete') %></th>
<th class="span4"><%= t('feed.status.status') %></th>
<% end %>
</tr>
</thead>
<tbody id="tbody_locations" class="sort-holder">
<% @feeds.each do |feed| %>
<tr class="with_action">
<td><%= feed.name %></td>
<%if is_manager? %>
<td><%= link_to t('feed.edit'), edit_panel_feed_back_end_feed_path(feed) %></td>
<td><%= link_to t('feed.cancel'), panel_feed_back_end_feed_path(feed), method: :delete, confirm: t(:sure?) %></td>
<td>
<%- if feed.accepted? %>
<%= t('feed.status.accepted') %>
<% else %>
<%= t('feed.status.unaccepted') %>
<% end -%>
</td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<%if is_manager? %>
<br />
<%= link_to t('feed.new'), new_panel_feed_back_end_feed_path, :class => "btn btn-primary pull-right", :id => "create_event_btn", :ref => "add-btn" %>
<% end %>
<table class="table">
<thead>
<tr><th><h3><%= t('feed.status.permission') %></h3></th></tr>
<tr>
<th class="span4"><%= t('URL') %></th>
<%if is_manager? %>
<th class="span4"><%= t('feed.permit') %></th>
<% end %>
</tr>
</thead>
<tbody id="tbody_locations" class="sort-holder">
<% @permission_feeds.each do |feed| %>
<tr class="with_action">
<td><%= feed.from_request_link %></td>
<%if is_manager? %>
<td><%= link_to t('feed.agree'), agree_panel_feed_back_end_feeds_path(feed), method: :post, class: "btn btn-primary" %></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>

View File

@ -0,0 +1,31 @@
<%= form_for @feed, :url => panel_feed_back_end_feeds_path, :html => { :class=>"form-horizontal"} do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<% end %>
<script type="text/javascript">
$(function() {
var $checkboxes = $('.checkbox').find('input');
var categories = <%= @current_categories.to_json.html_safe %>;
for (var i = 0; i < $checkboxes.length; i++) {
if ($.inArray($checkboxes[i].value, categories) != -1) {
$checkboxes[i].checked = true;
} else {
continue;
}
}
$checkboxes.on('click', function() {
if ($(this).val() == "全部") {
for (var i = 1; i < $checkboxes.length; i++) {
$checkboxes[i].checked = false;
}
} else {
$checkboxes[0].checked = false;
}
});
});
</script>

22
config/locales/en.yml Normal file
View File

@ -0,0 +1,22 @@
en:
feed:
all: All
choose: Choose a Category
choose_rss: Choose a RSS site
current_rss: Current RSS site
feed: RSS
channel: Announcement RSS
status:
status: Status
accepted: Accepted
unaccepted: Unaccepted
permission: Announcement RSS Waiting for Permission
new: New
edit: Edit
delete: Delete
cancel: Cancel RSS
enter: Enter
name: Name
permit: Permit
agree: Agree
connection_fail: Connection Fail

22
config/locales/zh_tw.yml Normal file
View File

@ -0,0 +1,22 @@
zh_tw:
feed:
all: 全部
choose: 選擇訂閱類別
choose_rss: 選擇訂閱RSS站
current_rss: 訂閱的RSS站
feed: RSS
channel: 公告RSS訂閱
status:
status: 狀態
accepted: 已授權
unaccepted: 未授權
permission: 待授權公告RSS訂閱
new: 新增
edit: 編輯
delete: 刪除
cancel: 取消訂閱
enter: 輸入
name: 名稱
permit: 授權
agree: 同意
connection_fail: 無法取得與對方的連線!

16
config/routes.rb Normal file
View File

@ -0,0 +1,16 @@
Rails.application.routes.draw do
namespace :panel do
namespace :feed do
namespace :back_end do
resources :feeds do
collection do
post "/:id/agree" => "feeds#agree", :as => 'agree'
end
end
post "feed_requests/transferred_request" => "feed_requests#transferred_request", :as => 'transferred_request'
post "feed_requests/accepted_request" => "feed_requests#accepted_request", :as => 'accepted_request'
end
end
end
end

22
feed.gemspec Normal file
View File

@ -0,0 +1,22 @@
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "feed/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "feed"
s.version = Feed::VERSION
s.authors = ["RulingDigital"]
s.email = ["service@rulingcom.com"]
s.description = "Orbit Announcement module"
s.summary = ""
s.homepage = "http://www.rulingcom.com"
s.license = "RulingDigital"
s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
s.test_files = Dir["test/**/*"]
s.add_development_dependency "bundler", "~> 1.3"
s.add_development_dependency "rake"
end

30
lib/feed.rb Normal file
View File

@ -0,0 +1,30 @@
module Feed
class Engine < Rails::Engine
initializer "feed" do
OrbitApp.registration "Feed",:type=> 'ModuleApp' do
module_label 'feed.feed'
base_url File.expand_path File.dirname(__FILE__)
# personal_plugin :enable => true,:path=>"panel/location/plugin/profile",:i18n=>'admin.location'
version "0.1"
organization "Rulingcom"
author "RulingDigital"
intro "Orbit Feed Module"
update_info 'some update_info'
#enable_frontend true
categorizable
authorizable
side_bar do
head_label_i18n 'feed.channel', :icon_class=>"icon-plus"
available_for [:admin, :guest, :manager, :sub_manager]
active_for_controllers( {:private => ['feeds']} )
head_link_path "panel_feed_back_end_feeds_path"
end
end
end
end
end

3
lib/feed/version.rb Normal file
View File

@ -0,0 +1,3 @@
module Feed
VERSION = "0.0.1"
end

114
lib/rss_dynamic.rb Normal file
View File

@ -0,0 +1,114 @@
# encoding: utf-8
require 'rss'
require 'mongo'
require 'mongoid'
# Change this according to local DB
DB_NAME = "orbit_site_new"
Mongoid.configure do |config|
config.master = Mongo::Connection.new("localhost", 27017).db("#{DB_NAME}")
end
class Bulletin
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::MultiParameterAttributes
end
class BufferCategory
include Mongoid::Document
include Mongoid::Timestamps
end
# Create a hash rss site list from mongodb
db = Mongo::Connection.new("localhost", 27017).db("#{DB_NAME}")
SITES = Hash[ db["announcement_feeds"].find(accepted: true).entries.collect {|f| [ f["name"], f["link"] ]} ]
CATEGORIES = Array( db["announcement_feeds"].find().entries.collect {|f| f["categories"]} )
yesterday = Time.now - 86400
two_weeks_ago = Time.new - 60 * 60 * 24 * 14
recent_feed = {}
SITES.each_with_index do |(name, url), i|
open("http://#{url}/panel/announcement/front_end/bulletins.rss?inner=true") do |rss|
# Giving 'false' parameter is for skipping irregular format of the RSS
feed = RSS::Parser.parse(rss, false)
feed.items.each do |item|
category = item.category.to_s.gsub(/\<(\/)*category\>/, '')
if ( item.pubDate > yesterday ) && ( CATEGORIES[i][0] == "全部" || CATEGORIES[i].include?(category) )
recent_feed[item.title.strip] = { date: item.pubDate, description: item.description.gsub("\r\n", '<br/>').strip,
link: item.link, category: category, source: name }
end
end
end
end
def get_category_id(category, categories, coll_cat)
db = Mongo::Connection.new("localhost", 27017).db("#{DB_NAME}")
if categories.keys.include? "rss_#{category}"
[categories["rss_#{category}"], categories]
else
cat = {
_type: "Category",
key: "rss_#{category}",
disable: false,
title: {:zh_tw => "rss_#{category}"},
created_at: Time.now,
updated_at: Time.now,
module_app_id: db["module_apps"].find({:key=>"announcement"}).first['_id']
}
categories["rss_#{category}"] = result = coll_cat.save(cat)
[result, categories]
end
end
def get_mongo_and_categories
db = Mongo::Connection.new("localhost", 27017).db("#{DB_NAME}")
coll_bulletin = db["bulletins"]
coll_cat = db["categories"]
categories = coll_cat.find().to_a.inject({}) do |categories, category|
categories[category['key']] = category['_id']
categories
end
[categories, coll_bulletin, coll_cat]
end
recent_feed.each do |title, bulletin|
categories, coll_bulletin, coll_cat = get_mongo_and_categories
category_id, categories = get_category_id(bulletin[:category], categories, coll_cat)
unless coll_bulletin.find_one(rss_link: bulletin[:link])
bulletin = { _type: "Bulletin",
postdate: bulletin[:date],
created_at: bulletin[:date],
updated_at: bulletin[:date],
category_id: category_id,
title: {:zh_tw => title, :en => ""},
text: {:zh_tw => bulletin[:description], :en => ""},
available_for_zh_tw: true,
available_for_en: false,
rss_link: bulletin[:link],
rss_source: bulletin[:source],
is_top: false,
is_hot: false,
is_hidden: false }
# coll_bulletin.save(bulletin)
bulletin = Bulletin.new(bulletin)
bulletin.save!
category = { _type: "BufferCategory",
category_id: category_id,
categorizable_type: "Bulletin",
categorizable_id: bulletin.id }
buffer_category = BufferCategory.new(category)
buffer_category.save!
end
end

6
script/rails Executable file
View File

@ -0,0 +1,6 @@
#!/usr/bin/env ruby
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
ENGINE_PATH = File.expand_path('../..', __FILE__)
load File.expand_path('../../test/dummy/script/rails', __FILE__)