remove unused twitter tables and no-op jobs

test plan:
 * edit course settings, there should not be an error
 * copy a course, there should not be an error

Change-Id: I733bef83b69d9c513be801d3e4b25422bcd10ebd
Reviewed-on: https://gerrit.instructure.com/13832
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Cody Cutrer 2012-09-20 09:59:20 -06:00
parent c508d0dab0
commit d70945c1bd
19 changed files with 48 additions and 512 deletions

View File

@ -1,85 +0,0 @@
#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class ShortMessagesController < ApplicationController
before_filter :require_context
include Twitter
def index
if authorized_action(@context, @current_user, :read)
@associations = @context.short_message_associations
@hashtag = @context.hashtag_model rescue nil
found = []
@associations += @hashtag.short_message_associations if @hashtag
@associations.map! do |a|
res = (found.include?(a.short_message_id) || !a.short_message) ? nil : a
found << a.short_message_id
res
end
@associations = @associations.compact.sort_by{|m| m.short_message.created_at}.reverse
end
end
def create
@association = @context.short_message_associations.new
if authorized_action(@association, @current_user, :create)
@association = @context.short_message_associations.create
@message = ShortMessage.new(params[:short_message])
@message.user = @current_user
@message.save
@association.short_message = @message
@association.save
# Don't add an association to the hashtags, since this will happen
# via twitter_searcher if the twitterer wants it to be public
send_twitter = params.delete(:send_twitter) == "1"
respond_to do |format|
if @association.valid? && @message.valid?
if send_twitter && @current_user
# begin
res = twitter_send @message.message
@message.service = "twitter"
@message.service_message_id = res["id"]
@message.service_user_name = res["user"]["screen_name"] rescue nil
@message.save
# rescue
# end
end
format.json { render :json => @association.to_json(:include => :short_message, :permissions => {:user => @current_user, :session => session}) }
elsif !@association.valid?
format.json { render :json => @association.errors.to_json, :status => :bad_request }
else
format.json { render :json => @message.errors.to_json, :status => :bad_request }
end
end
end
end
def destroy
@association = @context.short_message_associations.find_by_short_message_id(params[:id])
if authorized_action(@association, @current_user, :delete)
respond_to do |format|
if @association.destroy
format.json { render :json => @association.to_json(:include => :short_message) }
else
format.json { render :json => @association.errors.to_json, :status => :bad_request }
end
end
end
end
end

View File

@ -1,20 +0,0 @@
#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
module ShortMessagesHelper
end

View File

@ -51,7 +51,6 @@ module Context
QuizSubmission = ::QuizSubmission
Rubric = ::Rubric
RubricAssociation = ::RubricAssociation
ShortMessage = ::ShortMessage
Submission = ::Submission
WebConference = ::WebConference
Wiki = ::Wiki

View File

