diff --git a/app/models/advertisement.rb b/app/models/advertisement.rb new file mode 100644 index 000000000..03d41a3e1 --- /dev/null +++ b/app/models/advertisement.rb @@ -0,0 +1,66 @@ +class Advertisement < ActiveRecord::Base + validates_inclusion_of :ad_type, :in => %w(horizontal vertical) + has_many :hits, :class_name => "AdvertisementHit" + + def hit!(ip_addr) + hits.create(:ip_addr => ip_addr) + end + + def hit_sum(start_date, end_date) + hits.where(["created_at BETWEEN ? AND ?", start_date, end_date]).count + end + + def date_path + created_at.strftime("%Y%m%d") + end + + def image_url + "/images/ads-#{date_path}/#{file_name}" + end + + def image_path + "#{Rails.root}/public/#{image_url}" + end + + def file=(f) + if f.size > 0 + self.created_at ||= Time.now + self.file_name = f.original_filename + FileUtils.mkdir_p(File.dirname(image_path)) + + if f.local_path + FileUtils.cp(f.local_path, image_path) + else + File.open(image_path, 'wb') {|nf| nf.write(f.read)} + end + + File.chmod(0644, image_path) + + image_size = ImageSize.new(File.open(image_path, "rb")) + self.width = image_size.get_width + self.height = image_size.get_height + end + end + + def preview_width + if width > 200 || height > 200 + if width < height + ratio = 200.0 / height + return (width * ratio).to_i + else + return 200 + end + end + end + + def preview_height + if width > 200 || height > 200 + if height < width + ratio = 200.0 / width + return (height * ratio) + else + return 200 + end + end + end +end diff --git a/app/models/advertisement_hit.rb b/app/models/advertisement_hit.rb new file mode 100644 index 000000000..49988ce8f --- /dev/null +++ b/app/models/advertisement_hit.rb @@ -0,0 +1,3 @@ +class AdvertisementHit < ActiveRecord::Base + belongs_to :advertisement +end diff --git a/db/development_structure.sql b/db/development_structure.sql index c4aa790ef..780a59630 100644 --- a/db/development_structure.sql +++ b/db/development_structure.sql @@ -74,6 +74,75 @@ SET default_tablespace = ''; SET default_with_oids = false; +-- +-- Name: advertisement_hits; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE advertisement_hits ( + id integer NOT NULL, + advertisement_id integer NOT NULL, + ip_addr inet NOT NULL, + created_at timestamp without time zone, + updated_at timestamp without time zone +); + + +-- +-- Name: advertisement_hits_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE advertisement_hits_id_seq + START WITH 1 + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + + +-- +-- Name: advertisement_hits_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE advertisement_hits_id_seq OWNED BY advertisement_hits.id; + + +-- +-- Name: advertisements; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE advertisements ( + id integer NOT NULL, + referral_url text NOT NULL, + ad_type character varying(255) NOT NULL, + status character varying(255) NOT NULL, + hit_count integer DEFAULT 0 NOT NULL, + width integer NOT NULL, + height integer NOT NULL, + file_name character varying(255) NOT NULL, + created_at timestamp without time zone, + updated_at timestamp without time zone +); + + +-- +-- Name: advertisements_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE advertisements_id_seq + START WITH 1 + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + + +-- +-- Name: advertisements_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE advertisements_id_seq OWNED BY advertisements.id; + + -- -- Name: artist_urls; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -1051,6 +1120,20 @@ CREATE SEQUENCE wiki_pages_id_seq ALTER SEQUENCE wiki_pages_id_seq OWNED BY wiki_pages.id; +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE advertisement_hits ALTER COLUMN id SET DEFAULT nextval('advertisement_hits_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE advertisements ALTER COLUMN id SET DEFAULT nextval('advertisements_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -1247,6 +1330,22 @@ ALTER TABLE wiki_page_versions ALTER COLUMN id SET DEFAULT nextval('wiki_page_ve ALTER TABLE wiki_pages ALTER COLUMN id SET DEFAULT nextval('wiki_pages_id_seq'::regclass); +-- +-- Name: advertisement_hits_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY advertisement_hits + ADD CONSTRAINT advertisement_hits_pkey PRIMARY KEY (id); + + +-- +-- Name: advertisements_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY advertisements + ADD CONSTRAINT advertisements_pkey PRIMARY KEY (id); + + -- -- Name: artist_urls_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -1471,6 +1570,27 @@ ALTER TABLE ONLY wiki_pages ADD CONSTRAINT wiki_pages_pkey PRIMARY KEY (id); +-- +-- Name: index_advertisement_hits_on_advertisement_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_advertisement_hits_on_advertisement_id ON advertisement_hits USING btree (advertisement_id); + + +-- +-- Name: index_advertisement_hits_on_created_at; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_advertisement_hits_on_created_at ON advertisement_hits USING btree (created_at); + + +-- +-- Name: index_advertisements_on_ad_type; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_advertisements_on_ad_type ON advertisements USING btree (ad_type); + + -- -- Name: index_artist_urls_on_artist_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -1962,4 +2082,8 @@ INSERT INTO schema_migrations (version) VALUES ('20100215182234'); INSERT INTO schema_migrations (version) VALUES ('20100215213756'); -INSERT INTO schema_migrations (version) VALUES ('20100215223541'); \ No newline at end of file +INSERT INTO schema_migrations (version) VALUES ('20100215223541'); + +INSERT INTO schema_migrations (version) VALUES ('20100215224629'); + +INSERT INTO schema_migrations (version) VALUES ('20100215224635'); \ No newline at end of file diff --git a/db/migrate/20100215224629_create_advertisements.rb b/db/migrate/20100215224629_create_advertisements.rb new file mode 100644 index 000000000..4e0c31972 --- /dev/null +++ b/db/migrate/20100215224629_create_advertisements.rb @@ -0,0 +1,20 @@ +class CreateAdvertisements < ActiveRecord::Migration + def self.up + create_table :advertisements do |t| + t.column :referral_url, :text, :null => false + t.column :ad_type, :string, :null => false + t.column :status, :string, :null => false + t.column :hit_count, :integer, :null => false, :default => 0 + t.column :width, :integer, :null => false + t.column :height, :integer, :null => false + t.column :file_name, :string, :null => false + t.timestamps + end + + add_index :advertisements, :ad_type + end + + def self.down + drop_table :advertisements + end +end diff --git a/db/migrate/20100215224635_create_advertisement_hits.rb b/db/migrate/20100215224635_create_advertisement_hits.rb new file mode 100644 index 000000000..578dcc6c6 --- /dev/null +++ b/db/migrate/20100215224635_create_advertisement_hits.rb @@ -0,0 +1,16 @@ +class CreateAdvertisementHits < ActiveRecord::Migration + def self.up + create_table :advertisement_hits do |t| + t.column :advertisement_id, :integer, :null => false + t.column :ip_addr, "inet", :null => false + t.timestamps + end + + add_index :advertisement_hits, :advertisement_id + add_index :advertisement_hits, :created_at + end + + def self.down + drop_table :advertisement_hits + end +end diff --git a/test/factories/advertisement.rb b/test/factories/advertisement.rb new file mode 100644 index 000000000..a93d641b1 --- /dev/null +++ b/test/factories/advertisement.rb @@ -0,0 +1,8 @@ +Factory.define(:advertisement) do |f| + f.referral_url "http://google.com" + f.ad_type "vertical" + f.status "active" + f.width 728 + f.height 90 + f.file_name "google.gif" +end diff --git a/test/unit/advertisement_test.rb b/test/unit/advertisement_test.rb new file mode 100644 index 000000000..98b545da9 --- /dev/null +++ b/test/unit/advertisement_test.rb @@ -0,0 +1,16 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class AdvertisementTest < ActiveSupport::TestCase + context "An advertisement" do + should "create new hit records" do + ad = Factory.create(:advertisement) + assert_difference("AdvertisementHit.count") do + ad.hit!("0.0.0.0") + end + assert_equal("0.0.0.0", AdvertisementHit.first.ip_addr) + assert_equal(1, AdvertisementHit.first.advertisement_id) + assert_equal(1, ad.hit_sum(1.day.ago, 1.day.from_now)) + assert_equal(0, ad.hit_sum(2.days.ago, 1.day.ago)) + end + end +end