diff --git a/Gemfile b/Gemfile index 25613881246..972db79b18e 100644 --- a/Gemfile +++ b/Gemfile @@ -8,6 +8,7 @@ gem 'message_bus', path: 'vendor/gems/message_bus' gem 'rails_multisite', path: 'vendor/gems/rails_multisite' gem 'simple_handlebars_rails', path: 'vendor/gems/simple_handlebars_rails' +gem 'redcarpet', require: false gem 'activerecord-postgres-hstore' gem 'acts_as_paranoid' gem 'active_attr' # until we get ActiveModel::Model with Rails 4 diff --git a/Gemfile.lock b/Gemfile.lock index 393f96f4c62..ca00a65f730 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -332,6 +332,7 @@ GEM ffi (>= 0.5.0) rdoc (3.12.1) json (~> 1.4) + redcarpet (2.2.2) redis (3.0.2) redis-actionpack (3.2.3) actionpack (~> 3.2.3) @@ -494,6 +495,7 @@ DEPENDENCIES rake rb-fsevent rb-inotify (~> 0.8.8) + redcarpet redis redis-rails rest-client diff --git a/app/assets/javascripts/discourse/helpers/application_helpers.js.coffee b/app/assets/javascripts/discourse/helpers/application_helpers.js.coffee index 460df3aa2ba..d1e456b8a9f 100644 --- a/app/assets/javascripts/discourse/helpers/application_helpers.js.coffee +++ b/app/assets/javascripts/discourse/helpers/application_helpers.js.coffee @@ -20,7 +20,9 @@ Handlebars.registerHelper 'shorten', (property, options) -> Handlebars.registerHelper 'topicLink', (property, options) -> topic = Ember.Handlebars.get(this, property, options) - "#{Handlebars.Utils.escapeExpression(topic.get('title'))}" + + title = topic.get('fancy_title') || topic.get('title') + "#{title}" Handlebars.registerHelper 'categoryLink', (property, options) -> category = Ember.Handlebars.get(this, property, options) diff --git a/app/assets/javascripts/discourse/templates/topic.js.handlebars b/app/assets/javascripts/discourse/templates/topic.js.handlebars index add9aec92ba..fec4e5dcd86 100644 --- a/app/assets/javascripts/discourse/templates/topic.js.handlebars +++ b/app/assets/javascripts/discourse/templates/topic.js.handlebars @@ -15,9 +15,9 @@ {{else}}

