manage bookmarks, bugfixes
[smr.git] / gui / lib / smr / blog.rb
blob7a8baf7628510bd39af869280a0a085d45f3fb31
2 # This file is part of SMR.
4 # SMR is free software: you can redistribute it and/or modify it under the
5 # terms of the GNU General Public License as published by the Free Software
6 # Foundation, either version 3 of the License, or (at your option) any later
7 # version.
9 # SMR is distributed in the hope that it will be useful, but WITHOUT ANY
10 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License along with
14 # SMR.  If not, see <http://www.gnu.org/licenses/>.
16 require 'link'
19 # Collection of most recent SmrBlogItem objects of given User.id.
21 # As of now all items from previous 30 days are collected.
22 class Smr::Blog
24     # Optional pattern String used to match Smr::BlogItems.
25     attr_reader :pattern
27     ##
28     # Collects BlogItem objects relevant at given :date. The given User
29     # should be authenticated!
30     #
31     # By default all BlogItem objects within the 30 days preceeding :date are
32     # shown.
33     #
34     # If a :pattern String is given, it will be matched against all models
35     # appearing in the blog. Time constraints are ignord when a :pattern is
36     # given.
37     #
38     def initialize(user, date=Time.now,
39           options={
40               :pattern=>false
41           }
42         )
43         raise ':user must be of User' unless user.is_a?(User)
44         raise ':date must be of Time' unless date.is_a?(Time)
45         @collection = Array.new
46         @pattern = (options[:pattern].blank? ? nil : options[:pattern])
48         start_date = (date - 30.days).to_i
49         end_date = date.to_i
51         # find Comment records
52         q = if pattern?
53           Comment.where(:id_user=>user.id).ransack({:title_or_comment_cont=>@pattern})
54         else
55           Comment.where(:id_user=>user.id).where( :date_recorded=>(start_date..end_date) ).ransack
56         end
57         q.result.to_a.each do |c|
58             @collection << Smr::BlogItem.new(
59               c.time_recorded, c.class, c.title, c.comment,
60               :link=>Smr::Link.new(:comment_edit, c.id)
61             )
62         end
64         # find Order commentary
65         q = if pattern?
66          Order.joins('LEFT JOIN position p ON p.id = order.id_position')
67               .joins('LEFT JOIN portfolio po ON po.id = p.id_portfolio')
68               .where('po.id_user=%i' % user.id).ransack({:ransackcolumns_cont=>@pattern})
69         else
70           Order.where.not(:comment=>'')
71               .where( :date_issued=>(start_date..end_date) )
72               .joins('LEFT JOIN position p ON p.id = order.id_position')
73               .joins('LEFT JOIN portfolio po ON po.id = p.id_portfolio')
74               .where('po.id_user=%i' % user.id).ransack
75         end
76         q.result.to_a.each do |o|
77           title = if o.Position.is_cash_position? and o.PositionRevision.first
78                      o.PositionRevision.first.describe_type
79                   else '%s %s' % [o.type.upcase, o.Security.to_s] end
80           @collection << Smr::BlogItem.new(
81               o.time_issued, o.class, title, o.comment,
82               :link=>Smr::Link.new(:order, o.id)
83           )
84         end
86         # find Quoterecord commentary
87         q = if pattern?
88           Quoterecord.where(:id_user=>user.id).ransack({:ransackcolumns_cont=>@pattern})
89         else
90           Quoterecord.where(:id_user=>user.id)
91               .where( :date_created=>(start_date..end_date) )
92               .where.not(:comment=>'').ransack
93         end
94         q.result.to_a.each do |qr|
95               @collection << Smr::BlogItem.new(qr.time_created, qr.class, qr.to_s, qr.comment)
96         end
98         # find Document commentary
99         q = if pattern?
100           Document.where(:id_user=>user.id).ransack({:comment_cont=>@pattern})
101         else
102           Document.where(:id_user=>user.id)
103               .where( :date_upload=>(start_date..end_date) )
104               .where.not(:comment=>'').ransack
105         end
106         q.result.to_a.each do |d|
107             @collection << Smr::BlogItem.new(d.time_upload, d.class, 'Commented Upload', d.comment)
108         end
110         # find Workdesk entries
111         q = if pattern?
112           Workdesk.where(:id_user=>user.id).ransack({:ransackcolumns_cont=>@pattern})
113         else
114           Workdesk.where(:id_user=>user.id)
115               .where( :date_added=>(start_date..end_date) )
116               .where.not(:comment=>'').ransack
117         end
118         q.result.to_a.each do |wi|
119               @collection << Smr::BlogItem.new(wi.time_added, wi.class, wi.to_s, wi.comment)
120         end
122         @collection.sort_by!{|i| i.date}.reverse!
123         true
124     end
126     ##
127     # Tells whether this Blog actually performed a pattern match.
128     def pattern?
129         not @pattern.blank?
130     end
132     ##
133     # loops over Smr::BlogItem collection
134     def each(&block)
135         @collection.each(&block)
136     end
138     ##
139     # number of Smr::BlogItem objects the blog has available for viewing.
140     def count
141         @collection.count
142     end
144     ##
145     # tell whether there is anything in the collection
146     def empty?
147         @collection.empty?
148     end
150   
151   
153 # Represents a single Blog item, ie. for rendering in a view.
154 class Smr::BlogItem
156     # reader for data field
157     attr_reader :date
158     attr_reader :type
159     attr_reader :title
160     attr_reader :body
161     attr_reader :link
163     ##
164     # - optionally pass a Smr::Link as :link to reference this BlogItem to
165     #   something else
166     def initialize(date, type, title, body, options={})
167         options.reverse_merge!({
168           :link=>false
169         })
170         raise ':date must be of type Time' unless date.is_a? Time
171         raise ':link must be of Smr::Link' if options[:link] and not options[:link].is_a? Smr::Link
172         @date=date; @type=type.to_s; @title=title; @body=body;
173         @link=options[:link]
174     end
176     ##
177     # Identifier of this item. Unique hopefully and a String.
178     def id
179         ::Digest::MD5.hexdigest title + date.to_i.to_s
180     end