Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 15
- Log:
Attempt to update Typo to a Typo SVN HEAD release from around the
time the prototype installation was set up on the RISC OS Open Limited
web site. Timestamps place this at 04-Jul so a revision from 05-Jul or
earlier was pulled and copied over the 2.6.0 tarball stable code.
- Author:
- adh
- Date:
- Sat Jul 22 23:27:35 +0100 2006
- Size:
- 6241 Bytes
1 | require 'uri' |
2 | require 'net/http' |
3 | |
4 | class Article < Content |
5 | include TypoGuid |
6 | |
7 | content_fields :body, :extended |
8 | |
9 | has_many :pings, :dependent => true, :order => "created_at ASC" |
10 | has_many :comments, :dependent => true, :order => "created_at ASC" |
11 | has_many :trackbacks, :dependent => true, :order => "created_at ASC" |
12 | has_many :resources, :order => "created_at DESC", |
13 | :class_name => "Resource", :foreign_key => 'article_id' |
14 | has_and_belongs_to_many :categories, :foreign_key => 'article_id' |
15 | has_and_belongs_to_many :tags, :foreign_key => 'article_id' |
16 | belongs_to :user |
17 | has_many :triggers, :as => :pending_item |
18 | |
19 | after_destroy :fix_resources |
20 | |
21 | def stripped_title |
22 | self.title.gsub(/<[^>]*>/,'').to_url |
23 | end |
24 | |
25 | def location(anchor=nil, only_path=true) |
26 | blog.article_url(self, only_path, anchor) |
27 | end |
28 | |
29 | def html_urls |
30 | urls = Array.new |
31 | (body_html.to_s + extended_html.to_s).gsub(/<a [^>]*>/) do |tag| |
32 | if(tag =~ /href="([^"]+)"/) |
33 | urls.push($1) |
34 | end |
35 | end |
36 | |
37 | urls |
38 | end |
39 | |
40 | def really_send_pings(serverurl = blog.server_url, articleurl = location(nil, false)) |
41 | return unless blog.send_outbound_pings |
42 | |
43 | weblogupdatesping_urls = blog.ping_urls.gsub(/ +/,'').split(/[\n\r]+/) |
44 | pingback_or_trackback_urls = self.html_urls |
45 | |
46 | ping_urls = weblogupdatesping_urls + pingback_or_trackback_urls |
47 | |
48 | ping_urls.uniq.each do |url| |
49 | begin |
50 | unless pings.collect { |p| p.url }.include?(url.strip) |
51 | ping = pings.build("url" => url) |
52 | |
53 | if weblogupdatesping_urls.include?(url) |
54 | ping.send_weblogupdatesping(serverurl, articleurl) |
55 | else pingback_or_trackback_urls.include?(url) |
56 | ping.send_pingback_or_trackback(articleurl) |
57 | end |
58 | end |
59 | rescue |
60 | # in case the remote server doesn't respond or gives an error, |
61 | # we should throw an xmlrpc error here. |
62 | end |
63 | end |
64 | end |
65 | |
66 | def send_pings |
67 | state.send_pings(self) |
68 | end |
69 | |
70 | def next |
71 | Article.find(:first, :conditions => ['published_at > ?', published_at], |
72 | :order => 'published_at asc') |
73 | end |
74 | |
75 | def previous |
76 | Article.find(:first, :conditions => ['published_at < ?', published_at], |
77 | :order => 'published_at desc') |
78 | end |
79 | |
80 | # Count articles on a certain date |
81 | def self.count_by_date(year, month = nil, day = nil, limit = nil) |
82 | from, to = self.time_delta(year, month, day) |
83 | Article.count(["published_at BETWEEN ? AND ? AND published = ?", |
84 | from, to, true]) |
85 | end |
86 | |
87 | # Find all articles on a certain date |
88 | def self.find_all_by_date(year, month = nil, day = nil) |
89 | from, to = self.time_delta(year, month, day) |
90 | Article.find_published(:all, :conditions => ["published_at BETWEEN ? AND ?", |
91 | from, to]) |
92 | end |
93 | |
94 | # Find one article on a certain date |
95 | |
96 | def self.find_by_date(year, month, day) |
97 | find_all_by_date(year, month, day).first |
98 | end |
99 | |
100 | # Finds one article which was posted on a certain date and matches the supplied dashed-title |
101 | def self.find_by_permalink(year, month, day, title) |
102 | from, to = self.time_delta(year, month, day) |
103 | find_published(:first, |
104 | :conditions => ['permalink = ? AND ' + |
105 | 'published_at BETWEEN ? AND ?', |
106 | title, from, to ]) |
107 | end |
108 | |
109 | # Fulltext searches the body of published articles |
110 | def self.search(query) |
111 | if !query.to_s.strip.empty? |
112 | tokens = query.split.collect {|c| "%#{c.downcase}%"} |
113 | find_published(:all, |
114 | :conditions => [(["(LOWER(body) LIKE ? OR LOWER(extended) LIKE ? OR LOWER(title) LIKE ?)"] * tokens.size).join(" AND "), *tokens.collect { |token| [token] * 3 }.flatten]) |
115 | else |
116 | [] |
117 | end |
118 | end |
119 | |
120 | def keywords_to_tags |
121 | Article.transaction do |
122 | tags.clear |
123 | keywords.to_s.scan(/((['"]).*?\2|\w+)/).collect do |x| |
124 | x.first.tr("\"'", '') |
125 | end.uniq.each do |tagword| |
126 | tags << Tag.get(tagword) |
127 | end |
128 | end |
129 | end |
130 | |
131 | def interested_users |
132 | User.find_boolean(:all, :notify_on_new_articles) |
133 | end |
134 | |
135 | def notify_user_via_email(controller, user) |
136 | if user.notify_via_email? |
137 | EmailNotify.send_article(controller, self, user) |
138 | end |
139 | end |
140 | |
141 | def notify_user_via_jabber(controller, user) |
142 | if user.notify_via_jabber? |
143 | JabberNotify.send_message(user, "New post", |
144 | "A new message was posted to #{blog.blog_name}", |
145 | content.body_html) |
146 | end |
147 | end |
148 | |
149 | protected |
150 | |
151 | before_create :set_defaults, :create_guid, :add_notifications |
152 | after_save :keywords_to_tags |
153 | |
154 | def correct_counts |
155 | self.comments_count = self.comments_count |
156 | self.trackbacks_count = self.trackbacks_count |
157 | end |
158 | |
159 | def set_defaults |
160 | if self.attributes.include?("permalink") and self.permalink.blank? |
161 | self.permalink = self.stripped_title |
162 | end |
163 | correct_counts |
164 | if blog && self.allow_comments.nil? |
165 | self.allow_comments = blog.default_allow_comments |
166 | end |
167 | |
168 | if blog && self.allow_pings.nil? |
169 | self.allow_pings = blog.default_allow_pings |
170 | end |
171 | true |
172 | end |
173 | |
174 | def add_notifications |
175 | # Grr, how do I do :conditions => 'notify_on_new_articles = true' when on MySQL boolean DB tables |
176 | # are integers, Postgres booleans are booleans, and sqlite is basically just a string? |
177 | # |
178 | # I'm punting for now and doing the test in Ruby. Feel free to rewrite. |
179 | |
180 | self.notify_users = User.find_boolean(:all, :notify_on_new_articles) |
181 | self.notify_users << self.user if (self.user.notify_watch_my_articles? rescue false) |
182 | self.notify_users.uniq! |
183 | end |
184 | |
185 | def default_text_filter_config_key |
186 | 'text_filter' |
187 | end |
188 | |
189 | def self.time_delta(year, month = nil, day = nil) |
190 | from = Time.mktime(year, month || 1, day || 1) |
191 | |
192 | to = from.next_year |
193 | to = from.next_month unless month.blank? |
194 | to = from + 1.day unless day.blank? |
195 | to = to - 1 # pull off 1 second so we don't overlap onto the next day |
196 | return [from, to] |
197 | end |
198 | |
199 | |
200 | validates_uniqueness_of :guid |
201 | validates_presence_of :title |
202 | |
203 | private |
204 | |
205 | def fix_resources |
206 | Resource.find(:all, :conditions => "article_id = #{id}").each do |fu| |
207 | fu.article_id = nil |
208 | fu.save |
209 | end |
210 | end |
211 | end |