- {{#if view.topic.title}} + {{#if view.topic.fancy_title}} {{view Discourse.TopicStatusView topicBinding="view.topic"}} - {{unbound view.topic.title}} + {{{unbound view.topic.fancy_title}}} {{else}} {{#if view.topic.missing}} {{i18n topic.not_found.title}} diff --git a/app/assets/javascripts/discourse/views/topic_view.js.coffee b/app/assets/javascripts/discourse/views/topic_view.js.coffee index eff2af3e384..a30ad724575 100644 --- a/app/assets/javascripts/discourse/views/topic_view.js.coffee +++ b/app/assets/javascripts/discourse/views/topic_view.js.coffee @@ -280,7 +280,9 @@ window.Discourse.TopicView = Ember.View.extend Discourse.Scrolling, finishedEdit: -> if @get('editingTopic') topic = @get('topic') - topic.set('title', $('#edit-title').val()) + new_val = $('#edit-title').val() + topic.set('title', new_val) + topic.set('fancy_title', new_val) topic.save() @set('editingTopic', false) diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index 4146d7cd49b..b3d240694e3 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -138,6 +138,8 @@ class SiteSetting < ActiveRecord::Base setting(:new_user_period_days, 2) + setting(:title_fancy_entities, true) + client_setting(:educate_until_posts, 2) def self.call_discourse_hub? diff --git a/app/models/topic.rb b/app/models/topic.rb index 5977f5bd7ed..4df1c928a54 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -5,6 +5,7 @@ require_dependency 'rate_limiter' require_dependency 'text_sentinel' class Topic < ActiveRecord::Base + include ActionView::Helpers include RateLimiter::OnCreateRecord MAX_SORT_ORDER = 2147483647 @@ -67,7 +68,10 @@ class Topic < ActiveRecord::Base end before_validation do - self.title.strip! if self.title.present? + if self.title.present? + self.title = sanitize(self.title) + self.title.strip! + end end before_create do @@ -115,6 +119,14 @@ class Topic < ActiveRecord::Base errors.add(:title, I18n.t(:has_already_been_used)) if finder.exists? end + def fancy_title + return title unless SiteSetting.title_fancy_entities? + + # We don't always have to require this, if fancy is disabled + require 'redcarpet' + + Redcarpet::Render::SmartyPants.render(title) + end def title_quality # We don't care about quality on private messages diff --git a/app/serializers/basic_topic_serializer.rb b/app/serializers/basic_topic_serializer.rb index e99d45ff0b5..b2e2d2ca16e 100644 --- a/app/serializers/basic_topic_serializer.rb +++ b/app/serializers/basic_topic_serializer.rb @@ -3,8 +3,20 @@ require_dependency 'age_words' class BasicTopicSerializer < ApplicationSerializer include ActionView::Helpers - attributes :id, :title, :reply_count, :posts_count, :highest_post_number, :image_url, :created_at, - :last_posted_at, :age, :unseen, :last_read_post_number, :unread, :new_posts + attributes :id, + :title, + :fancy_title, + :reply_count, + :posts_count, + :highest_post_number, + :image_url, + :created_at, + :last_posted_at, + :age, + :unseen, + :last_read_post_number, + :unread, + :new_posts def age AgeWords.age_words(Time.now - (object.created_at || Time.now)) diff --git a/app/serializers/topic_link_serializer.rb b/app/serializers/topic_link_serializer.rb index d0b1fc3dfda..df696b0f6a2 100644 --- a/app/serializers/topic_link_serializer.rb +++ b/app/serializers/topic_link_serializer.rb @@ -1,6 +1,12 @@ class TopicLinkSerializer < ApplicationSerializer - attributes :url, :title, :internal, :reflection, :clicks, :user_id + attributes :url, + :title, + :fancy_title, + :internal, + :reflection, + :clicks, + :user_id def url object['url'] @@ -10,6 +16,10 @@ class TopicLinkSerializer < ApplicationSerializer object['title'] end + def fancy_title + object['fancy_title'] + end + def internal object['internal'] == 't' end @@ -25,6 +35,7 @@ class TopicLinkSerializer < ApplicationSerializer def user_id object['user_id'].to_i end + def include_user_id? object['user_id'].present? end diff --git a/app/serializers/topic_list_item_serializer.rb b/app/serializers/topic_list_item_serializer.rb index 63d8c2ba426..090544b5da6 100644 --- a/app/serializers/topic_list_item_serializer.rb +++ b/app/serializers/topic_list_item_serializer.rb @@ -1,6 +1,16 @@ class TopicListItemSerializer < BasicTopicSerializer - attributes :views, :like_count, :visible, :pinned, :closed, :archived, :last_post_age, :starred, :has_best_of, :archetype, :slug + attributes :views, + :like_count, + :visible, + :pinned, + :closed, + :archived, + :last_post_age, + :starred, + :has_best_of, + :archetype, + :slug has_one :category has_many :posters, serializer: TopicPosterSerializer, embed: :objects diff --git a/app/serializers/topic_view_serializer.rb b/app/serializers/topic_view_serializer.rb index 003b15d7f54..d7e62a6fc1b 100644 --- a/app/serializers/topic_view_serializer.rb +++ b/app/serializers/topic_view_serializer.rb @@ -4,6 +4,7 @@ class TopicViewSerializer < ApplicationSerializer def self.topic_attributes [:id, :title, + :fancy_title, :posts_count, :created_at, :views, diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 880a7580170..6e70a79bc35 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -342,12 +342,11 @@ en: email_time_window_mins: "How many minutes we wait before sending a user mail, to give them a chance to see it first." flush_timings_secs: "How frequently we flush timing data to the server, in seconds." - max_word_length: "The maximum word length in a topic title" title_min_entropy: "The minimum entropy for a topic title" body_min_entropy: "The minimum entropy for post body" - new_user_period_days: "How long a user is highlighted as being new, in days." + title_fancy_entities: "Convert fancy HTML entities in topic titles" notification_types: mentioned: "%{display_username} mentioned you in %{link}" diff --git a/db/structure.sql b/db/structure.sql index d83aa74de3c..0df0ec441d5 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -8,6 +8,13 @@ SET standard_conforming_strings = on; SET check_function_bodies = false; SET client_min_messages = warning; +-- +-- Name: backup; Type: SCHEMA; Schema: -; Owner: - +-- + +CREATE SCHEMA backup; + + -- -- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: - -- @@ -36,12 +43,1176 @@ CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public; COMMENT ON EXTENSION hstore IS 'data type for storing sets of (key, value) pairs'; -SET search_path = public, pg_catalog; +SET search_path = backup, pg_catalog; SET default_tablespace = ''; SET default_with_oids = false; +-- +-- Name: categories; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE categories ( + id integer NOT NULL, + name character varying(50) NOT NULL, + color character varying(6) DEFAULT 'AB9364'::character varying NOT NULL, + topic_id integer, + top1_topic_id integer, + top2_topic_id integer, + top1_user_id integer, + top2_user_id integer, + topic_count integer DEFAULT 0 NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + user_id integer NOT NULL, + topics_year integer, + topics_month integer, + topics_week integer, + slug character varying(255) NOT NULL +); + + +-- +-- Name: categories_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE categories_id_seq + START WITH 5 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: categories_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE categories_id_seq OWNED BY categories.id; + + +-- +-- Name: category_featured_topics; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE category_featured_topics ( + category_id integer NOT NULL, + topic_id integer NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: category_featured_users; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE category_featured_users ( + id integer NOT NULL, + category_id integer, + user_id integer, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: category_featured_users_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE category_featured_users_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: category_featured_users_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE category_featured_users_id_seq OWNED BY category_featured_users.id; + + +-- +-- Name: draft_sequences; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE draft_sequences ( + id integer NOT NULL, + user_id integer NOT NULL, + draft_key character varying(255) NOT NULL, + sequence integer NOT NULL +); + + +-- +-- Name: draft_sequences_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE draft_sequences_id_seq + START WITH 20 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: draft_sequences_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE draft_sequences_id_seq OWNED BY draft_sequences.id; + + +-- +-- Name: drafts; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE drafts ( + id integer NOT NULL, + user_id integer NOT NULL, + draft_key character varying(255) NOT NULL, + data text NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + sequence integer DEFAULT 0 NOT NULL +); + + +-- +-- Name: drafts_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE drafts_id_seq + START WITH 2 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: drafts_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE drafts_id_seq OWNED BY drafts.id; + + +-- +-- Name: email_logs; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE email_logs ( + id integer NOT NULL, + to_address character varying(255) NOT NULL, + email_type character varying(255) NOT NULL, + user_id integer, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: email_logs_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE email_logs_id_seq + START WITH 3 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: email_logs_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE email_logs_id_seq OWNED BY email_logs.id; + + +-- +-- Name: email_tokens; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE email_tokens ( + id integer NOT NULL, + user_id integer NOT NULL, + email character varying(255) NOT NULL, + token character varying(255) NOT NULL, + confirmed boolean DEFAULT false NOT NULL, + expired boolean DEFAULT false NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: email_tokens_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE email_tokens_id_seq + START WITH 3 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: email_tokens_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE email_tokens_id_seq OWNED BY email_tokens.id; + + +-- +-- Name: facebook_user_infos; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE facebook_user_infos ( + id integer NOT NULL, + user_id integer NOT NULL, + facebook_user_id integer NOT NULL, + username character varying(255) NOT NULL, + first_name character varying(255), + last_name character varying(255), + email character varying(255), + gender character varying(255), + name character varying(255), + link character varying(255), + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: facebook_user_infos_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE facebook_user_infos_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: facebook_user_infos_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE facebook_user_infos_id_seq OWNED BY facebook_user_infos.id; + + +-- +-- Name: incoming_links; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE incoming_links ( + id integer NOT NULL, + url character varying(1000) NOT NULL, + referer character varying(1000) NOT NULL, + domain character varying(100) NOT NULL, + topic_id integer, + post_number integer, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: incoming_links_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE incoming_links_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: incoming_links_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE incoming_links_id_seq OWNED BY incoming_links.id; + + +-- +-- Name: invites; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE invites ( + id integer NOT NULL, + invite_key character varying(32) NOT NULL, + email character varying(255) NOT NULL, + invited_by_id integer NOT NULL, + user_id integer, + redeemed_at timestamp without time zone, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + deleted_at timestamp without time zone +); + + +-- +-- Name: invites_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE invites_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: invites_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE invites_id_seq OWNED BY invites.id; + + +-- +-- Name: notifications; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE notifications ( + id integer NOT NULL, + notification_type integer NOT NULL, + user_id integer NOT NULL, + data character varying(255) NOT NULL, + read boolean DEFAULT false NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + topic_id integer, + post_number integer, + post_action_id integer +); + + +-- +-- Name: notifications_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE notifications_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: notifications_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE notifications_id_seq OWNED BY notifications.id; + + +-- +-- Name: onebox_renders; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE onebox_renders ( + id integer NOT NULL, + url character varying(255) NOT NULL, + cooked text NOT NULL, + expires_at timestamp without time zone NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + preview text +); + + +-- +-- Name: onebox_renders_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE onebox_renders_id_seq + START WITH 2 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: onebox_renders_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE onebox_renders_id_seq OWNED BY onebox_renders.id; + + +-- +-- Name: post_action_types; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE post_action_types ( + name_key character varying(50) NOT NULL, + is_flag boolean DEFAULT false NOT NULL, + icon character varying(20), + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + id integer NOT NULL +); + + +-- +-- Name: post_action_types_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE post_action_types_id_seq + START WITH 6 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: post_action_types_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE post_action_types_id_seq OWNED BY post_action_types.id; + + +-- +-- Name: post_actions; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE post_actions ( + id integer NOT NULL, + post_id integer NOT NULL, + user_id integer NOT NULL, + post_action_type_id integer NOT NULL, + deleted_at timestamp without time zone, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: post_actions_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE post_actions_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: post_actions_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE post_actions_id_seq OWNED BY post_actions.id; + + +-- +-- Name: post_onebox_renders; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE post_onebox_renders ( + post_id integer NOT NULL, + onebox_render_id integer NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: post_replies; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE post_replies ( + post_id integer, + reply_id integer, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: post_timings; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE post_timings ( + topic_id integer NOT NULL, + post_number integer NOT NULL, + user_id integer NOT NULL, + msecs integer NOT NULL +); + + +-- +-- Name: posts; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE posts ( + id integer NOT NULL, + user_id integer NOT NULL, + topic_id integer NOT NULL, + post_number integer NOT NULL, + raw text NOT NULL, + cooked text NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + reply_to_post_number integer, + cached_version integer DEFAULT 1 NOT NULL, + reply_count integer DEFAULT 0 NOT NULL, + quote_count integer DEFAULT 0 NOT NULL, + reply_below_post_number integer, + deleted_at timestamp without time zone, + off_topic_count integer DEFAULT 0 NOT NULL, + offensive_count integer DEFAULT 0 NOT NULL, + like_count integer DEFAULT 0 NOT NULL, + incoming_link_count integer DEFAULT 0 NOT NULL, + bookmark_count integer DEFAULT 0 NOT NULL, + avg_time integer, + score double precision, + reads integer DEFAULT 0 NOT NULL, + post_type integer DEFAULT 1 NOT NULL, + vote_count integer DEFAULT 0 NOT NULL, + sort_order integer, + last_editor_id integer +); + + +-- +-- Name: posts_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE posts_id_seq + START WITH 16 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: posts_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE posts_id_seq OWNED BY posts.id; + + +-- +-- Name: site_customizations; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE site_customizations ( + id integer NOT NULL, + name character varying(255) NOT NULL, + stylesheet text, + header text, + "position" integer NOT NULL, + user_id integer NOT NULL, + enabled boolean NOT NULL, + key character varying(255) NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + override_default_style boolean DEFAULT false NOT NULL, + stylesheet_baked text DEFAULT ''::text NOT NULL +); + + +-- +-- Name: site_customizations_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE site_customizations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: site_customizations_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE site_customizations_id_seq OWNED BY site_customizations.id; + + +-- +-- Name: site_settings; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE site_settings ( + id integer NOT NULL, + name character varying(255) NOT NULL, + data_type integer NOT NULL, + value text, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: site_settings_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE site_settings_id_seq + START WITH 4 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: site_settings_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE site_settings_id_seq OWNED BY site_settings.id; + + +-- +-- Name: topic_allowed_users; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE topic_allowed_users ( + id integer NOT NULL, + user_id integer NOT NULL, + topic_id integer NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: topic_allowed_users_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE topic_allowed_users_id_seq + START WITH 3 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: topic_allowed_users_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE topic_allowed_users_id_seq OWNED BY topic_allowed_users.id; + + +-- +-- Name: topic_invites; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE topic_invites ( + id integer NOT NULL, + topic_id integer NOT NULL, + invite_id integer NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: topic_invites_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE topic_invites_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: topic_invites_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE topic_invites_id_seq OWNED BY topic_invites.id; + + +-- +-- Name: topic_link_clicks; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE topic_link_clicks ( + id integer NOT NULL, + topic_link_id integer NOT NULL, + user_id integer, + ip bigint NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: topic_link_clicks_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE topic_link_clicks_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: topic_link_clicks_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE topic_link_clicks_id_seq OWNED BY topic_link_clicks.id; + + +-- +-- Name: topic_links; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE topic_links ( + id integer NOT NULL, + topic_id integer NOT NULL, + post_id integer, + user_id integer NOT NULL, + url character varying(500) NOT NULL, + domain character varying(100) NOT NULL, + internal boolean DEFAULT false NOT NULL, + link_topic_id integer, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + reflection boolean DEFAULT false, + clicks integer DEFAULT 0 NOT NULL, + link_post_id integer +); + + +-- +-- Name: topic_links_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE topic_links_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: topic_links_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE topic_links_id_seq OWNED BY topic_links.id; + + +-- +-- Name: topic_users; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE topic_users ( + user_id integer NOT NULL, + topic_id integer NOT NULL, + starred boolean DEFAULT false NOT NULL, + posted boolean DEFAULT false NOT NULL, + last_read_post_number integer, + seen_post_count integer, + starred_at timestamp without time zone, + muted_at timestamp without time zone, + last_visited_at timestamp without time zone, + first_visited_at timestamp without time zone, + notifications integer DEFAULT 2, + notifications_changed_at timestamp without time zone, + notifications_reason_id integer, + CONSTRAINT test_starred_at CHECK (((starred = false) OR (starred_at IS NOT NULL))) +); + + +-- +-- Name: topics; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE topics ( + id integer NOT NULL, + title character varying(255) NOT NULL, + last_posted_at timestamp without time zone, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + views integer DEFAULT 0 NOT NULL, + posts_count integer DEFAULT 0 NOT NULL, + user_id integer NOT NULL, + last_post_user_id integer NOT NULL, + reply_count integer DEFAULT 0 NOT NULL, + featured_user1_id integer, + featured_user2_id integer, + featured_user3_id integer, + avg_time integer, + deleted_at timestamp without time zone, + highest_post_number integer DEFAULT 0 NOT NULL, + image_url character varying(255), + off_topic_count integer DEFAULT 0 NOT NULL, + offensive_count integer DEFAULT 0 NOT NULL, + like_count integer DEFAULT 0 NOT NULL, + incoming_link_count integer DEFAULT 0 NOT NULL, + bookmark_count integer DEFAULT 0 NOT NULL, + star_count integer DEFAULT 0 NOT NULL, + category_id integer, + visible boolean DEFAULT true NOT NULL, + moderator_posts_count integer DEFAULT 0 NOT NULL, + closed boolean DEFAULT false NOT NULL, + pinned boolean DEFAULT false NOT NULL, + archived boolean DEFAULT false NOT NULL, + bumped_at timestamp without time zone NOT NULL, + sub_tag character varying(255), + has_best_of boolean DEFAULT false NOT NULL, + meta_data public.hstore, + vote_count integer DEFAULT 0 NOT NULL, + archetype character varying(255) DEFAULT 'regular'::character varying NOT NULL, + featured_user4_id integer +); + + +-- +-- Name: topics_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE topics_id_seq + START WITH 16 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: topics_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE topics_id_seq OWNED BY topics.id; + + +-- +-- Name: trust_levels; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE trust_levels ( + id integer NOT NULL, + name_key character varying(255) NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: trust_levels_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE trust_levels_id_seq + START WITH 3 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: trust_levels_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE trust_levels_id_seq OWNED BY trust_levels.id; + + +-- +-- Name: twitter_user_infos; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE twitter_user_infos ( + id integer NOT NULL, + user_id integer NOT NULL, + screen_name character varying(255) NOT NULL, + twitter_user_id integer NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: twitter_user_infos_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE twitter_user_infos_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: twitter_user_infos_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE twitter_user_infos_id_seq OWNED BY twitter_user_infos.id; + + +-- +-- Name: uploads; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE uploads ( + id integer NOT NULL, + user_id integer NOT NULL, + topic_id integer NOT NULL, + original_filename character varying(255) NOT NULL, + filesize integer NOT NULL, + width integer, + height integer, + url character varying(255) NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: uploads_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE uploads_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: uploads_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE uploads_id_seq OWNED BY uploads.id; + + +-- +-- Name: user_actions; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE user_actions ( + id integer NOT NULL, + action_type integer NOT NULL, + user_id integer NOT NULL, + target_topic_id integer, + target_post_id integer, + target_user_id integer, + acting_user_id integer, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: user_actions_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE user_actions_id_seq + START WITH 40 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: user_actions_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE user_actions_id_seq OWNED BY user_actions.id; + + +-- +-- Name: user_open_ids; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE user_open_ids ( + id integer NOT NULL, + user_id integer NOT NULL, + email character varying(255) NOT NULL, + url character varying(255) NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + active boolean NOT NULL +); + + +-- +-- Name: user_open_ids_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE user_open_ids_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: user_open_ids_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE user_open_ids_id_seq OWNED BY user_open_ids.id; + + +-- +-- Name: user_visits; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE user_visits ( + id integer NOT NULL, + user_id integer NOT NULL, + visited_at date NOT NULL +); + + +-- +-- Name: user_visits_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE user_visits_id_seq + START WITH 4 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: user_visits_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE user_visits_id_seq OWNED BY user_visits.id; + + +-- +-- Name: users; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE users ( + id integer NOT NULL, + username character varying(20) NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + name character varying(255), + bio_raw text, + seen_notification_id integer DEFAULT 0 NOT NULL, + last_posted_at timestamp without time zone, + email character varying(256) NOT NULL, + password_hash character varying(64), + salt character varying(32), + active boolean, + username_lower character varying(20) NOT NULL, + auth_token character varying(32), + last_seen_at timestamp without time zone, + website character varying(255), + admin boolean DEFAULT false NOT NULL, + moderator boolean DEFAULT false NOT NULL, + last_emailed_at timestamp without time zone, + email_digests boolean DEFAULT true NOT NULL, + trust_level_id integer DEFAULT 1 NOT NULL, + bio_cooked text, + email_private_messages boolean DEFAULT true, + email_direct boolean DEFAULT true NOT NULL, + approved boolean DEFAULT false NOT NULL, + approved_by_id integer, + approved_at timestamp without time zone, + topics_entered integer DEFAULT 0 NOT NULL, + posts_read_count integer DEFAULT 0 NOT NULL, + digest_after_days integer DEFAULT 7 NOT NULL, + previous_visit_at timestamp without time zone +); + + +-- +-- Name: users_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE users_id_seq + START WITH 3 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: users_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE users_id_seq OWNED BY users.id; + + +-- +-- Name: versions; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE versions ( + id integer NOT NULL, + versioned_id integer, + versioned_type character varying(255), + user_id integer, + user_type character varying(255), + user_name character varying(255), + modifications text, + number integer, + reverted_from integer, + tag character varying(255), + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: versions_id_seq; Type: SEQUENCE; Schema: backup; Owner: - +-- + +CREATE SEQUENCE versions_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: versions_id_seq; Type: SEQUENCE OWNED BY; Schema: backup; Owner: - +-- + +ALTER SEQUENCE versions_id_seq OWNED BY versions.id; + + +-- +-- Name: views; Type: TABLE; Schema: backup; Owner: -; Tablespace: +-- + +CREATE TABLE views ( + parent_id integer NOT NULL, + parent_type character varying(50) NOT NULL, + ip bigint NOT NULL, + viewed_at timestamp without time zone NOT NULL, + user_id integer +); + + +SET search_path = public, pg_catalog; + -- -- Name: categories; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -1264,6 +2435,213 @@ CREATE TABLE views ( ); +SET search_path = backup, pg_catalog; + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY categories ALTER COLUMN id SET DEFAULT nextval('categories_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY category_featured_users ALTER COLUMN id SET DEFAULT nextval('category_featured_users_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY draft_sequences ALTER COLUMN id SET DEFAULT nextval('draft_sequences_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY drafts ALTER COLUMN id SET DEFAULT nextval('drafts_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY email_logs ALTER COLUMN id SET DEFAULT nextval('email_logs_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY email_tokens ALTER COLUMN id SET DEFAULT nextval('email_tokens_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY facebook_user_infos ALTER COLUMN id SET DEFAULT nextval('facebook_user_infos_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY incoming_links ALTER COLUMN id SET DEFAULT nextval('incoming_links_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY invites ALTER COLUMN id SET DEFAULT nextval('invites_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY notifications ALTER COLUMN id SET DEFAULT nextval('notifications_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY onebox_renders ALTER COLUMN id SET DEFAULT nextval('onebox_renders_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY post_action_types ALTER COLUMN id SET DEFAULT nextval('post_action_types_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY post_actions ALTER COLUMN id SET DEFAULT nextval('post_actions_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY posts ALTER COLUMN id SET DEFAULT nextval('posts_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY site_customizations ALTER COLUMN id SET DEFAULT nextval('site_customizations_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY site_settings ALTER COLUMN id SET DEFAULT nextval('site_settings_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY topic_allowed_users ALTER COLUMN id SET DEFAULT nextval('topic_allowed_users_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY topic_invites ALTER COLUMN id SET DEFAULT nextval('topic_invites_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY topic_link_clicks ALTER COLUMN id SET DEFAULT nextval('topic_link_clicks_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY topic_links ALTER COLUMN id SET DEFAULT nextval('topic_links_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY topics ALTER COLUMN id SET DEFAULT nextval('topics_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY trust_levels ALTER COLUMN id SET DEFAULT nextval('trust_levels_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY twitter_user_infos ALTER COLUMN id SET DEFAULT nextval('twitter_user_infos_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY uploads ALTER COLUMN id SET DEFAULT nextval('uploads_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY user_actions ALTER COLUMN id SET DEFAULT nextval('user_actions_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY user_open_ids ALTER COLUMN id SET DEFAULT nextval('user_open_ids_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY user_visits ALTER COLUMN id SET DEFAULT nextval('user_visits_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: backup; Owner: - +-- + +ALTER TABLE ONLY versions ALTER COLUMN id SET DEFAULT nextval('versions_id_seq'::regclass); + + +SET search_path = public, pg_catalog; + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -1467,6 +2845,242 @@ ALTER TABLE ONLY users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regcl ALTER TABLE ONLY versions ALTER COLUMN id SET DEFAULT nextval('versions_id_seq'::regclass); +SET search_path = backup, pg_catalog; + +-- +-- Name: actions_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY user_actions + ADD CONSTRAINT actions_pkey PRIMARY KEY (id); + + +-- +-- Name: categories_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY categories + ADD CONSTRAINT categories_pkey PRIMARY KEY (id); + + +-- +-- Name: category_featured_users_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY category_featured_users + ADD CONSTRAINT category_featured_users_pkey PRIMARY KEY (id); + + +-- +-- Name: draft_sequences_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY draft_sequences + ADD CONSTRAINT draft_sequences_pkey PRIMARY KEY (id); + + +-- +-- Name: drafts_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY drafts + ADD CONSTRAINT drafts_pkey PRIMARY KEY (id); + + +-- +-- Name: email_logs_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY email_logs + ADD CONSTRAINT email_logs_pkey PRIMARY KEY (id); + + +-- +-- Name: email_tokens_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY email_tokens + ADD CONSTRAINT email_tokens_pkey PRIMARY KEY (id); + + +-- +-- Name: facebook_user_infos_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY facebook_user_infos + ADD CONSTRAINT facebook_user_infos_pkey PRIMARY KEY (id); + + +-- +-- Name: forum_thread_link_clicks_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY topic_link_clicks + ADD CONSTRAINT forum_thread_link_clicks_pkey PRIMARY KEY (id); + + +-- +-- Name: forum_thread_links_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY topic_links + ADD CONSTRAINT forum_thread_links_pkey PRIMARY KEY (id); + + +-- +-- Name: forum_threads_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY topics + ADD CONSTRAINT forum_threads_pkey PRIMARY KEY (id); + + +-- +-- Name: incoming_links_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY incoming_links + ADD CONSTRAINT incoming_links_pkey PRIMARY KEY (id); + + +-- +-- Name: invites_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY invites + ADD CONSTRAINT invites_pkey PRIMARY KEY (id); + + +-- +-- Name: notifications_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY notifications + ADD CONSTRAINT notifications_pkey PRIMARY KEY (id); + + +-- +-- Name: onebox_renders_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY onebox_renders + ADD CONSTRAINT onebox_renders_pkey PRIMARY KEY (id); + + +-- +-- Name: post_action_types_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY post_action_types + ADD CONSTRAINT post_action_types_pkey PRIMARY KEY (id); + + +-- +-- Name: post_actions_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY post_actions + ADD CONSTRAINT post_actions_pkey PRIMARY KEY (id); + + +-- +-- Name: posts_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY posts + ADD CONSTRAINT posts_pkey PRIMARY KEY (id); + + +-- +-- Name: site_customizations_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY site_customizations + ADD CONSTRAINT site_customizations_pkey PRIMARY KEY (id); + + +-- +-- Name: site_settings_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY site_settings + ADD CONSTRAINT site_settings_pkey PRIMARY KEY (id); + + +-- +-- Name: topic_allowed_users_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY topic_allowed_users + ADD CONSTRAINT topic_allowed_users_pkey PRIMARY KEY (id); + + +-- +-- Name: topic_invites_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY topic_invites + ADD CONSTRAINT topic_invites_pkey PRIMARY KEY (id); + + +-- +-- Name: trust_levels_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY trust_levels + ADD CONSTRAINT trust_levels_pkey PRIMARY KEY (id); + + +-- +-- Name: twitter_user_infos_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY twitter_user_infos + ADD CONSTRAINT twitter_user_infos_pkey PRIMARY KEY (id); + + +-- +-- Name: uploads_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY uploads + ADD CONSTRAINT uploads_pkey PRIMARY KEY (id); + + +-- +-- Name: user_open_ids_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY user_open_ids + ADD CONSTRAINT user_open_ids_pkey PRIMARY KEY (id); + + +-- +-- Name: user_visits_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY user_visits + ADD CONSTRAINT user_visits_pkey PRIMARY KEY (id); + + +-- +-- Name: users_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY users + ADD CONSTRAINT users_pkey PRIMARY KEY (id); + + +-- +-- Name: versions_pkey; Type: CONSTRAINT; Schema: backup; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY versions + ADD CONSTRAINT versions_pkey PRIMARY KEY (id); + + +SET search_path = public, pg_catalog; + -- -- Name: actions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -1723,6 +3337,430 @@ ALTER TABLE ONLY versions ADD CONSTRAINT versions_pkey PRIMARY KEY (id); +SET search_path = backup, pg_catalog; + +-- +-- Name: cat_featured_threads; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX cat_featured_threads ON category_featured_topics USING btree (category_id, topic_id); + + +-- +-- Name: idx_search_thread; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX idx_search_thread ON topics USING gin (to_tsvector('english'::regconfig, (title)::text)); + + +-- +-- Name: idx_search_user; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX idx_search_user ON users USING gin (to_tsvector('english'::regconfig, (username)::text)); + + +-- +-- Name: idx_unique_actions; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX idx_unique_actions ON post_actions USING btree (user_id, post_action_type_id, post_id) WHERE (deleted_at IS NULL); + + +-- +-- Name: idx_unique_rows; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX idx_unique_rows ON user_actions USING btree (action_type, user_id, target_topic_id, target_post_id, acting_user_id); + + +-- +-- Name: incoming_index; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX incoming_index ON incoming_links USING btree (topic_id, post_number); + + +-- +-- Name: index_actions_on_acting_user_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_actions_on_acting_user_id ON user_actions USING btree (acting_user_id); + + +-- +-- Name: index_actions_on_user_id_and_action_type; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_actions_on_user_id_and_action_type ON user_actions USING btree (user_id, action_type); + + +-- +-- Name: index_categories_on_forum_thread_count; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_categories_on_forum_thread_count ON categories USING btree (topic_count); + + +-- +-- Name: index_categories_on_name; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_categories_on_name ON categories USING btree (name); + + +-- +-- Name: index_category_featured_users_on_category_id_and_user_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_category_featured_users_on_category_id_and_user_id ON category_featured_users USING btree (category_id, user_id); + + +-- +-- Name: index_draft_sequences_on_user_id_and_draft_key; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_draft_sequences_on_user_id_and_draft_key ON draft_sequences USING btree (user_id, draft_key); + + +-- +-- Name: index_drafts_on_user_id_and_draft_key; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_drafts_on_user_id_and_draft_key ON drafts USING btree (user_id, draft_key); + + +-- +-- Name: index_email_logs_on_created_at; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_email_logs_on_created_at ON email_logs USING btree (created_at DESC); + + +-- +-- Name: index_email_logs_on_user_id_and_created_at; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_email_logs_on_user_id_and_created_at ON email_logs USING btree (user_id, created_at DESC); + + +-- +-- Name: index_email_tokens_on_token; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_email_tokens_on_token ON email_tokens USING btree (token); + + +-- +-- Name: index_facebook_user_infos_on_facebook_user_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_facebook_user_infos_on_facebook_user_id ON facebook_user_infos USING btree (facebook_user_id); + + +-- +-- Name: index_facebook_user_infos_on_user_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_facebook_user_infos_on_user_id ON facebook_user_infos USING btree (user_id); + + +-- +-- Name: index_forum_thread_link_clicks_on_forum_thread_link_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_forum_thread_link_clicks_on_forum_thread_link_id ON topic_link_clicks USING btree (topic_link_id); + + +-- +-- Name: index_forum_thread_links_on_forum_thread_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_forum_thread_links_on_forum_thread_id ON topic_links USING btree (topic_id); + + +-- +-- Name: index_forum_thread_links_on_forum_thread_id_and_post_id_and_url; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_forum_thread_links_on_forum_thread_id_and_post_id_and_url ON topic_links USING btree (topic_id, post_id, url); + + +-- +-- Name: index_forum_thread_users_on_forum_thread_id_and_user_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_forum_thread_users_on_forum_thread_id_and_user_id ON topic_users USING btree (topic_id, user_id); + + +-- +-- Name: index_forum_threads_on_bumped_at; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_forum_threads_on_bumped_at ON topics USING btree (bumped_at DESC); + + +-- +-- Name: index_forum_threads_on_category_id_and_sub_tag_and_bumped_at; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_forum_threads_on_category_id_and_sub_tag_and_bumped_at ON topics USING btree (category_id, sub_tag, bumped_at); + + +-- +-- Name: index_invites_on_email_and_invited_by_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_invites_on_email_and_invited_by_id ON invites USING btree (email, invited_by_id); + + +-- +-- Name: index_invites_on_invite_key; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_invites_on_invite_key ON invites USING btree (invite_key); + + +-- +-- Name: index_notifications_on_post_action_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_notifications_on_post_action_id ON notifications USING btree (post_action_id); + + +-- +-- Name: index_notifications_on_user_id_and_created_at; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_notifications_on_user_id_and_created_at ON notifications USING btree (user_id, created_at); + + +-- +-- Name: index_onebox_renders_on_url; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_onebox_renders_on_url ON onebox_renders USING btree (url); + + +-- +-- Name: index_post_actions_on_post_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_post_actions_on_post_id ON post_actions USING btree (post_id); + + +-- +-- Name: index_post_onebox_renders_on_post_id_and_onebox_render_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_post_onebox_renders_on_post_id_and_onebox_render_id ON post_onebox_renders USING btree (post_id, onebox_render_id); + + +-- +-- Name: index_post_replies_on_post_id_and_reply_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_post_replies_on_post_id_and_reply_id ON post_replies USING btree (post_id, reply_id); + + +-- +-- Name: index_posts_on_reply_to_post_number; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_posts_on_reply_to_post_number ON posts USING btree (reply_to_post_number); + + +-- +-- Name: index_posts_on_topic_id_and_post_number; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_posts_on_topic_id_and_post_number ON posts USING btree (topic_id, post_number); + + +-- +-- Name: index_site_customizations_on_key; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_site_customizations_on_key ON site_customizations USING btree (key); + + +-- +-- Name: index_topic_allowed_users_on_topic_id_and_user_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_topic_allowed_users_on_topic_id_and_user_id ON topic_allowed_users USING btree (topic_id, user_id); + + +-- +-- Name: index_topic_allowed_users_on_user_id_and_topic_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_topic_allowed_users_on_user_id_and_topic_id ON topic_allowed_users USING btree (user_id, topic_id); + + +-- +-- Name: index_topic_invites_on_invite_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_topic_invites_on_invite_id ON topic_invites USING btree (invite_id); + + +-- +-- Name: index_topic_invites_on_topic_id_and_invite_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_topic_invites_on_topic_id_and_invite_id ON topic_invites USING btree (topic_id, invite_id); + + +-- +-- Name: index_twitter_user_infos_on_twitter_user_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_twitter_user_infos_on_twitter_user_id ON twitter_user_infos USING btree (twitter_user_id); + + +-- +-- Name: index_twitter_user_infos_on_user_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_twitter_user_infos_on_user_id ON twitter_user_infos USING btree (user_id); + + +-- +-- Name: index_uploads_on_forum_thread_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_uploads_on_forum_thread_id ON uploads USING btree (topic_id); + + +-- +-- Name: index_uploads_on_user_id; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_uploads_on_user_id ON uploads USING btree (user_id); + + +-- +-- Name: index_user_open_ids_on_url; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_user_open_ids_on_url ON user_open_ids USING btree (url); + + +-- +-- Name: index_user_visits_on_user_id_and_visited_at; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_user_visits_on_user_id_and_visited_at ON user_visits USING btree (user_id, visited_at); + + +-- +-- Name: index_users_on_auth_token; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_users_on_auth_token ON users USING btree (auth_token); + + +-- +-- Name: index_users_on_email; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_users_on_email ON users USING btree (email); + + +-- +-- Name: index_users_on_last_posted_at; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_users_on_last_posted_at ON users USING btree (last_posted_at); + + +-- +-- Name: index_users_on_username; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_users_on_username ON users USING btree (username); + + +-- +-- Name: index_users_on_username_lower; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_users_on_username_lower ON users USING btree (username_lower); + + +-- +-- Name: index_versions_on_created_at; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_versions_on_created_at ON versions USING btree (created_at); + + +-- +-- Name: index_versions_on_number; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_versions_on_number ON versions USING btree (number); + + +-- +-- Name: index_versions_on_tag; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_versions_on_tag ON versions USING btree (tag); + + +-- +-- Name: index_versions_on_user_id_and_user_type; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_versions_on_user_id_and_user_type ON versions USING btree (user_id, user_type); + + +-- +-- Name: index_versions_on_user_name; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_versions_on_user_name ON versions USING btree (user_name); + + +-- +-- Name: index_versions_on_versioned_id_and_versioned_type; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_versions_on_versioned_id_and_versioned_type ON versions USING btree (versioned_id, versioned_type); + + +-- +-- Name: index_views_on_parent_id_and_parent_type; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX index_views_on_parent_id_and_parent_type ON views USING btree (parent_id, parent_type); + + +-- +-- Name: post_timings_summary; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE INDEX post_timings_summary ON post_timings USING btree (topic_id, post_number); + + +-- +-- Name: post_timings_unique; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX post_timings_unique ON post_timings USING btree (topic_id, post_number, user_id); + + +-- +-- Name: unique_views; Type: INDEX; Schema: backup; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX unique_views ON views USING btree (parent_id, parent_type, ip, viewed_at); + + +SET search_path = public, pg_catalog; + -- -- Name: cat_featured_threads; Type: INDEX; Schema: public; Owner: -; Tablespace: -- diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb index ecb1f3bc76d..c99243b4276 100644 --- a/spec/models/topic_spec.rb +++ b/spec/models/topic_spec.rb @@ -109,6 +109,41 @@ describe Topic do end + context 'html in title' do + let(:topic) { Fabricate(:topic, title: " is my topic title" ) } + + it "should escape the HTML" do + topic.title.should == "is my topic title" + end + + end + + context 'fancy title' do + let(:topic) { Fabricate(:topic, title: "\"this topic\" -- has ``fancy stuff''" ) } + + context 'title_fancy_entities disabled' do + before do + SiteSetting.stubs(:title_fancy_entities).returns(false) + end + + it "doesn't change the title to add entities" do + topic.fancy_title.should == topic.title + end + end + + context 'title_fancy_entities enabled' do + before do + SiteSetting.stubs(:title_fancy_entities).returns(true) + end + + it "converts the title to have fancy entities" do + topic.fancy_title.should == "“this topic” – has “fancy stuff”" + end + end + + + end + context 'message bus' do it 'calls the message bus observer after create' do