@ -32,7 +32,6 @@ class Course < ActiveRecord::Base
:publish_grades_immediately,
:allow_student_wiki_edits,
:allow_student_assignment_edits,
:hashtag,
:show_public_context_messages,
:syllabus_body,
:public_description,
@ -155,8 +154,6 @@ class Course < ActiveRecord::Base
has_many :rubric_associations, :as => :context, :include => :rubric, :dependent => :destroy
has_many :collaborations, :as => :context, :order => 'title, created_at', :dependent => :destroy
has_one :scribd_account, :as => :scribdable
has_many :short_message_associations, :as => :context, :include => :short_message, :dependent => :destroy
has_many :short_messages, :through => :short_message_associations, :dependent => :destroy
has_many :grading_standards, :as => :context
has_many :context_modules, :as => :context, :order => :position, :dependent => :destroy
has_many :active_context_modules, :as => :context, :class_name => 'ContextModule', :conditions => {:workflow_state => 'active'}
@ -589,7 +586,6 @@ class Course < ActiveRecord::Base
end
def assert_defaults
Hashtag.find_or_create_by_hashtag(self.hashtag) if self.hashtag && self.hashtag != ""
self.tab_configuration ||= [] unless self.tab_configuration == []
self.name = nil if self.name && self.name.strip.empty?
self.name ||= t('missing_name', "Unnamed Course")
@ -773,10 +769,6 @@ class Course < ActiveRecord::Base
end
end
def hashtag_model
Hashtag.find_by_hashtag(self.hashtag) if self.hashtag
end
workflow do
state :created do
event :claim, :transitions_to => :claimed
@ -2244,7 +2236,7 @@ class Course < ActiveRecord::Base
def self.clonable_attributes
[ :group_weighting_scheme, :grading_standard_id, :is_public,
:publish_grades_immediately, :allow_student_wiki_edits,
:allow_student_assignment_edits, :hashtag, :show_public_context_messages,
:allow_student_assignment_edits, :show_public_context_messages,
:syllabus_body, :allow_student_forum_attachments,
:default_wiki_editing_roles, :allow_student_organized_groups,
:default_view, :show_all_discussion_entries, :open_enrollment,

View File

@ -54,8 +54,6 @@ class Group < ActiveRecord::Base
has_many :web_conferences, :as => :context, :dependent => :destroy
has_many :collaborations, :as => :context, :order => 'title, created_at', :dependent => :destroy
has_one :scribd_account, :as => :scribdable
has_many :short_message_associations, :as => :context, :include => :short_message, :dependent => :destroy
has_many :short_messages, :through => :short_message_associations, :dependent => :destroy
has_many :media_objects, :as => :context
has_many :zip_file_imports, :as => :context
has_many :collections, :as => :context

View File

@ -1,72 +0,0 @@
#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class Hashtag < ActiveRecord::Base
has_many :short_message_associations, :as => :context
has_many :short_messages, :through => :short_message_associations
attr_accessible :hashtag
before_save :infer_defaults
def infer_defaults
self.refresh_at ||= Time.now.utc
end
protected :infer_defaults
def user_contexts
res = {}
contexts.each do |context|
context.users.each do |user|
res[user.id] ||= []
res[user.id] << context
end
end
res
end
def contexts
Group.with_hashtag(self.hashtag) + Course.with_hashtag(self.hashtag)
end
def add_short_message(user, result, public=false)
message = ShortMessage.find_by_service_message_id_and_service(result["id"], 'twitter')
user ||= UserService.find_by_service_user_name_and_service(result["from_user"], "twitter").user rescue nil
message ||= ShortMessage.create(
:service_message_id => result["id"],
:service => "twitter",
:user => user,
:message => result["text"],
:created_at => Time.parse(result["created_at"]),
:service_user_name => result["from_user"]
)
message.is_public ||= public
message.save
self.short_message_associations.find_or_create_by_short_message_id(message.id) if public
contexts = user_contexts[user.id] if user
contexts ||= []
contexts.each do |context|
context.short_message_associations.find_or_create_by_short_message_id(message.id)
end
end
named_scope :to_be_polled, lambda {
{ :conditions => ['hashtags.refresh_at <= ?', Time.now ], :order => :refresh_at, :limit => 1 }
}
end

View File

@ -1,27 +0,0 @@
#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class ShortMessage < ActiveRecord::Base
attr_accessible :message, :user, :author_name, :is_public, :service_message_id, :service, :service_user_name
has_many :short_message_associations, :dependent => :destroy
belongs_to :user
def author_name
self.user ? self.user.name : self.service_user_name
end
end

View File

@ -1,38 +0,0 @@
#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class ShortMessageAssociation < ActiveRecord::Base
attr_accessible :context, :short_message
belongs_to :short_message
belongs_to :context, :polymorphic => true
set_policy do
given {|user, session| self.context.grants_rights?(user, session, :read)[:read] }
can :read
given {|user, session| self.context.grants_right?(user, session, :participate_as_student) }
can :read and can :create
given {|user, session| user && self.short_message && self.short_message.user_id == user.id }
can :read and can :delete
given {|user, session| self.context.grants_rights?(user, session, :manage)[:manage] }
can :read and can :create and can :delete
end
end

View File

@ -472,10 +472,6 @@ class User < ActiveRecord::Base
end
protected :assign_uuid
def hashtag
nil
end
named_scope :with_service, lambda { |service|
if service.is_a?(UserService)
{:include => :user_services, :conditions => ['user_services.service = ?', service.service]}
@ -919,7 +915,7 @@ class User < ActiveRecord::Base
'calendar_events','collaborations',
'context_module_progressions','discussion_entries','discussion_topics',
'enrollments','group_memberships','page_comments',
'rubric_assessments','short_messages',
'rubric_assessments',
'submission_comment_participants','user_services','web_conferences',
'web_conference_participants','wiki_pages'].each do |key|
updates[key] = "user_id"

View File

@ -50,17 +50,6 @@
<% end %>
<span class="course_info name"><%= @context.name %></span>
</td>
<% if feature_and_service_enabled?(:twitter) %>
<td class="hashtag_form" style="<%= hidden unless @context.hashtag && @context.hashtag != "" %> vertical-align: top;"><%= f.blabel :hashtag, :en => "Hashtag" %></td>
<td class="hashtag_form" style="<%= hidden unless @context.hashtag && @context.hashtag != "" %> width: 60%;">
<%= f.text_field :hashtag, :class => "course_form" %>
<span class="course_info" id="course_hashtag"><%= @context.hashtag %></span>
<div style="font-size: 0.8em;" id="hashtag_options"><span class="course_form">
<%= f.check_box :show_public_context_messages %>
<%= f.label :show_public_context_messages, :en => "collect public messages for this hashtag" %>
</span></div>
</td>
<% end %>
</tr>
<tr>
<td class="nobr"><%= f.blabel :course_code, :en => "Course Code" %></td>
@ -72,33 +61,6 @@
<% end %>
<span class="course_info course_code"><%= @context.course_code %></span>
</td>
<% if feature_and_service_enabled?(:twitter) %>
<td colspan="2" style=" display: none; padding-left: 10px;"><span class="course_form" style="font-size: 0.8em;">
<a href="#" class="hashtag_dialog_link help"> <%= t('links.hashtag_help', %{What's a hashtag?}) %></a>
<div id="hashtag_dialog" style="display: none; font-size: 0.8em;">
<%= image_tag "twitter.png", :style => "float: left; margin: 10px;" %>
<%= mt 'help.hashtags', %{Hashtags are special phrases that let people consistently mention the same idea (like a course) on web sites like Twitter. For example, the message "I like #instructure" is using the hashtag "instructure".
Hashtags should consist of letters, numbers, dashes and underscores (no spaces). The hashtag should be unique, easily recognizable, and short. Short hashtags are better since sites like Twitter limit the number of letters per message.}%>
<p><%= before_label('examples', %{Examples}) %><br/>
<table style="margin-left: 20px;"><tr>
<td><%= before_label('too_general_twitter_hashtag.description', %{too general}) %></td>
<td><b> <%= t('too_general_twitter_hashtag.example', %{#biology}) %></b></td>
</tr><tr>
<td><%= before_label('too_long_twitter_hashtag.description', %{too long}) %></td>
<td><b> <%= t('too_long_twitter_hashtag.example', %{#san-fransisco-university-biology-100}) %></b></td>
</tr><tr>
<td><%= before_label('good_twitter_hashtag.description', %{much better}) %></td>
<td><b> <%= t('good_twitter_hashtag.example', %{#sfu-bio100}) %></b></td>
</tr></table>
</p>
<div class="button-container">
<button type="button" class="close_dialog_button button"><%= t('buttons.kthxbai', %{Cool, Thanks}) %></button>
</div>
</div>
</span>
</td>
<% end %>
<% if @context.sis_source_id && can_do(@context.root_account, @current_user, :read_sis) || can_do(@context.root_account, @current_user, :manage_sis) %>
</tr><tr>
<td><%= f.blabel :sis_source_id, :en => "SIS ID" %></td>

View File

@ -27,7 +27,7 @@ class ActiveRecord::Base
'calendar_events' => %w(calendar_event_repeat_id for_repeat_on),
'content_tags' => %w(sequence_position context_module_association_id),
'course_sections' => %w(sis_cross_listed_section_id sis_cross_listed_section_sis_batch_id sticky_xlist sis_name students_can_participate_before_start_at section_organization_name long_section_code),
'courses' => %w(section hidden_tabs sis_name sis_course_code),
'courses' => %w(section hidden_tabs sis_name sis_course_code hashtag),
'discussion_topics' => %w(authorization_list_id),
'enrollment_terms' => %w(sis_data sis_name),
'enrollments' => %w(invitation_email can_participate_before_start_at limit_priveleges_to_course_sections),

View File

@ -52,13 +52,6 @@ Delayed::Periodic.cron 'CrocodocDocument.update_process_states', '*/5 * * * *' d
end
end
Delayed::Periodic.cron 'Twitter processing', '*/15 * * * *' do
Shard.with_each_shard do
TwitterSearcher.process
TwitterUserPoller.process
end
end
Delayed::Periodic.cron 'Reporting::CountsReport.process', '0 11 * * *' do
Reporting::CountsReport.process
end

View File

@ -268,7 +268,6 @@ ActionController::Routing::Routes.draw do |map|
end
course.resources :collaborations
course.resources :short_messages
course.resources :gradebook_uploads
course.resources :rubrics
@ -411,7 +410,6 @@ ActionController::Routing::Routes.draw do |map|
add_conferences(group)
add_media(group)
group.resources :collaborations
group.resources :short_messages
group.old_calendar 'calendar', :controller => 'calendars', :action => 'show'
group.profile 'profile', :controller => :groups, :action => 'profile', :conditions => {:method => :get}
end

View File

@ -0,0 +1,44 @@
class DropHashtags < ActiveRecord::Migration
tag :postdeploy
def self.up
drop_table :short_message_associations
drop_table :short_messages
drop_table :hashtags
remove_column :courses, :hashtag
end
def self.down
add_column :courses, :hashtag, :string
create_table "hashtags" do |t|
t.string "hashtag"
t.datetime "refresh_at"
t.string "last_result_id"
t.timestamps
end
create_table "short_messages" do |t|
t.string "message"
t.integer "user_id", :limit => 8
t.string "author_name"
t.timestamps
t.boolean "is_public", :default => false
t.string "service_message_id"
t.string "service"
t.string "service_user_name"
end
add_index "short_messages", ["user_id"]
create_table "short_message_associations" do |t|
t.integer "context_id", :limit => 8
t.string "context_type"
t.integer "short_message_id", :limit => 8
t.timestamps
end
add_index "short_message_associations", ["context_id", "context_type"]
add_index "short_message_associations", ["short_message_id"]
end
end

View File

@ -50,7 +50,7 @@ module CC::Importer::Canvas
return course unless doc
course[:migration_id] = get_node_att(doc, 'course', 'identifier')
['title', 'course_code', 'hashtag', 'default_wiki_editing_roles',
['title', 'course_code', 'default_wiki_editing_roles',
'turnitin_comments', 'default_view', 'license', 'locale',
'group_weighting_scheme', 'storage_quota', 'grading_standard_identifier_ref'].each do |string_type|
val = get_node_val(doc, string_type)

View File

@ -1,85 +0,0 @@
#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class TwitterSearcher
REFRESH_INTERVAL = 30.minutes
REFRESH_INTERVAL_EMPTY = 60.minutes
MAX_TAGS_PER_PROCESS = 100
def self.process
TwitterSearcher.new.process
end
def initialize
@logger = RAILS_DEFAULT_LOGGER
end
def process
count = 0
while hashtag = Hashtag.to_be_polled.first and (count += 1) < MAX_TAGS_PER_PROCESS
hashtag.refresh_at = Time.now.utc + REFRESH_INTERVAL
hashtag.save
require 'net/http'
@logger.info("hashtag found: #{hashtag} -- requesting public twitter search")
url = "http://search.twitter.com/search.json?q=%23#{CGI::escape(hashtag.hashtag)}&rpp=25"
url += "&since_id=#{hashtag.last_result_id}" if hashtag.last_result_id
url = URI.parse url
@logger.info("request url: #{url}")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url.path + (url.query ? ('?' + url.query) : ''))
response = http.request(request)
case response
when Net::HTTPSuccess
@logger.info('request succeeded')
begin
results = ActiveSupport::JSON.decode(response.body)["results"]
@logger.info("found #{results.length} results")
since_id = results[0]["id"] rescue nil
results.each do |result|
hashtag.add_short_message(nil, result, true)
end
hashtag.last_result_id = since_id if since_id
hashtag.refresh_at = Time.now.utc + (results.empty? ? REFRESH_INTERVAL_EMPTY : REFRESH_INTERVAL)
hashtag.save
@logger.info('results successfully added')
rescue => e
ErrorReport.log_exception(:processing, e, {
:message => e.to_s,
:url => (request.url rescue "none")
})
@logger.info("** unexpected error: #{e.to_s}")
@logger.info(e.backtrace)
end
else
@logger.info("throttled! Retry after: #{response['Retry-After']}")
# TODO: This assumes that Retry-After will always be sent as delta-seconds. We should probably support HTTP-date too:
# http://webee.technion.ac.il/labs/comnet/netcourse/CIE/RFC/2068/201.htm
wait_time = response['Retry-After'].to_i if response['Retry-After']
hashtag.refresh_at = Time.now.utc + wait_time
hashtag.save
end
end
if count >= MAX_TAGS_PER_PROCESS
@logger.info("more hashtags to process... scheduling another job")
TwitterSearcher.send_later_engueue_args(:process, { :priority => Delayed::LOW_PRIORITY })
end
end
end

View File

@ -1,94 +0,0 @@
#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class TwitterUserPoller
REFRESH_INTERVAL = 30.minutes
REFRESH_INTERVAL_EMPTY = 60.minutes
MAX_PER_PROCESS = 100
include Twitter
def self.process
TwitterUserPoller.new.process
end
def initialize
@logger = RAILS_DEFAULT_LOGGER
end
def retrieve_tweets(service, attempt=0)
@twitter_service = service
twitter_list(nil, service.last_result_id)
end
def process
count = 0
while service = UserService.to_be_polled.for_service('twitter').first and (count += 1) < MAX_PER_PROCESS
service.updated_at = Time.now.utc
service.save
@logger.info("user found: #{service.service_user_name} retrieving tweets...")
since_id = nil
count = 0
tweets = nil
begin
tweets = retrieve_tweets(service)
rescue => e
retry_after = REFRESH_INTERVAL_EMPTY
if e.to_s =~ /Retry After (\d+)/
retry_after = $1
@logger.info("throttled! Retry after: #{retry_after}")
else
ErrorReport.log_exception(:processing, e, {
:message => e.to_s,
:url => (request.url rescue "none")
})
@logger.info("unexpected error: #{e.to_s} #{e.backtrace.join "\n"}")
end
retry_after = [REFRESH_INTERVAL_EMPTY, retry_after.to_i].max
service.refresh_at = Time.now.utc + retry_after + 1.minute
service.save
end
if tweets
@logger.info("found #{tweets.length} tweets")
tweets.each do |tweet|
scans = (tweet['text'] || '').scan(/#([^#\s])/)
@logger.info("message found: #{tweet['id']} with #{scans.length} hashtags")
scans.each do |scan|
hash = scan[0]
if hashtag = Hashtag.find_by_hashtag(hash)
hashtag.add_short_message(service.user, tweet, false)
@logger.info("added for #{hash}")
end
end
since_id ||= tweet['id'] if tweet['id']
end
service.last_result_id = since_id if since_id
service.refresh_at = Time.now.utc + (since_id ? REFRESH_INTERVAL : REFRESH_INTERVAL_EMPTY)
service.save
end
end
if count >= MAX_PER_PROCESS
@logger.info("more services to process... scheduling another job")
TwitterUserPoller.send_later_engueue_args(:process, { :priority => Delayed::LOW_PRIORITY })
end
end
end

View File

@ -115,8 +115,6 @@ define([
var $add_section_form = $("#add_section_form"),
$edit_section_form = $("#edit_section_form"),
$course_form = $("#course_form"),
$hashtag_form = $(".hashtag_form"),
$course_hashtag = $("#course_hashtag"),
$enrollment_dialog = $("#enrollment_dialog"),
$tabBar = $("#course_details_tabs"),
// as of jqueryui 1.9, the cookie trumps the fragment :(. so we hack
@ -253,23 +251,6 @@ define([
axis: 'y'
}).disableSelection();
$(".hashtag_dialog_link").click(function(event) {
event.preventDefault();
$("#hashtag_dialog").dialog({
title: I18n.t('titles.hashtag_help', "What's a Hashtag?"),
width: 500
});
});
$(".close_dialog_button").click(function() {
$("#hashtag_dialog").dialog('close');
});
$("#course_hashtag").bind('blur change keyup', function() {
var val = $(this).val() || "";
val = val.replace(/(\s)+/g, "_").replace(/#/, "");
$("#hashtag_options").showIf(val && val !== "");
$(this).val(val);
});
$(document).fragmentChange(function(event, hash) {
function handleFragmentType(val){
$("#tab-users-link").click();
@ -293,8 +274,6 @@ define([
$("#course_account_id").val(ui.item.id);
}
});
$hashtag_form.showIf($course_hashtag.text().length > 0);
$course_hashtag.triggerHandler('blur');
});
$(".move_course_link").click(function(event) {
event.preventDefault();
@ -311,7 +290,6 @@ define([
}).change();
$course_form.formSubmit({
processData: function(data) {
data['course[hashtag]'] = (data['course[hashtag]'] || "").replace(/\s/g, "_").replace(/#/g, "");
if(data['course[start_at]']) {
data['course[start_at]'] += " 12:00am";
}
@ -348,7 +326,6 @@ define([
$(this).text($.replaceTags($(this).text(), 'self_enrollment_code', course.self_enrollment_code));
});
}
$(".hashtag_form").showIf($("#course_hashtag").text().length > 0);
},
error: function(data) {
$(this).loadingImage('remove');
@ -359,7 +336,6 @@ define([
.find(".cancel_button")
.click(function() {
$course_form.removeClass('editing');
$hashtag_form.showIf($course_hashtag.text().length > 0);
$(".course_form_more_options").hide();
}).end()
.find(":text:not(.date_entry)").keycodes('esc', function() {

View File

@ -105,7 +105,6 @@ describe ContentMigration do
@copy_from.publish_grades_immediately = false
@copy_from.allow_student_wiki_edits = true
@copy_from.allow_student_assignment_edits = true
@copy_from.hashtag = 'oi'
@copy_from.show_public_context_messages = false
@copy_from.allow_student_forum_attachments = false
@copy_from.default_wiki_editing_roles = 'teachers'