[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
calendar-0.1 (patch): very basic calendar
From: |
boud |
Subject: |
calendar-0.1 (patch): very basic calendar |
Date: |
Wed, 14 Feb 2007 01:44:48 +0100 (CET) |
hi samizdat-devel,
Here is version 0.1 of a calendar patch.
DESCRIPTION:
The admin publishes a message which is intended to become the calendar
superfocus and puts its ID in the site config file. Any logged in member
looking at a message X sees an additional prompt _('Put this in the
calendar') below the Add another focus prompt. S/he clicks, chooses a
date, and submits.
If the date is valid, then a new message Y is created with a title
corresponding to that date in %Y-%m-%d format if no such message
already exists, message X is joined (relation created) to that date
message (converting it into a focus), and the date message Y is
joined (relation created) to the calendar message, which becomes
a superfocus (if this didn't happen before).
The title + link of message X is written into date message Y (in text/textile
format).
Displaying of the calendar superfocus is made an exception from that
of normal focuses. The list of related resources (i.e. date messages
like Y) are sorted by their titles (not their last modified dates), in
increasing numerical (chronological) order starting from "today", so
that the soonest days with events are the most obvious. Older dates
are not displayed under the calendar superfocus, but remain related
to it, and the messages which had been related to them retain these
relations.
The dates are created wikified, i.e. as "open for editing", so users
have the liberty of e.g. modifying the content of events that
have already past.
FILES:
config.yaml - one line: calendar: <ID-of-calendar-message-superfocus>
template.rb - html stuff
cgi-bin/resource.rb - create foci, relations, display calendar superfocus
message.rb - one line - update call to focus_fields method
DISCUSSION:
DEEP:
My guess is that a more elegant and in the long term more powerful
technical solution would be to dig more deeply into the rdf core
of samizdat :), e.g. at least link message to dates via a dublin core
property, so that they can be more easily/systematically communicated
around the web:
http://purl.org/dc/terms/dcq.rdf
<rdf:Property rdf:about="http://purl.org/dc/terms/temporal">
However, what i've done seems to work and i've learn a bit more ruby.
i'm sure some bits can be written much more compactly while providing
equivalent functionality. Anyone feel free to propose a better version. :)
BELLS & WHISTLES:
i didn't do the "5 row 7 column" typical month - change to day -
change to year visual type calendar stuff, but i'm also not totally
convinced that people are likely to use them that much. The examples
i remember seem to be too separate from their associated cms or wiki -
my feeling is that by having a calendar which has essentially the same
look and feel as the news items, people might be more likely to use
them and integrate planning and publishing... Of course, i'm not against
the visual stuff, but i've spent enough time on this anyway and IMHO
it should be enough to be useful.
Any feedback would be welcome.
cheers
boud
--- lib/samizdat/engine/template.rb 2007-01-20 12:59:03.000000000 +0100
+++ /usr/lib/ruby/1.8/samizdat/engine/template.rb 2007-02-14
00:18:11.128912464 +0100
@@ -1,6 +1,6 @@
# Samizdat HTML templates
#
-# Copyright (c) 2002-2006 Dmitry Borodaenko <address@hidden>
+# Copyright (c) 2002-2007 Dmitry Borodaenko <address@hidden>
#
# This program is free software.
# You can distribute/modify this program under the terms of
@@ -32,6 +32,31 @@
# document navigation links (made, start, next, ...)
attr_accessor :link
+
+ # some calendar constants
+ days_s = [ [0, _("SELECT DAY")] ]
+ for i in 1..31
+ days_s += [ [i, i.to_s] ]
+ end
+ Days_s = days_s
+
+ months_s = []
+ Months_inv = Date::MONTHS.invert
+ for i in 1..12
+# months_s += [ [i, Months_inv[i] ] ] # needs l10n
+ months_s += [ [i, i.to_s ] ]
+ end
+ Months_s = months_s
+
+ years_s = []
+ thisyear= Time.now.year
+
+ for i in 0..3 # default 4 years' calendar
+ years_s += [ [thisyear+i, (thisyear+i).to_s] ]
+ end
+ Years_s = years_s
+
+
# HTML header, title, and style settings
#
def head(title='', options={})
@@ -276,6 +301,14 @@
fbox += box(nil,
'<p><a title="'+_('Click to relate this resource to another focus')+%{"
href="resource.rb?id=#{related.id}&focus=select">}+_('Add another focus')+'</a></p>'
)
+ if config['calendar']
+ fbox += box(nil,
+ '<p><a title="'+
+ _('Click to put this resource in the calendar')+
+
%{"href="resource.rb?id=#{related.id}&focus=select&calendar=start">}+
+ _('Put this in the calendar')+ '</a></p>'
+ )
+ end # if config['calendar']
end
fbox
end
@@ -291,7 +324,18 @@
# form fields for vote on focus rating
#
- def focus_fields(id, focus, advanced=('advanced' == @session.cookie('ui')))
+ def focus_fields(id, focus, calendar, advanced=('advanced' ==
@session.cookie('ui')))
+ if 'start' == calendar
+ fields =
+ [ [:hidden, 'id', id],
+ [:label, 'calendar_date', _('Select the date at which this event is
planned for')],
+ [:select, 'cal_year', Years_s, Time.now.year],
+ [:select, 'cal_month', Months_s, Time.now.month],
+ [:select, 'cal_day', Days_s, 0], # default day is invalid day
+ [:hidden, 'rating', 1],
+ [:hidden, 'calendar', 'send'],
+ ]
+ else
focuses = Focus.collect_focuses {|f,|
[f, Resource.new(@session, f).render(:title)]
}
@@ -318,6 +362,7 @@
else
fields.push([:hidden, 'rating', 1])
end
+ end #end if calendar
end
# transform date to a standard string representation
@@ -498,10 +543,18 @@
else
message_content(translation, mode)
end
+ html =
%{<div class="message" id="id#{message.id}">
#{title}<div class="info">#{info}</div>
<div class="content">#{content}</div>
</div>\n}
+ if message.current
+ current_message_hidden = rdf.get_property(message.current, 's::hidden')
+ end
+ if message.hidden or current_message_hidden
+ html = %{<div class="message-hidden">\n#{html}</div>\n}
+ end
+ html
end
# language selection
@@ -597,12 +650,21 @@
left = left.join if left.kind_of? Array
right = right.join if right.kind_of? Array
width = right ? ' style="width: 50%"' : ' colspan="2"'
+
+ if old[:hidden] or new[:hidden]
+ div_hide = %{<div class="message-hidden">}
+ else
+ div_hide = "<div>"
+ end
+
left and left = {:format => old[:format], :content => left,
:class => (right ? ' class="delete"' : '')}
right and right = {:format => new[:format], :content => right,
:class => ' class="add"'}
%{<tr>\n} + [left, right].compact.collect {|line|
-%{<td#{width}#{line[:class] if line[:content].size > 0}><div
class="content">#{MessageContent.render_cacheable(line[:content], line[:format])}#{' ' unless
line[:content].size > 0}</div></td>\n}
+# %{<td#{width}#{line[:class] if line[:content].size > 0}><div
class="content">#{MessageContent.render_cacheable(line[:content], line[:format])}#{' ' unless
line[:content].size > 0}</div></td>\n}
+ %{<td#{width}#{line[:class] if line[:content].size > 0}><div class="content">} +
+ div_hide + %{#{MessageContent.render_cacheable(line[:content], line[:format])}#{' ' unless line[:content].size > 0}</div></div></td>\n}
}.join + "</tr>\n"
}.join + %{</tbody></table>\n}
end
--- cgi-bin/resource.rb 2007-01-08 03:10:18.000000000 +0100
+++ /usr/share/samizdat/cgi-bin/resource.rb 2007-02-14 00:28:49.116923544
+0100
@@ -2,7 +2,7 @@
#
# Samizdat resource display
#
-# Copyright (c) 2002-2006 Dmitry Borodaenko <address@hidden>
+# Copyright (c) 2002-2007 Dmitry Borodaenko <address@hidden>
#
# This program is free software.
# You can distribute/modify this program under the terms of
@@ -11,6 +11,7 @@
# vim: et sw=2 sts=2 ts=8 tw=0
require 'samizdat/engine'
+#require 'date'
# messages that are related to this focus
#
@@ -31,6 +32,25 @@
ORDER BY ?date DESC}, limit_page, limit_page * skip
).collect {|m,| m } # unwrap DBI::Row
end
+
+ if config['calendar'] and id.to_i == config['calendar']
+ # TODO rewrite this using .collect instead of .each
+ list_titles = []
+ today=Time.now.strftime("%Y-%m-%d")
+ list.each do |msg|
+ m_title, = rdf.select_one %{
+SELECT ?title
+WHERE (dc::title #{msg} ?title)}
+ if m_title >= today # ignore old events
+ list_titles += [[m_title, msg]] # add a pair
+ end
+ end
+ list_titles.sort! { |a,b| a[0] <=> b[0] }
+
+
+ list = list_titles.collect { |pair| pair[1] }
+
+ end
list.collect {|msg| yield msg }
end
@@ -59,7 +79,7 @@
end
end
-request do |session|
+each_request do |session|
# RewriteRule ^(/samizdat-base)/([0-9]+)$ $1/resource.rb?id=$2 [PT]
#
@@ -81,26 +101,122 @@
body = session.has_key?('skip')? r[:messages] : r.to_s
# vote on focus rating
- if session.has_key?('focus') or session.has_key?('focus_id')
+ if session.has_key?('focus') or session.has_key?('focus_id') or
+ (session.has_key?('calendar') and config['calendar'])
session.access('vote') or raise AuthError,
sprintf(_('Your current access level (%s) does not allow to vote'),
_(session.role))
- focus, focus_id, rating = session.params %w[focus focus_id rating]
+ # focus, focus_id, rating = session.params %w[focus focus_id rating]
+ focus, focus_id, rating, calendar, cal_year, cal_month, cal_day, creator, format, description =
+ session.params %w[focus focus_id rating calendar cal_year cal_month cal_day creator format description]
+
focus = nil if 'select' == focus
+
+ # julian date if date is valid, otherwise set to nil
+ jd= Date::valid_civil?(cal_year.to_i, cal_month.to_i, cal_day.to_i)
+
+ if 'send' == calendar and config['calendar']
+ if jd
+ dd = cal_day.to_s
+ dd = "0" + dd if cal_day.to_i < 10
+ mm = cal_month.to_s
+ mm = "0" + mm if cal_month.to_i < 10
+
+ focus_title= cal_year.to_s + "-" + mm + "-" + dd
+
+ # find out if a message for this date already exists
+ db.transaction do |db|
+ focus_id, = db.select_one 'SELECT id FROM Message
+ WHERE title = ? ', focus_title
+ end
+ if focus_id
+ # do nothing
+ else
+ # calendar focus is created as open for editing by members
+ if config['locale']['languages'][0]
+ lang= config['locale']['languages'][0]
+ else
+ lang= NULL
+ end
+
+ message = PublishMessage.new(session)
+
+ db.transaction do |db|
+ focus_id, = rdf.assert( %{
+INSERT ?msg
+WHERE (dc::creator ?msg :creator)
+ (dc::title ?msg :title)
+ (dc::language ?msg :language)
+ (dc::format ?msg :format)
+ (dc::description ?msg :desc)
+ (s::content ?msg :content)
+ (s::openForAll ?msg :open)
+ (s::inReplyTo ?msg :parent)
+},
+ {
+ :creator => creator,
+ :title => focus_title,
+ :language => lang,
+ :format => 'text/textile',
+ :desc => description,
+ :content => ' ',
+ :open => true,
+ :parent => nil
+ } )
+ end # db.transaction
+ end # if focus_id
+
+ # add link (editing is open, so this is not hardwiring)
+ db.transaction do |db|
+ f_content, = db.select_one 'SELECT content FROM Message
+ WHERE id = ? ', focus_id
+ m_title, = db.select_one 'SELECT title FROM Message
+ WHERE id = ? ', id
+ db.do 'UPDATE Message SET content = ?
+ WHERE id = ? ',
+ f_content + %{\n"} + m_title + %{":/} + id.to_s + %{\n},
+ focus_id
+ db.do 'UPDATE Message SET format = ? WHERE id = ? ',
+ "text/textile", focus_id
+ end # db.transaction do |db|
+
+ calendar_superfocus = config['calendar']
+ else # invalid date - try again
+ calendar = 'start'
+ end
+ end # if 'send' == calendar
+
+
if focus_id = Resource.validate_id(focus_id)
# manual entry overrides selection
focus = focus_id
end
+ focus_id = focus # needed for Resource.new
+# old_id = id # needed for session.redirect
focus = Focus.new(session, focus, resource) if focus
if focus.kind_of?(Focus) and rating # commit vote
# rating is validated by Focus#rating=
db.transaction {|db| focus.rating = rating }
- session.redirect(id.to_s)
+
+ if Resource.validate_id(calendar_superfocus)
+ focus_r = Resource.new(session, focus_id) # focus as Resource object
+ calendar_superfocus = Focus.new(session, calendar_superfocus, focus_r)
+ if calendar_superfocus.kind_of?(Focus)
+ db.transaction {|db| calendar_superfocus.rating = rating }
+ end
+ session.redirect(focus_id.to_s) # otherwise session may be confused
+ else
+ session.redirect(id.to_s)
+ end
+
+
+# session.redirect(old_id.to_s)
else # display vote form
vote_form = t.form( 'resource.rb',
- *t.focus_fields(id, focus) +
+# *t.focus_fields(id, focus) +
+ *t.focus_fields(id, focus, calendar) +
[ [:br], [:submit, nil, _('Submit')] ]
)
next t.page(_('Vote') + ': ' + r[:head],
--- lib/samizdat/engine/message.rb 2007-01-20 13:02:29.000000000 +0100
+++ /usr/lib/ruby/1.8/samizdat/engine/message.rb 2007-02-11
01:40:22.000000000 +0100
@@ -1,6 +1,6 @@
# Samizdat message handling
#
-# Copyright (c) 2002-2006 Dmitry Borodaenko <address@hidden>
+# Copyright (c) 2002-2007 Dmitry Borodaenko <address@hidden>
#
# This program is free software.
# You can distribute/modify this program under the terms of
@@ -542,7 +544,8 @@
]
# select focus for new message
- form.push(*t.focus_fields(nil, nil, false)) if
+# form.push(*t.focus_fields(nil, nil, false)) if
+ form.push(*t.focus_fields(nil, nil, false, false)) if
@session.access('vote') and @parent.nil?
# advanced parameters
--- data/samizdat/config.yaml 2006-11-28 17:57:47.000000000 +0100
+++ /etc/samizdat/sites/config.yaml 2007-02-14 00:08:16.498310056 +0100
+
+# Basic Calendar
+#
+# First publish a message by hand which you wish to become the
+# calendar focus. Put its ID here and then stop/start samizdat.
+# Members should then be able to add messages to the calendar.
+#
+# e.g. if message with ID 9999 is the calendar message (focus), then
+# put:
+#
+# calendar: 9999
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- calendar-0.1 (patch): very basic calendar,
boud <=